OpenTelemetry (OTel) is a set of APIs, libraries, and agents to capture distributed traces and metrics from your app. It’s a Cloud Native Computing Foundation (CNCF) project that was started to create a unified solution for service and app performance monitoring.
The OpenTelemetry project has published strong specifications for the three main pillars of observability: logs, traces, and metrics. These schemas are supported by all tools and services that support interacting with OpenTelemetry. Axiom supports OpenTelemetry natively on an API level, allowing you to connect any existing OpenTelemetry shipper, library, or tool to Axiom for sending data.
OpenTelemetry-compatible events flow into Axiom, where they’re organized into datasets for easy segmentation. Users can create a dataset to receive OpenTelemetry data and obtain an API token for ingestion. Axiom provides comprehensive observability through browsing, querying, dashboards, and alerting of OpenTelemetry data.
OTel traces and OTel logs support are already live. Axiom will soon support OpenTelemetry Metrics (OTel Metrics).
OpenTelemetry Collector
Configuring the OpenTelemetry collector is as simple as creating an HTTP exporter that sends data to the Axiom API together with headers to set the dataset and API token:
exporters:
otlphttp:
compression: gzip
endpoint: https://api.axiom.co
headers:
authorization: Bearer <YOUR_API_TOKEN>
x-axiom-dataset: <YOUR_DATASET>
service:
pipelines:
traces:
receivers:
- otlp
processors:
- memory_limiter
- batch
exporters:
- otlphttp
When using the OTLP/HTTP endpoint for traces and logs, the following endpoint URLs should be used in your SDK exporter OTel configuration.
- Traces:
https://api.axiom.co/v1/traces
- Logs:
https://api.axiom.co/v1/logs
OpenTelemetry for Go
The example below configures a Go app using the OpenTelemetry SDK for Go to send OpenTelemetry data to Axiom.
package main
import (
"context"
"crypto/tls"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/sdk/trace"
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
)
const (
serviceName = "axiom-go-otel"
serviceVersion = "0.1.0"
otlpEndpoint = "api.axiom.co"
bearerToken = "Bearer $API_TOKEN"
deploymentEnvironment = "production"
)
func SetupTracer() (func(context.Context) error, error) {
ctx := context.Background()
return InstallExportPipeline(ctx)
}
func Resource() *resource.Resource {
return resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(serviceName),
semconv.ServiceVersionKey.String(serviceVersion),
attribute.String("environment", deploymentEnvironment),
)
}
func InstallExportPipeline(ctx context.Context) (func(context.Context) error, error) {
exporter, err := otlptracehttp.New(ctx,
otlptracehttp.WithEndpoint(otlpEndpoint),
otlptracehttp.WithHeaders(map[string]string{
"Authorization": bearerToken,
"X-AXIOM-DATASET": "$DATASET_NAME",
}),
otlptracehttp.WithTLSClientConfig(&tls.Config{}),
)
if err != nil {
return nil, err
}
tracerProvider := trace.NewTracerProvider(
trace.WithBatcher(exporter),
trace.WithResource(Resource()),
)
otel.SetTracerProvider(tracerProvider)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
propagation.TraceContext{},
propagation.Baggage{},
))
return tracerProvider.Shutdown, nil
}
OpenTelemetry for Ruby
To send traces to an OpenTelemetry Collector using the OTLP over HTTP in Ruby, use the opentelemetry-exporter-otlp-http
gem provided by the OpenTelemetry project.
require 'opentelemetry/sdk'
require 'opentelemetry/exporter/otlp'
require 'opentelemetry/instrumentation/all'
OpenTelemetry::SDK.configure do |c|
c.service_name = 'ruby-traces'
c.use_all
c.add_span_processor(
OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
OpenTelemetry::Exporter::OTLP::Exporter.new(
endpoint: 'https://api.axiom.co/v1/traces',
headers: {
'Authorization' => 'Bearer API_TOKEN',
'X-AXIOM-DATASET' => 'DATASET'
}
)
)
)
end
OpenTelemetry for Java
Here is a basic configuration for a Java app that sends traces to an OpenTelemetry Collector using OTLP over HTTP using the OpenTelemetry Java SDK:
package com.example;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import java.util.concurrent.TimeUnit;
public class OtelConfiguration {
private static final String SERVICE_NAME = "SERVICE_NAME";
private static final String SERVICE_VERSION = "SERVICE_VERSION";
private static final String OTLP_ENDPOINT = "https://api.axiom.co/v1/traces";
private static final String BEARER_TOKEN = "Bearer API_TOKEN";
private static final String AXIOM_DATASET = "DATASET";
public static OpenTelemetry initializeOpenTelemetry() {
Resource resource = Resource.getDefault()
.merge(Resource.create(Attributes.of(
AttributeKey.stringKey("service.name"), SERVICE_NAME,
AttributeKey.stringKey("service.version"), SERVICE_VERSION
)));
OtlpHttpSpanExporter spanExporter = OtlpHttpSpanExporter.builder()
.setEndpoint(OTLP_ENDPOINT)
.addHeader("Authorization", BEARER_TOKEN)
.addHeader("X-Axiom-Dataset", AXIOM_DATASET)
.build();
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
.addSpanProcessor(BatchSpanProcessor.builder(spanExporter)
.setScheduleDelay(100, TimeUnit.MILLISECONDS)
.build())
.setResource(resource)
.build();
OpenTelemetrySdk openTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.buildAndRegisterGlobal();
Runtime.getRuntime().addShutdownHook(new Thread(sdkTracerProvider::close));
return openTelemetry;
}
}
OpenTelemetry for .NET
You can send traces to Axiom using the OpenTelemetry .NET SDK by configuring an OTLP HTTP exporter in your .NET app. Here is a simple example:
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using System;
using System.Diagnostics;
using System.Reflection;
public static class TracingConfiguration
{
private static readonly ActivitySource ActivitySource = new("MyCustomActivitySource");
public static void ConfigureOpenTelemetry()
{
var serviceName = Assembly.GetExecutingAssembly().GetName().Name ?? "UnknownService";
var serviceVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "UnknownVersion";
Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(
ResourceBuilder.CreateDefault().AddService(serviceName, serviceVersion: serviceVersion)
.AddAttributes(new[] { new KeyValuePair<string, object>("environment", "development") })
.AddTelemetrySdk()
.AddEnvironmentVariableDetector())
.AddSource(ActivitySource.Name)
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddOtlpExporter(options =>
{
options.Endpoint = new Uri("https://api.axiom.co/v1/traces");
options.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.HttpProtobuf;
options.Headers = "Authorization=Bearer API_TOKEN, X-Axiom-Dataset=DATASET";
})
.Build();
}
public static Activity? StartActivity(string activityName, ActivityKind kind = ActivityKind.Internal)
{
return ActivitySource.StartActivity(activityName, kind);
}
}
OpenTelemetry for Python
You can send traces to Axiom using the OpenTelemetry Python SDK by configuring an OTLP HTTP exporter in your Python app. Here is a simple example:
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.resources import Resource, SERVICE_NAME
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
resource = Resource(attributes={
SERVICE_NAME: "NAME_OF_SERVICE"
})
provider = TracerProvider(resource=resource)
otlp_exporter = OTLPSpanExporter(
endpoint="https://api.axiom.co/v1/traces",
headers={
"Authorization": "Bearer API_TOKEN",
"X-Axiom-Dataset": "DATASET_NAME"
}
)
processor = BatchSpanProcessor(otlp_exporter)
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
service1_tracer = trace.get_tracer("service1")
OpenTelemetry for Node
You can send traces to Axiom using the OpenTelemetry Node SDK by configuring an OTLP HTTP exporter in your Node app. Here is a simple example:
const opentelemetry = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-proto');
const { BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
const traceExporter = new OTLPTraceExporter({
url: 'https://api.axiom.co/v1/traces',
headers: {
'Authorization': 'Bearer $API_TOKEN',
'X-Axiom-Dataset': '$DATASET'
},
});
const resource = new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'node traces',
});
const sdk = new opentelemetry.NodeSDK({
spanProcessor: new BatchSpanProcessor(traceExporter),
resource: resource,
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
OpenTelemetry for Cloudflare Workers
Configure OpenTelemetry in Cloudflare Workers to send telemetry data to Axiom using the OTel CF Worker package. Here is an example exporter configuration:
import { trace } from '@opentelemetry/api';
import { instrument, ResolveConfigFn } from '@microlabs/otel-cf-workers';
export interface Env {
AXIOM_API_TOKEN: string,
AXIOM_DATASET: string
}
const handler = {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
await fetch('https://cloudflare.com');
const greeting = "Welcome to Axiom Cloudflare instrumentation";
trace.getActiveSpan()?.setAttribute('greeting', greeting);
ctx.waitUntil(fetch('https://workers.dev'));
return new Response(`${greeting}!`);
},
};
const config: ResolveConfigFn = (env: Env, _trigger) => {
return {
exporter: {
url: 'https://api.axiom.co/v1/traces',
headers: {
'Authorization': `Bearer ${env.AXIOM_API_TOKEN}`,
'X-Axiom-Dataset': `${env.AXIOM_DATASET}`
},
},
service: { name: 'axiom-cloudflare-workers' },
};
};
export default instrument(handler, config);
Additional resources
For further guidance on integrating OpenTelemetry with Axiom, explore the following guides: