kadai.log.json.JsonLogging.scala Maven / Gradle / Ivy
The newest version!
package kadai
package log
package json
import io.circe.{ Encoder, Json }
import io.circe.syntax._
/**
* Mixin if you want your class to be able to log structured objects in
* JSON format. You will need an argonaut.EncodeJson instance in implicit
* scope for the object you try and log.
*
* To get the instances, you need to also "import JsonLogging._"
*
* Note that you normally only need an implicit EncodeJson[A] for any type
* you want to log in order to encode the JSON representation that is logged.
* If you do not have an EncodeJson for the message object, then it will fall back
* to a String representation given by the Show[Foo] instance in scope.
*
* If you want fine-grained control of the output, and in particular want to
* control the top level names that are produced, please create a custom implicit
* JsonMessgae.Qualified[Foo] that turns your Foo into a List[JsonAssoc]. Care is
* needed though about the names as any clashes can lead to bugs in some log
* processing systems, such as https://github.com/elastic/elasticsearch/issues/12366
*
* See JsonLayout for details on how to configure log4j2 to support JSON output
*/
trait JsonLogging extends Logging
object JsonLogging extends JsonLoggingInstances
trait JsonLoggingInstances {
implicit def QualifiedEncodeJsonLogWriter[A: JsonMessage.Qualified]: LogWriter[A] =
new LogWriter[A] {
def apply(a: => A) = JsonMessage(a, JsonMessage.Qualified[A].fields(a))
}
implicit val EncodeInvalid: Encoder[Invalid] =
Encoder.instance {
case Invalid.Err(t) => Json.obj("error" -> EncodeThrowable(t))
case Invalid.Message(m) => Json.obj("error" -> m.asJson)
case Invalid.Composite(i) => Json.obj("errors" -> i.list.toList.asJson)
case Invalid.Zero => Json.obj()
}
implicit val EncodeThrowable: Encoder[Throwable] =
Encoder.instance { t =>
Json.obj(
"message" -> Option(t.getMessage).asJson,
"class" -> t.getClass.getName.asJson,
"stacktrace" -> t.getStackTrace.toVector.asJson,
"cause" -> Option(t.getCause).filter(_ != t).asJson
)
}
implicit val EncodeStackTraceElement: Encoder[StackTraceElement] =
Encoder[String].contramap { _.toString }
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy