Custom reporters

It’s possible to create OpenTracing compatible tracers programmatically, by providing a Cinnamon TracerFactory that creates the Tracer directly. Also, there is a TracerSpecific class to implement, and a TracerSpecificFactory marker interface to use.

For example, the LightStep Tracer can be used by implementing a TracerFactory such as:

package sample {

  import com.lightbend.cinnamon.logging.LoggingProvider
  import com.lightbend.cinnamon.opentracing.{ TracerFactory, TracerSpecific, TracerSpecificFactory }
  import com.typesafe.config.Config
  import io.opentracing.{ Tracer, SpanContext }

  /**
   * Optional parameters for an implementation of a TracerFactory (in this specific order):
   *
   * @param configPath      path to section in config for the tracer, e.g. `cinnamon.opentracing.lightstep`
   * @param config          the configuration for this `ActorSystem`
   * @param loggingProvider a Cinnamon `LoggingProvider`
   */
  class LightStepTracerFactory(configPath: String, config: Config, loggingProvider: LoggingProvider)
    extends TracerFactory with TracerSpecificFactory {

    def create(): Tracer = {
      new com.lightstep.tracer.jre.JRETracer(
        new com.lightstep.tracer.shared.Options.OptionsBuilder()
          .withAccessToken("{your_access_token}")
          .build()
      )
    }

    def createTracerSpecific(): TracerSpecific = {
      new LightstepTracerSpecific
    }
  }

  class LightstepTracerSpecific extends TracerSpecific {

    def isSampled(context: SpanContext): Boolean = {
      // always sampled for lightstep
      true
    }

    def isDebug(context: SpanContext): Boolean = {
      // could add debug trace integration here...
      false
    }

    def getTraceId(context: SpanContext): String = {
      import com.lightstep.tracer.shared.{ SpanContext => LightstepSpanContext }

      context match {
        case s: LightstepSpanContext =>
          // get the trace id from the lightstep context
          s.toTraceId
        case _ =>
          // or return null for no trace id
          null
      }
    }
  }
}

Make sure that you add the Cinnamon OpenTracing module dependency to your build file:

sbt
libraryDependencies += Cinnamon.library.cinnamonOpenTracing
Maven
<dependency>
  <groupId>com.lightbend.cinnamon</groupId>
  <artifactId>cinnamon-opentracing_2.12</artifactId>
  <version>2.14.2</version>
</dependency>
Gradle
dependencies {
    compile group: 'com.lightbend.cinnamon', name: 'cinnamon-opentracing_2.12', version: '2.14.2'
}

And then configuring Cinnamon to use this tracer:

cinnamon.opentracing {
  tracers = [lightstep]

  lightstep {
    debug = on
    factory-class = "sample.LightStepTracerFactory"
  }
}

Adding the debug = on setting into the tracer config during development will help to debug issues if any occur during the custom tracer creation. Also make sure that the Cinnamon loglevel is set to DEBUG.

Note: Cinnamon currently staying on 0.32 to be compatible across tracers, Datadog tracer in particular.