• Stars
    star
    520
  • Rank 83,202 (Top 2 %)
  • Language
    C#
  • License
    Apache License 2.0
  • Created about 8 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

OpenTracing API for C# (.NET). 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163

Gitter chat Build Status Build status NuGet

OpenTracing API for .NET

This solution includes the .NET platform API for OpenTracing.

Required Reading

In order to understand the .NET platform API, one must first be familiar with the OpenTracing project and terminology more specifically.

Installation

Install the NuGet package:

Install-Package OpenTracing

Usage

Initialization

Initialization is OpenTracing-implementation-specific. Generally speaking, the pattern is to initialize a ITracer once for the entire process and to use that ITracer for the remainder of the process lifetime. It is a best practice to set the GlobalTracer, even if also making use of cleaner, more modern dependency injection. (See the next section below for rationale)

Accessing the ITracer

Where possible, use some form of dependency injection (of which there are many) to access the ITracer instance. For vanilla application code, this is often reasonable and cleaner for all of the usual DI reasons.

That said, instrumentation for packages that are themselves statically configured (e.g., ODBC drivers) may be unable to make use of said DI mechanisms for ITracer access, and as such they should fall back on GlobalTracer. By and large, OpenTracing instrumentation should always allow the programmer to specify a ITracer instance to use for instrumentation, though the GlobalTracer is a reasonable fallback or default value.

Scopes and within-process propagation

For any thread, at most one ISpan may be "active". Of course, there may be many other spans involved with the thread which are (a) started, (b) not finished, and yet (c) not "active": perhaps they are waiting for I/O, blocked on a child span, or otherwise off of the critical path.

It's inconvenient to pass an active ISpan from function to function manually, so OpenTracing requires that every ITracer contains a IScopeManager that grants access to the active ISpan through a IScope. Any ISpan may be transferred to another callback or thread, but not IScope; more on this below.

Accessing the active Span through IScope

Access to the active span is straightforward:

OpenTracing.ITracer tracer = ...;
...
IScope scope = tracer.ScopeManager.Active;
if (scope != null) {
    scope.Span.Log("...");
}

Starting a new Span

The common case starts a IScope that's automatically registered for intra-process propagation via IScopeManager.

Note that StartActive(finishSpanOnDispose: true) finishes the span on IScope.Dispose().

OpenTracing.ITracer tracer = ...;
...
using (IScope scope = tracer.BuildSpan("someWork").StartActive(finishSpanOnDispose: true))
{
    try
    {
        // Do things.
    }
    catch (Exception ex)
    {
        Tags.Error.Set(scope.Span, true);
    }

    // No need to call scope.Span.Finish() as we've set finishSpanOnDispose:true in StartActive.
}

If there is a IScope, it will act as the parent to any newly started ISpan unless the programmer invokes IgnoreActiveSpan() at BuildSpan() time or specified parent context explicitly:

OpenTracing.ITracer tracer = ...;
...
IScope scope = tracer.BuildSpan("someWork").IgnoreActiveSpan().StartActive(finishSpanOnDispose: true);

Using scopes with async/await

OpenTracing contains an IScopeManager implementation that uses AsyncLocal to flow spans with the execution. It is therefore possible to use scopes and spans with async/await:

OpenTracing.ITracer tracer = ...;
...
using (IScope parentScope = tracer.BuildSpan("Parent").StartActive(finishSpanOnDispose: true))
{
    await SomeAsynchronousWork();

    // It's still possible to access the current span
    parentScope.Span.Log(...);

    // The child scope will automatically use parentScope as its parent.
    using (IScope childScope = tracer.BuildSpan("Child").StartActive(finishSpanOnDispose: true))
    {
        childScope.Span.Log(...);

        await SomeMoreAsynchronousWork();

        childScope.Span.Log(...);
    }
}

public async Task SomeAsynchronousWork()
{
    // use ITracer.ActiveSpan to access the current span - which will be "parentScope.Span".
    tracer.ActiveSpan.Log(...);

    await SomeExternalCall();
}

public async Task SomeMoreAsynchronousWork()
{
    // The active span in this case will be "childScope.Span".
    tracer.ActiveSpan.Log(...);

    await SomeExternalCall();
}

Contributing

If you would like to contribute code you can do so through GitHub by forking the repository and sending a pull request.

By contributing your code, you agree to license your contribution under the terms of the APLv2: https://github.com/opentracing/opentracing-csharp/blob/master/LICENSE

License

All files are released with the Apache 2.0 license.

More Repositories

1

opentracing-go

OpenTracing API for Go. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
Go
3,489
star
2

opentracing-java

OpenTracing API for Java. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
Java
1,679
star
3

specification

A place to document (and discuss) the OpenTracing specification. 🛑 This project is DEPRECATED! https://github.com/opentracing/specification/issues/163
1,173
star
4

opentracing-javascript

OpenTracing API for Javascript (both Node and browser). 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
TypeScript
1,089
star
5

opentracing-python

OpenTracing API for Python. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
Python
755
star
6

opentracing-php

OpenTracing API for PHP
PHP
505
star
7

opentracing-cpp

OpenTracing API for C++. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
C++
319
star
8

opentracing-ruby

OpenTracing API for Ruby
Ruby
172
star
9

opentracing.io

OpenTracing website
SCSS
116
star
10

basictracer-go

Basic implementation of the OpenTracing API for Go. 🛑 This library is DEPRECATED!
Go
81
star
11

opentracing-rust

OpenTracing API for Rust
Rust
77
star
12

opentracing-c

ANSI C API for OpenTracing
C
33
star
13

opentracing-lua

OpenTracing API for Lua
Lua
28
star
14

opentracing-objc

OpenTracing API for Objective-C. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
Objective-C
28
star
15

basictracer-python

The Python implementation of the "BasicTracer" reference implementation. 🛑 This library is DEPRECATED!
Python
26
star
16

opentracing-swift

This is a prototype OpenTracing API for the Swift language. This is intended to explore and validate decisions about implementing the OpenTracing API in Swift.
Swift
17
star
17

lua-bridge-tracer

Provides an implementation of the Lua OpenTracing API on top of the C++ API
C++
14
star
18

basictracer-csharp

Reference implementation of OpenTracing API in C#
12
star
19

documentation

Please see opentracing.io repo instead
7
star
20

basictracer-javascript

JavaScript
7
star
21

contrib

A place (or, really, a pointer) for community contributions to OpenTracing
5
star
22

opentracing-java-v030

Backwards compatibility layer for Java v0.30
Java
3
star
23

c-bridge-tracer

Experimental C binding for C++ tracers
1
star