Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve support for structured logging (Json and possibly other formats) #643

Open
justcoon opened this issue Feb 2, 2023 · 5 comments
Open

Comments

@justcoon
Copy link
Contributor

justcoon commented Feb 2, 2023

in current implementation we have json logger
however there is not way have to do case class logging to json in structured way

there is also limitation in relation to ZIO#log* interface which only supports strings, zio core log annotation also supporting just string values
in relation to that currently it could be possible to do

object ConsoleJsonApp extends ZIOAppDefault {
  
  case class User(id: UUID, name: String) {
    def toJson = s"""{ "id": "$id", "name": "$name"}""".stripMargin
  }
  private val userLogAnnotation = LogAnnotation[User]("user", (_, i) => i, _.toJson)

  override val bootstrap: ZLayer[ZIOAppArgs, Any, Any] =
    Runtime.removeDefaultLoggers >>> consoleJson(
      LogFormat.default + LogFormat.annotation(LogAnnotation.TraceId) + LogFormat.annotation(
        userLogAnnotation
      )
    )

  private val users = List.fill(2)(UUID.randomUUID())

  override def run: ZIO[Scope, Any, ExitCode] =
    (for {
      traceId <- ZIO.succeed(UUID.randomUUID())
      _       <- ZIO.foreachPar(users) { uId =>
                   {
                     ZIO.logInfo("Starting operation") *>
                       ZIO.sleep(500.millis) *>
                       ZIO.logInfo("Stopping operation")
                   } @@ userLogAnnotation(User(uId, "aaa"))
                 } @@ LogAnnotation.TraceId(traceId)
      _       <- ZIO.logInfo("Done")
    } yield ExitCode.success)
}

however current json logger is not able recognise json string value

{"timestamp":"2023-01-26T23:39:19.142999+01:00","level":"INFO","thread":"zio-fiber-5","message":"Starting operation","trace_id":"01087a2a-a46c-4ff5-b4de-1c3c680b55a6","user":"{ \"id\": \"d894df3a-265f-4fc2-8abf-1808e52b5c4f\", \"name\": \"aaa\"}"}
{"timestamp":"2023-01-26T23:39:19.143007+01:00","level":"INFO","thread":"zio-fiber-6","message":"Starting operation","trace_id":"01087a2a-a46c-4ff5-b4de-1c3c680b55a6","user":"{ \"id\": \"3e9a023e-9f4c-4ebb-aa9d-e231c8e17400\", \"name\": \"aaa\"}"}

this could be fixed, but it is probably not very safe and future proof

also other thing which we could consider is support for zio-schema, which then could allow different structured output based on given schema

we need to analyze the possibilities how to add this functionality and make it more user friendly

@justcoon
Copy link
Contributor Author

justcoon commented Feb 8, 2023

probably we should do it in phases:

  1. modify current json logger to able recognise json string value and add it like json value
  2. analyse the possibilities how do structured logging and add better support for structured logging, consider usage of zio-schema

@jdegoes
Copy link
Member

jdegoes commented Feb 9, 2023

To do (1), we should create a high-performance, zero-allocation JSON recognizer (String => Boolean), which looks through a string and returns true / false depending on whether it contains valid JSON.

If it contains valid JSON, then it can be inserted as-is, without the need to wrap it into a String and escape the contents.

If it does NOT contain valid JSON, then the current behavior should occur.

I think we can add logStructured("message", myValue) which uses ZIO Schema to log myValue in a structured way, by rendering to JSON and then passing to underlying.

@ipetkovic
Copy link
Contributor

ipetkovic commented Feb 10, 2023

I could come up with something regarding (1), have something ready to show next week.
Do we want strict json validation?
Regarding (2), does it make sense to have support for structured logging of annotations as well?
For example, if I write something like:
logInfo("mesage") @@ myannotation(myValue)
that myValue is logged in structured way.

@ipetkovic
Copy link
Contributor

ipetkovic commented Feb 14, 2023

Could you have a look at the #657 ?
I also put some remarks/concerns in comment of the PR. I am happy to hear any feedback. Thanks!

@ipetkovic
Copy link
Contributor

Once again, updated #657
Can you have a look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants