On This Page

Home / LLM Observability/ Instrument LLMs/Instrument Azure OpenAI Applications with OpenTelemetry

Instrument Azure OpenAI Applications with OpenTelemetry

Cribl SearchCribl Stream

Learn how to instrument Azure OpenAI-based applications with OpenTelemetry and export large language model (LLM) telemetry via OTLP into Cribl Search. Once your data is in Cribl Search, you can explore and investigate it to troubleshoot issues, analyze model behavior, and monitor performance.

You’ll complete the following high-level steps:

  1. Configure an OpenTelemetry (OTel) Source in Cribl Search to receive OTLP data.
  2. Instrument your Azure OpenAI application (Node.js or Python) with OpenTelemetry.
  3. Explore LLM telemetry use cases in Cribl Search.

Each Azure OpenAI API call produces a trace span with these attributes:

CategoryDataExample
TimingCall duration.1.2s.
ModelDeployment name (and resolved model where reported).gpt-4o-deployment, gpt-4o-2024-08-06.
Token usageInput, output, and total tokens.150 input, 85 output.
Request paramsTemperature, max tokens.temperature=0.7.
ResponseFinish reason, response ID.stop, chatcmpl-abc123.
ErrorsHTTP status, error message.429 Rate limit exceeded, deployment not found.
ContentPrompt and completion text.(opt-in, disabled by default).

Semantic conventions follow OpenTelemetry GenAI Semantic Conventions where applicable.

Prerequisites

You’ll need:

  • Cribl.Cloud Enterprise.
  • Search Admin permission or higher.
  • An Azure OpenAI resource with at least one chat deployment; optionally an embeddings deployment if you plan to trace embedding calls.
  • An Azure OpenAI API key with access to the deployments you want to monitor.
  • Node.js 18+ or Python 3.9+ depending on your application language.

Complete these steps before you instrument your LLM application:

  1. Add a lakehouse engine. This provides storage and compute for data you’re going to ingest into Cribl Search.
  2. Add a Cribl Search OpenTelemetry Source to start ingesting the data.
  3. Set up your Datatype rules to parse and structure the incoming data.
  4. Set up your Dataset rules to route ingested events into individual Search Datasets. This will let you scope your queries and control retention.

A lakehouse engine is the storage-and-compute unit in Cribl Search that holds ingested OTLP (and other Source data) until Dataset retention expires. See Lakehouse Engines in Cribl Search to learn how to setup a new lakehouse engine.

To receive OTLP from your LLM application directly in Cribl Search, add an OpenTelemetry Source.

  1. On the Cribl.Cloud top bar, select Products > Search. Under Data, select Add Source > OpenTelemetry.

  2. In the New Source modal, configure the following under General Settings:

    • ID: Unique Source ID across your Cribl.Cloud Workspace. Use letters, numbers, underscores, and hyphens.
    • Description (optional): Describe the Source (for example, OTLP from LLM-instrumented apps).
    • Address: Hostname that your OpenTelemetry collector or agent connects to. You will use this in exporter configuration.
    • Port: Network port to listen on. Defaults to 4317 for gRPC and 4318 for HTTP (OTLP standard). Change if you use a custom port.
    • OTLP version: Version that matches your upstream sender (default 1.3.1).
    • Protocol: gRPC (default) or HTTP. This must match your OpenTelemetry exporter.
  3. Under Authentication, choose None, Basic, Basic (Credentials Secret), Auth Tokens, or Auth Token (Text Secret) as required. See Set up Authentication.

  4. Under Encrypt, enable TLS and set the minimum TLS version when senders must connect over TLS. See Set Up Encryption.

  5. Select Save to create the Source.

Set Datatype Rules

Next, configure Datatype rules to parse, filter, and normalize your data into structured fields.

On the Cribl.Cloud top bar, select Products > Search > Data > Datatyping (auto). Here, you can:

  • Use Auto-Datatyping to parse your data automatically.
  • Check for uncategorized data that didn’t match any Datatype rules.
  • Handle the uncategorized data by adding custom Datatype rules.

See also:

Add a Dataset and Set Dataset Rules

Next, create a Dataset and add Dataset rules to route parsed events into it.

