Coder Social home page Coder Social logo

elastic / elastic-otel-dotnet Goto Github PK

View Code? Open in Web Editor NEW
15.0 5.0 2.0 1.4 MB

Elastic OpenTelemetry .NET Distribution

License: Apache License 2.0

C# 90.27% Batchfile 0.03% Shell 0.05% F# 9.65%
elastic observability opentelemetry opentelemetry-dotnet

elastic-otel-dotnet's Introduction

Pull Request Validation

Elastic Distribution for OpenTelemetry .NET

The Elastic Distribution for OpenTelemetry .NET provides a zero code change extension to OpenTelemetry SDK for .NET. These extensions ensure a smooth and rich out of the box experience with Elastic Observability through strictly OpenTelemetry native means.

This ensures there are no new concepts to learn with the full OpenTelemetry ecosystem remains at ones fingertips. Read more about the concept of OpenTelemetry Distributions.

The Elastic Distribution for OpenTelemetry .NET includes some Elastic-specific processors to ensure the best compatibility when exporting OpenTelemetry signal data Elastic Observability. The distribution also preconfigures the collection of tracing, metrics and logs signals, applying some opinionated defaults, such as which sources are collected by default. The distribution also ensures that the OTLP exporter is enabled by default.

IMPORTANT: The Elastic Distribution for OpenTelemetry .NET is currently in early alpha release status. It is not yet feature complete and may contain bugs. We are actively working on improving the distribution and adding new features.

If you would like to experience the alpha and help us improve the distribution by providing early feedback, you can follow the steps below to get started.

Getting started

As the distribution is a lightweight extension of the OpenTelemetry SDK, you should be broadly familiar with the OpenTelemetry SDK concepts and instrumenting applications using the Microsoft diagnostic APIs. If you are not, we recommend you read the OpenTelemetry SDK documentation first.

It's an explicit goal of this distribution to introduce no new concepts as defined by the wider OpenTelemetry community.

Prerequisites

The current documentation and examples are written with .NET 6 and newer applications in mind. Before continuing, ensure that you have a supported .NET SDK version installed locally.

Installation

To get started with the Elastic Distribution for OpenTelemetry .NET, you must add the Elastic.OpenTelemetry NuGet package to your project. This can be achieved by adding the package reference to your project file.

<PackageReference Include="Elastic.OpenTelemetry" Version="<LATEST>" />

NOTE: Replace the <LATEST> placeholder with the latest available package from NuGet.org.

After adding the package reference, you can start using the Elastic Distribution for OpenTelemetry .NET in your application. The distribution includes a transitive dependency on the OpenTelemetry SDK, so you do not need to add the OpenTelemetry SDK package to your project, although doing so will cause no harm and may be used to opt into newer SDK versions before the Elastic Distribution for OpenTelemetry .NET references them.

The Elastic Distribution for OpenTelemetry .NET is designed to be easy to use and integrate into your applications. This includes applications which have previously used the OpenTelemetry SDK directly. In situations where the OpenTelemetry SDK is already used, the only required change is
to add the Elastic.OpenTelemetry NuGet package to the project. Doing so will automatically switch to the opinionated configuration provided by the Elastic Distribution for OpenTelemetry .NET.

ASP.NET Core usage

A common requirement is to instrument ASP.NET Core applications based on the Microsoft.Extensions.Hosting libraries which provide dependency injection via an IServiceProvider.

The OpenTelemetry SDK and the Elastic Distribution for OpenTelemetry .NET provide extension methods to enable observability features in your application by adding a few lines of code.

In this section, we'll focus on instrumenting an ASP.NET Core minimal API application using the Elastic OpenTelemetry distribution. Similar steps can also be used to instrument other ASP.NET Core workloads and other host-based applications such as worker services.

NOTE: These examples assume the use of the top-level statements feature introduced in C# 9.0 and the default choice for applications created using the latest templates.

To take advantage of the OpenTelemetry SDK instrumentation for ASP.NET Core, add the following NuGet package to your project:

