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

Added Logger that takes an implicit parameter (e.g. CorrelationId) #83

Merged
merged 10 commits into from
Feb 5, 2018
Merged

Conversation

pwliwanow
Copy link

@pwliwanow pwliwanow commented Jun 5, 2017

Including request contextual data in the logs (e.g. CorrelationId, UserId, etc.) is a common scenario, however currently there is no good way to do it.

With Java common approach is to use MDC, however I think that in Scala it's a bad idea for two reasons:

  • in case of async computations custom execution context is needed, but more importantly
  • correlationId value is not present in the function signature and then it's taken out of thin air which in Scala should be a serious red flag

Here is relevant part of the code that expresses idea in this pull request:

trait CanLog[A] {
  def logMessage(originalMsg: String, a: A): String
  def afterLog(a: A): Unit = ()
}

class LoggerTakingImplicit[A] (val underlying: Underlying)(implicit val canLogEv: CanLog[A]) { 
  def error(message: String)(implicit a: A): Unit
}

It should also solve #80

@analytically
Copy link
Collaborator

analytically commented Jun 28, 2017

What's the pattern for two implicits?

@pwliwanow
Copy link
Author

If you want to log multiple values I think it's natural to put them inside one class:

case class TracingDetails(messageId: String, causationId: String, correlationId: String)

I don't see a very good reason for having more than one implicit in the signature.

@Kreinoee
Copy link

Kreinoee commented Oct 5, 2017

I like you approach for handling this. How about adding a default MDCMap class, that would basically just be a wrapper arround an immutable map, and then a default implementation of the CanLog trait that takes an MDCMap and add them to the MDC context. Something like:

final case class MDCMap(map: scala.collection.immutable.HashMap[String, String])

implicit object CanLogMDCMap extends CanLog[MDCMap] {
  override def logMessage(originalMsg: String, a: MDCMap): String = {
    a.map.foreach(t  MDC.put(t._1, t._2))
    originalMsg
  }

  override def afterLog(a: MDCMap): Unit = {
    a.map.keys.foreach(MDC.remove)
  }
}

That would provide a default bridge to the java world. The reason that is important, is that a lot of tools are build arround the concept of MDC values.

@pwliwanow
Copy link
Author

@Kreinoee thanks, I could add that class as well or you could create pull request after this one is merged :)

@analytically if you like this idea and you would like to merge it, please let me know, so I can update the pull request. And if you don't like it, I think it should be closed

@analytically
Copy link
Collaborator

@pwliwanow yeah I like this idea, please update your PR

def afterLog(a: A): Unit = ()
}

@SerialVersionUID(957385465L)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why a SerialVersionUID and why Serializable?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's remove this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just SerialVersionUID or also Serializable?

Responding to an earlier question, it just mirrors whats in "regular" Logger + to allow Spark users to use it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok makes sense

@Kreinoee
Copy link

Kreinoee commented Feb 5, 2018

Hi @pwliwanow. Will you update the pull request, or should I create a new pull request based on this one, with the CanLogMDCMap objct and MDCMap class?

@pwliwanow
Copy link
Author

@Kreinoee sorry, I forgot about this one. I will update the pull request this week

@Kreinoee
Copy link

Kreinoee commented Feb 5, 2018

Super sounds great.

And like analytically I am a bit curious about why CanLog should be serializable?

@analytically analytically merged commit 93b881d into lightbend-labs:master Feb 5, 2018
@Kreinoee
Copy link

Kreinoee commented Feb 6, 2018

We ended up not including the CanLogMDCMap and MDCMap classes. Is it something I should create a new pull request for, or do you think its best without them?

@analytically
Copy link
Collaborator

You're welcome to open a new PR.

@Atry
Copy link
Contributor

Atry commented Feb 13, 2018

I think CanLogMDCMap can be implemented from MDC.setContextMap(map.asJava), which is more efficient than Map.foreach

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

Successfully merging this pull request may close these issues.

4 participants