Add a Dataset

  1. On the Cribl.Cloud top bar, select Products > Search > Data > Datasets.
  2. Select Add Dataset.
  3. Enter a unique ID.
  4. Optionally add a Description and Tags.
  5. Set Dataset Provider set to lakehouse.
  6. Select the Lakehouse engine that will store the data.
  7. Set the Retention period.
  8. Select Save.

Set Dataset Rules

Dataset rules enable you to route ingested events into individual Search Datasets so you can scope your queries and control retention.

See Organize Your Data for details around how to configure your Dataset rules and plan your Search Datasets based on estimated future storage costs.

Pick Node.js or Python below. Both paths emit OTLP spans from the official OpenAI client libraries into the Source you configured earlier.

Node.jsPython

Use the openai npm package with Node.js 18+. The two options below are an explicit NodeSDK plus tracing.js, or the auto-instrumentations register hook if you prefer a single preload entry.

@opentelemetry/instrumentation-openai supports the openai npm package >=4.19.0 <7.

SDK-Based Setup

Register the OpenAI instrumentation on a NodeSDK, and load that setup before your application entrypoint so openai client calls are traced.

  1. Install the required packages:
npm install @opentelemetry/sdk-node \
  @opentelemetry/api \
  @opentelemetry/exporter-trace-otlp-grpc \
  @opentelemetry/instrumentation-openai \
  openai
  1. Create a tracing.js file and require it before your application code:
// tracing.js: load this BEFORE your app code
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');
const { OpenAIInstrumentation } = require('@opentelemetry/instrumentation-openai');

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter(),
  instrumentations: [new OpenAIInstrumentation()],
});
sdk.start();
  1. Run your application:
node -r ./tracing.js app.js

The exporter reads its endpoint from OTEL_EXPORTER_OTLP_ENDPOINT automatically.

Auto-Instrumentation

Load supported Node instrumentations from a single register hook instead of maintaining a custom tracing.js file.

  1. Install the auto-instrumentation bundle:
npm install @opentelemetry/auto-instrumentations-node \
  @opentelemetry/sdk-node \
  @opentelemetry/exporter-trace-otlp-grpc \
  openai
  1. Run with auto-instrumentation:
node --require @opentelemetry/auto-instrumentations-node/register app.js

Use the official openai Python library with Python 3.9+. Start with automatic instrumentation for the least code churn, or use code-based setup when you want to own tracer initialization and import order.

Auto-Instrumentation

Install the OpenAI v2 instrumentor packages and run your app under opentelemetry-instrument so the openai library emits spans with minimal code changes.

  1. Install the distro and OpenAI instrumentation:
pip install opentelemetry-distro opentelemetry-instrumentation-openai-v2 opentelemetry-exporter-otlp
  1. Optionally, bootstrap additional instrumentation packages:
opentelemetry-bootstrap -a install
  1. Write your application using an Azure base_url and deployment name:
import os
from openai import OpenAI

base_url = os.environ.get("AZURE_OPENAI_BASE_URL")
if not base_url:
    resource = os.environ["AZURE_OPENAI_RESOURCE_NAME"]
    base_url = f"https://{resource}.openai.azure.com/openai/v1/"
api_version = os.environ.get("AZURE_OPENAI_API_VERSION", "2024-02-01")

client = OpenAI(
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
    base_url=base_url,
    default_query={"api-version": api_version},
)

deployment = os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"]