<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="<LATEST>" />

NOTE: Replace the <LATEST> placeholder with the latest available package from NuGet.org.

This package includes instrumentation to collect traces for requests handled by ASP.NET Core endpoints.

NOTE: The ASP.NET Core instrumentation is not included by default in the Elastic Distribution for OpenTelemetry .NET. As with all optional instrumentation libraries, you can choose to include them in your application by adding a suitable package reference.

Inside the Program.cs file of the ASP.NET Core application, add the following two using directives:

using OpenTelemetry;
using OpenTelemetry.Trace;

The OpenTelemetry SDK provides extension methods on the IServiceCollection to support enabling the providers and configuring the SDK. The Elastic Distribution for OpenTelemetry .NET overrides the default SDK registration, adding several opinionated defaults.

In the minimal API template, the WebApplicationBuilder exposes a Services property that can be used to register services with the dependency injection container. To enable tracing and metrics collection, ensure that the OpenTelemetry SDK is registered.

var builder = WebApplication.CreateBuilder(args);

builder.Services
	.AddHttpClient() <1>
	.AddOpenTelemetry() <2>
		.WithTracing(t => t.AddAspNetCoreInstrumentation()); <3>

<1> The AddHttpClient method registers the IHttpClientFactory service with the dependency injection container. This is NOT required to enable OpenTelemetry, but the example endpoint will use it to send an HTTP request.

<2> The AddOpenTelemetry method registers the OpenTelemetry SDK with the dependency injection container. When available, the Elastic Distribution for OpenTelemetry .NET will override this to add opinionated defaults.

<3> Configure tracing to instrument requests handled by ASP.NET Core.

With these limited changes to the Program.cs file, the application is now configured to use the OpenTelemetry SDK and the Elastic Distribution for OpenTelemetry .NET to collect traces and metrics, which are exported via OTLP.

To demonstrate the tracing capabilities, add a simple endpoint to the application:

app.MapGet("/", async (IHttpClientFactory httpClientFactory) =>
{
	using var client = httpClientFactory.CreateClient();

	await Task.Delay(100);
	var response = await client.GetAsync("http://elastic.co"); <1>
	await Task.Delay(50);

	return response.StatusCode == System.Net.HttpStatusCode.OK ? Results.Ok() : Results.StatusCode(500);
});

<1> Using this URL will require two redirects, allowing us to see multiple spans in the trace.

The Elastic Distribution for OpenTelemetry .NET will automatically enable the exporting of signals via the OTLP exporter. This exporter requires that endpoint(s) are configured. A common mechanism for configuring endpoints is via environment variables.

This demo uses an Elastic Cloud deployment as the destination for our observability data. From Kibana running in Elastic Cloud, navigate to the observability set up guides. Select the OpenTelemetry option to view the configuration details that should be supplied to the application.

Elastic Cloud OpenTelemetry configuration

Configure environment variables for the application either in launchSettings.json or in the environment where the application is running.

Once configured, run the application and make a request to the root endpoint. A trace will be generated and exported to the OTLP endpoint.

To view the traces, you can use the Elastic APM UI.

Minimal API request trace sample in the Elastic APM UI

Microsoft.Extensions.Hosting usage

For console applications, services, etc that are written against a builder that exposes an IServiceCollection you can install this package:

<PackageReference Include="Elastic.OpenTelemetry" Version="<LATEST>" />

NOTE: Replace the <LATEST> placeholder with the latest available package from NuGet.org.

Ensure you call AddOpenTelemetry to enable OpenTelemetry just as you would when using OpenTelemetry directly. Our package intercepts this call to set up our defaults, but can be further build upon as per usual:

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddOpenTelemetry()
	.ConfigureResource(r => r.AddService(serviceName: "MyService"))
	.WithTracing(t => t.AddSource(Worker.ActivitySourceName).AddConsoleExporter())
	.WithMetrics(m => m.AddMeter(Worker.MeterName).AddConsoleExporter());

