The span itself is created with the correct name and all sub-spans one runs in the app get the correct parent span. But the request itself will have it's name overwritten when it is completed, then reverting it back to the original URL/path name.
package com.area51
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpRequest}
import akka.http.scaladsl.server.Directives.{complete, get, pathPrefix, _}
import akka.http.scaladsl.server.Route
import akka.stream.ActorMaterializer
import com.typesafe.config.{Config, ConfigFactory}
import kamon.akka.http.AkkaHttp.OperationNameGenerator
import kamon.metric.PeriodSnapshot
import kamon.{Kamon, MetricReporter}
class SimpleNameGenerator extends OperationNameGenerator {
override def clientOperationName(request: HttpRequest): String = "MY-CLIENT"
override def serverOperationName(request: HttpRequest): String = "MY-SERVER"
}
class SimpleMetricReporter extends MetricReporter {
override def start(): Unit = {}
override def stop(): Unit = {}
override def reconfigure(config: Config): Unit = {}
override def reportPeriodSnapshot(snapshot: PeriodSnapshot): Unit = {
//snapshot.metrics.histograms
snapshot.metrics.histograms.filter(_.name.startsWith("span.processing")).foreach(println)
}
}
object SimpleKamon extends App {
private val cfg = ConfigFactory.parseString(
"""kamon {
| environment.service = "simple-kamon"
|
| akka-http {
| name-generator = "com.area51.SimpleNameGenerator"
| not-found-operation-name = "unhandled"
| add-http-status-code-as-metric-tag = true
| }
|
| span-metric.tags.upstream-service = no
| modules {
| kamon-system-metrics.auto-start = false
| kamon-akka-http.requires-aspectj = true
| }
| span-metrics.scope-spans-to-parent=false
| system-metrics {
| host.enabled = false
| jmx.enabled = false
| }
| metric.tick-interval = 10 seconds
|}""".stripMargin
)
.withFallback(ConfigFactory.defaultReference())
.resolve()
private implicit val system = ActorSystem("simple-kamon")
private implicit val materializer = ActorMaterializer()
private implicit val executionContext = system.dispatcher
private val route: Route =
pathPrefix("api") {
pathPrefix("execute") {
get {
println(Kamon.currentSpan().operationName())
Kamon.buildSpan("read.user.data").withMetricTag("component", "database").start().finish()
Kamon.buildSpan("update.cache").withMetricTag("component", "in-memory").start().finish()
complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, s"<h1>HELLO WORLD!</h1>"))
}
}
}
Kamon.reconfigure(cfg)
Kamon.addReporter(new SimpleMetricReporter())
Http().bindAndHandle(route, "0.0.0.0", 6969).foreach(_ => println("Started!"))
}
val akkaVersion = "2.5.25"
lazy val kamon = project.in(file("kamon"))
.settings(
organization := "com.area51",
scalaVersion := "2.12.10",
mainClass in (Compile, run) := Some("com.area51.SimpleKamon"),
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-slf4j" % akkaVersion,
"com.typesafe.akka" %% "akka-stream" % akkaVersion,
"com.typesafe.akka" %% "akka-http-core" % "10.1.9",
"com.typesafe.akka" %% "akka-http" % "10.1.9",
"io.kamon" %% "kamon-core" % "1.1.6",
"io.kamon" %% "kamon-akka-http-2.5" % "1.1.2",
"io.kamon" %% "kamon-akka-2.5" % "1.1.4"
)
)
MY-SERVER
MetricDistribution(span.processing-time,Map(operation -> /api/execute, error -> false, span.kind -> server, http.status_code -> 200),MeasurementUnit(Dimension(time),Magnitude(nanoseconds,1.0E-9)),DynamicRange(1,3600000000000,2),kamon.metric.SnapshotCreation$ZigZagCountsDistribution@9e07ae2)
MetricDistribution(span.processing-time,Map(operation -> read.user.data, error -> false, component -> database, parentOperation -> MY-SERVER),MeasurementUnit(Dimension(time),Magnitude(nanoseconds,1.0E-9)),DynamicRange(1,3600000000000,2),kamon.metric.SnapshotCreation$ZigZagCountsDistribution@48b2e947)
MetricDistribution(span.processing-time,Map(operation -> update.cache, error -> false, component -> in-memory, parentOperation -> MY-SERVER),MeasurementUnit(Dimension(time),Magnitude(nanoseconds,1.0E-9)),DynamicRange(1,3600000000000,2),kamon.metric.SnapshotCreation$ZigZagCountsDistribution@5ca82cba)