response = client.chat.completions.create(
    model=deployment,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
  1. Run your application with the auto-instrumentor:
opentelemetry-instrument python app.py

The instrumentor reads its configuration from OTEL_* environment variables.

Code-Based Setup

Initialize OpenTelemetry and OpenAIInstrumentor in a dedicated module, and import that module before you construct an OpenAI client.

  1. Create a tracing.py file:
# tracing.py: import this BEFORE your app code
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor

provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(provider)

# This monkey-patches the openai library to emit spans on every API call
OpenAIInstrumentor().instrument()
  1. Import tracing at the top of your application entry point before any Azure OpenAI calls:
import os
import tracing  # must be first - instruments the openai module
from openai import OpenAI

base_url = os.environ.get("AZURE_OPENAI_BASE_URL")
if not base_url:
    resource = os.environ["AZURE_OPENAI_RESOURCE_NAME"]
    base_url = f"https://{resource}.openai.azure.com/openai/v1/"

client = OpenAI(
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
    base_url=base_url,
    default_query={"api-version": os.environ.get("AZURE_OPENAI_API_VERSION", "2024-02-01")},
)

deployment = os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"]
response = client.chat.completions.create(
    model=deployment,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)

Set these environment variables before running your instrumented application:

Use gRPC (port 4317)

Set environment variables using gRPC. This is the recommended method:

export OTEL_EXPORTER_OTLP_ENDPOINT="http://<cribl-host>:4317"
export OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
export OTEL_SERVICE_NAME="my-azure-openai-app"

# Only if you enabled auth on the Cribl OTEL Source:
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <token>"

Optionally set additional OTLP exporter variables (for example if your environment expects explicit exporter selection):

export OTEL_RESOURCE_ATTRIBUTES="service.name=my-azure-openai-app"
export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="otlp"
export OTEL_LOGS_EXPORTER="otlp"
export OTEL_PYTHON_LOG_CORRELATION="true"
export OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED="true"

Use HTTP/protobuf (port 4318)

If your OTLP exporter or network path requires HTTP/protobuf instead of gRPC, use port 4318 and set the protocol as shown.

export OTEL_EXPORTER_OTLP_ENDPOINT="http://<cribl-host>:4318"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_SERVICE_NAME="my-azure-openai-app"

# Only if you enabled auth on the Cribl OTEL Source:
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <token>"

Environment Variable Reference

Use this table to set OTLP export options, optional auth headers for the Cribl Source, and Azure OpenAI settings for the openai SDK.

VariableRequiredDescription
OTEL_EXPORTER_OTLP_ENDPOINTYesCribl Search OpenTelemetry Source URL (http://<cribl-host>:4317 for gRPC, :4318 for HTTP).
OTEL_EXPORTER_OTLP_PROTOCOLYesgrpc or http/protobuf.
OTEL_SERVICE_NAMEYesLogical name for your application (appears in traces).
OTEL_EXPORTER_OTLP_HEADERSNoAuth header if the Source requires it (e.g., Authorization=Bearer <token>).
AZURE_OPENAI_API_KEYYesAzure OpenAI API key.
AZURE_OPENAI_CHAT_DEPLOYMENTYesChat deployment name (the model argument in chat.completions.create).
AZURE_OPENAI_BASE_URLOne of the URL optionsFull base URL including /openai/v1/.
AZURE_OPENAI_RESOURCE_NAMEOne of the URL optionsResource name only; samples build https://{name}.openai.azure.com/openai/v1/ when AZURE_OPENAI_BASE_URL is unset.
AZURE_OPENAI_ENDPOINTOne of the URL optionsPortal-style endpoint https://{name}.openai.azure.com; append /openai/v1/ in code if you construct base_url from this value.
AZURE_OPENAI_API_VERSIONNoDefaults to 2024-02-01 in samples if unset; use an API version supported for your resource.
AZURE_OPENAI_CHAT_DEPLOYMENT_ALTNoOptional second deployment for tests that compare models.
AZURE_OPENAI_EMBEDDING_DEPLOYMENTNoOptional embeddings deployment; omit if you do not call embeddings.

Capture Prompt/Completion Content

Enabling content capture may expose sensitive data in your telemetry pipeline.

By default, prompt and completion content is not captured to protect sensitive data. To enable it:

export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT="true"

After completing the instrumentation process, confirm OTLP events flow from your instrumented app into Cribl Search.

  1. On the Cribl.Cloud top bar, select Products > Search > Data > Live Data.
  2. Select your OpenTelemetry Source and confirm that events appear while you trigger traffic from your Azure OpenAI application.
  3. For full Live Data behavior and troubleshooting, check See Live Data Flow.

Common Search Issues and Fixes

SymptomCauseFix
No events returned.OpenTelemetry Source is not receiving data, or Dataset rules are not routing data correctly.Verify the Source address, port, protocol, and auth settings. Check Data > Live Data for the OpenTelemetry Source, then confirm your Dataset rule sends matching events to the correct Search Dataset.
Empty time range.No recent traffic, or event timestamps are outside your selected window.Widen Time range; generate a test Azure OpenAI call from your instrumented app. Review timestamp parsing in your Datatype configuration.
Fields not where you expect.Auto-Datatyping did not classify the events as expected, or your Datatype rules need refinement.Review the data in Live Data, check for Uncategorized events, and update or add Datatype rules so the data parses into the fields you expect.
Slow or expensive searches.Large partitions scanned.Narrow time range, increase sampling, or pre-aggregate in Stream.
Permission errors.Insufficient Search role.Ask an Admin to grant Editor (or higher) for Dataset management, or User for running searches per org policy.
404 or invalid URL from Azure.The OpenAI SDK is pointed at the wrong URL for Azure: the hostname does not match your resource, or the path does not end with /openai/v1/.Ensure the OpenAI SDK base URL ends with /openai/v1/ (see Azure OpenAI Service REST API reference).
DeploymentNotFound or wrong model.model= is not the deployment name.Set AZURE_OPENAI_CHAT_DEPLOYMENT to the deployment name shown in Azure AI Studio or the Azure portal.
401 from Azure.Key or Entra setup.Verify AZURE_OPENAI_API_KEY matches the resource (or your token credential).
API version errors from Azure.Unsupported api-version.Set AZURE_OPENAI_API_VERSION to a version supported for your resource and deployment.

With data flowing into Cribl Search, you can explore and gain visibility towards your Azure OpenAI telemetry:

  • Explore LLM telemetry: Explore your Search Dataset in Cribl Search and query it with KQL. Filter and slice by service, model, environment, token usage, cost signals, and error or status fields.
  • Investigate incidents and performance regressions: During elevated errors or latency, investigate your LLM Search Dataset. Use aggregations such as summarize or timestats to break down failures by model, deployment, feature, tenant, or region. Use join or related patterns with infrastructure, gateway, or security Datasets for end-to-end context.
  • Build dashboards for LLM usage and cost: Use Cribl Search Dashboards to track requests over time by model or app, token usage and derived cost, error rates by environment or tenant, and latency percentiles (for example P95/P99) plus token distributions and traffic share.
  • Automate checks with scheduled searches and notifications: Turn important queries (for example, when estimated LLM cost or error rate crosses a threshold over a time window) into Scheduled Searches and attach Notifications to email, Slack, SNS, webhooks, and other targets.

See more detailed LLM telemetry use cases in Cribl Search.

Learn how to instrument Azure OpenAI-based applications with OpenTelemetry, export large language model (LLM) telemetry via OTLP, and send it into Cribl Stream. Once data is in Cribl Stream, you can route, mask, and enrich it before it reaches your observability backends.

You’ll complete the following high-level steps:

  1. Configure an OpenTelemetry (OTel) Source in Cribl Stream to receive OTLP data.
  2. Instrument your Azure OpenAI application (Node.js or Python) with OpenTelemetry.
  3. Explore LLM telemetry use cases for Cribl Stream.

Telemetry Captured

Each Azure OpenAI API call produces a trace span with these attributes:

CategoryDataExample
TimingCall duration.1.2s.
ModelDeployment name (and resolved model where reported).gpt-4o-deployment, gpt-4o-2024-08-06.
Token usageInput, output, and total tokens.150 input, 85 output.
Request paramsTemperature, max tokens.temperature=0.7.
ResponseFinish reason, response ID.stop, chatcmpl-abc123.
ErrorsHTTP status, error message.429 Rate limit exceeded, deployment not found.
ContentPrompt and completion text.(opt-in, disabled by default).

Semantic conventions follow OpenTelemetry GenAI Semantic Conventions where applicable.

Prerequisites

  • A Cribl Stream instance (v4.x+) with an OpenTelemetry (OTel) Source enabled.
  • An Azure OpenAI resource with at least one chat deployment; optionally an embeddings deployment if you plan to trace embedding calls.
  • An Azure OpenAI API key with access to the deployments you want to monitor.
  • Node.js 18+ or Python 3.9+ depending on your application language.

Configure the OpenTelemetry (OTel) Source in Cribl Stream

Before instrumenting your Azure OpenAI app, configure Cribl Stream to receive OTLP data.

Configure an OTel Source

To receive OTLP from your LLM application, add or edit an OpenTelemetry Source on your Worker Group as follows.

  1. On the top bar, select Products, and then select Cribl Stream. Under Worker Groups, select a Worker Group. Next, you have two options:

    • To configure via QuickConnect, navigate to Routing > QuickConnect (Stream) or Collect (Edge). Select Add Source and select the Source you want from the list, choosing either Select Existing or Add New.
    • To configure via the Routes, select Data > Sources (Stream) or More > Sources (Edge). Select the Source you want. Next, select Add Source.
  2. In the New Source modal, configure the following under General Settings:

    • Input ID: Unique ID for this Source. For example, OTel042.
    • Description: Optionally, enter a description.
    • OTLP version: The drop-down offers 0.10.0 and 1.3.1 (default).
    • Protocol: Use the drop-down to choose the protocol matching the data you will ingest: gRPC (default), or HTTP.
    • Address: Enter the hostname/IP to listen on. Defaults to 0.0.0.0 (all addresses, IPv4 format).
    • Port: By default, OTel applications send output to port 4317 when using the gRPC protocol, and port 4318 when using HTTP. This setting defaults to 4317 - you must change it if you set Protocol (below) to HTTP, or you want Cribl Stream to collect data from an OTel application that is using a different port.

    Port 4318 is not available on Cribl-managed Worker Groups in Cribl.Cloud.

    • The Extract spans, Extract metrics, and Extract logs settings are specific to the OpenTelemetry Source. By default, these options are toggled off, allowing Cribl Stream to act as a pass-through that generates a single event for each incoming OTel payload. This is useful when you want to forward complete OTel events to downstream systems, such as persistent storage, without breaking them apart. You can enable these settings to extract and process individual records from within OTel events:
      • Extract spans: Generates an individual event for each span in a trace. Traces typically contain multiple spans.
      • Extract metrics: Generates an individual event for each data point in a metric event. OTel metrics often contain multiple data points per event.
      • Extract logs: Available only when OTLP version is set to 1.3.1. Generates an individual event for each log record. Cribl recommends enabling this option to simplify log transformation and manipulation.
    • Tags: Optionally, add tags to help filter and group Sources within Cribl Stream’s UI. Tags are not included in the event data. Separate tag names using a tab or hard return.
  3. Optionally, you can adjust the Authentication, TLS, Persistent Queue Settings, Processing, and Advanced settings, or Connected Destinations.

  4. Select Save, then Commit & Deploy.

Instrument Your Application

Pick Node.js or Python below. Both paths emit OTLP spans from the official OpenAI client libraries into the Source you configured earlier.

Node.jsPython

Use the openai npm package with Node.js 18+. The two options below are an explicit NodeSDK plus tracing.js, or the auto-instrumentations register hook if you prefer a single preload entry.

@opentelemetry/instrumentation-openai supports the openai npm package >=4.19.0 <7.

SDK-Based Setup

Register the OpenAI instrumentation on a NodeSDK, and load that setup before your application entrypoint so openai client calls are traced.

  1. Install the required packages:
npm install @opentelemetry/sdk-node \
  @opentelemetry/api \
  @opentelemetry/exporter-trace-otlp-grpc \
  @opentelemetry/instrumentation-openai \
  openai
  1. Create a tracing.js file and require it before your application code:
// tracing.js: load this BEFORE your app code
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');
const { OpenAIInstrumentation } = require('@opentelemetry/instrumentation-openai');

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter(),
  instrumentations: [new OpenAIInstrumentation()],
});
sdk.start();
  1. Run your application:
