Skip to content

Commit

Permalink
feat: Configure OpenTelemetryTestReporter by ScalaTest's ConfigMap
Browse files Browse the repository at this point in the history
  • Loading branch information
NomadBlacky committed Jun 12, 2024
1 parent 37c740a commit 55ec774
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 10 deletions.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,23 @@ Open the Jaeger UI in your browser (http://localhost:16686/) and you will see th

![img.png](jaeger-trace.png)

## Blogs
## Configuration

You can configure the behavior of the reporter by [ScalaTest's config map](https://www.scalatest.org/user_guide/using_the_runner).

```scala
Test / testOptions += Tests.Argument(
TestFrameworks.ScalaTest,
"-C",
"example.JaegerTestReporter",
"-Dscalatest-otel-reporter.root-span-name=my-awesome-tests",
)
```

| Key | Description | Default |
|------------------------------------------|----------------------------|-------------|
| `scalatest-otel-reporter.root-span-name` | The name of the root span. | `scalatest` |

## Posts

- [テストでも Observability したいっ! ScalaTest を OpenTelemetry で計装してみた (ScalaMatsuri 2024 Unconference)](https://cobalt-lupin-e48.notion.site/Observability-ScalaTest-OpenTelemetry-b2d3e69d75f146b1a26fe9199d51e3e9)
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,6 @@ lazy val `example-manual-configuration` = (project in file("examples/manual-conf
TestFrameworks.ScalaTest,
"-C",
"dev.nomadblacky.scalatest_otel_reporter.examples.JaegerTestReporter",
"-Dscalatest-otel-reporter.root-span-name=example-manual-configuration",
),
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package dev.nomadblacky.scalatest_otel_reporter.examples

import org.scalatest.funsuite.AnyFunSuiteLike

class SimpleTests extends AnyFunSuiteLike {
class SucceededTests extends AnyFunSuiteLike {

test("sum") {
assert(1 + 1 == 2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import java.util.concurrent.ConcurrentHashMap
import java.util.logging.Logger

trait OpenTelemetryTestReporter extends Reporter {
import OpenTelemetryTestReporter._

def otel: OpenTelemetry

private val tracer = otel.getTracerProvider.get("scalatest")
Expand All @@ -27,8 +29,8 @@ trait OpenTelemetryTestReporter extends Reporter {
*/
case starting: RunStarting =>
logger.fine(s"RunStarting")
// TODO: Make possible to configure the root span name
testRootSpan = tracer.spanBuilder("UNIT_TEST").startSpan()
val rootSpanName = starting.configMap.getWithDefault(ConfigKeyRootSpanName, DefaultRootSpanName)
testRootSpan = tracer.spanBuilder(rootSpanName).startSpan()

case completed: RunCompleted =>
logger.fine(s"RunCompleted")
Expand Down Expand Up @@ -143,3 +145,8 @@ trait OpenTelemetryTestReporter extends Reporter {
case _: MarkupProvided => ()
}
}

object OpenTelemetryTestReporter {
val ConfigKeyRootSpanName = "scalatest-otel-reporter.root-span-name"
val DefaultRootSpanName = "scalatest"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package dev.nomadblacky.scalatest_otel_reporter

import org.scalatest.{ConfigMap, ParallelTestExecution}
import org.scalatest.events.{Ordinal, RunCompleted, RunStarting}

class ConfigurationSpec extends UnitTestSuite with OTelMockServer with ParallelTestExecution {
import OpenTelemetryTestReporter._

test("Configure the root span name") {
val spans = instrumentWithMockServer { mockServer =>
val reporter = new WireMockOTelTestReporter(host, mockServer.port())
reporter.apply(RunStarting(new Ordinal(0), 0, new ConfigMap(Map(ConfigKeyRootSpanName -> "my-awesome-tests"))))
reporter.apply(RunCompleted(ordinal = new Ordinal(1)))
}

logger.info(s"Received spans: $spans")

assert(spans.size == 1)
val span = spans.head
span.getName shouldBe "my-awesome-tests"
}

test("Fallback to the default root span name") {
val spans = instrumentWithMockServer { mockServer =>
val reporter = new WireMockOTelTestReporter(host, mockServer.port())
reporter.apply(RunStarting(new Ordinal(0), 0, new ConfigMap(Map.empty)))
reporter.apply(RunCompleted(ordinal = new Ordinal(1)))
}

logger.info(s"Received spans: $spans")

assert(spans.size == 1)
val span = spans.head
span.getName shouldBe DefaultRootSpanName
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package dev.nomadblacky.scalatest_otel_reporter

import com.github.tomakehurst.wiremock.client.WireMock
import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest
import io.opentelemetry.proto.trace.v1.Status
import org.scalatest.funsuite.AnyFunSuiteLike
import org.scalatest.{Args, ParallelTestExecution}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import io.opentelemetry.proto.trace.v1.Status
import org.scalatest.Args
import org.scalatest.funspec.AnyFunSpecLike

class SimpleTestSpec extends UnitTestSuite with OTelMockServer {
class SucceededTestSpec extends UnitTestSuite with OTelMockServer {

test("SimpleTest") {
class SimpleTests extends AnyFunSpecLike {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter
import io.opentelemetry.sdk.OpenTelemetrySdk
import io.opentelemetry.sdk.resources.Resource
import io.opentelemetry.sdk.trace.SdkTracerProvider
import io.opentelemetry.sdk.trace.`export`.BatchSpanProcessor
import io.opentelemetry.sdk.trace.`export`.SimpleSpanProcessor
import io.opentelemetry.semconv.ResourceAttributes

import java.util.concurrent.TimeUnit
Expand All @@ -25,7 +25,7 @@ class WireMockOTelTestReporter(host: String, port: Int) extends OpenTelemetryTes

// Set to process the spans by the WireMock Exporter
val tracerProvider = SdkTracerProvider.builder
.addSpanProcessor(BatchSpanProcessor.builder(wireMockOtlpExporter).build)
.addSpanProcessor(SimpleSpanProcessor.builder(wireMockOtlpExporter).build())
.setResource(Resource.getDefault.merge(serviceNameResource))
.build

Expand Down

0 comments on commit 55ec774

Please sign in to comment.