Manual Instrumentation usage

In environments where an IServiceCollection is unavailable you may manually start instrumenting by creating an instance of ElasticOpenTelemetryBuilder.

await using var session = new ElasticOpenTelemetryBuilder()
    .WithTracing(b => b.AddSource(ActivitySourceName))
    .Build();

This will setup instrumentation for as long as session is not disposed. We would generally expect the session to live for the life of the application.

ElasticOpenTelemetryBuilder is an implementation of IOpenTelemetryBuilder.

This is important to know because any instrumentation configuration is automatically exposed by the base OpenTelemetry package as extension methods on IOpenTelemetryBuilder. You will not lose functionality by using our builder.

elastic-otel-dotnet's People

Contributors

bmorelli25 avatar dependabot[bot] avatar mpdreamz avatar reakaleek avatar stevejgordon avatar v1v avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

elastic-otel-dotnet's Issues

.NET - GA release

GA release of the Elastic distro of the OTel .NET SDK/API/Instrumentations

Decide whether Elastic.OpenTelemetry acts as a base package or meta package.

Decide what we want our user story to be

  • Package Elastic.OpenTelemetry as a base package for configuration / setup and minimal instrumentation. Have a .FullFramework and .AspNetCore packages to include more supported instrumentations.

  • A single Elastic.OpenTelemetry package that includes all supported instrumentations OOTB.

Add migration guide docs

We should have a migration section in the docs which covers migrating two scenarios:

  • Migrate from Elastic APM Agent (ASP.NET Core)
  • Migrate for "vanilla" OpenTelemetry SDK (ASP.NET Core) where the before code adds OTLP + instrumentation. Show that we can reduce the code needed for this common scenario.

.NET Alpha release

Alpha release of the Elastic distro of the OTel .NET SDK/API/Instrumentations

Agent: Produce a simple, minimal code agent with opinionated defaults

We now have a basic POC completed for an Agent distribution. This identified some limitations in the design of the API surface which should be addressed. For example:

  • We should not force our notion of a Service \ Resource on the consumer. Instead, we should provide hooks such that the built-in ResourceBuilder can be accessed by consumers for more advanced scenarios.
  • We should register default sources to listen to a recommended set of ActivitySource providers.
  • We should export by default using OTLP to an Elastic backend.
  • We should support consumers registering processors and exporters which we then apply to the builders in the appropriate order.

Docs: Example project ASP.NET Core

We should include a working example project for an ASP.NET Core application that demonstrates registering the agent and including custom spans.

APM libraries and this library

Hey Elastic!

Thanks for bridging the gap between OpenTelemetry and the native features of ElasticSearch telemetry.

I stumbled upon this repository, and I have been battling a lot with how to configure apps correctly.

Currently, we use Serilog, with the EcsTextFormatter and the APM Serilog enricher with the Serilog console sink in our k8s pods, which gets picked up by a Filebeat scraping the stdout of the containers and with manual instrumentation of APM.

All of our application code currently uses the MEL ILogger<T>, with Serilog behind the scenes, and we also use message templates across our solutions.

I was wondering, since I don't seem like I can find any example that shows this. How do these APM libraries, and this library, cooperate? Is it either this, or the APM library?

I look forward to hearing from you.

Investigate APM UI breaks e.g. metrics dashboard

We should expand the examples into a small microservice application and send traces via both OTel SDK (OTLP) and Elastic APM (Intake v2) to compare the UI for traces, metrics, dashboards, etc.

From this, we should formulate plans for how to address gaps, where fixes should be made (processors, APM data, et.c) and open relevant issues.

Agent: Support resource customisation

Consumers should be able to provide their own resource configuration when initialising the agent. We should always add our distribution attributes:

  • telemetry.distro.name
  • telemetry.distro.version

Avoid interim `IServiceProvider`

One of our overloads of AddElasticOpenTelemetry currently builds an IServiceProvider in order to access the builder. Can we avoid this in the design?

Agent: Integration with `IServiceProvider` [Research]