node -r ./tracing.js app.js

The exporter reads its endpoint from OTEL_EXPORTER_OTLP_ENDPOINT automatically.

Auto-Instrumentation

Load supported Node instrumentations from a single register hook instead of maintaining a custom tracing.js file.

  1. Install the auto-instrumentation bundle:
npm install @opentelemetry/auto-instrumentations-node \
  @opentelemetry/sdk-node \
  @opentelemetry/exporter-trace-otlp-grpc \
  openai
  1. Run with auto-instrumentation:
node --require @opentelemetry/auto-instrumentations-node/register app.js

Use the official openai Python library with Python 3.9+. Start with automatic instrumentation for the least code churn, or use code-based setup when you want to own tracer initialization and import order.

Auto-Instrumentation

Install the OpenAI v2 instrumentor packages and run your app under opentelemetry-instrument so the openai library emits spans with minimal code changes.

  1. Install the distro and OpenAI instrumentation:
pip install opentelemetry-distro opentelemetry-instrumentation-openai-v2 opentelemetry-exporter-otlp
  1. Optionally, bootstrap additional instrumentation packages:
opentelemetry-bootstrap -a install
  1. Write your application using an Azure base_url and deployment name:
import os
from openai import OpenAI

base_url = os.environ.get("AZURE_OPENAI_BASE_URL")
if not base_url:
    resource = os.environ["AZURE_OPENAI_RESOURCE_NAME"]
    base_url = f"https://{resource}.openai.azure.com/openai/v1/"
