Skip to content

Instantly share code, notes, and snippets.

@Krever
Created July 12, 2018 19:44
Show Gist options
  • Select an option

  • Save Krever/637af27a1dd6e90b0e8a295b20f0db9f to your computer and use it in GitHub Desktop.

Select an option

Save Krever/637af27a1dd6e90b0e8a295b20f0db9f to your computer and use it in GitHub Desktop.
//simplified logger from scala-logging
trait LoggerTakingImplicit[T] {
def log(msg: String)(implicit ev: CanLog[T])
}
trait CanLog[T] {
def logMessage(originalMsg: String, a: T): String
}
// simplified logback MDC
object MDC {
def put(key: String, value: String): Unit = ()
}
//carrier of traceid ... because microservices
trait RequestCtx {
def traceId: String
}
object RequestCtx {
implicit object CanLogInstance extends CanLog[RequestCtx] {
def logMessage(originalMsg: String, a: RequestCtx): String = {
MDC.put("traceId", a.traceId)
originalMsg
}
}
}
// class in a library - http client to external service
trait JiraClient {
def addComment(comment: String)(implicit ctx: RequestCtx)
}
//previously all our apps were backend-only microservices but now we have a frontend so ..
trait UserRequestCtx {
def traceId: String
def username: String
}
// Problem: how do we make logs from JiraClient handle username properly
//Version leveraging inheritance:
object WithInheritance {
trait RequestCtx {
def traceId: String
def mdcValues: Map[String, String] = Map("traceId" -> traceId)
}
object RequestCtx {
implicit object CanLogInstance extends CanLog[RequestCtx] {
def logMessage(originalMsg: String, a: RequestCtx): String = {
a.mdcValues.foreach(x => MDC.put(x._1, x._2))
originalMsg
}
}
}
trait UserRequestCtx extends RequestCtx {
def username: String
override def mdcValues: Map[String, String] = super.mdcValues + ("username" -> username)
}
}
//Version leveraging typeclasses only:
object WithoutInheritance {
// Every user of `LoggerTakingImplicit` must be now parametrized by ctx type
class JiraClient[Ctx : CanLog] {
def addComment(comment: String)(implicit ctx: Ctx) = ???
}
// Imagine 20 microservices, and 10 libraries and only one of the microservices wants to change something in
// RequestCtx. Parametrization will leak to all of that projects complicating them without any purpose
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment