Skip to main content
Guide

Telemetry

Route a sandbox's logs, OpenTelemetry signals, operational metrics, and network egress decisions to the observability backends you already run. Telemetry is opt-in and configured per sandbox at creation time through the telemetryConfig object.

A sandbox emits four categories of telemetry. You choose which categories to collect and which destinations receive them by attaching one or more endpoints to the sandbox's telemetryConfig. Each endpoint declares its kind (the destination type), the data it should receive, and how to authenticate. If you omit telemetryConfig, no telemetry is exported.

What you can collect

Each endpoint's data array selects one or more of these categories.

Data categoryWhat it is
ContainerStdoutStderrEverything your container writes to stdout and stderr.
ContainerOtelOpenTelemetry traces, metrics, and logs emitted by your code through an OTEL SDK. When an endpoint requests this, the sandbox injects OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 into the container so the SDK exports with no extra configuration.
MetricsOperational metrics for the sandbox itself — CPU, memory, and network. Collected on an interval you control with metricsIntervalSeconds.
NetworkEgressDecisionsOne record per outbound request describing the egress policy decision (allow / deny / rewrite) and the enforcement mode that produced it.

Where you can send it

The kind discriminator selects the destination type. A single telemetryConfig can mix kinds — for example, container logs to your OTLP collector and egress decisions to Log Analytics.

Endpoint kindDestinationAuthentication
OTLPAny OTLP-compatible collector or backend (Azure Monitor, Datadog, Honeycomb, Grafana, and others).Optional header injection from a secret.
LogAnalyticsAzure Monitor Log Analytics through the Logs Ingestion API (Data Collection Endpoint + Data Collection Rule).Managed identity assigned to the sandbox group.
ApplicationInsightsAzure Monitor Application Insights.Connection-string secret.

Configure telemetry when you create a sandbox

Pass telemetryConfig in the sandbox creation request. The example below sends container logs and OTEL signals to an OTLP collector, authenticating with an x-api-key header resolved from a sandbox group secret.

{
"telemetryConfig": {
"metricsIntervalSeconds": 15,
"endpoints": [
{
"kind": "OTLP",
"data": ["ContainerStdoutStderr", "ContainerOtel", "Metrics"],
"endpoint": "https://collector.example.com/otlp",
"protocol": "Grpc",
"auth": {
"headerName": "x-api-key",
"secretId": "otel-credentials",
"secretKey": "apiKey"
}
}
]
}
}

metricsIntervalSeconds is optional. It sets how often Metrics are sampled, must be at least 2, and defaults to 15.

Endpoint reference

OTLP

Sends telemetry to any OTLP-compatible collector.

FieldTypeDescription
endpointstring (URI)OTLP endpoint URL.
protocolGrpc | HttpOTLP transport. Required.
datastring[]Any of ContainerStdoutStderr, ContainerOtel, Metrics, NetworkEgressDecisions.
authobjectOptional. Injects a header whose value comes from a secret.
auth.headerNamestringHeader to inject, such as x-api-key or Authorization.
auth.secretIdstringName of a sandbox group secret.
auth.secretKeystringKey within that secret whose value becomes the header value.

Log Analytics (Logs Ingestion API)

Sends telemetry to Azure Monitor through a Data Collection Endpoint and Data Collection Rule. Authenticated with a managed identity assigned to the sandbox group.

FieldTypeDescription
dceEndpointstring (URI)Data Collection Endpoint URL.
dcrImmutableIdstringImmutable ID of the Data Collection Rule.
tableNamestringTarget stream name declared in the DCR.
datastring[]Which categories to route.
authobjectManaged identity. See below.
{
"kind": "LogAnalytics",
"data": ["NetworkEgressDecisions"],
"dceEndpoint": "https://dce-xxx.eastus-1.ingest.monitor.azure.com",
"dcrImmutableId": "dcr-a1b2c3d4e5f6",
"tableName": "Custom-EgressDecisions_CL",
"auth": {
"kind": "ManagedIdentity",
"identity": "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<name>"
}
}

For a user-assigned identity, set auth.kind to ManagedIdentity and supply the identity's full ARM resource ID in auth.identity. For the sandbox group's system-assigned identity, use { "kind": "SystemAssignedManagedIdentity" } with no resource ID. The identity must be assigned to the sandbox group — see Identity.

Application Insights

Sends telemetry to an Application Insights resource. The connection string is resolved at runtime from a secret, so it never has to enter the sandbox.

FieldTypeDescription
datastring[]Which categories to route.
auth.secretIdstringName of a sandbox group secret holding the connection string.
auth.secretKeystringKey within that secret whose value is the Application Insights connection string.
{
"kind": "ApplicationInsights",
"data": ["NetworkEgressDecisions"],
"auth": { "secretId": "appinsights-credentials", "secretKey": "connectionString" }
}

Authenticate endpoints

Telemetry endpoints never carry credentials inline. They reference credentials one of two ways:

  • SecretsOTLP and ApplicationInsights resolve their credential from a sandbox group secret at runtime. Create the secret once on the group, then reference it by secretId and secretKey. Rotate the value in place without editing the sandbox.
  • Managed identityLogAnalytics (Logs Ingestion API) authenticates with a user-assigned or system-assigned identity assigned to the sandbox group. See Identity.

Export network egress decisions

Adding NetworkEgressDecisions to an endpoint's data exports one record per outbound request — allowed, denied, or rewrite-blocked — to that destination.

Export and enforcement are independent settings. Whether decisions are exported is controlled only by the data array; whether denied requests are blocked is controlled by the egress policy's enforcement mode. You can keep enforcement on (denies stay blocked) and still export every decision.

Shape the log schema (optional)

For ContainerStdoutStderr, two optional endpoint fields let you control the output schema:

  • columns — a map that projects log records into named columns (static values or references to sandbox attributes such as the sandbox ID, region, or stream). Reserved names (time, message, timeGenerated, and anything starting with adc.) are rejected.
  • dynamicJsonColumns — when true, JSON log lines are parsed and their top-level keys become columns. Keys named message are dropped, so emit structured text under a different key such as msg.

Both fields apply only to ContainerStdoutStderr. They have no effect on ContainerOtel, whose schema is owned by your OTEL SDK.