Expand description

An Azure Application Insights exporter implementation for OpenTelemetry Rust.

Disclaimer: This is not an official Microsoft product.


Configure a OpenTelemetry pipeline using the Application Insights exporter and start creating spans (this example requires the reqwest-client feature):

use opentelemetry::trace::Tracer as _;

fn main() {
    let connection_string = std::env::var("APPLICATIONINSIGHTS_CONNECTION_STRING").unwrap();
    let tracer = opentelemetry_application_insights::new_pipeline_from_connection_string(connection_string)
        .expect("valid connection string")

    tracer.in_span("main", |_cx| {});

Simple or Batch

The functions build_simple and install_simple build/install a trace pipeline using the simple span processor. This means each span is processed and exported synchronously at the time it ends.

The functions build_batch and install_batch use the batch span processor instead. This means spans are exported periodically in batches, which can be better for performance. This feature requires an async runtime such as Tokio or async-std. If you decide to use a batch span processor, make sure to call opentelemetry::global::shutdown_tracer_provider() before your program exits to ensure all remaining spans are exported properly (this example requires the reqwest-client and opentelemetry/rt-tokio features).

use opentelemetry::trace::Tracer as _;

async fn main() {
    let tracer = opentelemetry_application_insights::new_pipeline_from_env()
        .expect("env var APPLICATIONINSIGHTS_CONNECTION_STRING is valid connection string")

    tracer.in_span("main", |_cx| {});


Async runtimes and HTTP clients

In order to support different async runtimes, the exporter requires you to specify an HTTP client that works with your chosen runtime. The opentelemetry-http crate comes with support for:

  • surf for async-std: enable the surf-client and opentelemetry/rt-async-std features and configure the exporter with with_client(surf::Client::new()).
  • reqwest for tokio: enable the reqwest-client and opentelemetry/rt-tokio features and configure the exporter with either with_client(reqwest::Client::new()) or with_client(reqwest::blocking::Client::new()).

Alternatively you can bring any other HTTP client by implementing the HttpClient trait.


Please note: Metrics are still experimental both in the OpenTelemetry specification as well as Rust implementation.

Please note: The metrics export configuration is still a bit rough in this crate. But once configured it should work as expected.

This requires the metrics feature.

use opentelemetry::global;
use opentelemetry_sdk::metrics::{MeterProvider, PeriodicReader};
use std::time::Duration;

async fn main() {
    // Setup exporter
    let connection_string = std::env::var("APPLICATIONINSIGHTS_CONNECTION_STRING").unwrap();
    let exporter = opentelemetry_application_insights::Exporter::new_from_connection_string(
    .expect("valid connection string");
    let reader = PeriodicReader::builder(exporter, opentelemetry_sdk::runtime::Tokio).build();
    let meter_provider = MeterProvider::builder().with_reader(reader).build();

    // Record value
    let meter = global::meter("example");
    let histogram = meter.f64_histogram("pi").init();
    histogram.record(3.14, &[]);

    // Simulate work, during which metrics will periodically be reported.

Live Metrics

Enable live metrics collection: https://learn.microsoft.com/en-us/azure/azure-monitor/app/live-stream.

Metrics are based on traces. See attribute mapping below for how traces are mapped to requests, dependencies and exceptions and how they are deemed “successful” or not.

To configure role, instance, and machine name provide service.name, service.instance.id, and host.name resource attributes respectively in the trace config.

Sample telemetry is not supported, yet.

This requires the live-metrics feature and the build_batch/install_batch methods.

use opentelemetry::trace::Tracer as _;

async fn main() {
    let tracer = opentelemetry_application_insights::new_pipeline_from_env()
        .expect("env var APPLICATIONINSIGHTS_CONNECTION_STRING is valid connection string")

    // ... send traces ...


Attribute mapping

OpenTelemetry and Application Insights are using different terminology. This crate tries it’s best to map OpenTelemetry fields to their correct Application Insights pendant.


The OpenTelemetry SpanKind determines the Application Insights telemetry type:

OpenTelemetry SpanKindApplication Insights telemetry type

The Span’s status determines the Success field of a Dependency or Request. Success is false if the status Error; otherwise true.

The following of the Span’s attributes map to special fields in Application Insights (the mapping tries to follow the OpenTelemetry semantic conventions for trace and resource).

Note: for INTERNAL Spans the Dependency Type is always "InProc".

OpenTelemetry attribute keyApplication Insights field
service.versionContext: Application version (ai.application.ver)
enduser.idContext: Authenticated user id (ai.user.authUserId)
service.namespace + service.nameContext: Cloud role (ai.cloud.role)
service.instance.idContext: Cloud role instance (ai.cloud.roleInstance)
telemetry.sdk.name + telemetry.sdk.versionContext: Internal SDK version (ai.internal.sdkVersion)
SpanKind::Server + http.request.method + http.routeContext: Operation Name (ai.operation.name)
ai.*Context: AppInsights Tag (ai.*)
url.fullDependency Data
db.statementDependency Data
http.request.header.hostDependency Target
server.address + server.portDependency Target
server.socket.address + server.socket.portDependency Target
db.nameDependency Target
http.response.status_codeDependency Result code
db.systemDependency Type
messaging.systemDependency Type
rpc.systemDependency Type
"HTTP" if any http. attribute existsDependency Type
"DB" if any db. attribute existsDependency Type
url.fullRequest Url
url.scheme + http.request.header.host + url.path + url.queryRequest Url
url.scheme + server.address + server.port + url.path + url.queryRequest Url
client.addressRequest Source
client.socket.addressRequest Source
http.response.status_codeRequest Response code

All other attributes are directly converted to custom properties.

For Requests the attributes http.request.method and http.route override the Name.

Deprecated attributes

The following deprecated attributes also work:

AttributeDeprecated attribute
url.path + url.queryhttp.target
server.addressnet.peer.name (for client spans)
server.portnet.peer.port (for client spans)
server.socket.addressnet.sock.peer.addr (for client spans)
server.socket.addressnet.peer.ip (for client spans)
server.socket.portnet.sock.peer.port (for client spans)
server.addressnet.host.name (for server spans)
server.portnet.host.port (for server spans)


Events are converted into Exception telemetry if the event name equals "exception" (see OpenTelemetry semantic conventions for exceptions) with the following mapping:

OpenTelemetry attribute keyApplication Insights field
exception.typeException type
exception.messageException message
exception.stacktraceException call stack

Events are converted into Event telemetry if the event name equals "ai.custom" with the following mapping:

OpenTelemetry attribute keyApplication Insights field
ai.customEvent.nameEvent name

All other events are converted into Trace telemetry with the follwing mapping:

OpenTelemetry attribute keyApplication Insights field
level (tracing::Level)Severity level

All other attributes are directly converted to custom properties.


Metrics get reported to Application Insights as Metric Data. The Aggregation determines how the data is represented.

AggregatorData representation
Histogramaggregation with sum, count, min, and max (buckets are not exported)
Gaugeone measurement
Sumaggregation with only a value


  • Attributes for Application Insights context fields



  • Errors that occurred during span export.


  • A minimal interface necessary for export spans over HTTP.