kadai.log.json.JsonMessage.scala Maven / Gradle / Ivy
The newest version!
package kadai.log
package json
import io.circe.{ Encoder, Json }
import scala.reflect.ClassTag
/**
* A Jsonable message. JsonLayout knows how to encode this payload.
*/
case class JsonMessage[A](value: A, json: List[(String, Json)]) extends LogMessage[A]
object JsonMessage {
val Default = "msg" // preserves backwards-compatibility
// need to fully qualify the JSON objects with a root qualifiers due to limitations in ElasticSearch indexing
final case class Qualified[A](fields: A => List[(String, Json)])
object Qualified extends LowPriorityImplicits {
def apply[A: Qualified]: Qualified[A] =
implicitly[Qualified[A]]
/**
* Override the default name used, uses an EncodeJson for the object, eg:
*
* { name: { (encoded json object } }
*/
def by[A](name: String)(implicit ev: Encoder[A]): Qualified[A] =
Qualified { a => List(name -> ev(a)) }
/**
* Control the list of top level names that are output and their individual representations. Eg:
*
* List("foo" -> fooJson, "bar" -> barJson, "baz" -> bazJson)
*
* will output:
*
* {
* foo: (encoded fooJson)
* bar: (encoded barJson)
* baz: (encoded bazJson)
* }
*/
def using[A](f: A => List[(String, Json)]): Qualified[A] =
Qualified(f)
}
}
sealed trait LowPriorityImplicits {
import JsonMessage.Qualified
implicit val QualifiedString: Qualified[String] =
Qualified.by(JsonMessage.Default)
implicit def QualifiedOption[A: Qualified]: Qualified[Option[A]] =
Qualified { _.fold(List[(String, Json)]())(Qualified[A].fields) }
implicit def QualifiedTuple2[A: Qualified, B: Qualified]: Qualified[(A, B)] =
new Qualified({ case (a, b) => Qualified[A].fields(a) ::: Qualified[B].fields(b) })
implicit def QualifiedTuple3[A: Qualified, B: Qualified, C: Qualified]: Qualified[(A, B, C)] =
new Qualified({ case (a, b, c) => Qualified[A].fields(a) ::: Qualified[B].fields(b) ::: Qualified[C].fields(c) })
implicit def QualifiedTuple4[A: Qualified, B: Qualified, C: Qualified, D: Qualified]: Qualified[(A, B, C, D)] =
new Qualified({ case (a, b, c, d) => Qualified[A].fields(a) ::: Qualified[B].fields(b) ::: Qualified[C].fields(c) ::: Qualified[D].fields(d) })
/** Fallback to simple class name. */
implicit def defaultQualified[A: ClassTag: Encoder]: JsonMessage.Qualified[A] =
Qualified.by[A](implicitly[ClassTag[A]].runtimeClass.getSimpleName)
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy