Skip to content

Instantly share code, notes, and snippets.

@wsargent
Created December 11, 2022 20:35
Show Gist options
  • Save wsargent/3d789a043e4df5913c4b056fbbe237a9 to your computer and use it in GitHub Desktop.
Save wsargent/3d789a043e4df5913c4b056fbbe237a9 to your computer and use it in GitHub Desktop.
package com.example
import com.tersesystems.echopraxia.api.{Condition => JCondition, _}
import com.tersesystems.echopraxia.plusscala.{DefaultLoggerMethods, Logger}
import com.tersesystems.echopraxia.plusscala.api.{FieldBuilder, _}
import scala.jdk.FunctionConverters.enrichAsJavaFunction
case class Foo(name: String, age: Int)
case class Bar(name: String, age: Int)
trait FooBuilder extends FieldBuilder {
implicit val fooToObjectValue: ToValue[Foo] = { value =>
ToObjectValue(
keyValue("name", value.name),
keyValue("age", value.age)
)
}
implicit val barToObjectValue: ToValue[Bar] = { value =>
ToObjectValue(
keyValue("name", value.name),
keyValue("age", value.age)
)
}
def apply(fields: Field*): FieldBuilderResult = list(fields)
def apply[A1: ToField, A2: ToField](a1: A1, a2: A2): FieldBuilderResult = {
list(
implicitly[ToField[A1]].toField(a1),
implicitly[ToField[A2]].toField(a2)
)
}
trait ToField[T] {
def toField(t: T): Field
}
implicit def tupleToField[T: ToValue]: ToField[(String, T)] = (t1: (String, T)) => keyValue(t1._1 -> t1._2)
}
object FooBuilder extends FooBuilder
object Main {
val foo: Foo = Foo("foo", 1)
val bar: Bar = Bar("bar", 1)
private val logger = CustomLoggerFactory.getLogger
def main(args: Array[String]): Unit = {
logger.debug("using direct {} {}", fb => fb(fb.keyValue("foo" -> foo)))
logger.debug("using direct {} {}", _("foo" -> foo, "bar" -> bar))
logger.debug("using direct {} {}", "foo" -> foo, "bar" -> bar)
}
}
object CustomLoggerFactory {
private val FQCN: String = classOf[DefaultLoggerMethods[_]].getName
private val fieldBuilder: FooBuilder.type = FooBuilder
def getLogger(name: String): CustomLogger[FooBuilder.type] = {
val core = CoreLoggerFactory.getLogger(FQCN, name)
new CustomLogger(core, fieldBuilder)
}
def getLogger(clazz: Class[_]): CustomLogger[FooBuilder.type] = {
val core = CoreLoggerFactory.getLogger(FQCN, clazz.getName)
new CustomLogger(core, fieldBuilder)
}
def getLogger: CustomLogger[FooBuilder.type] = {
val core = CoreLoggerFactory.getLogger(FQCN, Caller.resolveClassName)
new CustomLogger(core, fieldBuilder)
}
}
class CustomLogger[FB <: FooBuilder](val core: CoreLogger, val fieldBuilder: FB) extends Logger[FB] with DefaultLoggerMethods[FB] {
override def name: String = core.getName
def debug[A1: fieldBuilder.ToField, A2: fieldBuilder.ToField](message: String, a1: A1, a2: A2): Unit = {
debug(message, fb => fb.list(
implicitly[fieldBuilder.ToField[A1]].toField(a1),
implicitly[fieldBuilder.ToField[A2]].toField(a2)
))
}
override def withCondition(condition: Condition): CustomLogger[FB] = {
condition match {
case Condition.always =>
this
case Condition.never =>
newLogger(newCoreLogger = core.withCondition(Condition.never.asJava), fieldBuilder)
case other =>
newLogger(newCoreLogger = core.withCondition(other.asJava))
}
}
override def withFields(f: FB => FieldBuilderResult): CustomLogger[FB] = {
newLogger(newCoreLogger = core.withFields(f.asJava, fieldBuilder))
}
override def withThreadContext: CustomLogger[FB] = {
newLogger(
newCoreLogger = core.withThreadContext(Utilities.threadContext())
)
}
override def withFieldBuilder[NEWFB <: FooBuilder](newFieldBuilder: NEWFB): CustomLogger[NEWFB] = {
newLogger(newFieldBuilder = newFieldBuilder)
}
@inline
private def newLogger[T <: FooBuilder](
newCoreLogger: CoreLogger = core,
newFieldBuilder: T = fieldBuilder
): CustomLogger[T] =
new CustomLogger[T](newCoreLogger, newFieldBuilder)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment