kamon-io / Kamon

Distributed Tracing, Metrics and Context Propagation for applications running on the JVM
https://kamon.io
Other
1.41k stars 327 forks source link

Context propagation in actor system after migration from Kamon 1.x to 2.x #825

Open sebarys opened 4 years ago

sebarys commented 4 years ago

Hello,

I've tried migrate to Kamon 2.1.4 from 1.1.6. Application is forming akka-cluster and use communication between actors to process some logic. We're using context propagation to have some informations in logs like traceId, clientName etc.

In Kamon 1.x we had util function to init context:


def withContext[T](clientName: String, otherOptionalParam: Option[String], traceId: String)(func: => T): T = {

  Kamon.withContext(Kamon.currentContext() 
      .withKey[String](LogbackTraceIdConverter.TraceIdKey, traceId) 
      .withKey[String](LogbackClientNameConverter.ClientNameKey, clientName)
      .withKey[String](LogbackOtherOptionalParamConverter.OtherOptionalParamKey, otherOptionalParam.getOrElse(""))) { 
          func
      }
}

those informations were used later to log context values in log entries using "io.kamon" %% "kamon-logback" % "1.0.7"

it was converted after migration to Kamon 2.x to:

  def withContext[T](clientName: String, otherOptionalParam: Option[String], traceId: String)(func: => T): T = {

      Kamon.runWithContext(Kamon.currentContext()
        .withTag(TraceIdKey, traceId)
        .withTag(ClientNameKey, clientName)
        .withTag(OtherOptionalParamKey, otherOptionalParam.getOrElse(""))) {

        func
      }
  }

//in logback
    <conversionRule conversionWord="traceId" converterClass="kamon.instrumentation.logback.tools.ContextTagConverter" />
    <conversionRule conversionWord="clientName" converterClass="kamon.instrumentation.logback.tools.ContextTagConverter" />
    <conversionRule conversionWord="otherOptionalParam" converterClass="kamon.instrumentation.logback.tools.ContextTagConverter" />

Unfortunately after migration values that were propagated properly, now aren't propagated, instead each field is reporting null.

Am I missing some not documented configuration part or I need add sth more to build.sbt than dependency to

      "io.kamon" %% "kamon-bundle" % "2.1.4"

and init Kamon before creating actorSystem:

  Kamon.init()

  implicit val system = ActorSystem(config.getString("cluster.name"), config)

?

Thanks in advance for help :)

sebarys commented 4 years ago

Ok, I figured this out:

  1. I thought that kanela is in bundle and there is not need for adding kanela agent as javaagent: https://kamon.io/docs/latest/guides/installation/setting-up-the-agent/ section Using sbt-native-packager (works also with sbt assembly)
  2. If I'm providing values to context as tags, in logback.xml only ContextTagConverter is required and to call variables put into context before use %contextTag{KEY_NAME} syntax
    <conversionRule conversionWord="contextTag" converterClass="kamon.instrumentation.logback.tools.ContextTagConverter" />
    ...
    <provider class="net.logstash.logback.composite.loggingevent.LoggingEventPatternJsonProvider">
                    <pattern>
                        {
                        "logger":"%logger",
                        "message":"%msg",
                        "thread":"%thread",
                        "actor":"%X{akkaSource}",
                        "clientName":"%contextTag{clientName}",
                        "otherOptionalParam":"%contextTag{otherOptionalParam}",
                        "traceId":"%contextTag{traceId}"
                        }
                    </pattern>
                </provider>

There are many places where documentation (even latest) is inconsistent, I think that having simple example app with akka http endpoint where actor is requested to process sth to show how integrate with the newest version of Kamon context propagation, metrics and logback (IMO 3 most used features) would help a lot people that just started using your framework.