api_version = os.environ.get("AZURE_OPENAI_API_VERSION", "2024-02-01")

client = OpenAI(
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
    base_url=base_url,
    default_query={"api-version": api_version},
)

deployment = os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"]

response = client.chat.completions.create(
    model=deployment,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
  1. Run your application with the auto-instrumentor:
opentelemetry-instrument python app.py

The instrumentor reads its configuration from OTEL_* environment variables.

Code-Based Setup

Initialize OpenTelemetry and OpenAIInstrumentor in a dedicated module, and import that module before you construct an OpenAI client.

  1. Create a tracing.py file:
# tracing.py: import this BEFORE your app code
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor

provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(provider)

# This monkey-patches the openai library to emit spans on every API call
OpenAIInstrumentor().instrument()
  1. Import tracing at the top of your application entry point before any Azure OpenAI calls:
import os
import tracing  # must be first - instruments the openai module
from openai import OpenAI

base_url = os.environ.get("AZURE_OPENAI_BASE_URL")
if not base_url:
    resource = os.environ["AZURE_OPENAI_RESOURCE_NAME"]
    base_url = f"https://{resource}.openai.azure.com/openai/v1/"

client = OpenAI(
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
    base_url=base_url,
    default_query={"api-version": os.environ.get("AZURE_OPENAI_API_VERSION", "2024-02-01")},
)

deployment = os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT"]
response = client.chat.completions.create(
    model=deployment,
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)

Set Environment Variables

Set these environment variables before running your instrumented application:

Use gRPC (port 4317)

Set environment variables using gRPC. This is the recommended method:

export OTEL_EXPORTER_OTLP_ENDPOINT="http://<cribl-host>:4317"
export OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
export OTEL_SERVICE_NAME="my-azure-openai-app"

# Only if you enabled auth on the Cribl OTEL Source:
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <token>"

Optionally set additional OTLP exporter variables:

export OTEL_RESOURCE_ATTRIBUTES="service.name=my-azure-openai-app"
export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="otlp"
export OTEL_LOGS_EXPORTER="otlp"
export OTEL_PYTHON_LOG_CORRELATION="true"
export OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED="true"

Use HTTP/protobuf (port 4318)

If your OTLP exporter or network path requires HTTP/protobuf instead of gRPC, use port 4318 and set the protocol as shown.

export OTEL_EXPORTER_OTLP_ENDPOINT="http://<cribl-host>:4318"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_SERVICE_NAME="my-azure-openai-app"

# Only if you enabled auth on the Cribl OTEL Source:
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <token>"

Environment Variable Reference

Use this table to set OTLP export options, optional auth headers for the Cribl Source, and Azure OpenAI settings for the openai SDK.

VariableRequiredDescription
OTEL_EXPORTER_OTLP_ENDPOINTYesCribl Stream OTEL Source URL (http://<cribl-host>:4317 for gRPC, :4318 for HTTP).
OTEL_EXPORTER_OTLP_PROTOCOLYesgrpc or http/protobuf.
OTEL_SERVICE_NAMEYesLogical name for your application (appears in traces).
OTEL_EXPORTER_OTLP_HEADERSNoAuth header if Cribl Source requires it (e.g., Authorization=Bearer <token>).
AZURE_OPENAI_API_KEYYesAzure OpenAI API key.
AZURE_OPENAI_CHAT_DEPLOYMENTYesChat deployment name (the model argument in chat.completions.create).
AZURE_OPENAI_BASE_URLOne of the URL optionsFull base URL including /openai/v1/.
AZURE_OPENAI_RESOURCE_NAMEOne of the URL optionsResource name only; samples build https://{name}.openai.azure.com/openai/v1/ when AZURE_OPENAI_BASE_URL is unset.
AZURE_OPENAI_ENDPOINTOne of the URL optionsPortal-style endpoint https://{name}.openai.azure.com; append /openai/v1/ in code if you construct base_url from this value.
AZURE_OPENAI_API_VERSIONNoDefaults to 2024-02-01 in samples if unset.
AZURE_OPENAI_CHAT_DEPLOYMENT_ALTNoOptional second deployment for tests that compare models.
AZURE_OPENAI_EMBEDDING_DEPLOYMENTNoOptional embeddings deployment.

Capture Prompt/Completion Content

Enabling content capture may expose sensitive data in your telemetry pipeline. Use Cribl Stream’s masking and redaction functions to sanitize data before routing to downstream destinations.

By default, prompt and completion content is not captured to protect sensitive data. To enable it:

export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT="true"

Verify Data Flow in Cribl Stream

After completing the instrumentation process, confirm OTLP events flow from your instrumented app into Cribl Stream.

  1. In Cribl Stream, go to Monitoring > Sources and select your OTel Source.
  2. Open the Live Data tab.
  3. Select Start Capture.
  4. Trigger a request in your Azure OpenAI application.
  5. Confirm that events appear in Live Data for your OTel Source.

After Azure OpenAI OTLP data reaches Cribl Stream, add a Cribl Search Destination so you can explore and investigate LLM telemetry to troubleshoot issues, analyze model behavior, and monitor performance. See the Cribl Search Destination guide for setup instructions.

Common Issues and Fixes

If spans are missing or the exporter cannot reach Cribl Stream, use this table to narrow down endpoint, authentication, TLS, library versions, Azure configuration, and how instrumentation is loaded.

SymptomCauseFix
No data in Cribl Stream.Wrong endpoint or port.Verify OTEL_EXPORTER_OTLP_ENDPOINT matches the Cribl OTEL Source address and port.
Connection refused.Source not running or firewall blocking.Ensure the OTEL Source is enabled and the port is open.
401 Unauthorized.Auth mismatch.Check OTEL_EXPORTER_OTLP_HEADERS matches the auth config on the Cribl Source.
Missing spans.Instrumentation not loaded.Ensure tracing.js is required first (Node.js) or opentelemetry-instrument is used (Python).
No token counts.Older OpenAI library.Upgrade openai to >=4.19.0 (Node.js) or latest version (Python).
401 / 403 from Azure.Invalid API key or RBAC.Verify AZURE_OPENAI_API_KEY or your token credential; confirm the principal can invoke the deployment.
404 from Azure.The OpenAI SDK is pointed at the wrong URL for Azure: the hostname does not match your resource, or the path does not end with /openai/v1/.Ensure the OpenAI SDK base URL ends with /openai/v1/.
DeploymentNotFound.model= is not the deployment name.Set AZURE_OPENAI_CHAT_DEPLOYMENT to the deployment name in Azure AI Studio or the Azure portal.
API version errors from Azure.Unsupported api-version.Set AZURE_OPENAI_API_VERSION to a version supported for your resource.
TLS errors.TLS mismatch.Use https:// in the endpoint if TLS is enabled on the Source, or disable TLS on the Source for local testing.

LLM Telemetry Use Cases

With data flowing into Cribl Stream, you can route Azure OpenAI telemetry to any supported Destination. For example:

  • Cribl Search: Search and analyze full-fidelity LLM traces and logs interactively.
  • Cribl Lake: Store and search traces natively with partitioning optimized for Cribl Search, so you can query Azure OpenAI traces at scale without re-ingesting them into a separate system.
  • Amazon S3 or other object storage: Archive traces for compliance or long-term analysis using partitioning schemes aligned with Cribl Search, so you can query data in place without moving it.
  • OpenTelemetry: Forward LLM traces in standard OTLP format to downstream systems.

To set up routing:

  1. Add Routes in Routing > Data Routes to match OTel data and direct it to your chosen Destinations.
  2. Go to Processing > Pipelines and create a Pipeline to process data flowing down your Route.
  3. Use Functions to enrich, filter, sample, or redact data before delivery. For example:
    • Mask prompt/completion content containing sensitive information.
    • Sample high-volume traces to reduce cost.
    • Aggregate token usage metrics by model or service.

For more detailed LLM telemetry use cases, see LLM Telemetry Use Cases in Cribl.