This guide explains how Azure Monitor OpenTelemetry collects telemetry automatically, how community instrumentation libraries can be added, and how to configure resource detectors to enrich that telemetry with consistent metadata. You learn what signals are collected by default and how resource detectors populate attributes like service identity and environment details so your Application Insights data is easier to filter, correlate, and troubleshoot across .NET, Java, Node.js, and Python applications.
This guide provides instructions on integrating and customizing OpenTelemetry (OTel) instrumentation within Azure Monitor Application Insights.
To learn more about OpenTelemetry concepts, see the OpenTelemetry overview or OpenTelemetry FAQ.
Automatic data collection
The distros automatically collect data by bundling OpenTelemetry instrumentation libraries.
Included instrumentation libraries
Requests
Dependencies
Logging
To reduce or increase the number of logs sent to Azure Monitor, configure logging to set the appropriate log level or apply filters. For example, you can choose to send only Warning and Error logs to OpenTelemetry/Azure Monitor. OpenTelemetry doesn't control log routing or filtering - your ILogger configuration makes these decisions. For more information on configuring ILogger, see Configure logging.
For more information about ILogger, see Logging in C# and .NET and code examples.
The Azure Monitor Exporter doesn't include any instrumentation libraries.
You can collect dependencies from the Azure Software Development Kits (SDKs) using the following code sample to manually subscribe to the source.
// Create an OpenTelemetry tracer provider builder.
// It is important to keep the TracerProvider instance active throughout the process lifetime.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
// The following line subscribes to dependencies emitted from Azure SDKs
.AddSource("Azure.*")
.AddAzureMonitorTraceExporter()
.AddHttpClientInstrumentation(o => o.FilterHttpRequestMessage = (_) =>
{
// Azure SDKs create their own client span before calling the service using HttpClient
// In this case, we would see two spans corresponding to the same operation
// 1) created by Azure SDK 2) created by HttpClient
// To prevent this duplication we are filtering the span from HttpClient
// as span from Azure SDK contains all relevant information needed.
var parentActivity = Activity.Current?.Parent;
if (parentActivity != null && parentActivity.Source.Name.Equals("Azure.Core.Http"))
{
return false;
}
return true;
})
.Build();
To reduce or increase the number of logs sent to Azure Monitor, configure logging to set the appropriate log level or apply filters. For example, you can choose to send only Warning and Error logs to OpenTelemetry/Azure Monitor. OpenTelemetry doesn't control log routing or filtering - your ILogger configuration makes these decisions. For more information on configuring ILogger, see Configure logging.
Requests
- Java Message Service (JMS) consumers
- Kafka consumers
- Netty
- Quartz
- RabbitMQ
- Servlets
- Spring scheduling
Note
Servlet and Netty autoinstrumentation covers most Java HTTP services, including Java EE, Jakarta EE, Spring Boot, Quarkus, and Micronaut.
Dependencies (plus downstream distributed trace propagation)
- Apache HttpClient
- Apache HttpAsyncClient
- AsyncHttpClient
- Google HttpClient
- gRPC
- java.net.HttpURLConnection
- Java 11 HttpClient
- JAX-RS client
- Jetty HttpClient
- JMS
- Kafka
- Netty client
- OkHttp
- RabbitMQ
Dependencies (without downstream distributed trace propagation)
- Supports Cassandra
- Supports Java Database Connectivity (JDBC)
- Supports MongoDB (async and sync)
- Supports Redis (Lettuce and Jedis)
Metrics
- Micrometer Metrics, including Spring Boot Actuator metrics
- Java Management Extensions (JMX) Metrics
Logs
- Logback (including MDC properties) ¹
- Log4j (including MDC/Thread Context properties) ¹
- JBoss Logging (including MDC properties) ¹
- java.util.logging ¹
To reduce or increase the number of logs that Azure Monitor collects, first set the desired logging level (such as WARNING or ERROR) in the application's logging library.
Default collection
Telemetry emitted by the following Azure SDKs is automatically collected by default:
[//]: # "Azure Cosmos DB 4.22.0+ due to https://github.com/Azure/azure-sdk-for-java/pull/25571"
[//]: # "the remaining above names and links scraped from https://azure.github.io/azure-sdk/releases/latest/java.html"
[//]: # "and version synched manually against the oldest version in maven central built on azure-core 1.14.0"
[//]: # ""
[//]: # "var table = document.querySelector('#tg-sb-content > div > table')"
[//]: # "var str = ''"
[//]: # "for (var i = 1, row; row = table.rows[i]; i++) {"
[//]: # " var name = row.cells[0].getElementsByTagName('div')[0].textContent.trim()"
[//]: # " var stableRow = row.cells[1]"
[//]: # " var versionBadge = stableRow.querySelector('.badge')"
[//]: # " if (!versionBadge) {"
[//]: # " continue"
[//]: # " }"
[//]: # " var version = versionBadge.textContent.trim()"
[//]: # " var link = stableRow.querySelectorAll('a')[2].href"
[//]: # " str += '* [' + name + '](' + link + ') ' + version + '\n'"
[//]: # "}"
[//]: # "console.log(str)"
Requests for Spring Boot native applications
- Spring Web
- Spring Web MVC (Model-View-Controller)
- Spring WebFlux
Dependencies for Spring Boot native applications
Metrics
Logs for Spring Boot native applications
To reduce or increase the number of logs that Azure Monitor collects, first set the desired logging level (such as WARNING or ERROR) in the application's logging library.
For Quartz native applications, look at the Quarkus documentation.
Note
The Quarkus community supports and maintains Quarkus extensions. For help, use Quarkus community support channels. Microsoft doesn't provide technical support for this integration.
The following OpenTelemetry Instrumentation libraries are included as part of the Azure Monitor Application Insights Distro. For more information, see Azure SDK for JavaScript.
Requests
Dependencies
Logs
To reduce or increase the number of logs that Azure Monitor collects, first set the desired logging level (such as WARNING or ERROR) in the application's logging library.
Instrumentations can be configured using AzureMonitorOpenTelemetryOptions:
export class BunyanInstrumentationSample {
static async run() {
// Dynamically import Azure Monitor and Bunyan
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const bunyanMod = await import("bunyan");
const bunyan = (bunyanMod as any).default ?? bunyanMod;
// Enable Azure Monitor integration and bunyan instrumentation
const options = {
instrumentationOptions: {
bunyan: { enabled: true },
},
};
const monitor = useAzureMonitor(options);
// Emit a test log entry
const log = (bunyan as any).createLogger({ name: "testApp" });
log.info(
{
testAttribute1: "testValue1",
testAttribute2: "testValue2",
testAttribute3: "testValue3",
},
"testEvent"
);
console.log("Bunyan log emitted");
}
}
Requests
Dependencies
Logs
To reduce or increase the number of logs that Azure Monitor collects, first set the desired logging level (such as WARNING or ERROR) in the application's logging library.
Examples of using the Python logging library can be found on GitHub.
Telemetry emitted by Azure Software Development Kits (SDKs) is automatically collected by default.
Footnotes
- ¹: Supports automatic reporting of unhandled/uncaught exceptions
- ²: Supports OpenTelemetry Metrics
Tip
All OpenTelemetry metrics whether automatically collected from instrumentation libraries or manually collected from custom coding are currently considered Application Insights "custom metrics" for billing purposes. Learn more.
You can collect more data automatically when you include instrumentation libraries from the OpenTelemetry community.
Caution
We don't support or guarantee the quality of community instrumentation libraries. To suggest one for our distro, post or up-vote in our feedback community. Be aware, some are based on experimental OpenTelemetry specs and might introduce future breaking changes.
To add a community library, use the ConfigureOpenTelemetryMeterProvider or ConfigureOpenTelemetryTracerProvider methods,
after adding the NuGet package for the library.
The following example demonstrates how the Runtime Instrumentation can be added to collect extra metrics:
dotnet add package OpenTelemetry.Instrumentation.Runtime
// Create a new ASP.NET Core web application builder.
var builder = WebApplication.CreateBuilder(args);
// Configure the OpenTelemetry meter provider to add runtime instrumentation.
builder.Services.ConfigureOpenTelemetryMeterProvider((sp, builder) => builder.AddRuntimeInstrumentation());
// Add the Azure Monitor telemetry service to the application.
// This service will collect and send telemetry data to Azure Monitor.
builder.Services.AddOpenTelemetry().UseAzureMonitor();
// Build the ASP.NET Core web application.
var app = builder.Build();
// Start the ASP.NET Core web application.
app.Run();
The following example demonstrates how the Runtime Instrumentation can be added to collect extra metrics:
// Create a new OpenTelemetry meter provider and add runtime instrumentation and the Azure Monitor metric exporter.
// It is important to keep the MetricsProvider instance active throughout the process lifetime.
var metricsProvider = Sdk.CreateMeterProviderBuilder()
.AddRuntimeInstrumentation()
.AddAzureMonitorMetricExporter();
You can't extend the Java Distro with community instrumentation libraries. To request that we include another instrumentation library, open an issue on our GitHub page. You can find a link to our GitHub page in Next Steps.
You can't use community instrumentation libraries with GraalVM Java native applications.
export class RegisterExpressInstrumentationSample {
static async run() {
// Dynamically import Azure Monitor and Express instrumentation
const { useAzureMonitor } = await import("@azure/monitor-opentelemetry");
const { registerInstrumentations } = await import("@opentelemetry/instrumentation");
const { ExpressInstrumentation } = await import("@opentelemetry/instrumentation-express");
// Initialize Azure Monitor (uses env var if set)
const monitor = useAzureMonitor();
// Register the Express instrumentation
registerInstrumentations({
instrumentations: [new ExpressInstrumentation()],
});
console.log("Express instrumentation registered");
}
}
To add a community instrumentation library (not officially supported/included in Azure Monitor distro), you can instrument directly with the instrumentations. The list of community instrumentation libraries can be found here.
Note
Instrumenting a supported instrumentation library manually with instrument() and the distro configure_azure_monitor() isn't recommended. It's not a supported scenario and you could get undesired behavior for your telemetry.
# Import the `configure_azure_monitor()`, `SQLAlchemyInstrumentor`, `create_engine`, and `text` functions from the appropriate packages.
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
from sqlalchemy import create_engine, text
# Configure OpenTelemetry to use Azure Monitor.
configure_azure_monitor()
# Create a SQLAlchemy engine.
engine = create_engine("sqlite:///:memory:")
# SQLAlchemy instrumentation is not officially supported by this package, however, you can use the OpenTelemetry `instrument()` method manually in conjunction with `configure_azure_monitor()`.
SQLAlchemyInstrumentor().instrument(
engine=engine,
)
# Database calls using the SQLAlchemy library will be automatically captured.
with engine.connect() as conn:
result = conn.execute(text("select 'hello world'"))
print(result.all())
Resource detectors
Resource detectors discover environment metadata at startup and populate OpenTelemetry resource attributes such as service.name, cloud.provider, and cloud.resource_id. This metadata powers experiences in Application Insights like Application Map and compute linking, and it improves correlation across traces, metrics, and logs.
Tip
Resource attributes describe the process and its environment. Span attributes describe a single operation. Use resource attributes for app-level properties like service.name.
Supported environments
| Environment |
How detection works |
Notes |
| Azure App Service |
The language SDK or Azure Monitor distro reads well-known App Service environment variables and host metadata |
Works with .NET, Java, Node.js, and Python when you use the guidance in this article. |
| Azure Functions |
See the Azure Functions OpenTelemetry how‑to |
All Azure Functions guidance lives there. |
| Azure Virtual Machines |
The language SDK or distro queries the Azure Instance Metadata Service |
Ensure the VM has access to the Instance Metadata Service endpoint. |
| Azure Kubernetes Service (AKS) |
Use the OpenTelemetry Collector k8sattributes processor to add Kubernetes metadata |
Recommended for all languages running in AKS. |
| Azure Container Apps |
Detectors map environment variables and resource identifiers when available |
You can also set OTEL_RESOURCE_ATTRIBUTES to fill gaps. |
Manual and automatic instrumentation
Automatic instrumentation and the Azure Monitor distros enable resource detection when running in Azure environments where supported.
For manual setups, you can set resource attributes directly with standard OpenTelemetry options:
# Applies to .NET (ASP.NET/ASP.NET Core), Java, Node.js, and Python
export OTEL_SERVICE_NAME="my-service"
export OTEL_RESOURCE_ATTRIBUTES="cloud.provider=azure,cloud.region=westus,cloud.resource_id=/subscriptions/<SUB>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<APP>"
On Windows PowerShell:
$Env:OTEL_SERVICE_NAME="my-service"
$Env:OTEL_RESOURCE_ATTRIBUTES="cloud.provider=azure,cloud.region=westus,cloud.resource_id=/subscriptions/<SUB>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<APP>"
OTLP ingestion considerations
Application Insights uses service.name to derive Cloud Role Name. Choose a stable name per service to avoid fragmented nodes in Application Map.
cloud.resource_id improves compute linking to Azure resources. If this attribute is missing, some experiences may not show the Azure resource that produced the data.
Next steps
- To further configure the OpenTelemetry distro, see Azure Monitor OpenTelemetry configuration.
- To review the source code, see the Azure Monitor AspNetCore GitHub repository.
- To install the NuGet package, check for updates, or view release notes, see the Azure Monitor AspNetCore NuGet Package page.
- To become more familiar with Azure Monitor and OpenTelemetry, see the Azure Monitor Example Application.
- To learn more about OpenTelemetry and its community, see the OpenTelemetry .NET GitHub repository.
- To enable usage experiences, enable web or browser user monitoring.
- To review frequently asked questions, troubleshooting steps, support options, or to provide OpenTelemetry feedback, see OpenTelemetry help, support, and feedback for Azure Monitor Application Insights.
- To further configure the OpenTelemetry distro, see Azure Monitor OpenTelemetry configuration
- To review the source code, see the Azure Monitor Exporter GitHub repository.
- To install the NuGet package, check for updates, or view release notes, see the Azure Monitor Exporter NuGet Package page.
- To become more familiar with Azure Monitor and OpenTelemetry, see the Azure Monitor Example Application.
- To learn more about OpenTelemetry and its community, see the OpenTelemetry .NET GitHub repository.
- To enable usage experiences, enable web or browser user monitoring.
- To review frequently asked questions, troubleshooting steps, support options, or to provide OpenTelemetry feedback, see OpenTelemetry help, support, and feedback for Azure Monitor Application Insights.
- To review configuration options, see Java autoinstrumentation configuration options.
- To review the source code, see the Azure Monitor Java autoinstrumentation GitHub repository.
- To learn more about OpenTelemetry and its community, see the OpenTelemetry Java GitHub repository.
- To enable usage experiences, see Enable web or browser user monitoring.
- To see release notes, see release notes on GitHub.
- To review frequently asked questions, troubleshooting steps, support options, or to provide OpenTelemetry feedback, see OpenTelemetry help, support, and feedback for Azure Monitor Application Insights.
Note
The Quarkus community supports and maintains Quarkus extensions. For help, use Quarkus community support channels. Microsoft doesn't provide technical support for this integration.
- To review the source code, see the Azure Monitor OpenTelemetry GitHub repository.
- To install the npm package and check for updates, see the
@azure/monitor-opentelemetry npm Package page.
- To become more familiar with Azure Monitor Application Insights and OpenTelemetry, see the Azure Monitor Example Application.
- To learn more about OpenTelemetry and its community, see the OpenTelemetry JavaScript GitHub repository.
- To enable usage experiences, enable web or browser user monitoring.
- To review frequently asked questions, troubleshooting steps, support options, or to provide OpenTelemetry feedback, see OpenTelemetry help, support, and feedback for Azure Monitor Application Insights.
- To review the source code and extra documentation, see the Azure Monitor Distro GitHub repository.
- To see extra samples and use cases, see Azure Monitor Distro samples.
- To see the release notes, see release notes on GitHub.
- To install the PyPI package, check for updates, or view release notes, see the Azure Monitor Distro PyPI Package page.
- To become more familiar with Azure Monitor Application Insights and OpenTelemetry, see the Azure Monitor Example Application.
- To learn more about OpenTelemetry and its community, see the OpenTelemetry Python GitHub repository.
- To see available OpenTelemetry instrumentations and components, see the OpenTelemetry Contributor Python GitHub repository.
- To enable usage experiences, enable web or browser user monitoring.
- To review frequently asked questions, troubleshooting steps, support options, or to provide OpenTelemetry feedback, see OpenTelemetry help, support, and feedback for Azure Monitor Application Insights.