Skip to content

Latest commit

 

History

History
97 lines (64 loc) · 4.73 KB

OpenTelemetry.md

File metadata and controls

97 lines (64 loc) · 4.73 KB

FusionCache logo

🔭 OpenTelemetry

⚡ TL;DR (quick version)
Full observability of traces and metrics is done via native OpenTelemetry support: simply enable it at setup time and it will just work. In the same spirit, it's also possible to do extensive logging.

Observability is a key feature of modern software systems that allows us to clearly see what is going on at any given time.

It is composed from 3 main signals:

  • Logs
  • Traces
  • Metrics

FusionCache has rich logging support via the standard ILogger interface, with various options available to granularly configure it.

For metrics and traces though, no unified abstraction has ever been available for app and library authors to produce signals, and 3rd party services to consume them, in a consistent and cross-platform way.

That changed when OpenTelemetry has been introduced.

From some time now OpenTelemetry has become a fundamental staple in modern software development to bring complete observability to our applications: after the official standard, the semantic conventions and all the needed pieces finally become v1.0, FusionCache happily adopted it as the observability mechanism.

This is an example of the visibility we can achieve, in this case in Honeycomb.io:

An example of the visibility obtainable by using OpenTelemetry, in this case thanks to the Honeycomb SAAS

ℹ️ Please note that I don't have any affiliation, partnership or else with Honeycomb: I just created a free trial to test the OpenTelemetry integration.

Other than that I've used a couple of their free Observability Office Hours to chat with the awesome Martin Thwaites to better understand the right way to name activity sources, which tags to use in the metrics and so on: thanks Martin!

OpenTelemetry in .NET

Normally in other languages there's an OpenTelemetry SDK being made available but the kind folks working on it, so that library authors can use that SDK to integrate into the OpenTelemetry world and communicate with processors, exporters and so no.

This is also true for .NET, but with a nice catch: in .NET there's always been some form of observability support via core primitives like Activity, ActivitySource, Meter and similar classes already part of the BCL, so instead of creating new primitives the OpenTelemetry team decided to use the existing abstractions and "talk" to them: in this way it's possible for library authors not to take a hard dependency on the OpenTelemetry packages and simply use the existing primitives and have the consuming side of the whole OpenTelemetry pipeline interact with them.

Nice, very nice, and this is what FusionCache did.

How to use it

It is possible to opt-in to generate traces and metrics for both:

  • high-level operations: things like GetOrSet/Set/Remove operations, Hit/Miss events, etc
  • low-level operations: things like memory/distributed level operations, backplane events, etc

There's also a new package specific for OpenTelemetry that adds native support to instrument our applications, with FusionCache specific options ready to use, like including low-level signals or not.

It's then possible to simply plug one of the existing OpenTelemetry-compatible exporters for systems like Jaeger, Prometheus or Honeycomb and voilà, there we have full observability of our FusionCache instances.

👩‍💻 Example

Add the package:

PM> Install-Package ZiggyCreatures.FusionCache.OpenTelemetry

and enable either traces, metrics or both for FusionCache.

Without dependency injection we can do this:

// SETUP TRACES
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
  .AddFusionCacheInstrumentation()
  .AddConsoleExporter()
  .Build();

// SETUP METRICS
using var meterProvider = Sdk.CreateMeterProviderBuilder()
  .AddFusionCacheInstrumentation()
  .AddConsoleExporter()
  .Build();

Or via dependency injection, like this:

services.AddOpenTelemetry()
  // SETUP TRACES
  .WithTracing(tracing => tracing
    .AddFusionCacheInstrumentation()
    .AddConsoleExporter()
  )
  // SETUP METRICS
  .WithMetrics(metrics => metrics
    .AddFusionCacheInstrumentation()
    .AddConsoleExporter()
  );

Easy peasy.