Skip to main content

Logging auto derivation

The problem

Often you see that in well modularized apps log messages are quite the same:

def method(args: Args) = for {
_ <- info"Started method with $args"
result <- foo(bar(args))
_ <- info"Ended method with $result"
} yield result

tofu.logging allows to automatically generate those lines about entering and exiting the method.

Autogenerated logging

You can automatically generate log messages stating when the method of some service has been entered and left.

import tofu.higherKind.derived.representableK
import derevo.derive
import tofu.logging.derivation._
import tofu.logging.Logging

@derive(representableK, loggingMid)
trait MyService[F[_]] {
def makeThis: F[Unit]

def makeThat(arg1: Int, arg2: String): F[Long]
}

object MyService extends Logging.Companion[MyService] {

def make[F[_] : Logging.Make : Monad]: MyService[F] = {
val core = new Impl[F]
core.attachLogs
}

class Impl[F[_] : Monad] extends MyService[F] {
//implementation
}
}

There is also an alternative — loggingMidErr which also logs any error happened during method execution.

How it works

The idea is based on the Mid concept. For every method def foo(bar: Bar): F[Baz] = impl it generates it's logging compartment, looking close to that:

def foo(bar: Bar): F[Baz] = debug"Entering foo with $bar" *> impl <* debug"Exiting foo with $baz"

Example

Check out the example here.