Telemetry & Observability

Telemetry & Observability

Monitor your authorization decisions, track performance, and gain insights into your D2 deployment

Two Types of Telemetry

OpenTelemetry Metrics

Standard OTLP metrics sent to your observability platform (Prometheus, Grafana, etc.)

Usage Events

Usage events record information that is relevant to the d2 authorization product. For the full list see the Key Metrics table below.

Telemetry Configuration

Control what telemetry is sent using the D2_TELEMETRY environment variable:

off

No telemetry

metrics

OTLP only

usage

Events only

all

Everything (default)

OpenTelemetry integration

Automatic Setup

D2 automatically configures OpenTelemetry metrics when the required libraries are installed. No crashes if exporters aren't available - telemetry gracefully degrades.

Required Dependencies

pip install opentelemetry-api opentelemetry-sdk pip install opentelemetry-exporter-otlp-proto-http

Key Metrics

MetricTypeDescription
d2.authz.decision.totalCounterTotal authorization decisions by tool_id, result, mode
d2.authz.decision.latency.msHistogramAuthorization decision latency (typically <1ms)
d2.tool.exec.latency.msHistogramProtected function execution time
d2.tool.invocation.totalCounterPost-authorization tool executions by tool_id, status
d2.policy.poll.updatedCounterPolicy bundle updates from cloud
d2.policy.bundle.age.secondsGaugeAge of current policy bundle
d2.context.leak.totalCounterDetected context leaks (security issue)

Configuration Example

Environment Variables

export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 export OTEL_SERVICE_NAME=my-d2-app export OTEL_RESOURCE_ATTRIBUTES=service.version=1.0.0 export D2_TELEMETRY=all

Python Code

import d2 # D2 automatically configures OTLP if libraries are available await d2.configure_rbac_async() # Your protected functions will now emit metrics @d2.d2_guard("user_data") def get_user_profile(user_id: str): return {"id": user_id, "name": "John Doe"}

Usage events

Event Collection

When D2_TOKEN is set, the SDK sends detailed usage events to D2 Cloud for product analytics and quota management.

Event Types

  • policy_load - Bundle loaded
  • authz_decision - Authorization check
  • tool_invoked - Function execution
  • context_leak - Security issues

Event Delivery

  • • Buffered (max 1000 events)
  • • Sent every 60s ±10% jitter
  • • Respects 429 rate limits
  • • Quota-aware chunking

Server-driven sampling

The D2 Cloud platform returns sampling rates for different event types to control telemetry volume:

Event TypeDefault RatePurpose
authz_decision100%Security monitoring
tool_invoked100%Usage analytics
policy_poll_interval10%Reduce noise
missing_policy50%Error detection

Privacy & Security

  • No sensitive data: Function arguments are never sent in usage events
  • Local mode privacy: Usage events only sent in cloud mode (when D2_TOKEN is set)
  • Configurable: Set D2_TELEMETRY=off to disable all telemetry
  • User identifiers: Any user_id you pass to d2.set_user() is included as-is; hash or pseudonymise if you don’t want to send real IDs
  • Transparent: All event schemas documented in the SDK reference

Troubleshooting

Common Issues

Metrics not appearing in your observability platform?

  • • Verify OTLP libraries are installed: pip list | grep opentelemetry
  • • Check OTEL_EXPORTER_OTLP_ENDPOINT environment variable
  • • Ensure D2_TELEMETRY is set to metrics or all
  • • Look for D2 startup logs indicating telemetry status

High authorization latency?

  • • Check d2.authz.decision.latency.ms histogram
  • • Normal latency is <1ms for local decisions
  • • High latency may indicate policy bundle issues or network problems
  • • Monitor d2.policy.bundle.age.seconds for stale policies

Context leaks detected?

  • • Monitor d2.context.leak.total counter
  • • Use @clear_context decorators on web handlers
  • • Always call d2.clear_user_context() in finally blocks
  • • Use with d2.set_user_context() for automatic cleanup