Skip to content

tersesystems/echopraxia-scala-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Example Echopraxia + Scala Project

This is a demonstration project that shows the Scala API for Echopraxia in use and how you can set up logging your way.

The code base is set up so that the domain models used all have a mapping that sets up the names and values used in logging

trait Logging extends LoggingBase with FutureValueTypes with HeterogeneousFieldSupport {
  implicit def futureToName[TV: ToValue: ClassTag]: ToName[Future[TV]] = _ => s"future[${classTag[TV].runtimeClass.getName}]"

  // everyone wants different things out of maps, so implementing that
  // is up to the individual application
  implicit def mapToValue[TV: ToValue]: ToValue[Map[String, TV]] = { v =>
    val value: Seq[Value.ObjectValue] = v.map { case (k, v) =>
      ToObjectValue("key" -> k, "value" -> v)
    }.toSeq
    ToArrayValue(value)
  }

  implicit val personToField: ToField[Person] = ToField(_ => "person", p => ToObjectValue("firstName" -> p.firstName, "lastName" -> p.lastName))

  implicit val titleToField: ToField[Title] = ToField(_ => "title", t => ToValue(t.raw).asString().abbreviateAfter(5))

  implicit val authorToField: ToField[Author] = ToField(_ => "author", a => ToValue(a.raw))

  implicit val categoryToField: ToField[Category] = ToField(_ => "category", c => ToValue(c.raw))

  implicit val currencyToField: ToField[Currency] = ToField(_ => "currency", currency => ToValue(currency.getCurrencyCode))

  // Says we want a toString of $8.95 in a message template for a price
  implicit val priceToField: ToField[Price] = ToField(_ => "price", price => ToObjectValue(price.currency, "amount" -> price.amount).withToStringValue(price.toString))

  implicit val bookToField: ToField[Book] = ToField(_ => "book", book => ToObjectValue(book.title, book.category, book.author, book.price))

  implicit val uuidToField: ToField[UUID] = ToField(_ => "uuid", uuid => ToValue(uuid.toString))
}

and structured logging can either be done with arguments alone, or using tuples:

val person1 = Person("Person1", "Last Name")
val person2 = Person("Person2", "Last Name")

// This uses the "personToField" mapping
logger.info("template shows {}", person1)
logger.info(person1)

// Can define custom mapping with tuples
logger.info("person1" -> person1, "person2" -> person2)

// Options work out of the box
val optPerson: Option[Person] = Option(person1)
logger.info("optPerson" -> optPerson)

// As does either
val eitherPerson: Either[Person, Person] = Left(person1)
logger.info("eitherPerson" -> eitherPerson)

// And so do lists
logger.info("people" -> Seq(person1, person2))

// And maps
logger.info("people" -> Map("person1" -> person1, "person2" -> person2))

// You can also use "withFields" to render JSON on every message (this will not show in line format)
logger.withFields(Seq[Field](book1, person1)).info("testing")

The logger itself is built on top of the core logger, so it's very simple to extend and customize:

And the technical details are in LoggerBase, essentially some type classes and implicit conversions for the logger.

About

Example project using echopraxia-plusscala

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages