Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/opentracing-contrib/scala-concurrent

OpenTracing instrumentation for scala.concurrent package
https://github.com/opentracing-contrib/scala-concurrent

opentracing scala

Last synced: about 2 months ago
JSON representation

OpenTracing instrumentation for scala.concurrent package

Awesome Lists containing this project

README

        

[![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Released Version][maven-img]][maven]

# OpenTracing instrumentation for `scala.concurrent`
OpenTracing instrumentation for `scala.concurrent` package.

## Installation

### Scala 2.12
```sbt
libraryDependencies += "io.opentracing.contrib" % "opentracing-scala-concurrent_2.12" % "VERSION"
```

### Scala 2.13
```sbt
libraryDependencies += "io.opentracing.contrib" % "opentracing-scala-concurrent_2.13" % "VERSION"
```

## Usage

Please see the examples directory. Overall, an `ExecutionContext` is wrapped
so the active Span can be captured and activated for a given Scala `Future`.

Create a `TracedExecutionContext` wrapping the actually used `ExecutionContext`,
and pass it around when creating `Future`s:

```scala
// Instantiate tracer
val tracer: Tracer = ...
val ec: ExecutionContext = new TracedExecutionContext(executionContext, tracer);
```

### Span Propagation

```scala
Future {
// The active Span at Future creation time, if any,
// will be captured and restored here.
tracer.activeSpan().setTag("status.code", getStatusCode())
}(ec)
```

`Future.onComplete` and other `Future` methods will
capture too *any* active `Span` by the time they were registered, so you have
to make sure that both happened under the same active `Span`/`Scope` for this
to work smoothly.

`Span` lifetime handling is not done at the `TracedExecutionContext`,
and hence explicit calls to `Span.finish()` must be put in place - usually
either in the last `Future`/message block or in a `onComplete` callback
function:

```scala
Future {
...
}(ec).onComplete { _ => {
tracer.activeSpan().finish()
}
}(ec)
```

### Auto finish Span handling

Span auto-finish is supported through a reference-count system using the specific
`AutoFinishScopeManager` -which needs to be provided at `Tracer` creation time-,
along with using `TracedAutoFinishExecutionContext`:

```scala
val scopeManager = new AutoFinishScopeManager();
val tracer: Tracer = ??? // Use the created scopeManager here.
val ec = new TracedAutoFinishExecutionContext(executionContext, tracer)
...
val span = tracer.buildSpan("request").start()
val scope = tracer.activateSpan(span)
try {
Future {
// Span will be reactivated here
...
Future {
// Span will be reactivated here as well.
// By the time this future is done,
// the Span will be automatically finished.
} (ec)
} (ec)
} finally {
scope.close()
}
```

Reference count for `Span`s is set to 1 at creation, and is increased when
registering `onComplete`, `andThen`, `map`, and similar
`Future` methods - and is decreased upon having such function/callback executed:

```scala
Future {
...
}(ec)
.map {...}(ec)
.onComplete {
// No need to call `Span.finish()` here at all, as
// lifetime handling is done implicitly.
}(ec)
```

## License

[Apache 2.0 License](./LICENSE).

[ci-img]: https://travis-ci.org/opentracing-contrib/scala-concurrent.svg?branch=master
[ci]: https://travis-ci.org/opentracing-contrib/scala-concurrent
[cov-img]: https://coveralls.io/repos/github/opentracing-contrib/scala-concurrent/badge.svg?branch=master
[cov]: https://coveralls.io/github/opentracing-contrib/scala-concurrent?branch=master
[maven-img]: https://img.shields.io/maven-central/v/io.opentracing.contrib/opentracing-scala-concurrent_2.13.svg
[maven]: http://search.maven.org/#search%7Cga%7C1%7Copentracing-scala-concurrent_2.13