The existing OpenTelemetry SDK includes support for integrating with IServiceProvider. For example, the resource builder can read from a resolved IConfiguration instance. We should ensure that our distribution behaves nicely with this usage pattern and that we don't prevent any scenarios that depend on the IServiceProvider mechanisms.

Example:

var builder = WebApplication.CreateBuilder(args);

const string serviceName = "roll-dice";

builder.Logging.AddOpenTelemetry(options =>
{
    options
        .SetResourceBuilder(
            ResourceBuilder.CreateDefault()
                .AddService(serviceName))
        .AddConsoleExporter();
});
builder.Services.AddOpenTelemetry()
      .ConfigureResource(resource => resource.AddService(serviceName))
      .WithTracing(tracing => tracing
          .AddAspNetCoreInstrumentation()
          .AddConsoleExporter())
      .WithMetrics(metrics => metrics
          .AddAspNetCoreInstrumentation()
          .AddConsoleExporter());

var app = builder.Build();

Auto Instrumentation packaging

Ensure we have our own artefacts for the auto instrumentation.

We want to ensure the setting of the plugin environment is as seamless as possible.

How to use elastic features while still using "vanilla" otel?

Hi,

we are long time elastic users but decided a while ago that auto-instrumentation and the elastic nuget APM packages were not the best option for us and decided to fully switch to OTel and live with the shortcomings (i.e. metrics in Kibana APM, etc.).
We have some special configurations and stuff going on in OTel so we would still like to use the "vanilla" configuration way but also be able to get a better integration into elastic that this package may provide.
Is there (apart from manually checking the code) way to integrate your processors, etc. into the OTel configuration or a chance that in the future there might be an extention method that provided this?

something like

services.AddOpenTelemetry()
                .WithTracing(builder =>
                {
                    ...
                    builder.AddElasticTracingExtensions();
                    ...
                })
                .WithMetrics(builder =>
                {
                    ...
                    builder.AddElasticMetricsExtensions();
                    ...
                })
                .WithLogging(....);

This would allow us to still do it on our own (like configure instrumentation, exporters, etc) but still get some of the goodies that you are providing apart from the "easy" installation (which is of course great for some users and I really like the way this is going regard the use of OTel vs. Elastic APM).

Regards,
Jan

GA Documentation

Define a set of documentation required for GA and create those docs.

Agent: Diagnostic logging

Use EventSource / DiagnosticSource to emit library "logging" from the distribution code. We should implement a listener which logs to a file in a default location.

In a (separate) library, we could include an ILogger implementation that listens to events and logs them. This should also listen to OpenTelemetry EventSources so that these can be included in diagnostic logging.

This is an important element to make this agent easy to support.

Agent: Send custom UserAgent and agent details

We should override the UserAgent when exporting data, such that we can easily identify the version of the distribution. We should likely still include details of the version of the Otel SDK on which the agent is wrapping.

We should ensure that the data we send to APM also includes correct attributes such that the agent.name and agent.version are populated based on our agent distribution.

Default metrics dashboards

Let's make sure metrics dashboards are shown for the OTel distro in the Metrics tab and that the metrics shown are meaningful. This task might also require some UI task coordination and portable dashboard work.
If work was done for this issue, it's possible some of it could be reused.

Ensure AddOtlpExporter can be called multiple times.

Right now we add it automatically when calling AddOpenTelemetry() as a cross cutting exporter using UseOtlpExporter().

If later signal specific calls add it using AddOtlpExporter they will get an exception.

Unhandled exception. System.NotSupportedException: Signal-specific AddOtlpExporter methods and the cross-cutting UseOtlpExporter method being invoked on the same IServiceCollect
ion is not supported.

Mpdreamz/opentelemetry-demo@b5ae9bf.

I personally think it be better if this was a NOOP if the AddOtlpExporter does not throw on repeated invocations if the configuration matches the already configured OTLP exporter.

We'll need to investigate if we think this is possible and a good idea and then propose this upstream.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.