Enable Azure Monitor OpenTelemetry for .NET, Node.js, Python and Java applications
Article
This article describes how to enable and configure OpenTelemetry-based data collection to power the experiences within Azure Monitor Application Insights. We will walk through how to install the "Azure Monitor OpenTelemetry Distro." To learn more about OpenTelemetry concepts, see the OpenTelemetry overview or OpenTelemetry FAQ.
OpenTelemetry Release Status
OpenTelemetry offerings are available for .NET, Node.js, Python and Java applications.
We have not tested the Azure Monitor OpenTelemetry Distro running side-by-side with the OpenTelemetry Community Package. We recommend you uninstall any OpenTelemetry-related packages before installing the Distro.
If you are upgrading from an earlier 3.x version, you may be impacted by changing defaults or slight differences in the data we collect. For more information, see the migration section in the release notes.
3.4.0,
3.3.0,
3.2.0, and
3.1.0
To enable Azure Monitor Application Insights, you will make a minor modification to your application and set your "Connection String". The Connection String tells your application where to send the telemetry the Distro collects, and it's unique to you.
Add UseAzureMonitor() to your application startup. Depending on your version of .NET, this will be in either your startup.cs or program.cs class.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTelemetry().UseAzureMonitor();
var app = builder.Build();
app.Run();
Add the Azure Monitor Exporter to each OpenTelemetry signal in application startup. Depending on your version of .NET, this will be in either your startup.cs or program.cs class.
var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddAzureMonitorTraceExporter();
var metricsProvider = Sdk.CreateMeterProviderBuilder()
.AddAzureMonitorMetricExporter();
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddOpenTelemetry(options =>
{
options.AddAzureMonitorLogExporter();
});
});
Java autoinstrumentation is enabled through configuration changes; no code changes are required.
Point the JVM to the jar file by adding -javaagent:"path/to/applicationinsights-agent-3.4.13.jar" to your application's JVM args.
B. Set via Configuration File - Java Only (Recommended)
Create a configuration file named applicationinsights.json, and place it in the same directory as applicationinsights-agent-3.4.13.jar with the following content:
If you set the connection string in more than one place, we adhere to the following precendence:
Code
Environment Variable
Configuration File
Confirm data is flowing
Run your application and open your Application Insights Resource tab in the Azure portal. It might take a few minutes for data to show up in the portal.
That's it. Your application is now being monitored by Application Insights. Everything else below is optional and available for further customization.
If you have two or more services that emit telemetry to the same Application Insights resource, you're required to set Cloud Role Names to represent them properly on the Application Map.
As part of using Application Insights instrumentation, we collect and send diagnostic data to Microsoft. This data helps us run and improve Application Insights. To learn more, see Statsbeat in Azure Application Insights.
Automatic data collection
The distros automatically collect data by bundling in OpenTelemetry "instrumentation libraries".
The OpenTelemetry-based offerings currently emit all OpenTelemetry metrics as Custom Metrics and Performance Counters in Metrics Explorer. For .NET, Node.js, and Python, whatever you set as the meter name becomes the metrics namespace.
Add a community instrumentation library
You can collect more data automatically when you include instrumentation libraries from the OpenTelemetry community.
Note
We don't support and cannot guarantee the quality of community instrumentation libraries. If you would like to suggest a community instrumentation library us to include in our distro, post or up-vote an idea in our feedback community.
Caution
Some instrumentation libraries are based on experimental OpenTelemetry semantic specifications. Adding them may leave you vulnerable to future breaking changes.
To add a community library, use the ConfigureOpenTelemetryMeterProvider or ConfigureOpenTelemetryTraceProvider methods.
The following example demonstrates how the Runtime Instrumentation can be added to collect additional metrics.
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddRuntimeInstrumentation());
builder.Services.AddOpenTelemetry().UseAzureMonitor();
var app = builder.Build();
app.Run();
The following example demonstrates how the Runtime Instrumentation can be added to collect additional metrics.
var metricsProvider = Sdk.CreateMeterProviderBuilder()
.AddRuntimeInstrumentation()
.AddAzureMonitorMetricExporter();
You cannot extend the Java Distro with community instrumentation libraries. To request that we include another instrumentation library, please open an issue on our GitHub page. You can find a link to our GitHub page in Next Steps.
Other OpenTelemetry Instrumentations are available here and could be added using TraceHandler in ApplicationInsightsClient.
The following table represents the currently supported custom telemetry types:
Language
Custom Events
Custom Metrics
Dependencies
Exceptions
Page Views
Requests
Traces
ASP.NET Core
OpenTelemetry API
Yes
Yes
Yes
Yes
iLogger API
Yes
AI Classic API
Java
OpenTelemetry API
Yes
Yes
Yes
Yes
Logback, Log4j, JUL
Yes
Yes
Micrometer Metrics
Yes
AI Classic API
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Node.js
OpenTelemetry API
Yes
Yes
Yes
Yes
Console, Winston, Bunyan
Yes
AI Classic API
Yes
Yes
Yes
Yes
Yes
Yes
Yes
Python
OpenTelemetry API
Yes
Yes
Yes
Yes
Python Logging Module
Yes
Note
Application Insights Java 3.x listens for telemetry that's sent to the Application Insights Classic API. Similarly, Application Insights Node.js 3.x collects events created with the Application Insights Classic API. This makes upgrading easier and fills a gap in our custom telemetry support until all custom telemetry types are supported via the OpenTelemetry API.
Add Custom Metrics
Note
Custom Metrics are under preview in Azure Monitor Application Insights. Custom metrics without dimensions are available by default. To view and alert on dimensions, you need to opt-in.
Consider collecting more metrics beyond what's provided by the instrumentation libraries.
The OpenTelemetry API offers six metric "instruments" to cover various metric scenarios and you need to pick the correct "Aggregation Type" when visualizing metrics in Metrics Explorer. This requirement is true when using the OpenTelemetry Metric API to send metrics and when using an instrumentation library.
The following table shows the recommended aggregation types for each of the OpenTelemetry Metric Instruments.
OpenTelemetry Instrument
Azure Monitor Aggregation Type
Counter
Sum
Asynchronous Counter
Sum
Histogram
Min, Max, Average, Sum and Count
Asynchronous Gauge
Average
UpDownCounter
Sum
Asynchronous UpDownCounter
Sum
Caution
Aggregation types beyond what's shown in the table typically aren't meaningful.
The OpenTelemetry Specification
describes the instruments and provides examples of when you might use each one.
Tip
The histogram is the most versatile and most closely equivalent to the Application Insights GetMetric Classic API. Azure Monitor currently flattens the histogram instrument into our five supported aggregation types, and support for percentiles is underway. Although less versatile, other OpenTelemetry instruments have a lesser impact on your application's performance.
Application startup must subscribe to a Meter by name.
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddMeter("OTel.AzureMonitor.Demo"));
builder.Services.AddOpenTelemetry().UseAzureMonitor();
var app = builder.Build();
app.Run();
The Meter must be initialized using that same name.
var meter = new Meter("OTel.AzureMonitor.Demo");
Histogram<long> myFruitSalePrice = meter.CreateHistogram<long>("FruitSalePrice");
var rand = new Random();
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "red"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "green"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "red"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
public class Program
{
private static readonly Meter meter = new("OTel.AzureMonitor.Demo");
public static void Main()
{
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("OTel.AzureMonitor.Demo")
.AddAzureMonitorMetricExporter()
.Build();
Histogram<long> myFruitSalePrice = meter.CreateHistogram<long>("FruitSalePrice");
var rand = new Random();
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "red"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "green"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "apple"), new("color", "red"));
myFruitSalePrice.Record(rand.Next(1, 1000), new("name", "lemon"), new("color", "yellow"));
System.Console.WriteLine("Press Enter key to exit.");
System.Console.ReadLine();
}
}
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.Meter;
public class Program {
public static void main(String[] args) {
Meter meter = GlobalOpenTelemetry.getMeter("OTEL.AzureMonitor.Demo");
DoubleHistogram histogram = meter.histogramBuilder("histogram").build();
histogram.record(1.0);
histogram.record(100.0);
histogram.record(30.0);
}
}
Application startup must subscribe to a Meter by name.
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddMeter("OTel.AzureMonitor.Demo"));
builder.Services.AddOpenTelemetry().UseAzureMonitor();
var app = builder.Build();
app.Run();
The Meter must be initialized using that same name.
var process = Process.GetCurrentProcess();
var meter = new Meter("OTel.AzureMonitor.Demo");
ObservableGauge<int> myObservableGauge = meter.CreateObservableGauge("Thread.State", () => GetThreadState(process));
private static IEnumerable<Measurement<int>> GetThreadState(Process process)
{
foreach (ProcessThread thread in process.Threads)
{
yield return new((int)thread.ThreadState, new("ProcessId", process.Id), new("ThreadId", thread.Id));
}
}
public class Program
{
private static readonly Meter meter = new("OTel.AzureMonitor.Demo");
public static void Main()
{
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter("OTel.AzureMonitor.Demo")
.AddAzureMonitorMetricExporter()
.Build();
var process = Process.GetCurrentProcess();
ObservableGauge<int> myObservableGauge = meter.CreateObservableGauge("Thread.State", () => GetThreadState(process));
System.Console.WriteLine("Press Enter key to exit.");
System.Console.ReadLine();
}
private static IEnumerable<Measurement<int>> GetThreadState(Process process)
{
foreach (ProcessThread thread in process.Threads)
{
yield return new((int)thread.ThreadState, new("ProcessId", process.Id), new("ThreadId", thread.Id));
}
}
}
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.Meter;
public class Program {
public static void main(String[] args) {
Meter meter = GlobalOpenTelemetry.getMeter("OTEL.AzureMonitor.Demo");
meter.gaugeBuilder("gauge")
.buildWithCallback(
observableMeasurement -> {
double randomNumber = Math.floor(Math.random() * 100);
observableMeasurement.record(randomNumber, Attributes.of(AttributeKey.stringKey("testKey"), "testValue"));
});
}
}
const { ApplicationInsightsClient, ApplicationInsightsConfig } = require("applicationinsights");
const appInsights = new ApplicationInsightsClient(new ApplicationInsightsConfig());
const customMetricsHandler = appInsights.getMetricHandler().getCustomMetricsHandler();
const meter = customMetricsHandler.getMeter();
let gauge = meter.createObservableGauge("gauge");
gauge.addCallback((observableResult: ObservableResult) => {
let randomNumber = Math.floor(Math.random() * 100);
observableResult.observe(randomNumber, {"testKey": "testValue"});
});
from typing import Iterable
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import metrics
from opentelemetry.metrics import CallbackOptions, Observation
configure_azure_monitor(
connection_string="<your-connection-string>",
)
meter = metrics.get_meter_provider().get_meter("otel_azure_monitor_gauge_demo")
def observable_gauge_generator(options: CallbackOptions) -> Iterable[Observation]:
yield Observation(9, {"test_key": "test_value"})
def observable_gauge_sequence(options: CallbackOptions) -> Iterable[Observation]:
observations = []
for i in range(10):
observations.append(
Observation(9, {"test_key": i})
)
return observations
gauge = meter.create_observable_gauge("gauge", [observable_gauge_generator])
gauge2 = meter.create_observable_gauge("gauge2", [observable_gauge_sequence])
input()
Add Custom Exceptions
Select instrumentation libraries automatically report exceptions to Application Insights.
However, you may want to manually report exceptions beyond what instrumentation libraries report.
For instance, exceptions caught by your code aren't ordinarily reported. You may wish to report them
to draw attention in relevant experiences including the failures section and end-to-end transaction views.
const { ApplicationInsightsClient, ApplicationInsightsConfig } = require("applicationinsights");
const appInsights = new ApplicationInsightsClient(new ApplicationInsightsConfig());
const tracer = appInsights.getTraceHandler().getTracer();
let span = tracer.startSpan("hello");
try{
throw new Error("Test Error");
}
catch(error){
span.recordException(error);
}
The OpenTelemetry Python SDK is implemented in such a way that exceptions thrown are automatically captured and recorded. See the following code sample for an example of this behavior.
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace
configure_azure_monitor(
connection_string="<your-connection-string>",
)
tracer = trace.get_tracer("otel_azure_monitor_exception_demo")
# Exception events
try:
with tracer.start_as_current_span("hello") as span:
# This exception will be automatically recorded
raise Exception("Custom exception message.")
except Exception:
print("Exception raised")
If you would like to record exceptions manually, you can disable that option
within the context manager and use record_exception() directly as shown in the following example:
...
with tracer.start_as_current_span("hello", record_exception=False) as span:
try:
raise Exception("Custom exception message.")
except Exception as ex:
# Manually record exception
span.record_exception(ex)
...
Add Custom Spans
You may want to add a custom span in two scenarios. First, when there's a dependency request not already collected by an instrumentation library. Second, when you wish to model an application process as a span on the end-to-end transaction view.
The Activity and ActivitySource classes from the System.Diagnostics namespace represent the OpenTelemetry concepts of Span and Tracer, respectively. You create ActivitySource directly by using its constructor instead of by using TracerProvider. Each ActivitySource class must be explicitly connected to TracerProvider by using AddSource(). That's because parts of the OpenTelemetry tracing API are incorporated directly into the .NET runtime. To learn more, see Introduction to OpenTelemetry .NET Tracing API.
internal static readonly ActivitySource activitySource = new("ActivitySourceName");
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddSource("ActivitySourceName"));
builder.Services.AddOpenTelemetry().UseAzureMonitor();
var app = builder.Build();
app.MapGet("/", () =>
{
using (var activity = activitySource.StartActivity("CustomActivity"))
{
// your code here
}
return $"Hello World!";
});
app.Run();
When calling StartActivity it will default to ActivityKind.Internal but you can provide any other ActivityKind.
ActivityKind.Client, ActivityKind.Producer, and ActivityKind.Internal are mapped to Application Insights dependencies.
ActivityKind.Server and ActivityKind.Consumer are mapped to Application Insights requests.
Note
The Activity and ActivitySource classes from the System.Diagnostics namespace represent the OpenTelemetry concepts of Span and Tracer, respectively. You create ActivitySource directly by using its constructor instead of by using TracerProvider. Each ActivitySource class must be explicitly connected to TracerProvider by using AddSource(). That's because parts of the OpenTelemetry tracing API are incorporated directly into the .NET runtime. To learn more, see Introduction to OpenTelemetry .NET Tracing API.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("ActivitySourceName")
.AddAzureMonitorTraceExporter()
.Build();
var activitySource = new ActivitySource("ActivitySourceName");
using (var activity = activitySource.StartActivity("CustomActivity"))
{
// your code here
}
When calling StartActivity it will default to ActivityKind.Internal but you can provide any other ActivityKind.
ActivityKind.Client, ActivityKind.Producer, and ActivityKind.Internal are mapped to Application Insights dependencies.
ActivityKind.Server and ActivityKind.Consumer are mapped to Application Insights requests.
Use the OpenTelemetry annotation
The simplest way to add your own spans is by using OpenTelemetry's @WithSpan annotation.
Spans populate the requests and dependencies tables in Application Insights.
Add opentelemetry-instrumentation-annotations-1.21.0.jar (or later) to your application:
By default, the span ends up in the dependencies table with dependency type InProc.
For methods representing a background job not captured by autoinstrumentation, we recommend applying the attribute kind = SpanKind.SERVER to the @WithSpan annotation to ensure they appear in the Application Insights requests table.
Use the OpenTelemetry API
If the preceding OpenTelemetry @WithSpan annotation doesn't meet your needs,
you can add your spans by using the OpenTelemetry API.
Add opentelemetry-api-1.0.0.jar (or later) to your application:
The OpenTelemetry API can be used to add your own spans, which appear in the requests and dependencies tables in Application Insights.
The code example shows how to use the tracer.start_as_current_span() method to start, make the span current, and end the span within its context.
...
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
# The "with" context manager starts, makes the span current, and ends the span within it's context
with tracer.start_as_current_span("my first span") as span:
try:
# Do stuff within the context of this
except Exception as ex:
span.record_exception(ex)
...
By default, the span is in the dependencies table with a dependency type of InProc.
If your method represents a background job not already captured by autoinstrumentation, we recommend setting the attribute kind = SpanKind.SERVER to ensure it appears in the Application Insights requests table.
...
from opentelemetry import trace
from opentelemetry.trace import SpanKind
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("my request span", kind=SpanKind.SERVER) as span:
...
Send custom telemetry using the Application Insights Classic API
We recommend you use the OpenTelemetry APIs whenever possible, but there may be some scenarios when you have to use the Application Insights Classic APIs.
These attributes might include adding a custom property to your telemetry. You might also use attributes to set optional fields in the Application Insights schema, like Client IP.
Add a custom property to a Span
Any attributes you add to spans are exported as custom properties. They populate the customDimensions field in the requests, dependencies, traces, or exceptions table.
The advantage of using options provided by instrumentation libraries, when they're available, is that the entire context is available. As a result, users can select to add or filter more attributes. For example, the enrich option in the HttpClient instrumentation library gives users access to the HttpRequestMessage and the HttpResponseMessage itself. They can select anything from it and store it as an attribute.
Many instrumentation libraries provide an enrich option. For guidance, see the readme files of individual instrumentation libraries:
Add the processor shown here before adding Azure Monitor.
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddProcessor(new ActivityEnrichingProcessor()));
builder.Services.AddOpenTelemetry().UseAzureMonitor();
var app = builder.Build();
app.Run();
Add ActivityEnrichingProcessor.cs to your project with the following code:
public class ActivityEnrichingProcessor : BaseProcessor<Activity>
{
public override void OnEnd(Activity activity)
{
// The updated activity will be available to all processors which are called after this processor.
activity.DisplayName = "Updated-" + activity.DisplayName;
activity.SetTag("CustomDimension1", "Value1");
activity.SetTag("CustomDimension2", "Value2");
}
}
To add span attributes, use either of the following two ways:
Use options provided by instrumentation libraries.
Add a custom span processor.
Tip
The advantage of using options provided by instrumentation libraries, when they're available, is that the entire context is available. As a result, users can select to add or filter more attributes. For example, the enrich option in the HttpClient instrumentation library gives users access to the httpRequestMessage itself. They can select anything from it and store it as an attribute.
Many instrumentation libraries provide an enrich option. For guidance, see the readme files of individual instrumentation libraries:
Add the processor shown here before the Azure Monitor Exporter.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("OTel.AzureMonitor.Demo")
.AddProcessor(new ActivityEnrichingProcessor())
.AddAzureMonitorTraceExporter()
.Build();
Add ActivityEnrichingProcessor.cs to your project with the following code:
public class ActivityEnrichingProcessor : BaseProcessor<Activity>
{
public override void OnEnd(Activity activity)
{
// The updated activity will be available to all processors which are called after this processor.
activity.DisplayName = "Updated-" + activity.DisplayName;
activity.SetTag("CustomDimension1", "Value1");
activity.SetTag("CustomDimension2", "Value2");
}
}
You can use opentelemetry-api to add attributes to spans.
Adding one or more span attributes populates the customDimensions field in the requests, dependencies, traces, or exceptions table.
Add opentelemetry-api-1.0.0.jar (or later) to your application:
...
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace
configure_azure_monitor(
connection_string="<your-connection-string>",
)
span_enrich_processor = SpanEnrichingProcessor()
# Add the processor shown below to the current `TracerProvider`
trace.get_tracer_provider().add_span_processor(span_enrich_processor)
...
Add SpanEnrichingProcessor.py to your project with the following code:
from opentelemetry.sdk.trace import SpanProcessor
class SpanEnrichingProcessor(SpanProcessor):
def on_end(self, span):
span._name = "Updated-" + span.name
span._attributes["CustomDimension1"] = "Value1"
span._attributes["CustomDimension2"] = "Value2"
Set the user IP
You can populate the client_IP field for requests by setting the http.client_ip attribute on the span. Application Insights uses the IP address to generate user location attributes and then discards it by default.
You can populate the user_Id or user_AuthenticatedId field for requests by using the following guidance. User ID is an anonymous user identifier. Authenticated User ID is a known user identifier.
Important
Consult applicable privacy laws before you set the Authenticated User ID.
The Python logging library is autoinstrumented. You can attach custom dimensions to your logs by passing a dictionary into the extra argument of your logs.
...
logger.warning("WARNING: Warning log with properties", extra={"key1": "value1"})
...
Filter telemetry
You might use the following ways to filter out telemetry before it leaves your application.
Add the processor shown here before adding Azure Monitor.
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddProcessor(new ActivityFilteringProcessor()));
builder.Services.ConfigureOpenTelemetryTracerProvider((sp, builder) => builder.AddSource("ActivitySourceName"));
builder.Services.AddOpenTelemetry().UseAzureMonitor();
var app = builder.Build();
app.Run();
Add ActivityFilteringProcessor.cs to your project with the following code:
public class ActivityFilteringProcessor : BaseProcessor<Activity>
{
public override void OnStart(Activity activity)
{
// prevents all exporters from exporting internal activities
if (activity.Kind == ActivityKind.Internal)
{
activity.IsAllDataRequested = false;
}
}
}
If a particular source isn't explicitly added by using AddSource("ActivitySourceName"), then none of the activities created by using that source are exported.
Many instrumentation libraries provide a filter option. For guidance, see the readme files of individual instrumentation libraries:
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("OTel.AzureMonitor.Demo")
.AddProcessor(new ActivityFilteringProcessor())
.AddAzureMonitorTraceExporter()
.Build();
Add ActivityFilteringProcessor.cs to your project with the following code:
public class ActivityFilteringProcessor : BaseProcessor<Activity>
{
public override void OnStart(Activity activity)
{
// prevents all exporters from exporting internal activities
if (activity.Kind == ActivityKind.Internal)
{
activity.IsAllDataRequested = false;
}
}
}
If a particular source isn't explicitly added by using AddSource("ActivitySourceName"), then none of the activities created by using that source will be exported.
Use a custom processor. You can use a custom span processor to exclude certain spans from being exported. To mark spans to not be exported, set TraceFlag to DEFAULT.
Use the add custom property example, but replace the following lines of code:
Doing so excludes the endpoint shown in the following Flask example:
...
import flask
from azure.monitor.opentelemetry import configure_azure_monitor
# Configure Azure monitor collection telemetry pipeline
configure_azure_monitor(
connection_string="<your-connection-string>",
)
app = flask.Flask(__name__)
# Requests sent to this endpoint will not be tracked due to
# flask_config configuration
@app.route("/ignore")
def ignore():
return "Request received but not tracked."
...
Use a custom processor. You can use a custom span processor to exclude certain spans from being exported. To mark spans to not be exported, set TraceFlag to DEFAULT.
...
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace
configure_azure_monitor(
connection_string="<your-connection-string>",
)
trace.get_tracer_provider().add_span_processor(SpanFilteringProcessor())
...
Add SpanFilteringProcessor.py to your project with the following code:
from opentelemetry.trace import SpanContext, SpanKind, TraceFlags
from opentelemetry.sdk.trace import SpanProcessor
class SpanFilteringProcessor(SpanProcessor):
# prevents exporting spans from internal activities
def on_start(self, span):
if span._kind is SpanKind.INTERNAL:
span._context = SpanContext(
span.context.trace_id,
span.context.span_id,
span.context.is_remote,
TraceFlags.DEFAULT,
span.context.trace_state,
)
Get the trace ID or span ID
You might want to get the trace ID or span ID. If you have logs sent to a destination other than Application Insights, consider adding the trace ID or span ID. Doing so enables better correlation when debugging and diagnosing issues.
The Activity and ActivitySource classes from the System.Diagnostics namespace represent the OpenTelemetry concepts of Span and Tracer, respectively. That's because parts of the OpenTelemetry tracing API are incorporated directly into the .NET runtime. To learn more, see Introduction to OpenTelemetry .NET Tracing API.
The Activity and ActivitySource classes from the System.Diagnostics namespace represent the OpenTelemetry concepts of Span and Tracer, respectively. That's because parts of the OpenTelemetry tracing API are incorporated directly into the .NET runtime. To learn more, see Introduction to OpenTelemetry .NET Tracing API.