OpenTelemetry Collector¶
Subscription required
This section describes functionality which requires an active IAPM subscription. Start your subscription by choosing the plan right for you.
The OpenTelemetry Collector is a vendor-agnostic proxy that receives, processes, and exports telemetry data. This guide covers when to use a Collector, how to configure it for IAPM, and deployment options for Docker and Kubernetes.
When to Use a Collector¶
You can export telemetry directly from your application to IAPM, or route it through a Collector first. Here is when each approach makes sense:
| Approach | Best For |
|---|---|
| Direct export | Simple deployments, few services, getting started quickly |
| Via Collector | Production deployments, multiple services, when you need batching, retry, or enrichment |
Benefits of using a Collector:
- Centralized configuration - Change the OTLP endpoint or API key in one place instead of every service
- Batching and retry - The Collector handles buffering and retries, reducing load on your applications
- Enrichment - Add Kubernetes metadata, environment tags, or other attributes
- Sampling - Apply tail-based or probabilistic sampling before export
- Multiple destinations - Fan out telemetry to IAPM and other backends simultaneously
- Protocol translation - Accept telemetry over gRPC, HTTP, Zipkin, Jaeger, and export as OTLP
Collector Configuration¶
The Collector uses a YAML configuration file with four main sections: receivers, processors, exporters, and service pipelines.
Minimal Configuration¶
# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
send_batch_size: 1024
exporters:
otlp/iapm:
endpoint: otlp.iapm.app:443
headers:
API-Key: YOUR-API-KEY
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/iapm]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlp/iapm]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlp/iapm]
Production Configuration¶
A more complete configuration with memory limiting, resource detection, and health checks:
# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
send_batch_size: 1024
send_batch_max_size: 2048
memory_limiter:
check_interval: 5s
limit_mib: 512
spike_limit_mib: 128
resource:
attributes:
- key: environment
value: production
action: upsert
- key: team
value: platform
action: upsert
filter/health:
error_mode: ignore
traces:
span:
- 'attributes["http.route"] == "/health"'
- 'attributes["http.route"] == "/ready"'
exporters:
otlp/iapm:
endpoint: otlp.iapm.app:443
headers:
API-Key: ${env:IAPM_API_KEY}
retry_on_failure:
enabled: true
initial_interval: 5s
max_interval: 30s
max_elapsed_time: 300s
sending_queue:
enabled: true
num_consumers: 10
queue_size: 5000
extensions:
health_check:
endpoint: 0.0.0.0:13133
zpages:
endpoint: 0.0.0.0:55679
service:
extensions: [health_check, zpages]
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, filter/health, resource, batch]
exporters: [otlp/iapm]
metrics:
receivers: [otlp]
processors: [memory_limiter, resource, batch]
exporters: [otlp/iapm]
logs:
receivers: [otlp]
processors: [memory_limiter, resource, batch]
exporters: [otlp/iapm]
Configuration Reference¶
Receivers¶
| Receiver | Description |
|---|---|
otlp | Accepts OTLP over gRPC (port 4317) and HTTP (port 4318) |
zipkin | Accepts Zipkin format (port 9411) |
jaeger | Accepts Jaeger format (ports 14250, 14268) |
prometheus | Scrapes Prometheus metrics endpoints |
Processors¶
| Processor | Description |
|---|---|
batch | Batches telemetry for efficient export |
memory_limiter | Prevents the Collector from running out of memory |
resource | Adds, updates, or removes resource attributes |
filter | Drops unwanted spans, metrics, or logs |
k8sattributes | Enriches telemetry with Kubernetes metadata |
probabilistic_sampler | Samples a percentage of traces |
tail_sampling | Makes sampling decisions based on complete traces |
Exporters¶
| Exporter | Description |
|---|---|
otlp | Exports via OTLP gRPC |
otlphttp | Exports via OTLP HTTP |
debug | Prints telemetry to stdout (for development) |
Docker Compose Example¶
Run a Collector alongside your application using Docker Compose:
# docker-compose.yaml
version: "3.9"
services:
otel-collector:
image: otel/opentelemetry-collector-contrib:latest
command: ["--config", "/etc/otel/config.yaml"]
volumes:
- ./otel-collector-config.yaml:/etc/otel/config.yaml:ro
ports:
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
- "13133:13133" # Health check
environment:
- IAPM_API_KEY=YOUR-API-KEY
restart: unless-stopped
my-app:
build: .
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
- OTEL_SERVICE_NAME=my-app
depends_on:
- otel-collector
Run with:
Collector image
Use otel/opentelemetry-collector-contrib (the "contrib" distribution) for the full set of receivers, processors, and exporters. The base otel/opentelemetry-collector image has a smaller set of components.
Kubernetes Deployment¶
For Kubernetes deployments, see the Kubernetes Instrumentation Guide which covers:
- Deploying the Collector as a DaemonSet or sidecar
- Helm chart configuration
- Integration with the OpenTelemetry Operator
Quick Kubernetes Deployment (without Helm)¶
# collector-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: otel-collector
namespace: otel-system
spec:
replicas: 2
selector:
matchLabels:
app: otel-collector
template:
metadata:
labels:
app: otel-collector
spec:
containers:
- name: collector
image: otel/opentelemetry-collector-contrib:latest
args: ["--config", "/etc/otel/config.yaml"]
ports:
- containerPort: 4317
name: otlp-grpc
- containerPort: 4318
name: otlp-http
- containerPort: 13133
name: health
volumeMounts:
- name: config
mountPath: /etc/otel
envFrom:
- secretRef:
name: iapm-api-key
resources:
requests:
memory: 256Mi
cpu: 200m
limits:
memory: 512Mi
cpu: 500m
livenessProbe:
httpGet:
path: /
port: 13133
readinessProbe:
httpGet:
path: /
port: 13133
volumes:
- name: config
configMap:
name: otel-collector-config
---
apiVersion: v1
kind: Service
metadata:
name: otel-collector
namespace: otel-system
spec:
selector:
app: otel-collector
ports:
- name: otlp-grpc
port: 4317
targetPort: 4317
- name: otlp-http
port: 4318
targetPort: 4318
---
apiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector-config
namespace: otel-system
data:
config.yaml: |
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
timeout: 5s
memory_limiter:
check_interval: 5s
limit_mib: 400
exporters:
otlp/iapm:
endpoint: otlp.iapm.app:443
headers:
API-Key: ${env:IAPM_API_KEY}
extensions:
health_check:
endpoint: 0.0.0.0:13133
service:
extensions: [health_check]
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/iapm]
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/iapm]
logs:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/iapm]
Verify It's Working¶
-
Start the Collector and confirm it is healthy:
-
Send test telemetry using
telemetrygen(optional): -
Open portal.iapm.app and select your Grid
- Click Enter - you should see the test traces within a few minutes
Troubleshooting¶
Collector not starting¶
- Check the configuration file for YAML syntax errors. Use
otelcol validate --config=config.yamlto validate. - Ensure the ports (4317, 4318) are not already in use.
- Check container logs:
docker logs <container>orkubectl logs <pod>.
Data not reaching IAPM¶
- Verify the API key by copying a fresh one from portal.iapm.app under Administration > Grids > Instrument.
-
Check that the Collector can reach
otlp.iapm.app:443. Test from within the container: -
Enable the
debugexporter to see what the Collector is receiving:
High memory usage¶
- Tune the
memory_limiterprocessor. Setlimit_mibbelow the container memory limit. - Reduce
send_batch_max_sizein thebatchprocessor. - Consider adding sampling to reduce volume.
Applications not connecting to the Collector¶
- Ensure the application's
OTEL_EXPORTER_OTLP_ENDPOINTpoints to the Collector's address and port. - In Docker Compose, use the service name:
http://otel-collector:4317. - In Kubernetes, use the Service DNS:
http://otel-collector.otel-system.svc.cluster.local:4317.
Plain HTTP is acceptable for cluster-internal traffic
The http:// endpoints above are for application-to-Collector traffic within the same Docker network or Kubernetes cluster. The Collector's outbound connection to otlp.iapm.app always uses TLS. For multi-tenant clusters or strict security requirements, configure TLS between applications and the Collector as well.