When this question was asked OpenTelemetry standard and implementation was still quite young. Even as I write this answer some things are not quite fully implemented or settled yet but the TLDR; Yes, its possible, it works and its epic!
A good reference I go back to quite often can be found here
You need to understand there are three key things in Observability paradigm. Trace, Logs and Metrics. All these are separate, work and implemented separately.
The key findings that I have learnt so far to configure this in .NET Framework and AspNetCore are the same apart from how you configure it.
Trace and Metrics work with SDK Builders and Logging uses the ILoggerProvider pattern
These examples use the non DI methods for manual configuration. You
can use Contrib.Hosting and read the guides there for DI approach.
Trace
System.Diagnostics.Activity.DefaultIdFormat = System.Diagnostics.ActivityIdFormat.W3C;
That is required in NetFramework apps in your global in NetCore that is default
var traceProviderBuilder = Sdk.CreateTracerProviderBuilder();
Gets your builder setup
traceProviderBuilder
.AddSource("*")
.SetResourceBuilder(
ResourceBuilder.CreateDefault()
.AddService(ResourceNameHelper.ServiceName)
.AddAttributes(otelAttributes)
.AddTelemetrySdk());
There's a few things happening here
- AddSource("*") subsribes the SDK to ALL Events (System.Diagnostics) - I use this for ease of use
- SetResourceBuilder is used to set the name of your service so that Elastics can group these
- OtelAttributes is a KeyValue collection that has
new KeyValuePair<string, object>("deployment.environment", environmentName) in it so you can get the Environment drop down working in Elastics
That is the core configuration required so you can subscribe to your own Traces but you want to add Instrumentation afterwards like
AddAspNetInstrumentation(options => { options.RecordException = true; })
.AddHttpClientInstrumentation((httpConfig) => { httpConfig.RecordException = true; })
AddSqlClientInstrumentation((sqlConfig) => { sqlConfig.EnableConnectionLevelAttributes = true; sqlConfig.SetDbStatement = true; })
.AddAWSInstrumentation()
Now comes the import part, the OtlpExporter
traceProviderBuilder.AddOtlpExporter(options)
passing in your options
otlpExporter.Protocol = OtlpExportProtocol.Grpc;
otlpExporter.Endpoint = new Uri(otlpEndpoint);
otlpExporter.Headers = otlpHeaders;
The header is bearer token that you need from Kibana.
And finally you build it
.Build()
When manually configuring like this you need to manage the disposal of the SDK. That is why using DI is recommended.
Phew.. That is quite some configuration going on there. But once you get that running in the most basic form you will start to see Traces appear in the Observability part of Elastics. The first time you do this you need to give Elastics some time to sort out its indexing and trace streams (in the cloud version all that is done automagically given you have the NEW version of APM enabled in Fleet - Theres no mention of OpenTelemtry configuration on that page. just copy and paste the URLs and keys it gives you)
Metrics
The same applies for Metrics basically.. you have to do it all again but using
_meterProvider = Sdk.CreateMeterProviderBuilder().AddRuntimeMetrics()
And then all the instrumentation and OtlpExporter options.
In Framework the Metrics are quite limited abotu runtime metrics but in AspNetCore they are decent.
Logging
This is quite easy to implement following the Dotnet OpenTelemetry documentation but as of today is a bit buggy (Hopefully it will be stable in version 1.3)
I am sorry about long post but I hope this helps people a bit since I my self struggled with little or no documentation for this on Elastics, OpenTelemetry or the Dotnet Github pages.