This Quick Start guide shows you how to configure your .net applications to send OpenTelemetry traces to Lightstep Observability.
This guide does not provide documentation on application instrumentation. For .net-specific information on instrumentation, please see the .net OpenTelemetry getting started guide.
Sending OpenTelemetry data directly to Lightstep without a Collector for most developer setups will suffice. For non-development setups, however, it is highly recommended that you send OpenTelemetry data to Lightstep Observability by way of the OpenTelemetry Collector. This can be done with or without a Launcher, as we’ll see below.
The sections below contain code snippets only. For full code listings, please see open-telemetry/opentelemetry-dotnet
and open-telemetry/opentelemetry-dotnet-contrib
in the OpenTelemetry GitHub .NET repos.
Pre-Requisites
Before you get started with sending OpenTelemetry data to Lightstep, you will need the following:
- A Lightstep Observability account: create a free account here.
- A Lightstep access token for the Lightstep Observability project you would like to use.
- The OpenTelemetry Getting Started guide for .net.
Install OpenTelemetry Packages
In your application code, you will need to install dependencies and import OpenTelemetry packages before you can send data to Lightstep Observability.
Start by installing the OpenTelemetry Nuget packages.
Start tabs
Console App
1
2
3
dotnet add package OpenTelemetry --version 1.4.0-alpha.2
dotnet add package OpenTelemetry.Exporter.Console --version 1.4.0-alpha.2
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol --version 1.4.0-alpha.2
.NET Core App
1
2
3
4
5
dotnet add package OpenTelemetry --version 1.4.0-alpha.2
dotnet add package OpenTelemetry.Exporter.Console --version 1.4.0-alpha.2
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol --version 1.4.0-alpha.2
dotnet add package OpenTelemetry.Extensions.Hosting --version 1.0.0-rc9.6
dotnet add package OpenTelemetry.Instrumentation.Http --version 1.0.0-rc9.6
End tabs
Where:
OpenTelemetry
is the OpenTelemetry SDK, a reference implementation of the OpenTelemetry API.OpenTelemetry.Exporter.Console
outputs traces to the console during development.OpenTelemetry.Exporter.OpenTelemetryProtocol
exports traces to Lightstep or the OpenTelemetry Collector using the OpenTelemetry Protocol (OTLP).OpenTelemetry.Extensions.Hosting
is used to register the .NET OpenTelemetry provider (.NET Core only)
If you are using a .csproj
file, your dependencies would look like this:
Start tabs
Console App
1
2
3
4
5
6
7
8
9
...
<ItemGroup>
...
<PackageReference Include="OpenTelemetry" Version="1.4.0-alpha.2" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.4.0-alpha.2" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.4.0-alpha.2" />
...
</ItemGroup>
...
.NET Core App
1
2
3
4
5
6
7
8
9
10
11
...
<ItemGroup>
...
<PackageReference Include="OpenTelemetry" Version="1.4.0-alpha.2" />
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.4.0-alpha.2" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.4.0-alpha.2" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.0.0-rc9.6" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.0.0-rc9.6" />
...
</ItemGroup>
...
End tabs
Code Setup
Before you can start sending OpenTelemetry data to Lightstep, you will need to:
- Configure an Exporter (tells OpenTelemetry how to send data to Lightstep)
- Configure a TracerProvider (provides an entrypoint to the OpenTelemetry API, allowing you to create Spans)
Import OpenTelemetry Packages
Now that you’ve installed the OpenTelemetry packages, you will need to import them in your application code.
Open up your application code, and add the following imports to your .cs
file:
Start tabs
Console App
1
2
3
using OpenTelemetry;
using OpenTelemetry.Trace;
using OpenTelemetry.Resources;
.NET Core App
1
2
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
End tabs
Configure
The code snippet below shows how to configure OpenTelemetry for both a Console application and an .NET Core application.
Start tabs
Console App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
// Define some important constants to initialize tracing with
var serviceName = "MyCompany.MyProduct.MyService";
var serviceVersion = "1.0.0";
// Configure important OpenTelemetry settings and the console exporter
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddOtlpExporter(opt =>
{
opt.Endpoint = new Uri("ingest.lightstep.com:443");
opt.Headers = new Metadata
{
{ "lightstep-access-token", Environment.GetEnvironmentVariable("LS_ACCESS_TOKEN")}
};
opt.Credentials = new SslCredentials();
})
.AddSource(serviceName)
.SetResourceBuilder(
ResourceBuilder.CreateDefault()
.AddService(serviceName: serviceName,serviceVersion: serviceVersion))
.Build();
var MyActivitySource = new ActivitySource(serviceName);
...
.NET Core App
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
var serviceName = "MyCompany.MyProduct.MyService";
var serviceVersion = "1.0.0";
var builder = WebApplication.CreateBuilder(args);
// Configure to send data via the OTLP exporter.
// By default, it will send to port 4318, which the collector is listening on.
builder.Services.AddOpenTelemetryTracing(tracerProviderBuilder =>
{
tracerProviderBuilder
.AddOtlpExporter(opt =>
{
opt.Endpoint = new Uri("ingest.lightstep.com:443");
opt.Headers = new Metadata
{
{ "lightstep-access-token", Environment.GetEnvironmentVariable("LS_ACCESS_TOKEN")}
};
opt.Credentials = new SslCredentials();
})
.AddSource(serviceName)
.SetResourceBuilder(
ResourceBuilder.CreateDefault()
.AddService(serviceName: serviceName, serviceVersion: serviceVersion))
.AddHttpClientInstrumentation()
.AddAspNetCoreInstrumentation();
});
var app = builder.Build();
...
End code tabs
More on OtlpExporter
configuration can be found here
Notes: Configuration
- Be sure to set the
LS_ACCESS_TOKEN
environment variable Lightstep access token before running your application:export LS_ACCESS_TOKEN=<LS_ACCESS_TOKEN>
. AddOtlpExporter
sets up OpenTelemetry to send data to Lightstep using the OpenTelemetry Protocol (OTLP). I recommend sticking with OTLP in your clients.SetResourceBuilder
creates resources: key-value pairs which describe your service. It’s important to add as many relevant resources as you can, as this improves the quality of your tracing data. See Semantic Conventions for ideas on what to add. The two that are most important to add areservice.name
andservice.version
. If you don’t name your service, it will get namedunknown_service
by default.AddAspNetCoreInstrumentation()
enables .NET Core instrumentation. This does not apply to Console applications.AddHttpClientInstrumentation()
enables instrumentation for HTTP requests. If you want to instrument gRPC requests instead, useAddGrpcClientInstrumentation()
.
It is important to add instrumentation for every supported library. You can find all of the available instrumentation here.
To use HTTP instead of gRPC, the AddOtlpExporter
configuration would be altered as follows:
1
2
3
4
5
6
7
8
9
.AddOtlpExporter(opt =>
{
opt.Endpoint = new Uri("https://ingest.lightstep.com/traces/otlp/v0.9");
opt.Headers = new Metadata
{
{ "lightstep-access-token", Environment.GetEnvironmentVariable("LS_ACCESS_TOKEN")}
};
opt.Credentials = new SslCredentials();
})
More info on using OtlpExportProtocol.HttpProtobuf
can be found here.
Notes: Using a Collector
If you wish to use an OpenTelemetry Collector, the configuration for AddOtlpExporter
would look like this:
Start tabs
Collector (gRPC)
1
2
3
4
5
6
...
.AddOtlpExporter(opt =>
{
opt.Endpoint = new Uri("http://0.0.0.0:4317");
})
...
Collector (HTTP)
1
2
3
4
5
6
7
...
.AddOtlpExporter(opt =>
{
opt.Protocol = OtlpExportProtocol.HttpProtobuf;
opt.Endpoint = new Uri("http://0.0.0.0:4318/v1/traces");
})
...
Noteworthy items:
- When
opt.Protocol
is not specified, the default value isOtlpExportProtocol.Grpc
. - More info on using
OtlpExportProtocol.HttpProtobuf
can be found here.
End code tabs
Troubleshooting
Operation Names Aren’t Human Readable
Symptom
Operation names in Lightstep Observability are not clear or are very long and unhelpful.
This feature requires a Satellite upgrade to the June 2020 release.
This can happen because the auto-installer is getting the name from a parameter in Datadog that might not be appropriate for your language. You can set that parameter to different values to see if that results in better operation names.
You can use either the resource
or the name
parameter, or both.
Which to use (or if using the both, the order to use) depends on the language of the installer. Refer to the Datadog docs for more info.
To configure how the operation name is set, add the following parameter to your Microsatellite configuration:
1
2
3
4
5
receivers:
datadog:
operation_name_extractors:
- resource
- name
If you set both, the order of the values matters. Lightstep Observability tries to extract a name from the first variable value. If one isn’t found, it looks for the second value and uses that.
Check for multiple versions of OpenTelemetry
If multiple versions of OpenTelemetry are installed, traces are not created or propagated correctly. Check your dependencies to ensure that only a single version of OpenTelemetry is installed.
Check that security is configured correctly
Lightstep’s public Microsatellites only accept spans via a secure endpoint. If you see security related errors (e.g., Netty TLS errors with Java), you may not have the necessary root certificate installed on the machine where the tracer is running. To add a root certificate, see the documentation about encrypted connections.
Check that Metrics are enabled in the OpenTelemetry Collector
Not seeing metrics come through the OpenTelemetry Collector? Make sure that you have defined a Metrics pipeline in your Collector’s YAML config file.