mdsol / Medidata.ZipkinTracerModule

[Deprecated] Zipkin Request Tracing for .Net Apps
MIT License
53 stars 20 forks source link
study-conduct

Deprecated

This project is deprecated and no longer being maintained. Please use zipkin4net or other alternatives.

Medidata.ZipkinTracerModule

A .NET implementation of the Zipkin Tracer client.

Overview

This nuget package implements the zipkin tracer client for .net applications.

Medidata.ZipkinTracer.Core : core library for generating zipkin spans from ids sent through from CrossApplicationTracer and sending it to the zipkin collector using HTTP as the transport protocol. For more information and implementations in other languages, please check Openzipkin.

Enable/Disable zipkin tracing

Zipkin will record traces if IsSampled HTTP header is true.
This will happen if :

Configurations

Please use ZipkinConfig class to configure the module and verify these values and modify them according to your service/environment.

var config = new ZipkinConfig
{
    Bypass = request => request.Uri.AbsolutePath.StartsWith("/allowed"),
    Domain = request => new Uri("https://yourservice.com"), // or, you might like to derive a value from the request, like r => new Uri($"{r.Scheme}{Uri.SchemeDelimiter}{r.Host}"),
    ZipkinBaseUri = new Uri("http://zipkin.xyz.net:9411"),
    SpanProcessorBatchSize = 10,
    SampleRate = 0.5,
    NotToBeDisplayedDomainList = new[] { ".xyz.com", ".myApplication.net" },
    ExcludedPathList = new[] { "/check_uri", "/status" }
}

Tracing

Server trace (Inbound request)

Server Trace relies on OWIN Middleware. Please create OWIN Startup class then call UseZipkin().

using Medidata.ZipkinTracer.Core;
using Medidata.ZipkinTracer.Core.Middlewares;

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseZipkin(new ZipkinConfig
        {
            Domain = new Uri("https://yourservice.com"),
            ZipkinBaseUri = new Uri("http://zipkin.xyz.net:9411"),
            SpanProcessorBatchSize = 10,
            SampleRate = 0.5    
        });
    }
}

Client trace (Outbound request)

Client Trace relies on HttpMessageHandler for HttpClient. Please pass a ZipkinMessageHandler instance into HttpClient.

Note: You will need the GetOwinContext extension method. If you host in IIS with System.Web, this can be found in Microsoft.Owin.Host.SystemWeb.

using Medidata.ZipkinTracer.Core.Handlers;

public class HomeController : AsyncController
{
    public async Task<ActionResult> Index()
    {
        var context = System.Web.HttpContext.Current.GetOwinContext();
        var config = new ZipkinConfig // you can use Dependency Injection to get the same config across your app.
        {
            Domain = new Uri("https://yourservice.com"),
            ZipkinBaseUri = new Uri("http://zipkin.xyz.net:9411"),
            SpanProcessorBatchSize = 10,
            SampleRate = 0.5    
        }
        var client = new ZipkinClient(config, context);

        using (var httpClient = new HttpClient(new ZipkinMessageHandler(client))))
        {
            var response = await httpClient.GetAsync("http://www.google.com");
            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
            }
        }

        return View();
    }
}

Recording arbitrary events and additional information

NOTE:This can only be used if you are NOT using ZipkinMessageHandler as described above "Client trace (Outbound request)". RecordBinary<T() needs to be called before EndClientTrace() is invoked.

Additional annotations can be recorded by using the ZipkinClient's Record() and RecordBinary<T>() methods:

var context = System.Web.HttpContext.Current.GetOwinContext();
var config = new ZipkinConfig // you can use Dependency Injection to get the same config across your app.
{
    Domain = new Uri("https://yourservice.com"),
    ZipkinBaseUri = new Uri("http://zipkin.xyz.net:9411"),
    SpanProcessorBatchSize = 10,
    SampleRate = 0.5    
}
var zipkinClient = new ZipkinClient(config, context);
var url = "https://abc.xyz.com:8000";
var requestUri = "/object/1";
HttpResponseMessage result;
using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(url);

    // start client trace
    var span = zipkinClient.StartClientTrace(new Uri(client.BaseAddress, requestUri), "GET");

    zipkinClient.Record(span, "A description which will gets recorded with a timestamp.");

    result = await client.GetAsync(requestUri);

    // Record the total memory used after the call
    zipkinClient.RecordBinary(span, "client.memory", GC.GetTotalMemory(false));

    // end client trace
    zipkinClient.EndClientTrace(span);
}
...

In case of the ZipkinClient.Record() method, the second parameter(value) can be omitted during the call, in that case the caller member name (method, property etc.) will get recorded.

Recording a local component

With the RecordLocalComponent() method of the client a local component (or information) can be recorded for the current trace. This will result an additional binary annotation with the 'lc' key (LOCAL_COMPONENT) and a custom value.

Troubleshooting

Logs

Logging internal to the library is provided via the LibLog abstraction. Caveat: to get logs, you must have initialised your logging framework on application-start (console app example - a web-app might do this in OWIN Startup or Global.asax, or the inversion of control container initialisation).

Contributors

ZipkinTracer is (c) Medidata Solutions Worldwide and owned by its major contributors: