# Connectors Source: https://otel.fyi/components/connector/_index OpenTelemetry Connectors components # Count Source: https://otel.fyi/components/connector/countconnector OpenTelemetry connector for Count # Count Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib`, `k8s` **Maintainers:** [@akats7](https://github.com/akats7) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/countconnector) ## Overview The `count` connector can be used to count spans, span events, metrics, data points, and log records. ## Configuration If you are not already familiar with connectors, you may find it helpful to first visit the [Connectors README]. ### Default Configuration The `count` connector may be used without any configuration settings. The following table describes the default behavior of the connector. | \[Exporter Pipeline Type] | Description | Default Metric Names | | ------------------------- | ----------------------------------- | -------------------------------------------- | | traces | Counts all spans and span events. | `trace.span.count`, `trace.span.event.count` | | metrics | Counts all metrics and data points. | `metric.count`, `metric.datapoint.count` | | logs | Counts all log records. | `log.record.count` | For example, in the following configuration the connector will count spans and span events from the `traces/in` pipeline and emit metrics called `trace.span.count` and `trace.span.event.count` onto the `metrics/out` pipeline. ```yaml theme={null} receivers: foo: exporters: bar: connectors: count: service: pipelines: traces/in: receivers: [foo] exporters: [count] metrics/out: receivers: [count] exporters: [bar] ``` ### Custom Counts Optionally, emit custom counts by defining metrics under one or more of the following sections: * `spans` * `spanevents` * `metrics` * `datapoints` * `logs` Optionally, specify a description for the metric. Note: If any custom metrics are defined for a data type, the default metric will not be emitted. #### Conditions Conditions may be specified for custom metrics. If specified, data that matches any one of the conditions will be counted. i.e. Conditions are ORed together. ```yaml theme={null} receivers: foo: exporters: bar: connectors: count: spanevents: my.prod.event.count: description: The number of span events from my prod environment. conditions: - 'spanevent.attributes["env"] == "prod"' - 'spanevent.name == "prodevent"' ``` #### Attributes `spans`, `spanevents`, `datapoints`, and `logs` may be counted according to attributes. In such cases, attribute precedence follows this order: span(logRecord, DataPoint, profile) attributes > scope attributes > resource attributes. If attributes are specified for custom metrics, a separate count will be generated for each unique set of attribute values. Each count will be emitted as a data point on the same metric. Optionally, include a `default_value` for an attribute, to count data that does not contain the attribute. The `default_value` value can be of type string, integer, or float. ```yaml theme={null} receivers: foo: exporters: bar: connectors: count: logs: my.log.count: description: The number of logs from each environment. attributes: - key: env default_value: unspecified_environment ``` ### Example Usage Count spans and span events, only exporting the count metrics. ```yaml theme={null} receivers: foo: exporters: bar: connectors: count: service: pipelines: traces: receivers: [foo] exporters: [count] metrics: receivers: [count] exporters: [bar] ``` Count spans and span events, exporting both the original traces and the count metrics. ```yaml theme={null} receivers: foo: exporters: bar/traces_backend: bar/metrics_backend: connectors: count: service: pipelines: traces: receivers: [foo] exporters: [bar/traces_backend, count] metrics: receivers: [count] exporters: [bar/metrics_backend] ``` Count spans, span events, metrics, data points, and log records, exporting count metrics to a separate backend. ```yaml theme={null} receivers: foo/traces: foo/metrics: foo/logs: exporters: bar/all_types: bar/counts_only: connectors: count: service: pipelines: traces: receivers: [foo/traces] exporters: [bar/all_types, count] metrics: receivers: [foo/metrics] exporters: [bar/all_types, count] logs: receivers: [foo/logs] exporters: [bar/all_types, count] metrics/counts: receivers: [count] exporters: [bar/counts_only] ``` Count logs with a severity of ERROR or higher. ```yaml theme={null} receivers: foo: exporters: bar: connectors: count: logs: my.error.log.count: description: Error+ logs. conditions: - `severity_number >= SEVERITY_NUMBER_ERROR` service: pipelines: logs: receivers: [foo] exporters: [count] metrics: receivers: [count] exporters: [bar] ``` Count logs with a severity of ERROR or higher. Maintain a separate count for each environment. ```yaml theme={null} receivers: foo: exporters: bar: connectors: count: logs: my.error.log.count: description: Error+ logs. conditions: - `severity_number >= SEVERITY_NUMBER_ERROR` attributes: - key: env service: pipelines: logs: receivers: [foo] exporters: [count] metrics: receivers: [count] exporters: [bar] ``` Count all spans and span events (default behavior). Count metrics and data points based on the `env` attribute. ```yaml theme={null} receivers: foo/traces: foo/metrics: foo/logs: exporters: bar/all_types: bar/counts_only: connectors: count: metrics: my.prod.metric.count: conditions: - `attributes["env"] == "prod" my.test.metric.count: conditions: - `attributes["env"] == "test" datapoints: my.prod.datapoint.count: conditions: - `attributes["env"] == "prod" my.test.datapoint.count: conditions: - `attributes["env"] == "test" service: pipelines: traces: receivers: [foo/traces] exporters: [bar/all_types, count] metrics: receivers: [foo/metrics] exporters: [bar/all_types, count] metrics/counts: receivers: [count] exporters: [bar/counts_only] ``` [Connectors README]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md ## Configuration ### Example Configuration ```yaml theme={null} count: count/custom_description: spans: trace.span.count: description: My description for default span count metric. spanevents: trace.span.event.count: description: My description for default span event count metric. metrics: metric.count: description: My description for default metric count metric. datapoints: metric.datapoint.count: description: My description for default datapoint count metric. logs: log.record.count: description: My description for default log count metric. profiles: profile.count: description: My description for default profile count metric. count/custom_metric: spans: my.span.count: description: My span count. spanevents: my.spanevent.count: description: My span event count. metrics: my.metric.count: description: My metric count. datapoints: my.datapoint.count: description: My data point count. logs: my.logrecord.count: description: My log record count. profiles: my.profiling.count: description: My profile count. count/condition: spans: my.span.count: description: My span count. conditions: - IsMatch(resource.attributes["host.name"], "pod-s") spanevents: my.spanevent.count: description: My span event count. conditions: - IsMatch(resource.attributes["host.name"], "pod-e") metrics: my.metric.count: description: My metric count. conditions: - IsMatch(resource.attributes["host.name"], "pod-m") datapoints: my.datapoint.count: description: My data point count. conditions: - IsMatch(resource.attributes["host.name"], "pod-d") logs: my.logrecord.count: description: My log record count. conditions: - IsMatch(resource.attributes["host.name"], "pod-l") profiles: my.profiling.count: description: My profile count. conditions: - IsMatch(resource.attributes["host.name"], "pod-l") count/multiple_condition: spans: my.span.count: description: My span count. conditions: - IsMatch(resource.attributes["host.name"], "pod-s") - IsMatch(resource.attributes["foo"], "bar-s") spanevents: my.spanevent.count: description: My span event count. conditions: - IsMatch(resource.attributes["host.name"], "pod-e") - IsMatch(resource.attributes["foo"], "bar-e") metrics: my.metric.count: description: My metric count. conditions: - IsMatch(resource.attributes["host.name"], "pod-m") - IsMatch(resource.attributes["foo"], "bar-m") datapoints: my.datapoint.count: description: My data point count. conditions: - IsMatch(resource.attributes["host.name"], "pod-d") - IsMatch(resource.attributes["foo"], "bar-d") logs: my.logrecord.count: description: My log record count. conditions: - IsMatch(resource.attributes["host.name"], "pod-l") - IsMatch(resource.attributes["foo"], "bar-l") profiles: my.profiling.count: description: My profile count. conditions: - IsMatch(resource.attributes["host.name"], "pod-l") - IsMatch(resource.attributes["foo"], "bar-l") count/attribute: spans: my.span.count: description: My span count by environment. attributes: - key: env spanevents: my.spanevent.count: description: My span event count by environment. attributes: - key: env metrics: my.metric.count: description: My metric count. # Metrics do not have attributes. datapoints: my.datapoint.count: description: My data point count by environment. attributes: - key: env logs: my.logrecord.count: description: My log record count by environment. attributes: - key: env profiles: my.profiling.count: description: My profile count by environment. attributes: - key: env count/multiple_metrics: spans: my.span.count: description: My span count. limited.span.count: description: Limited span count. conditions: - IsMatch(resource.attributes["host.name"], "pod-s") attributes: - key: env - key: component default_value: other spanevents: my.spanevent.count: description: My span event count. limited.spanevent.count: description: Limited span event count. conditions: - IsMatch(resource.attributes["host.name"], "pod-e") attributes: - key: env - key: component default_value: other metrics: my.metric.count: description: My metric count. limited.metric.count: description: Limited metric count. conditions: - IsMatch(resource.attributes["host.name"], "pod-m") datapoints: my.datapoint.count: description: My data point count. limited.datapoint.count: description: Limited data point count. conditions: - IsMatch(resource.attributes["host.name"], "pod-d") attributes: - key: env - key: component default_value: other logs: my.logrecord.count: description: My log record count. limited.logrecord.count: description: Limited log record count. conditions: - IsMatch(resource.attributes["host.name"], "pod-l") attributes: - key: env - key: component default_value: other profiles: my.profiling.count: description: My profile count. limited.profiling.count: description: Limited profile count. conditions: - IsMatch(resource.attributes["host.name"], "pod-l") attributes: - key: env - key: component default_value: other count/default_values: logs: my.logrecord.count: description: My log record count with default values. limited.logrecord.count: description: Limited log record count. attributes: - key: env default_value: "local" - key: http_code default_value: 200 - key: request_success default_value: 0.85 - key: cache_hit default_value: true ``` *** *Last generated: 2026-08-03* # Datadog Source: https://otel.fyi/components/connector/datadogconnector OpenTelemetry connector for Datadog # Datadog Connector ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@mx-psi](https://github.com/mx-psi), [@dineshg13](https://github.com/dineshg13), [@jade-guiton-dd](https://github.com/jade-guiton-dd), [@IbraheemA](https://github.com/IbraheemA) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/datadogconnector) ## Overview ## Description The Datadog Connector is a connector component that derives APM statistics, in the form of metrics, from service traces, for display in the Datadog APM product. This component is *required* for trace-emitting services and their statistics to appear in Datadog APM. The Datadog connector can also forward the traces passed into it into another trace pipeline. Notably, if you plan to sample your traces with the [tailsamplingprocessor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor#tail-sampling-processor) or the [probabilisticsamplerprocessor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/probabilisticsamplerprocessor), you should place the Datadog connector upstream to ensure that the metrics are computed before sampling, ensuring their accuracy. An example is given below. ## Usage ```yaml theme={null} processors: # ... probabilistic_sampler: sampling_percentage: 20 connectors: # add the "datadog" connector definition and further configurations datadog/connector: exporters: datadog: api: key: ${env:DD_API_KEY} sending_queue: batch: service: pipelines: traces: receivers: [otlp] exporters: [datadog/connector] traces/2: # this pipeline uses sampling receivers: [datadog/connector] processors: [probabilistic_sampler] exporters: [datadog] metrics: receivers: [datadog/connector] exporters: [datadog] ``` In this example configuration, incoming traces are received through OTLP, and processed by the Datadog connector in the `traces` pipeline. The traces are then forwarded to the `traces/2` pipeline, where a sample of them is exported to Datadog. In parallel, the APM stats computed from the full stream of traces are sent to the `metrics` pipeline, where they are exported to Datadog as well. ## Configurations ```yaml theme={null} connectors: datadog/connector: traces: ## @param ignore_resources - list of strings - optional ## A blacklist of regular expressions can be provided to disable certain traces based on their resource name ## all entries must be surrounded by double quotes and separated by commas. # # ignore_resources: ["(GET|POST) /healthcheck"] ## @param span_name_remappings - map of key/value pairs - optional ## A map of Datadog span operation name keys and preferred name valuues to update those names to. This can be used to ## automatically map Datadog Span Operation Names to an updated value, and is useful when a user wants to ## shorten or modify span names to something more user friendly in the case of instrumentation libraries with ## particularly verbose names. # # span_name_remappings: # io.opentelemetry.javaagent.spring.client: spring.client # instrumentation:express.server: express # go.opentelemetry.io_contrib_instrumentation_net_http_otelhttp.client: http.client ## @param span_name_as_resource_name - use OpenTelemetry semantic convention for span naming - optional ## Option created to maintain similarity with the OpenTelemetry semantic conventions as discussed in the issue below. ## https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/trace/semantic_conventions ## https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/1909 # # span_name_as_resource_name: true ## @param compute_stats_by_span_kind - enables APM stats computation based on `span.kind` - optional ## If set to true, enables an additional stats computation check on spans to see they have an eligible `span.kind` (server, consumer, client, producer). ## If enabled, a span with an eligible `span.kind` will have stats computed. If disabled, only top-level and measured spans will have stats computed. ## NOTE: For stats computed from OTel traces, only top-level spans are considered when this option is off. # # compute_stats_by_span_kind: true ## @param peer_tags_aggregation - enables aggregation of peer related tags in Datadog exporter - optional ## If set to true, enables aggregation of peer related tags (e.g., `peer.service`, `db.instance`, etc.) in Datadog exporter. ## If disabled, aggregated trace stats will not include these tags as dimensions on trace metrics. ## For the best experience with peer tags, Datadog also recommends enabling `compute_stats_by_span_kind`. ## If you are using an OTel tracer, it's best to have both enabled because client/producer spans with relevant peer tags ## may not be marked by Datadog exporter as top-level spans. ## If enabling both causes Datadog exporter to consume too many resources, try disabling `compute_stats_by_span_kind` first. ## A high cardinality of peer tags or APM resources can also contribute to higher CPU and memory consumption. ## You can check for the cardinality of these fields by making trace search queries in the Datadog UI. ## The default list of peer tags can be found in https://github.com/DataDog/datadog-agent/blob/main/pkg/trace/stats/concentrator.go. # # peer_tags_aggregation: false ## @param trace_buffer - specifies the number of outgoing trace payloads to buffer before dropping - optional ## If unset, the default value is 1000. ## If you start seeing log messages like `Payload in channel full. Dropped 1 payload.` in the datadog exporter, consider ## setting a higher `trace_buffer` to avoid traces being dropped. # # trace_buffer: 1000 ## @param peer_tags - [BETA] Optional list of supplementary peer tags that go beyond the defaults. The Datadog backend validates all tags ## and will drop ones that are unapproved. The default set of peer tags can be found at ## https://github.com/DataDog/datadog-agent/blob/505170c4ac8c3cbff1a61cf5f84b28d835c91058/pkg/trace/stats/concentrator.go#L55. # # peer_tags: ["tag"] ## @param resource_attributes_as_container_tags - enables the use of resource attributes as container tags - Optional ## A list of resource attributes that should be used as container tags. # # resource_attributes_as_container_tags: ["cloud.availability_zone", "cloud.region"] ## @param bucket_interval specifies the time interval size of aggregation buckets that aggregate the Datadog trace metrics. ## It is also the time interval that Datadog trace metrics payloads are flushed to the pipeline. ## If you are concerned about the metric volume generated by the Datadog connector and the resulting networking egress, try increasing bucket_interval. ## Default is 10s if unset. # # bucket_interval: 30s ``` *** *Last generated: 2026-08-03* # Exceptions Source: https://otel.fyi/components/connector/exceptionsconnector OpenTelemetry connector for Exceptions # Exceptions Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib`, `k8s` **Maintainers:** [@marctc](https://github.com/marctc) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/exceptionsconnector) ## Overview ## Overview Generate metrics and logs from recorded [application exceptions](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md/) associated with spans. Each **metric** and **log** will have *at least* the following dimensions: * Service name * Span name * Span kind * Status code With the provided default config, each **metric** and **log** will also have the following dimensions: * Exception message * Exception type Each log will additionally have the following attributes: * Exception stacktrace * Span attributes. If you want to filter out some attributes (like only copying HTTP attributes starting with `http.`) use the [transform processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor/). ## Configurations If you are not already familiar with connectors, you may find it helpful to first visit the [Connectors README]. The following settings can be optionally configured: * `dimensions`: the list of dimensions to add together with the default dimensions defined above. Each additional dimension is defined with a `name` which is looked up in the span's collection of attributes or resource attributes. The provided default config includes `exception.type` and `exception.message` as additional dimensions. * `exemplars`: Use to configure how to attach exemplars to metrics. * `enabled` (default: `false`): enabling will add spans as Exemplars. ## Examples The following is a simple example usage of the `exceptions` connector. ```yaml theme={null} receivers: nop: exporters: nop: connectors: exceptions: service: pipelines: traces: receivers: [nop] exporters: [exceptions] metrics: receivers: [exceptions] exporters: [nop] logs: receivers: [exceptions] exporters: [nop] ``` The following is a more complex example usage of the `exceptions` connector using Prometheus and Loki as exporters. ```yaml theme={null} receivers: otlp: protocols: grpc: http: exporters: prometheus_remote_write: endpoint: http://prometheus:9090/api/v1/write loki: endpoint: http://loki:3100/loki/api/v1/push connectors: exceptions: service: pipelines: traces: receivers: [otlp] exporters: [exceptions] metrics: receivers: [exceptions] exporters: [prometheus_remote_write] logs: receivers: [exceptions] exporters: [loki] ``` The full list of settings exposed for this connector are documented in [exceptionsconnector/config.go](../../connector/exceptionsconnector/config.go). ### More Examples For more example configuration covering various other use cases, please visit the [testdata directory](../../connector/exceptionsconnector/testdata). [Connectors README]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md ## Configuration ### Example Configuration ```yaml theme={null} # default configuration exceptions/default: # configuration with all possible parameters exceptions/full: # Additional list of dimensions on top of: # - service.name # - span.name # - span.kind # - status.code # - exception.stacktrace (Only for log records) dimensions: - name: exception.type - name: exception.message ``` *** *Last generated: 2026-08-03* # Failover Source: https://otel.fyi/components/connector/failoverconnector OpenTelemetry connector for Failover # Failover Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib`, `k8s` **Maintainers:** [@akats7](https://github.com/akats7) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/failoverconnector) ## Overview Allows for health based routing between trace, metric, and log pipelines depending on the health of target downstream exporters. ## Configuration If you are not already familiar with connectors, you may find it helpful to first visit the [Connectors README]. The following settings are available: * `priority_levels (required)`: list of pipeline level priorities in a 1 - n configuration, multiple pipelines can sit at a single priority level. * `retry_interval (optional)`: the frequency at which the pipeline levels will attempt to reestablish connection with all higher priority levels. Default value is 10 minutes. (See Example below for further explanation) The connector intakes a list of `priority_levels` each of which can contain multiple pipelines. If any pipeline at a stable level fails, the level is considered unhealthy and the connector will move down one priority level and route all data to the new level (assuming it is stable). The connector will periodically try to reestablish a stable connection with the higher priority levels. `retry_interval` will be the frequency at which the connector will try to iterate through all unhealthy higher priority levels. #### Configuration Example: ```yaml theme={null} connectors: failover: priority_levels: - [traces/first, traces/also_first] - [traces/second] - [traces/third] retry_interval: 10s service: pipelines: traces: receivers: [otlp] exporters: [failover] traces/first: receivers: [failover] exporters: [otlp_grpc/first] traces/second: receivers: [failover] exporters: [otlp_grpc/second] traces/third: receivers: [failover] exporters: [otlp_grpc/third] traces/also_first: receivers: [failover] exporters: [otlp_grpc/fourth] ``` [Connectors README]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md [Exporter Pipeline Type]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md#exporter-pipeline-type [Receiver Pipeline Type]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md#receiver-pipeline-type [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib ## Configuration ### Example Configuration ```yaml theme={null} failover: failover/default: priority_levels: - [traces] failover/full: priority_levels: - [ traces/first, traces/also_first ] - [ traces/second ] - [ traces/third ] - [ traces/fourth ] retry_interval: 5m failover/queue: priority_levels: - [ traces/first, traces/also_first ] - [ traces/second ] - [ traces/third ] - [ traces/fourth ] sending_queue: enabled: true failover/invalid: priority_levels: - [ traces/first ] - [ traces/second ] retry_interval: 0m ``` *** *Last generated: 2026-08-03* # Grafanacloud Source: https://otel.fyi/components/connector/grafanacloudconnector OpenTelemetry connector for Grafanacloud # Grafanacloud Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@rlankfo](https://github.com/rlankfo), [@jcreixell](https://github.com/jcreixell) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/grafanacloudconnector) ## Overview ## Overview The Grafana Cloud Connector (grafanacloudconnector) is a connector component that can analyze telemetry in pipelines to generate usage metrics for the following Grafana Cloud products: * Application Observability ## Usage ```yaml theme={null} connectors: grafanacloud/connector: extensions: basicauth/grafana_cloud: client_auth: username: "${env:GRAFANA_CLOUD_INSTANCE_ID}" password: "${env:GRAFANA_CLOUD_API_KEY}" exporters: otlphttp/grafana_cloud: endpoint: "${env:GRAFANA_CLOUD_OTLP_ENDPOINT}" auth: authenticator: basicauth/grafana_cloud service: pipelines: traces: receivers: [otlp] exporters: [otlphttp/grafana_cloud, grafanacloud/connector] metrics: receivers: [otlp, grafanacloud/connector] exporters: [otlphttp/grafana_cloud] ``` In this example configuration, usage metrics for Grafana Cloud Application Observability are derived from incoming spans. ## Configuration ```yaml theme={null} connectors: grafanacloud/connector: ## @param host_identifiers List of span attributes used to identify the host running the workloads. ## The first matching attribute is used. # host_identifiers: ["host.id", "k8s.node.uid", "k8s.node.name"] ## @param metrics_flush_interval Interval at which host metrics are flushed. ## Valid values are between 15s and 5m. # metrics_flush_interval: 60s ``` ### Example configuration for the component ```yaml theme={null} connectors: grafanacloud: host_identifiers: ["mycompany.myHostAttribute", "host.id", "k8s.node.uid", "k8s.node.name"] metrics_flush_interval: 60s ``` This connector will generate a host info metric based on the first `host_identifiers` resource attribute found on spans. The rest are skipped. Valid flush intervals are between 15s and 5m. ## Configuration ### Example Configuration ```yaml theme={null} # default configuration grafanacloud: # custom configuration grafanacloud/custom: host_identifiers: - k8s.node.name - host.name - host.id metrics_flush_interval: 30s ``` *** *Last generated: 2026-08-03* # Metricsaslogs Source: https://otel.fyi/components/connector/metricsaslogsconnector OpenTelemetry connector for Metricsaslogs # Metricsaslogs Connector ![Status](https://img.shields.io/badge/status-development-orange) **Maintainers:** [@atoulme](https://github.com/atoulme) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/metricsaslogsconnector) ## Overview > **Deprecation Notice:** The component type has been renamed from `metricsaslogs` to `metrics_as_logs` > to follow the OpenTelemetry snake\_case naming convention. > The old name `metricsaslogs` still works but is deprecated and will be removed in a future release. > Please update your configuration to use `metrics_as_logs`. This connector converts OpenTelemetry metrics into logs, creating one log entry per metric data point. Each metric data point is transformed into a structured log record with configurable JSON body format. ## Current Limitations ⚠️ **Current implementation discards the following metric features:** * Metric exemplars * Advanced metadata These features may be added in future iterations. ## Configuration The following settings can be optionally configured: * `include_resource_attributes` (default = `true`): Whether to include resource attributes in the generated logs * `include_scope_info` (default = `true`): Whether to include instrumentation scope information in the generated logs ## Log Body Format The connector always generates log bodies in the following JSON format: ```json theme={null} {"metric_name": "$NAME", "value": "$VALUE"} ``` Where: * `$NAME` is the actual metric name * `$VALUE` is the metric value (simple values for gauge/sum, complex JSON for histogram/summary) ## Example Usage ### Basic Configuration ```yaml theme={null} connectors: metrics_as_logs: service: pipelines: logs: receivers: [metrics_as_logs] processors: [] exporters: [debug] metrics: receivers: [otlp] processors: [] exporters: [metrics_as_logs] ``` ### Advanced Configuration ```yaml theme={null} connectors: metrics_as_logs: include_resource_attributes: false include_scope_info: false ``` ### Example Metric Conversions For a gauge metric `cpu_usage` with value `85.2`: ```json theme={null} { "body": {"metric_name": "cpu_usage", "value": "85.2"}, "attributes": { "metric.name": "cpu_usage", "metric.type": "Gauge", "metric.description": "CPU usage percentage", "metric.unit": "%" } } ``` For a histogram metric `request_duration`: ```json theme={null} { "body": { "metric_name": "request_duration", "value": "{\"count\":100,\"sum\":1.5,\"bucket_counts\":[10,50,40],\"explicit_bounds\":[0.1,0.5,1.0]}" }, "attributes": { "metric.name": "request_duration", "metric.type": "Histogram", "metric.description": "Request duration in seconds", "metric.unit": "s", "metric.aggregation_temporality": "Delta" } } ``` ## Output Structure Each metric data point is converted to a log record with: * **Body**: Fixed JSON format: `{"metric_name": "$NAME", "value": "$VALUE"}` * **Timestamp**: Metric data point timestamp * **Observed Timestamp**: Metric data point start timestamp (if available) * **Attributes**: * Original metric data point attributes (labels) * `metric.name`: The metric name * `metric.type`: The metric type (Gauge, Sum, Histogram, etc.) * `metric.description`: Metric description (if available) * `metric.unit`: Metric unit (if available) * Additional type-specific attributes: * For Sum metrics: `metric.is_monotonic`, `metric.aggregation_temporality` * For Histogram/ExponentialHistogram: `metric.aggregation_temporality` * Resource attributes (if `include_resource_attributes` is true) * Instrumentation scope information (if `include_scope_info` is true) ## Supported Metric Types All OpenTelemetry metric types are supported: * **Gauge**: Point-in-time measurements * **Sum**: Cumulative or delta measurements * **Histogram**: Distribution of measurements with buckets * **Exponential Histogram**: Distribution with exponentially sized buckets * **Summary**: Distribution with quantile values ## Value Encoding The `value` field in the JSON body contains: * For simple metrics (Gauge, Sum): numeric value as string * For complex metrics (Histogram, etc.): JSON-encoded object as string All JSON special characters in metric names and values are properly escaped. *** *Last generated: 2026-08-03* # Otlpjson Source: https://otel.fyi/components/connector/otlpjsonconnector OpenTelemetry connector for Otlpjson # Otlpjson Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib`, `k8s` **Maintainers:** [@ChrsMark](https://github.com/ChrsMark) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/otlpjsonconnector) ## Overview > **Deprecation Notice:** The component type has been renamed from `otlpjson` to `otlp_json` > to follow the OpenTelemetry snake\_case naming convention. > The old name `otlpjson` still works but is deprecated and will be removed in a future release. > Please update your configuration to use `otlp_json`. Allows to extract otlpjson data from incoming Logs and specifically the `Body` field. The data is written in [Protobuf JSON encoding](https://developers.google.com/protocol-buffers/docs/proto3#json) using [OpenTelemetry protocol](https://github.com/open-telemetry/opentelemetry-proto). ## Configuration #### Configuration Example: ```yaml theme={null} receivers: file_log: include: - /var/log/foo.log exporters: debug: connectors: # Deprecated (still works): # otlpjson: # New name: otlp_json: service: pipelines: logs/raw: receivers: [file_log] exporters: [otlpjson] metrics/otlp: receivers: [otlpjson] exporters: [debug] logs/otlp: receivers: [otlpjson] exporters: [debug] traces/otlp: receivers: [otlpjson] exporters: [debug] ``` [Connectors README]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md [Exporter Pipeline Type]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md#exporter-pipeline-type [Receiver Pipeline Type]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md#receiver-pipeline-type [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib ## Configuration ### Example Configuration ```yaml theme={null} ``` *** *Last generated: 2026-08-03* # Roundrobin Source: https://otel.fyi/components/connector/roundrobinconnector OpenTelemetry connector for Roundrobin # Roundrobin Connector ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib`, `k8s` **Maintainers:** [@bogdandrutu](https://github.com/bogdandrutu) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/roundrobinconnector) ## Overview > **Deprecation Notice:** The component type has been renamed from `roundrobin` to `round_robin` > to follow the OpenTelemetry snake\_case naming convention. > The old name `roundrobin` still works but is deprecated and will be removed in a future release. > Please update your configuration to use `round_robin`. The `round_robin` connector can fork pipelines of the same type and equally split the load between them. ## Configuration If you are not already familiar with connectors, you may find it helpful to first visit the [Connectors README]. The `roundrobin` connector does not have any configuration settings. ```yaml theme={null} receivers: otlp: exporters: prometheus_remote_write/1: prometheus_remote_write/2: connectors: round_robin: ``` Preprocess data, then export using multiple exporter instances to scale the throughput if the exporter does not support scale well (e.g. prometheus\_remote\_write). ```yaml theme={null} receivers: otlp: processors: resource_detection: exporters: prometheus_remote_write/1: prometheus_remote_write/2: connectors: round_robin: service: pipelines: metrics: receivers: [otlp] processors: [resource_detection] exporters: [round_robin] metrics/1: receivers: [round_robin] exporters: [prometheus_remote_write/1] metrics/2: receivers: [round_robin] exporters: [prometheus_remote_write/2] ``` [Connectors README]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md *** *Last generated: 2026-08-03* # Routing Source: https://otel.fyi/components/connector/routingconnector OpenTelemetry connector for Routing # Routing Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib`, `k8s` **Maintainers:** [@TylerHelmuth](https://github.com/TylerHelmuth), [@evan-bradley](https://github.com/evan-bradley), [@edmocosta](https://github.com/edmocosta), [@bogdandrutu](https://github.com/bogdandrutu), [@mwear](https://github.com/mwear) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/routingconnector) ## Overview Routes logs, metrics or traces based on resource attributes to specific pipelines using [OpenTelemetry Transformation Language (OTTL)](../../pkg/ottl/README.md) statements as routing conditions. ## Configuration If you are not already familiar with connectors, you may find it helpful to first visit the [Connectors README]. The following settings are available: * `table (required)`: the routing table for this connector. * `table.condition`: the routing condition provided as the [OTTL] condition. Required if `table.statement` is not provided. Use context-qualified paths (e.g., `resource.attributes["key"]`, `span.attributes["key"]`) to automatically infer the context (see [Context Inference](#context-inference)). * `table.statement`: the routing condition provided as the [OTTL] statement. Required if `table.condition` is not provided. Generally `condition` is preferred since it is more terse. May not be used with the deprecated `request` context. * `table.context (optional)`: the [OTTL Context](#supported-contexts) in which the condition/statement will be evaluated. **Deprecated:** `request` — use `otelcol.client.metadata` or `otelcol.grpc.metadata` paths instead (see [Limitations](#limitations)). In most cases this field should be omitted; the context is inferred automatically from context-qualified paths. If specified, it takes precedence over inference. * `table.action (optional, default: move)`: determines what happens to the data when the routing condition is met. Valid values are `move` and `copy`. * `move`: Matched data is moved to the target pipeline(s) and removed from subsequent route evaluation. This is the default behavior. * `copy`: Matched data is copied to the target pipeline(s) but remains available for evaluation by subsequent routes. This allows the same data to be routed to multiple pipelines. * `table.pipelines (required)`: the list of pipelines to use when the routing condition is met. * `default_pipelines (optional)`: contains the list of pipelines to use when a record does not meet any of specified conditions. * `error_mode (optional)`: determines how errors returned from OTTL statements are handled. Valid values are `propagate`, `ignore` and `silent`. If `ignore` or `silent` is used and a statement's condition has an error then the payload will be routed to the default pipelines. When `silent` is used the error is not logged. If not supplied, `ignore` is used. ### Context Inference The routing connector supports OTTL context inference, allowing you to write clearer and more maintainable routing conditions using context-qualified paths. This is the recommended approach for specifying routing conditions. ```yaml theme={null} - condition: resource.attributes["env"] == "prod" pipelines: [logs/prod] - condition: span.attributes["http.method"] == "GET" pipelines: [traces/http] - condition: log.severity_text == "ERROR" pipelines: [logs/errors] ``` This approach makes it immediately clear which attributes you're accessing without needing a separate `context` field. ### Supported contexts | Context | Path prefix | Example | | ----------- | ------------ | -------------------------------------------------------------------------------- | | [Resource] | `resource.` | `resource.attributes["service.name"]` | | [Span] | `span.` | `span.attributes["http.method"]` | | [Log] | `log.` | `log.body`, `log.attributes["level"]` | | [Metric] | `metric.` | `metric.name` | | [Datapoint] | `datapoint.` | `datapoint.attributes["host"]` | | [OtelCol] | `otelcol.` | `otelcol.client.metadata["X-Tenant"][0]`, `otelcol.grpc.metadata["x-tenant"][0]` | [resource]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/contexts/ottlresource/README.md [span]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/contexts/ottlspan/README.md [metric]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/contexts/ottlmetric/README.md [datapoint]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/contexts/ottldatapoint/README.md [log]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/contexts/ottllog/README.md [otelcol]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/contexts/ottlotelcol/README.md The `otelcol.client.metadata` and `otelcol.grpc.metadata` paths provide access to incoming HTTP and gRPC request metadata respectively, and are valid in all signal contexts. ### Limitations * **Deprecated:** The `request` context is deprecated. Use `otelcol.client.metadata["key"]` (HTTP/client metadata) or `otelcol.grpc.metadata["key"]` (gRPC metadata) paths instead. These are supported in all signal contexts. A warning is logged when the `request` context is used. The `request` context only supports the `condition` field with a very limited grammar: `request["key"] == "value"` or `request["key"] != "value"`. * When using context inference without an explicit `context` field, the inferred context must be compatible with the pipeline signal type (e.g., `span` context can only be used in traces pipelines). ### Supported [OTTL] functions * [Standard OTTL Converter Functions](../../pkg/ottl/ottlfuncs/README.md#converters) * [delete\_key](../../pkg/ottl/ottlfuncs/README.md#delete_key) * [delete\_matching\_keys](../../pkg/ottl/ottlfuncs/README.md#delete_matching_keys) ## Additional Settings The full list of settings exposed for this connector are documented in [config.go](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/routingconnector/config.go) with detailed sample configuration files: * [logs](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/routingconnector/testdata/config/logs.yaml) * [metrics](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/routingconnector/testdata/config/metrics.yaml) * [traces](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/routingconnector/testdata/config/traces.yaml) ## Examples > \[!NOTE] > The examples below use context-qualified paths, which is the recommended configuration style. The explicit `context` field is still supported for backward compatibility but is no longer the primary documentation style. See [Context Inference](#context-inference) for details. ### Route logs based on tenant ```yaml theme={null} receivers: otlp: exporters: file/other: path: ./other.log file/acme: path: ./acme.log file/ecorp: path: ./ecorp.log connectors: routing: default_pipelines: [logs/other] table: - context: resource condition: otelcol.client.metadata["X-Tenant"][0] == "acme" pipelines: [logs/acme] - context: resource condition: otelcol.client.metadata["X-Tenant"][0] == "ecorp" pipelines: [logs/ecorp] service: pipelines: logs/in: receivers: [otlp] exporters: [routing] logs/acme: receivers: [routing] exporters: [file/acme] logs/ecorp: receivers: [routing] exporters: [file/ecorp] logs/other: receivers: [routing] exporters: [file/other] ``` ### Route logs based on region ```yaml theme={null} receivers: otlp: exporters: file/other: path: ./other.log file/east: path: ./east.log file/west: path: ./west.log connectors: routing: default_pipelines: [logs/other] table: - condition: log.attributes["region"] == "east" pipelines: [logs/east] - condition: log.attributes["region"] == "west" pipelines: [logs/west] service: pipelines: logs/in: receivers: [otlp] exporters: [routing] logs/east: receivers: [routing] exporters: [file/east] logs/west: receivers: [routing] exporters: [file/west] logs/other: receivers: [routing] exporters: [file/other] ``` ### Route low-severity logs to cheap storage, remainder by service name ```yaml theme={null} receivers: otlp: exporters: file/cheap: path: ./cheap.log file/service1: path: ./service1-important.log file/service2: path: ./service2-important.log connectors: routing: table: - condition: log.severity_number < SEVERITY_NUMBER_ERROR pipelines: [logs/cheap] - condition: resource.attributes["service.name"] == "service1" pipelines: [logs/service1] - condition: resource.attributes["service.name"] == "service2" pipelines: [logs/service2] service: pipelines: logs/in: receivers: [otlp] exporters: [routing] logs/cheap: receivers: [routing] exporters: [file/cheap] logs/service1: receivers: [routing] exporters: [file/service1] logs/service2: receivers: [routing] exporters: [file/service2] ``` ### Route low-severity logs to cheap storage, remainder by tenant ```yaml theme={null} receivers: otlp: exporters: file/cheap: path: ./cheap.log file/acme: path: ./acme.log file/ecorp: path: ./ecorp.log connectors: routing: table: - condition: log.severity_number < SEVERITY_NUMBER_ERROR pipelines: [logs/cheap] - context: resource condition: otelcol.client.metadata["X-Tenant"][0] == "acme" pipelines: [logs/acme] - context: resource condition: otelcol.client.metadata["X-Tenant"][0] == "ecorp" pipelines: [logs/ecorp] service: pipelines: logs/in: receivers: [otlp] exporters: [routing] logs/cheap: receivers: [routing] exporters: [file/cheap] logs/acme: receivers: [routing] exporters: [file/acme] logs/ecorp: receivers: [routing] exporters: [file/ecorp] ``` ### Route all logs to an archive, while also routing errors using `action: copy` Conditions with no OTTL paths (such as the literal `"true"`) cannot be inferred, so an explicit `context` field is required. ```yaml theme={null} receivers: otlp: exporters: file/archive: path: ./archive.log file/errors: path: ./errors.log file/other: path: ./other.log connectors: routing: default_pipelines: [logs/other] table: - context: resource condition: "true" action: copy pipelines: [logs/archive] - condition: log.severity_number >= SEVERITY_NUMBER_ERROR pipelines: [logs/errors] service: pipelines: logs/in: receivers: [otlp] exporters: [routing] logs/archive: receivers: [routing] exporters: [file/archive] logs/errors: receivers: [routing] exporters: [file/errors] logs/other: receivers: [routing] exporters: [file/other] ``` In this example: * All logs are first copied to the archive pipeline (using `action: copy`), which means the original data remains available for subsequent route evaluation. * Error logs are then moved to the errors pipeline (using the default `action: move`). * Any remaining logs (non-errors) go to the default pipeline. ### Route traces to multiple pipelines using `action: copy` ```yaml theme={null} receivers: otlp: exporters: file/prod: path: ./prod.json file/high-latency: path: ./high-latency.json file/other: path: ./other.json connectors: routing: default_pipelines: [traces/other] table: - condition: resource.attributes["env"] == "prod" action: copy pipelines: [traces/prod] - condition: span.attributes["http.duration_ms"] > 1000 pipelines: [traces/high-latency] service: pipelines: traces/in: receivers: [otlp] exporters: [routing] traces/prod: receivers: [routing] exporters: [file/prod] traces/high-latency: receivers: [routing] exporters: [file/high-latency] traces/other: receivers: [routing] exporters: [file/other] ``` In this example: * Production traces are copied to the prod pipeline. Since `action: copy` is used, the traces remain available for subsequent evaluation. * High-latency spans (>1000ms) are then moved to the high-latency pipeline. A production trace with high latency will appear in both the prod and high-latency pipelines. * Remaining traces go to the default pipeline. ## `match_once` The `match_once` field was deprecated as of `v0.116.0` and removed in `v0.120.0`. The following examples demonstrate some strategies for migrating a configuration from `match_once`. ### Example without `default_pipelines` If not using `default_pipelines`, you may be able to split the router into multiple parallel routers. In the following example, the `"env"` and `"region"` are not directly related. ```yaml theme={null} routing: match_once: false table: - condition: attributes["env"] == "prod" pipelines: [ logs/prod ] - condition: attributes["env"] == "dev" pipelines: [ logs/dev ] - condition: attributes["region"] == "east" pipelines: [ logs/east ] - condition: attributes["region"] == "west" pipelines: [ logs/west ] service: pipelines: logs/in::exporters: [routing] logs/prod::receivers: [routing] logs/dev::receivers: [routing] logs/east::receivers: [routing] logs/west::receivers: [routing] ``` Therefore, the same behavior can be achieved using separate routers. Listing both routers in the pipeline configuration will result in each receiving an independent handle to the data. The same data can then match routes in both routers. ```yaml theme={null} routing/env: table: - condition: resource.attributes["env"] == "prod" pipelines: [ logs/prod ] - condition: resource.attributes["env"] == "dev" pipelines: [ logs/dev ] routing/region: table: - condition: resource.attributes["region"] == "east" pipelines: [ logs/east ] - condition: resource.attributes["region"] == "west" pipelines: [ logs/west ] service: pipelines: logs/in::exporters: [routing/env, routing/region] logs/prod::receivers: [routing/env] logs/dev::receivers: [routing/env] logs/east::receivers: [routing/region] logs/west::receivers: [routing/region] ``` ### Example with `default_pipelines` The following example demonstrates strategies for migrating from `match_once: true` while using `default_pipelines`. ```yaml theme={null} routing: match_once: true default_pipelines: [ logs/default ] table: - condition: resource.attributes["env"] == "prod" pipelines: [ logs/prod ] - condition: resource.attributes["env"] == "dev" pipelines: [ logs/dev ] - condition: resource.attributes["region"] == "east" pipelines: [ logs/east ] - condition: resource.attributes["region"] == "west" pipelines: [ logs/west ] service: pipelines: logs/in::exporters: [routing] logs/default::receivers: [routing] logs/prod::receivers: [routing] logs/dev::receivers: [routing] logs/east::receivers: [routing] logs/west::receivers: [routing] ``` If the number of routes are limited, you may be able to articulate a route for each combination of conditions. This avoids the need to change any pipelines. ```yaml theme={null} routing: default_pipelines: [ logs/default ] table: - condition: resource.attributes["env"] == "prod" and resource.attributes["region"] == "east" pipelines: [ logs/prod, logs/east ] - condition: resource.attributes["env"] == "prod" and resource.attributes["region"] == "west" pipelines: [ logs/prod, logs/west ] - condition: resource.attributes["env"] == "dev" and resource.attributes["region"] == "east" pipelines: [ logs/dev, logs/east ] - condition: resource.attributes["env"] == "dev" and resource.attributes["region"] == "west" pipelines: [ logs/dev, logs/west ] service: pipelines: logs/in::exporters: [routing] logs/default::receivers: [routing] logs/prod::receivers: [routing] logs/dev::receivers: [routing] logs/east::receivers: [routing] logs/west::receivers: [routing] ``` A more general solution is to use a layered approach. In this design, the first layer is a single router that sorts data according to whether it matches *any route* or *no route*. This allows the second layer to work without `default_pipelines`. The downside to this approach is that the set of conditions in the first and second layers must be kept in sync. ```yaml theme={null} routing: default_pipelines: [ logs/default ] table: # all routes forward to second layer - condition: resource.attributes["env"] == "prod" pipelines: [ logs/env, logs/region ] - condition: resource.attributes["env"] == "dev" pipelines: [ logs/env, logs/region ] - condition: resource.attributes["region"] == "east" pipelines: [ logs/env, logs/region ] - condition: resource.attributes["region"] == "west" pipelines: [ logs/env, logs/region ] # Second layer routes logs based on environment and region routing/env: table: - condition: resource.attributes["env"] == "prod" pipelines: [ logs/prod ] - condition: resource.attributes["env"] == "dev" pipelines: [ logs/dev ] routing/region: table: - condition: resource.attributes["region"] == "east" pipelines: [ logs/east ] - condition: resource.attributes["region"] == "west" pipelines: [ logs/west ] service: pipelines: logs/in::exporters: [routing] logs/prod::receivers: [routing/env] logs/dev::receivers: [routing/env] logs/east::receivers: [routing/region] logs/west::receivers: [routing/region] ``` [Connectors README]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md [OTTL]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/README.md [OTTL Context]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/LANGUAGE.md#contexts *** *Last generated: 2026-08-03* # Servicegraph Source: https://otel.fyi/components/connector/servicegraphconnector OpenTelemetry connector for Servicegraph # Servicegraph Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib`, `k8s` **Maintainers:** [@mapno](https://github.com/mapno), [@JaredTan95](https://github.com/JaredTan95) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/servicegraphconnector) ## Overview > **Note:** The component type has been renamed from `servicegraph` to `service_graph`. > The old name still works but is deprecated and will be removed in a future release. > Please update your configuration to use `service_graph`. ## Overview The service graphs connector builds a map representing the interrelationships between various services in a system. The connector will analyse trace data and generate metrics describing the relationship between the services. These metrics can be used by data visualization apps (e.g. Grafana) to draw a service graph. Service graphs are useful for a number of use-cases: * Infer the topology of a distributed system. As distributed systems grow, they become more complex. Service graphs can help you understand the structure of the system. * Provide a high level overview of the health of your system. Service graphs show error rates, latencies, among other relevant data. * Provide an historic view of a system’s topology. Distributed systems change very frequently, and service graphs offer a way of seeing how these systems have evolved over time. This component is based on [Grafana Tempo's service graph processor](https://github.com/grafana/tempo/tree/main/modules/generator/processor/servicegraphs). ## How it works Service graphs work by inspecting traces and looking for spans with parent-children relationship that represent a request. The connector uses the OpenTelemetry semantic conventions to detect a myriad of requests. It currently supports the following requests: * A direct request between two services where the outgoing and the incoming span must have `span.kind` client and server respectively. * A request across a messaging system where the outgoing and the incoming span must have `span.kind` producer and consumer respectively. * A database request; in this case the connector looks for spans containing attributes `span.kind`=client as well as db.name. Every span that can be paired up to form a request is kept in an in-memory store, until its corresponding pair span is received or the maximum waiting time has passed. When either of these conditions are reached, the request is recorded and removed from the local store. Each emitted metrics series have the client and server label corresponding with the service doing the request and the service receiving the request. ``` traces_service_graph_request_total{client="app", server="db", connection_type="database"} 20 ``` TLDR: The connector will try to find spans belonging to requests as seen from the client and the server and will create a metric representing an edge in the graph. ## Metrics The following metrics are emitted by the connector: | Metric | Type | Labels | Description | | ---------------------------------------------- | --------- | -------------------------------- | ------------------------------------------------------------------------- | | traces\_service\_graph\_request\_total | Counter | client, server, connection\_type | Total count of requests between two nodes | | traces\_service\_graph\_request\_failed\_total | Counter | client, server, connection\_type | Total count of failed requests between two nodes | | traces\_service\_graph\_request\_server | Histogram | client, server, connection\_type | Number of seconds for a request between two nodes as seen from the server | | traces\_service\_graph\_request\_client | Histogram | client, server, connection\_type | Number of seconds for a request between two nodes as seen from the client | | traces\_service\_graph\_unpaired\_spans\_total | Counter | client, server, connection\_type | Total count of unpaired spans | | traces\_service\_graph\_dropped\_spans\_total | Counter | client, server, connection\_type | Total count of dropped spans | Duration is measured both from the client and the server sides. Possible values for `connection_type`: unset, `messaging_system`, or `database`. Additional labels can be included using the `dimensions` configuration option. Those labels will have a prefix to mark where they originate (client or server span kinds). The `client_` prefix relates to the dimensions coming from spans with `SPAN_KIND_CLIENT`, and the `server_` prefix relates to the dimensions coming from spans with `SPAN_KIND_SERVER`. Since the service graph connector has to process both sides of an edge, it needs to process all spans of a trace to function properly. If spans of a trace are spread out over multiple instances, spans are not paired up reliably. A possible solution to this problem is using the [load balancing exporter](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/loadbalancingexporter) in a layer on front of collector instances running this connector. ## Visualization Service graph metrics are natively supported by Grafana since v9.0.4. To run it, configure a Tempo data source's 'Service Graphs' by linking to the Prometheus backend where metrics are being sent: ```yaml theme={null} apiVersion: 1 datasources: # Prometheus backend where metrics are sent - name: Prometheus type: prometheus uid: prometheus url: jsonData: httpMethod: GET version: 1 - name: Tempo type: tempo uid: tempo url: jsonData: httpMethod: GET serviceMap: datasourceUid: 'prometheus' version: 1 ``` ## Configuration The following settings are required: * `latency_histogram_buckets`: the list of durations defining the latency histogram buckets. Make sure use either `latency_histogram_buckets` or `exponential_histogram_max_size`. * Default: `[2ms, 4ms, 6ms, 8ms, 10ms, 50ms, 100ms, 200ms, 400ms, 800ms, 1s, 1400ms, 2s, 5s, 10s, 15s]` * `exponential_histogram_max_size`: (no default) the maximum number of buckets per positive or negative number range. * `dimensions`: the list of dimensions to add together with the default dimensions defined above. The following settings can be optionally configured: * `store`: defines the config for the in-memory store used to find requests between services by pairing spans. * `ttl`: TTL is the time to live for items in the store. * Default: `2s` * `max_items`: MaxItems is the maximum number of items to keep in the store. * Default: `1000` * `cache_loop`: the interval at which to clean the cache. * Default: `1m` * `store_expiration_loop`: the time to expire old entries from the store periodically. * Default: `2s` * `virtual_node_peer_attributes`: the list of attributes, ordered by priority, whose presence in a client span will result in the creation of a virtual server node. An empty list disables virtual node creation. * Default: `[peer.service, db.name, db.system]` * `virtual_node_extra_label`: adds an extra label `virtual_node` with an optional value of `client` or `server`, indicating which node is the uninstrumented one. * Default: `false` * `metrics_flush_interval`: the interval at which metrics are flushed to the exporter. * Default: `60s` * `metrics_timestamp_offset`: the offset to subtract from metric timestamps. If set to a positive duration, metric timestamps will be set to (current time - offset), effectively shifting metrics to appear as if they were generated in the past. * Default: `0` * `database_name_attributes`: the list of attribute names used to identify the database name from span attributes. The attributes are tried in order, selecting the first match. * Default: `[db.name]` ## Example configurations ### Sample with custom buckets and dimensions ```yaml theme={null} receivers: otlp: protocols: grpc: connectors: service_graph: latency_histogram_buckets: [100ms, 250ms, 1s, 5s, 10s] dimensions: - dimension-1 - dimension-2 store: ttl: 1s max_items: 10 exporters: prometheus/servicegraph: endpoint: localhost:9090 namespace: servicegraph service: pipelines: traces: receivers: [otlp] exporters: [service_graph] metrics/servicegraph: receivers: [service_graph] exporters: [prometheus/servicegraph] ``` ### Sample with options for uninstrumented services identification ```yaml theme={null} receivers: otlp: protocols: grpc: connectors: service_graph: dimensions: - db.system - messaging.system virtual_node_peer_attributes: - db.name - db.system - messaging.system - peer.service virtual_node_extra_label: true exporters: prometheus/servicegraph: endpoint: localhost:9090 namespace: servicegraph service: pipelines: traces: receivers: [otlp] exporters: [service_graph] metrics/servicegraph: receivers: [service_graph] exporters: [prometheus/servicegraph] ``` *** *Last generated: 2026-08-03* # Signaltometrics Source: https://otel.fyi/components/connector/signaltometricsconnector OpenTelemetry connector for Signaltometrics # Signaltometrics Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@ChrsMark](https://github.com/ChrsMark), [@lahsivjar](https://github.com/lahsivjar) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/signaltometricsconnector) ## Overview ## Configuration The component can produce metrics from spans, datapoints (for metrics), and logs. At least one of the metrics for one signal type MUST be specified correctly for the component to work. All signal types can be configured to produce metrics with the same configuration structure. For example, the below configuration will produce delta temporality counters for counting number of events for each of the configured signals: ```yaml theme={null} signal_to_metrics: spans: - name: span.count description: Count of spans sum: value: Int(AdjustedCount()) # Count of total spans represented by each span monotonic: true datapoints: - name: datapoint.count description: Count of datapoints sum: value: "1" # increment by 1 for each datapoint monotonic: true logs: - name: logrecord.count description: Count of log records sum: value: "1" # increment by 1 for each log record monotonic: true profiles: - name: profile.count description: Count of profiles sum: value: "1" # increment by 1 for each profile monotonic: true ``` ### Path context prefixes in OTTL expressions OTTL strings in `conditions`, `value`, `count`, and `keys_expression` may use context path prefixes to disambiguate the target of a path. Unprefixed paths continue to work. It is recommended to use the new syntax to avoid future breaking changes. **Example (recommended):** ```yaml theme={null} signal_to_metrics: spans: - name: http.trace.span.duration attributes: - key: http.response.status_code conditions: - resource.attributes["service.name"] != nil sum: value: Int(Seconds(span.end_time - span.start_time)) monotonic: true ``` ### Error Handling The `error_mode` configuration option determines how the connector handles errors that occur while processing OTTL expressions: * `error_mode` (optional): Determines how errors returned from OTTL expressions are handled. Valid values are `propagate`, `ignore`, and `silent`. * `propagate` (default): Errors cause the entire batch to fail and be returned up the pipeline. This will result in the payload being dropped from the collector. * `ignore`: Errors are logged and the specific record that caused the error is skipped, but processing continues for the rest of the batch. * `silent`: Errors are not logged and the specific record that caused the error is skipped, but processing continues for the rest of the batch. **Example with error handling:** ```yaml theme={null} signaltometrics: error_mode: ignore # Log errors but continue processing other records spans: - name: span.count description: Count of spans sum: value: Int(AdjustedCount()) ``` ### Metrics types `signal_to_metrics` produces a variety of metric types by utilizing [OTTL](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/README.md) to extract the relevant data for a metric type from the incoming data. The component can produce the following metric types for each signal type: * [Sum](https://opentelemetry.io/docs/specs/otel/metrics/data-model/#sums) * [Gauge](https://opentelemetry.io/docs/specs/otel/metrics/data-model/#gauge) * [Histogram](https://opentelemetry.io/docs/specs/otel/metrics/data-model/#histogram) * [Exponential Histogram](https://opentelemetry.io/docs/specs/otel/metrics/data-model/#exponentialhistogram) The component does NOT perform any stateful or time based aggregations. The metric types are aggregated for the payload sent in each `Consume*` call. The final metric is then sent forward in the pipeline. #### Sum Sum metrics have the following configurations: ```yaml theme={null} sum: value: monotonic: ``` * \[**Required**] `value` represents an OTTL expression to extract a value from the incoming data. Only OTTL expressions that return a value are accepted. The returned value determines the value type of the `sum` metric (`int` or `double`). [OTTL converters](https://pkg.go.dev/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs#readme-converters) can be used to transform the data. * \[**Optional**] `monotonic` whether the generated metric is monotonic. It defaults to `false`. #### Gauge Gauge metrics aggregate the last value of a signal and have the following configuration: ```yaml theme={null} gauge: value: ``` * \[**Required**] `value`represents an OTTL expression to extract a numeric value from the signal. Only OTTL expressions that return a value are accepted. The returned value determines the value type of the `gauge` metric (`int` or `double`). * For logs: Use e.g. `ExtractGrokPatterns` with a single key selector (see below). * For other signals: Use a field such as `value_int`, `value_double`, or a valid OTTL expression. **Examples:** *Logs (with Grok pattern):* ```yaml theme={null} signal_to_metrics: logs: - name: logs.memory_mb description: Extract memory_mb from log records gauge: value: ExtractGrokPatterns(body, "Memory usage %{NUMBER:memory_mb:int}MB")["memory_mb"] ``` *Traces:* ```yaml theme={null} signal_to_metrics: spans: - name: span.duration.gauge description: Span duration as gauge gauge: value: Int(Seconds(end_time - start_time)) ``` #### Histogram Histogram metrics have the following configurations: ```yaml theme={null} histogram: buckets: []float64 count: value: ``` * \[**Optional**] `buckets` represents the buckets to be used for the histogram. If no buckets are configured then it defaults to: ```go theme={null} []float64{2, 4, 6, 8, 10, 50, 100, 200, 400, 800, 1000, 1400, 2000, 5000, 10_000, 15_000} ``` * \[**Optional**] `count` represents an OTTL expression to extract the count to be recorded in the histogram from the incoming data. If no expression is provided then it defaults to the count of the signal. [OTTL converters](https://pkg.go.dev/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs#readme-converters) can be used to transform the data. For spans, a special converter [adjusted count](#custom-ottl-functions), is provided to help calculate the span's [adjusted count](https://opentelemetry.io/docs/specs/otel/trace/tracestate-probability-sampling-experimental/#adjusted-count). * \[**Required**] `value` represents an OTTL expression to extract the value to be recorded in the histogram from the incoming data. [OTTL converters](https://pkg.go.dev/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs#readme-converters) can be used to transform the data. #### Exponential Histogram Exponential histogram metrics have the following configurations: ```yaml theme={null} exponential_histogram: max_size: count: value: ``` * \[**Optional**] `max_size` represents the maximum number of buckets per positive or negative number range. Defaults to `160`. * \[**Optional**] `count` represents an OTTL expression to extract the count to be recorded in the exponential histogram from the incoming data. If no expression is provided then it defaults to the count of the signal. [OTTL converters](https://pkg.go.dev/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs#readme-converters) can be used to transform the data. For spans, a special converter [adjusted count](#custom-ottl-functions), is provided to help calculate the span's [adjusted count](https://opentelemetry.io/docs/specs/otel/trace/tracestate-probability-sampling-experimental/#adjusted-count). * \[**Required**] `value` represents an OTTL expression to extract the value to be recorded in the exponential histogram from the incoming data. [OTTL converters](https://pkg.go.dev/github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs#readme-converters) can be used to transform the data. ### Attributes The component can produce metrics categorized by the attributes (span attributes for traces, datapoint attributes for datapoints, or log record attributes for logs) from the incoming data by configuring `attributes` for the configured metrics. If no `attributes` are configured then the metrics are produced without any attributes. ```yaml theme={null} attributes: - key: datapoint.foo - key: datapoint.bar default_value: bar - key: datapoint.baz optional: true - keys_expression: otelcol.client.metadata["x-dynamic-attributes"] ``` Each attribute entry must have exactly one of `key` or `keys_expression` set. If attributes are specified then a separate metric will be generated for each unique set of attribute values. There are four behaviors that can be configured for an attribute: * Without any extra parameters: `datapoint.foo` in the above yaml is an example of such configuration. In this configuration, only the signals which have the said attribute are processed with the attribute's value as one of the attributes for the output metric. If the attribute is missing then the signal is not processed. * With `default_value`: `datapoint.bar` in the above yaml is an example of such configuration. In this configuration all the signals are processed irrespective of the attribute being present or not in the input signal. The output metric is categorized as per the incoming value of the attribute and an extra bucket exists with the attribute set to the configured default value for all the signals that were missing the configured attribute. * With `optional` set to `true`: `datapoint.baz` in the above yaml is an example of such configuration. If the attribute is configured with `optional` and present in the incoming signal then it will be added directly to the output metric. If it is absent then a new metric with missing attributes will be created. In addition, the `optional` attribute will not impact the decision i.e. even if the `optional` attributes are not present in the incoming signal, the signal will be processed and will produce a metric given all other non-optional attributes are present or have a default value defined. * With `keys_expression`: The OTTL value expression is evaluated at runtime and must return a list of attribute keys (`pcommon.Slice` or `[]string`). Each resolved key is looked up in the signal's attributes and included in the output metric. If the expression returns `nil` (e.g. missing client metadata), it is treated as an empty list. Expression evaluation errors are governed by the `error_mode` configuration. The `optional` and `default_value` options can be combined with `keys_expression` and apply to each resolved key. Note that resource attributes are handled differently, check the resource attributes section for more details on this. Think of `attributes` as conditional filters for choosing which attributes should be included in the output metric whereas `include_resource_attributes` is an include list for customizing resource attributes of the output metric. ### Conditions Conditions are an optional list of OTTL conditions that are evaluated on the incoming data and are ORed together. For example: ```yaml theme={null} signal_to_metrics: datapoints: - name: datapoint.bar.sum description: Count total number of datapoints as per datapoint.bar attribute conditions: - resource.attributes["foo"] != nil - resource.attributes["bar"] != nil sum: value: "1" ``` The above configuration will produce sum metrics from datapoints with either `foo` OR `bar` resource attribute defined. Conditions can also be ANDed together, for example: ```yaml theme={null} signal_to_metrics: datapoints: - name: gauge.to.exphistogram conditions: - metric.type == 1 AND resource.attributes["resource.foo"] != nil exponential_histogram: count: "1" # 1 count for each datapoint value: Double(value_int) + value_double # handle both int and double ``` The above configuration produces exponential histogram from gauge metrics with resource attributes `resource.foo` set. ### Customizing resource attributes The component allows customizing the resource attributes for the produced metrics by specifying a list of attributes that should be included in the final metrics. If no attributes are specified for `include_resource_attributes` then no filtering is performed i.e. all resource attributes of the incoming data is considered. ```yaml theme={null} include_resource_attributes: - key: resource.foo # Include resource.foo attribute if present - key: resource.bar # Always include resource.bar attribute, default to bar default_value: bar - key: resource.baz # Optional resource.baz attribute is added if present optional: true - keys_expression: otelcol.client.metadata["x-dynamic-resource-attributes"] ``` Each entry must have exactly one of `key` or `keys_expression` set. With the above configuration the produced metrics would have the following resource attributes: * `resource.foo` will be present for the produced metrics if the incoming data also has the attribute defined. If the attribute is missing in the incoming data the output metric will be produced without the said attribute. * `resource.bar` will always be present because of the `default_value`. If the incoming data does not have a resource attribute with name `resource.bar` then the configured `default_value` of `bar` will be used. * `resource.baz` will behave exactly same as `resource.foo`. Since resource attributes are basically an include list, the `optional` option is a no-op i.e. the resource attributes with `optional` set to `true` behaves identical to an attribute configured without `default_value` or `optional`. * The `keys_expression` entry evaluates the OTTL value expression at runtime to resolve a list of attribute keys. The expression must return a list of strings (`pcommon.Slice` or `[]string`). Each resolved key is looked up in the resource attributes and included in the output metric. If the expression returns `nil` (e.g. missing client metadata), it is treated as an empty list. Expression evaluation errors are governed by the `error_mode` configuration. The `optional` and `default_value` options can be combined with `keys_expression` and apply to each resolved key. OTTL expressions for `include_resource_attributes` should only reference resource-level paths (e.g. `resource.attributes`) or context-level paths (e.g. `otelcol.client.metadata`), not signal-specific paths (e.g. `attributes`, `span.*`, `log.*`). ### Single writer Metrics data streams MUST obey [single-writer](https://opentelemetry.io/docs/specs/otel/metrics/data-model/#single-writer) principle. However, since `signal_to_metrics` component produces metrics from all signal types and also allows customizing the resource attributes, there is a possibility of violating the single-writer principle. To keep the single-writer principle intact, the component adds collector instance information as resource attributes. The following resource attribute is added to each produced metric: ```yaml theme={null} signal_to_metrics.service.instance.id: ``` ### Custom OTTL functions The component implements the following custom OTTL functions: 1. `AdjustedCount`: a converter capable of calculating [adjusted count for a span](https://github.com/open-telemetry/oteps/blob/main/text/trace/0235-sampling-threshold-in-trace-state.md). ## Configuration ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: spans: - name: with_resource_foo_only description: Spans with resource attribute including resource.foo as a int sum metric unit: s include_resource_attributes: - key: resource.foo sum: value: Int(Seconds(end_time - start_time)) monotonic: true - name: span_adjusted_count description: Adjusted count for the span as a sum metric unit: s sum: value: Int(AdjustedCount()) monotonic: true - name: http.trace.span.duration description: Span duration for HTTP spans as a int sum metric unit: s attributes: - key: http.response.status_code sum: value: Int(Seconds(end_time - start_time)) monotonic: true - name: db.trace.span.duration description: Span duration for DB spans as a int sum metric unit: s attributes: - key: db.system sum: value: Int(Seconds(end_time - start_time)) monotonic: true - name: msg.trace.span.duration description: Span duration for messaging spans as a double sum metric unit: s conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: messaging.system sum: value: Double(Seconds(end_time - start_time)) monotonic: true - name: ignored.sum description: Will be ignored due to conditions evaluating to false unit: s conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: messaging.system sum: value: Double(Seconds(end_time - start_time)) monotonic: true ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: spans: - name: with_resource_foo_only description: Spans with resource attribute including resource.foo as a int sum metric unit: s include_resource_attributes: - key: resource.foo sum: value: Int(Seconds(span.end_time - span.start_time)) monotonic: true - name: span_adjusted_count description: Adjusted count for the span as a sum metric unit: s sum: value: Int(AdjustedCount()) monotonic: true - name: http.trace.span.duration description: Span duration for HTTP spans as a int sum metric unit: s attributes: - key: http.response.status_code sum: value: Int(Seconds(span.end_time - span.start_time)) monotonic: true - name: db.trace.span.duration description: Span duration for DB spans as a int sum metric unit: s attributes: - key: db.system sum: value: Int(Seconds(span.end_time - span.start_time)) monotonic: true - name: msg.trace.span.duration description: Span duration for messaging spans as a double sum metric unit: s conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: messaging.system sum: value: Double(Seconds(span.end_time - span.start_time)) monotonic: true - name: ignored.sum description: Will be ignored due to conditions evaluating to false unit: s conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: messaging.system sum: value: Double(Seconds(span.end_time - span.start_time)) monotonic: true ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: spans: - name: with_priority_override description: Test that static key defined after keys_expression overrides dynamic resolution unit: s include_resource_attributes: - key: resource.foo attributes: # Dynamic entry first: resolves to ["db.system"]. For spans that # have db.system, this picks up the actual value (e.g. "mysql"). - keys_expression: otelcol.client.metadata["x-dynamic-attrs"] default_value: dynamic_override # Static entry second: overrides db.system with a fixed default. # Since this appears AFTER the dynamic entry, it should win. - key: db.system default_value: static_override sum: value: "1" monotonic: true ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: spans: - name: with_dynamic_resource_attrs description: Spans with dynamically resolved resource attributes from client metadata unit: s include_resource_attributes: - keys_expression: otelcol.client.metadata["x-dynamic-resource-attributes"] sum: value: Int(Seconds(end_time - start_time)) monotonic: true ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: spans: - name: metric.trace.duration description: Spans with resource attribute including resource.foo as a histogram metric unit: ms histogram: value: Int(Milliseconds(end_time - start_time)) - name: metric.trace.duration description: Spans with resource attribute including resource.foo as a exponential histogram metric unit: ms exponential_histogram: value: Int(Milliseconds(end_time - start_time)) - name: metric.trace.duration description: Spans with resource attribute including resource.foo as a sum metric unit: ms sum: value: Int(Milliseconds(end_time - start_time)) ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: spans: - name: with_resource_filter # with resource.foo filter description: Spans with resource attribute including resource.foo as a histogram metric unit: ms include_resource_attributes: - key: resource.foo histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: with_resource_filter # with resource.bar filter description: Spans with resource attribute including resource.bar as a histogram metric unit: ms include_resource_attributes: - key: resource.bar histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: with_custom_count description: Spans with custom count OTTL expression as a histogram metric unit: ms histogram: count: "2" # count each span twice value: Milliseconds(end_time - start_time) - name: http.trace.span.duration description: Span duration for HTTP spans as a histogram metric unit: ms attributes: - key: http.response.status_code histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: db.trace.span.duration description: Span duration for DB spans as a histogram metric unit: ms attributes: - key: db.system histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: msg.trace.span.duration description: Span duration for messaging spans as a histogram metric unit: ms conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: messaging.system histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: ignored.histogram description: Will be ignored due to conditions evaluating to false unit: ms conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: messaging.system histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: optional.histogram description: The configured optional attribute will be added as-is unit: ms include_resource_attributes: - key: resource.foo attributes: - key: db.name # All spans with db.name set will be bucketed and a separate bucket will be created with no db.name optional: true histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: spans: - name: with_resource_foo_only description: Spans with resource attribute including resource.foo as a int gauge metric unit: s include_resource_attributes: - key: resource.foo gauge: value: Double(Seconds(end_time - start_time)) - name: span_adjusted_count description: Adjusted count for the span as a int gauge metric unit: s gauge: value: Int(AdjustedCount()) - name: http.trace.span.duration description: Span duration for HTTP spans as a int gauge metric unit: s attributes: - key: http.response.status_code gauge: value: Int(Seconds(end_time - start_time)) - name: db.trace.span.duration description: Span duration for DB spans as a int gauge metric unit: s attributes: - key: db.system gauge: value: Double(Seconds(end_time - start_time)) - name: msg.trace.span.duration description: Span duration for messaging spans as a double gauge metric unit: s conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: messaging.system gauge: value: Int(Seconds(end_time - start_time)) - name: ignored.gauge description: Will be ignored due to conditions evaluating to false unit: s conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: messaging.system gauge: value: Double(Seconds(end_time - start_time)) ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: spans: - name: with_resource_filter # with resource.foo filter description: Spans with resource attribute including resource.foo as a exponential histogram metric unit: ms include_resource_attributes: - key: resource.foo exponential_histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: with_resource_filter # with resource.bar filter description: Spans with resource attribute including resource.bar as a exponential histogram metric unit: ms include_resource_attributes: - key: resource.bar exponential_histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: with_custom_count description: Spans with custom count OTTL expression as a exponential histogram metric unit: ms exponential_histogram: count: "2" # count each span twice value: Milliseconds(end_time - start_time) - name: http.trace.span.duration description: Span duration for HTTP spans as a exponential histogram metric unit: ms attributes: - key: http.response.status_code exponential_histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: db.trace.span.duration description: Span duration for DB spans as a exponential histogram metric unit: ms attributes: - key: db.system exponential_histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: msg.trace.span.duration description: Span duration for messaging spans as a exponential histogram metric unit: ms conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: messaging.system exponential_histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) - name: ignored.exphistogram description: Will be ignored due to conditions evaluating to false unit: ms conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: messaging.system exponential_histogram: count: "Int(AdjustedCount())" value: Milliseconds(end_time - start_time) ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: profiles: - name: total.profiles.sum description: Count total number of profiles sum: value: "1" monotonic: true - name: total.profiles.resource.foo.sum description: Count total number of profiles with resource attribute foo include_resource_attributes: - key: resource.foo sum: value: "1" monotonic: true - name: profiles.foo.sum description: Count total number of profiles as per profile.foo attribute attributes: - key: profile.foo sum: value: "1" monotonic: true - name: profiles.bar.sum description: Count total number of profiles as per profiles.bar attribute conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: profiles.bar sum: value: "1" monotonic: true - name: ignored.sum description: Will be ignored due to conditions evaluating to false conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: profiles.bar sum: value: "2" monotonic: true ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: profiles: - name: total.profiles.histogram description: Profiles as histogram with duration histogram: count: "1" value: duration_unix_nano buckets: [1, 10, 50, 100, 200] - name: total.profiles.resource.foo.histogram description: Profiles with resource attribute foo as histogram with duration include_resource_attributes: - key: resource.foo histogram: count: "1" value: duration_unix_nano buckets: [1, 10, 50, 100, 200] - name: profiles.foo.histogram description: Count total number of profiles as per profile.foo attribute as histogram with duration attributes: - key: profile.foo histogram: count: "1" value: duration_unix_nano buckets: [1, 10, 50, 100, 200] - name: profiles.bar.histogram description: Count total number of profiles as per profiles.bar attribute as histogram with duration conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: profiles.bar histogram: count: "1" value: duration_unix_nano buckets: [1, 10, 50, 100, 200] - name: ignored.histogram description: Will be ignored due to conditions evaluating to false conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: profiles.bar histogram: count: "2" value: duration_unix_nano buckets: [1, 50, 200] ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: profiles: - name: total.profiles.exphistogram description: Profiles as exponential histogram with duration exponential_histogram: count: "1" value: duration_unix_nano - name: total.profiles.resource.foo.exphistogram description: Profiles with resource attribute foo as exponential histogram with duration include_resource_attributes: - key: resource.foo exponential_histogram: count: "1" value: duration_unix_nano - name: profiles.foo.exphistogram description: Count total number of profiles as per profiles.foo attribute as exponential histogram with duration attributes: - key: profile.foo exponential_histogram: count: "1" value: duration_unix_nano - name: profiles.bar.exphistogram description: Count total number of profiles as per profiles.bar attribute as exponential histogram with duration conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: profiles.bar exponential_histogram: count: "1" value: duration_unix_nano - name: ignored.exphistogram description: Will be ignored due to conditions evaluating to false conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: profiles.bar exponential_histogram: count: "2" value: duration_unix_nano ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: datapoints: - name: total.datapoint.sum description: Count total number of datapoints sum: value: "1" monotonic: true - name: datapoint.foo.sum description: Count total number of datapoints as per datapoint.foo attribute attributes: - key: datapoint.foo sum: value: "1" monotonic: true - name: datapoint.bar.sum description: Count total number of datapoints as per datapoint.bar attribute conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: datapoint.bar sum: value: "1" monotonic: true - name: ignored.sum description: Will be ignored due to conditions evaluating to false conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: datapoint.bar sum: value: "2" monotonic: true - name: non.monotonic.sum description: A non-monotonic sum conditions: - metric.name == "sum-int" sum: value: datapoint.value_int # monotonic: false by default ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: datapoints: - name: gauge.to.histogram description: A histogram created from gauge values include_resource_attributes: - key: resource.foo attributes: - key: datapoint.foo conditions: - metric.type == 1 # select all gauges histogram: buckets: [1, 4, 5, 8, 200, 500, 1000] count: "1" # 1 count for each datapoint value: Double(value_int) + value_double # handle both int and double ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: datapoints: - name: datapoint.bar.gauge description: Last gauge as per datapoint.bar attribute attributes: - key: datapoint.bar conditions: - metric.type == 2 # select all sums gauge: value: Double(value_int) + value_double ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: datapoints: - name: gauge.to.exphistogram description: An exponential histogram created from gauge values include_resource_attributes: - key: resource.foo attributes: - key: datapoint.foo conditions: - metric.type == 1 # select all gauges exponential_histogram: count: "1" # 1 count for each datapoint value: Double(value_int) + value_double # handle both int and double ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: logs: - name: total.logrecords.sum description: Count total number of log records sum: value: "1" monotonic: true - name: total.logrecords.resource.foo.sum description: Count total number of log records with resource attribute foo include_resource_attributes: - key: resource.foo sum: value: "1" monotonic: true - name: log.foo.sum description: Count total number of log records as per log.foo attribute attributes: - key: log.foo sum: value: "1" monotonic: true - name: log.bar.sum description: Count total number of log records as per log.bar attribute conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: log.bar sum: value: "1" monotonic: true - name: ignored.sum description: Will be ignored due to conditions evaluating to false conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: log.bar sum: value: "2" monotonic: true ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: logs: - name: metric.log.duration description: Logrecords as histogram with log.duration from attributes histogram: count: "1" value: attributes["log.duration"] buckets: [1, 10, 50, 100, 200] - name: metric.log.duration description: Logrecords as exponential histogram with log.duration from attributes exponential_histogram: count: "1" value: attributes["log.duration"] max_size: 160 - name: metric.log.duration description: Logrecords as sum with log.duration from attributes sum: value: attributes["log.duration"] ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: logs: - name: total.logrecords.histogram description: Logrecords as histogram with log.duration from attributes histogram: count: "1" value: attributes["log.duration"] buckets: [1, 10, 50, 100, 200] - name: total.logrecords.resource.foo.histogram description: Logrecords with resource attribute foo as histogram with log.duration from attributes include_resource_attributes: - key: resource.foo histogram: count: "1" value: attributes["log.duration"] buckets: [1, 10, 50, 100, 200] - name: log.foo.histogram description: Count total number of log records as per log.foo attribute as histogram with log.duration from attributes attributes: - key: log.foo histogram: count: "1" value: attributes["log.duration"] buckets: [1, 10, 50, 100, 200] - name: log.bar.histogram description: Count total number of log records as per log.bar attribute as histogram with log.duration from attributes conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: log.bar histogram: count: "1" value: attributes["log.duration"] buckets: [1, 10, 50, 100, 200] - name: ignored.histogram description: Will be ignored due to conditions evaluating to false conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: log.bar histogram: count: "2" value: attributes["log.duration"] buckets: [1, 50, 200] ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: logs: - name: logs.memory_mb description: Extract memory_mb from log records gauge: value: ExtractGrokPatterns(body, "Memory usage %{NUMBER:memory_mb:int}MB")["memory_mb"] - name: logs.cpu description: Extract cpu from log records gauge: value: ExtractGrokPatterns(body, "CPU usage %{NUMBER:cpu:float}")["cpu"] - name: logs.foo.memory_mb description: Extract memory_mb from log records with attribute foo gauge: value: Int(ExtractPatterns(body, "Memory usage (?P\\d+(?:\\.\\d+)?)MB")["memory_mb"]) include_resource_attributes: - key: resource.foo attributes: - key: log.foo - name: logs.bar.memory_mb description: Extract memory_mb from log records with attribute bar and conditions conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.bar"] != nil gauge: value: ExtractGrokPatterns(body, "Memory usage %{NUMBER:memory_mb:double}MB", true)["memory_mb"] attributes: - key: log.bar - name: log.ignored.gauge description: Will be ignored due to conditions evaluating to false conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil include_resource_attributes: - key: resource.bar attributes: - key: log.bar gauge: value: ExtractGrokPatterns(body, "Memory usage %{NUMBER:memory_mb:int}MB")["memory_mb"] ``` ### config.yaml (testdata) ```yaml theme={null} signal_to_metrics: logs: - name: total.logrecords.exphistogram description: Logrecords as exponential histogram with log.duration from attributes exponential_histogram: count: "1" value: attributes["log.duration"] - name: total.logrecords.resource.foo.exphistogram description: Logrecords with resource attribute foo as exponential histogram with log.duration from attributes include_resource_attributes: - key: resource.foo exponential_histogram: count: "1" value: attributes["log.duration"] - name: log.foo.exphistogram description: Count total number of log records as per log.foo attribute as exponential histogram with log.duration from attributes attributes: - key: log.foo exponential_histogram: count: "1" value: attributes["log.duration"] - name: log.bar.exphistogram description: Count total number of log records as per log.bar attribute as exponential histogram with log.duration from attributes conditions: # Will evaluate to true - resource.attributes["404.attribute"] != nil - resource.attributes["resource.foo"] != nil attributes: - key: log.bar exponential_histogram: count: "1" value: attributes["log.duration"] - name: ignored.exphistogram description: Will be ignored due to conditions evaluating to false conditions: # Will evaluate to false - resource.attributes["404.attribute"] != nil attributes: - key: log.bar exponential_histogram: count: "2" value: attributes["log.duration"] ``` *** *Last generated: 2026-08-03* # Slowsql Source: https://otel.fyi/components/connector/slowsqlconnector OpenTelemetry connector for Slowsql # Slowsql Connector ![Status](https://img.shields.io/badge/status-development-orange) **Maintainers:** [@JaredTan95](https://github.com/JaredTan95), [@Frapschen](https://github.com/Frapschen), [@atoulme](https://github.com/atoulme) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/slowsqlconnector) ## Overview > **Deprecation Notice:** The component type has been renamed from `slowsql` to `slow_sql` > to follow the OpenTelemetry snake\_case naming convention. > The old name `slowsql` still works but is deprecated and will be removed in a future release. > Please update your configuration to use `slow_sql`. ## Overview Generate logs from recorded [slow database statement](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/exceptions/exceptions-spans.md/) associated with spans. Each **log** will have *at least* the following dimensions: * Service name * Span kind * Span name * Status code * Trace ID * Span ID * Database System * Database Statement * Database Statement Duration Each log will additionally have the following attributes: * Span attributes. If you want to filter out some attributes (like only copying HTTP attributes starting with `http.`) use the [transform processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor/). ## Configurations If you are not already familiar with connectors, you may find it helpful to first visit the [Connectors README]. The following settings can be optionally configured: * `dimensions`: the list of dimensions to add to *logs* with the default dimensions defined above. Each additional dimension is defined with a `name` which is looked up in the span's collection of attributes or resource attributes (AKA process tags) such as `ip`, `host.name` or `region`. * `db_system:` the list value of span attribute `db.system`, Filter specific db systems, define those database's statements need to be collected. ref: [https://opentelemetry.io/docs/specs/semconv/attributes-registry/db/](https://opentelemetry.io/docs/specs/semconv/attributes-registry/db/) * Default: `[h2, mongodb, mssql, mysql, oracle, postgresql, mariadb]` * `threshold`: define a threshold and collect when the `db.statement`, namely span duration, larger than this value. * Default: `500ms` ## Examples The following is a simple example usage of the `slow sql` connector. ```yaml theme={null} receivers: nop: exporters: nop: connectors: slow_sql: threshold: 600ms dimensions: - name: k8s.namespace.name - name: k8s.pod.name service: pipelines: traces: receivers: [nop] exporters: [slow_sql] logs: receivers: [slow_sql] exporters: [nop] ``` The following is a more complex example usage of the `slow_sql` connector using Elasticsearch as exporters. ```yaml theme={null} receivers: otlp: protocols: grpc: http: exporters: elasticsearch/slow_sql: tls: insecure: true mapping: mode: raw endpoints: - http://localhost:9200 user: elastic password: elastic connectors: slow_sql: threshold: 600ms dimensions: - name: k8s.namespace.name - name: k8s.pod.name service: pipelines: traces: receivers: [otlp] exporters: [slow_sql] logs: receivers: [slow_sql] exporters: [elasticsearch/slow_sql] ``` The full list of settings exposed for this connector is documented in [slowsqlconnector/config.go](../../connector/slowsqlconnector/config.go). ### More Examples For more example configuration covering various other use cases, please visit the [testdata directory](../../connector/slowsqlconnector/testdata). [Connectors README]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md ## Configuration ### Example Configuration ```yaml theme={null} # default configuration slow_sql/default: # configuration with all possible parameters slow_sql/full: threshold: 600ms db_system: - h2 - mysql dimensions: - name: k8s.namespace.name - name: k8s.pod.name ``` *** *Last generated: 2026-08-03* # Spanmetrics Source: https://otel.fyi/components/connector/spanmetricsconnector OpenTelemetry connector for Spanmetrics # Spanmetrics Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@portertech](https://github.com/portertech), [@Frapschen](https://github.com/Frapschen), [@iblancasa](https://github.com/iblancasa) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector) ## Overview > **Deprecation Notice:** The component type has been renamed from `spanmetrics` to `span_metrics` > to follow the OpenTelemetry snake\_case naming convention. > The old name `spanmetrics` still works but is deprecated and will be removed in a future release. > Please update your configuration to use `span_metrics`. ⚠️ Breaking Change Warning: The default duration metrics unit will change from `ms` to `s` to adhere to the OpenTelemetry semantic conventions and a feature gate `connector.spanmetrics.useSecondAsDefaultMetricsUnit` is also added. Currently, the feature gate is disabled by default, so the unit will remain `ms`. After one release cycle, the unit will switch to `s` and the feature gate will also be enabled by default. ## Overview Aggregates Request, Error and Duration (R.E.D) OpenTelemetry metrics from span data. **Request** counts are computed as the number of spans seen per unique set of dimensions, including Errors. Multiple metrics can be aggregated if, for instance, a user wishes to view call counts just on `service.name` and `span.name`. ``` traces.span.metrics.calls{service.name="shipping",span.name="get_shipping/{shippingId}",span.kind="SERVER",status.code="Ok"} ``` **Error** counts are computed from the Request counts which have an `Error` Status Code metric dimension. ``` traces.span.metrics.calls{service.name="shipping",span.name="get_shipping/{shippingId},span.kind="SERVER",status.code="Error"} ``` **Duration** is computed from the difference between the span start and end times and inserted into the relevant duration histogram time bucket for each unique set dimensions. ``` traces.span.metrics.duration{service.name="shipping",span.name="get_shipping/{shippingId}",span.kind="SERVER",status.code="Ok"} ``` Each metric will have *at least* the following dimensions because they are common across all spans: * `service.name` * `span.name` * `span.kind` * `status.code` (or `otel.status_code` when the `spanmetrics.statusCodeConvention.useOtelPrefix` feature gate is enabled) * `collector.instance.id` The `collector.instance.id` dimension is intended to add a unique UUID to all metrics, ensuring that the spanmetrics connector does not violate the **Single Writer Principle** when spanmetrics is used in a multi-deployment model. To disable, use `exclude_dimensions` setting: ```yaml theme={null} connectors: spanmetrics: exclude_dimensions: ['collector.instance.id'] ``` Or, disable via the feature gate: `--feature-gates=-connector.spanmetrics.includeCollectorInstanceID`. More detail, please see [Known Limitation: the Single Writer Principle](#known-limitation-the-single-writer-principle) ## Span to Metrics processor to Span to metrics connector The spanmetrics connector replaces [spanmetrics](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/processor/spanmetricsprocessor/v0.95.0/processor/spanmetricsprocessor/README.md) processor with multiple improvements and breaking changes. It was done to bring the `spanmetrics` connector closer to the OpenTelemetry specification and make the component agnostic to exporters logic. The `spanmetrics` processor essentially was mixing the OTel with Prometheus conventions by using the OTel data model and the Prometheus metric and attributes naming convention. The following changes were done to the connector component. Breaking changes: * The `operation` metric attribute was renamed to `span.name`. * The `latency` histogram metric name was changed to `duration`. * The `_total` metric prefix was dropped from generated metrics names. * The Prometheus-specific metrics labels sanitization was dropped. Improvements: * Added support for OTel exponential histograms for recording span duration measurements. * Added support for the milliseconds and seconds histogram units. * Added support for generating metrics resource scope attributes. The `spanmetrics` connector will generate the number of metrics resource scopes that corresponds to the number of the spans resource scopes meaning that more metrics are generated now. Previously, `spanmetrics` generated a single metrics resource scope. ## Configurations If you are not already familiar with connectors, you may find it helpful to first visit the [Connectors README]. The following settings can be optionally configured: * `histogram` (default: `explicit`): Use to configure the type of histogram to record calculated from spans duration measurements. Must be either `explicit` or `exponential`. * `disable` (default: `false`): Disable all histogram metrics. * `unit` (default: `ms`): The time unit for recording duration measurements. calculated from spans duration measurements. One of either: `ms` or `s`. * `dimensions`: additional attributes to add as dimensions to the `traces.span.metrics.duration` metric, which will be included *on top of* the common and configured `dimensions` for span attributes and resource attributes. * `explicit`: * `buckets`: the list of durations defining the duration histogram time buckets. Default buckets: `[2ms, 4ms, 6ms, 8ms, 10ms, 50ms, 100ms, 200ms, 400ms, 800ms, 1s, 1400ms, 2s, 5s, 10s, 15s]` * `exponential`: * `max_size` (default: `160`) the maximum number of buckets per positive or negative number range. * `dimensions`: the list of dimensions to add to `traces.span.metrics.calls`, `traces.span.metrics.duration` and `traces.span.metrics.event` metrics with the default dimensions defined above. Each list entry must set **exactly one** of: 1. `name` which is looked up in the span's collection of attributes or resource attributes (AKA process tags) such as `ip`, `host.name` or `region`. If the `name`d attribute is missing in the span, the optional provided `default` is used. If no `default` is provided, this dimension will be **omitted** from the metric. 2. `glob`: a glob pattern with '.' treated as a separator. Every span or resource attribute whose key matches the pattern is emitted as its own dimension. * `calls_dimensions`: additional attributes to add as dimensions to the `traces.span.metrics.calls` metric, which will be included *on top of* the common and configured `dimensions` for span attributes and resource attributes. * `exclude_dimensions`: the list of dimensions to be excluded from the default set of dimensions. Use to exclude unneeded data from metrics. * `dimensions_cache_size`: this setting is deprecated, please use aggregation\_cardinality\_limit instead. * `include_instrumentation_scope`: a list of instrumentation scope names to include from the traces. * `resource_metrics_cache_size` (default: `1000`): the size of the cache holding metrics for a service. This is mostly relevant for cumulative temporality to avoid memory leaks and correct metric timestamp resets. * `aggregation_temporality` (default: `AGGREGATION_TEMPORALITY_CUMULATIVE`): Defines the aggregation temporality of the generated metrics. One of either `AGGREGATION_TEMPORALITY_CUMULATIVE` or `AGGREGATION_TEMPORALITY_DELTA`. * `namespace` (default: `traces.span.metrics`): Defines the namespace of the generated metrics. If `namespace` provided, generated metric name will be added `namespace.` prefix. * `metrics_flush_interval` (default: `60s`): Defines the flush interval of the generated metrics. * `metrics_expiration` (default: `0`): Defines the expiration time as `time.Duration`, after which, if no new spans are received, metrics will no longer be exported. Setting to `0` means the metrics will never expire. * `series_expiration` (default: `0`): Defines the expiration time as `time.Duration` for individual metric series. When set, stale dimension combinations are removed on a later flush even if the parent metric and resource continue receiving other spans. Setting to `0` disables per-series expiration. * `metric_timestamp_cache_size` (default `1000`): Only relevant for delta temporality span metrics. Controls the size of the cache used to keep track of a metric's TimestampUnixNano the last time it was flushed. When a metric is evicted from the cache, its next data point will indicate a "reset" in the series. Downstream components converting from delta to cumulative, like `prometheusexporter`, may handle these resets by setting cumulative counters back to 0. * `exemplars`: Use to configure how to attach exemplars to metrics. * `enabled` (default: `false`): enabling will add spans as Exemplars to all metrics. Exemplars are only kept for one flush interval.rom the cache, its next data point will indicate a "reset" in the series. Downstream components converting from delta to cumulative, like `prometheusexporter`, may handle these resets by setting cumulative counters back to 0. * `max_per_data_point` (default: `5`): The maximum number of exemplars to attach to a single metric data point. * `events`: Use to configure the events metric. * `enabled`: (default: `false`): enabling will add the events metric. * `dimensions`: (mandatory if `enabled`) the list of the span's event attributes to add as dimensions to the `traces.span.metrics.events` metric, which will be included *on top of* the common and configured `dimensions` for span attributes and resource attributes. * `resource_metrics_key_attributes`: Filter the resource attributes used to produce the resource metrics key map hash(It's only used to build the hash key, not copy the attributes to metrics resource attributes). Use this in case changing resource attributes (e.g. process id) are breaking counter metrics. * `aggregation_cardinality_limit` (default: `0`): Defines the maximum number of unique combinations of dimensions that will be tracked for metrics aggregation. When the limit is reached, additional unique combinations will be dropped but registered under a new entry with `otel.metric.overflow="true"`. A value of `0` means no limit is applied. * `add_resource_attributes` (default: `false`): Add the resource attributes to the resulting metrics. This option enables the old behavior before the `connector.spanmetrics.excludeResourceMetrics` feature gate was introduced. When set to `true`, resource attributes will be included in the metrics even if the feature gate is enabled. See [GitHub issue #42103](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/42103) for more context. * `enable_metrics_sampling_method` (default: `false`): When enabled, adds the `sampling.method` attribute to metrics with value `"extrapolated"` (when the span has a valid tracestate sampling threshold) or `"counted"` (otherwise). The feature gate `connector.spanmetrics.legacyMetricNames` (disabled by default) controls the connector to use legacy metric names. ## Examples The following is a simple example usage of the `spanmetrics` connector. For configuration examples on other use cases, please refer to [More Examples](#more-examples). The full list of settings exposed for this connector are documented in [spanmetricsconnector/config.go](../../connector/spanmetricsconnector/config.go). ```yaml theme={null} receivers: nop: exporters: nop: connectors: span_metrics: histogram: dimensions: - name: url.scheme default: https explicit: buckets: [100us, 1ms, 2ms, 6ms, 10ms, 100ms, 250ms] dimensions: - name: http.method default: GET - name: http.status_code - glob: "k8s.*.name" # match single namespace between 'k8s' and 'name' ('k8s.cluster.name', not 'k8s.cluster.label.name') - glob: "db.**.name" # match any number of namespaces between 'db' and 'name' calls_dimensions: - name: http.url default: /ping exemplars: enabled: true exclude_dimensions: ['status.code'] aggregation_temporality: "AGGREGATION_TEMPORALITY_CUMULATIVE" metrics_flush_interval: 15s metrics_expiration: 5m series_expiration: 5m events: enabled: true dimensions: - name: exception.type - name: exception.message resource_metrics_key_attributes: - service.name - telemetry.sdk.language - telemetry.sdk.name include_instrumentation_scope: - express service: pipelines: traces: receivers: [nop] exporters: [span_metrics] metrics: receivers: [span_metrics] exporters: [nop] ``` ### Using `spanmetrics` with Prometheus components The `spanmetrics` connector can be used with Prometheus exporter components. For some functionality of the exporters, e.g. like generation of the `target_info` metric the incoming spans resource scope attributes must contain `service.name` and `service.instance.id` attributes. Let's look at the example of using the `spanmetrics` connector with the `prometheus_remote_write` exporter: ```yaml theme={null} receivers: otlp: protocols: http: grpc: exporters: prometheus_remote_write: endpoint: http://localhost:9090/api/v1/write target_info: enabled: true connectors: span_metrics: namespace: span.metrics service: pipelines: traces: receivers: [otlp] exporters: [span_metrics] metrics: receivers: [span_metrics] exporters: [prometheus_remote_write] ``` This configures the `spanmetrics` connector to generate metrics from received spans and export the metrics to the Prometheus Remote Write exporter. The `target_info` metric will be generated for each resource scope, while OpenTelemetry metric names and attributes will be [normalized](../../exporter/prometheusremotewriteexporter/README.md) to be compliant with Prometheus naming rules. For example, the generated `calls` OTel sum metric can result in multiple Prometheus `calls_total` (counter type) time series and the `target_info` time series. For example: ``` target_info{job="shippingservice", instance="...", ...} 1 calls_total{span_name="/Address", service_name="shippingservice", span_kind="SPAN_KIND_SERVER", status_code="STATUS_CODE_UNSET", ...} 142 ``` ### More Examples For more example configuration covering various other use cases, please visit the [testdata directory](../../connector/spanmetricsconnector/testdata). [Connectors README]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md ## Known Limitation: the Single Writer Principle Proper configuration of the `spanmetricsconnector` ensures compliance with the [Single Writer Principle](https://opentelemetry.io/docs/specs/otel/metrics/data-model/#single-writer), which is a core requirement in the OpenTelemetry metrics data model. Misconfiguration, however, may allow multiple components to write to the same metric stream, resulting in data inconsistency, metric conflicts, or the dropping of time series by metric backends. ### Why this happens This issue typically arises when: * Multiple pipelines use the same instance of the `spanmetricsconnector` * The connector is instantiated more than once without ensuring the resulting metric streams are distinct * The `resource_metrics_key_attributes` field is not configured correctly or includes common/shared attributes across all instances ### Recommendations To reduce the risk of conflicting writes: * Add `resource_metrics_key_attributes` to your configuration. ``` connectors: span_metrics: resource_metrics_key_attributes: - service.name - telemetry.sdk.language - telemetry.sdk.name ``` * The feature gate `connector.spanmetrics.includeCollectorInstanceID` is enabled by default to produce uniquely identified metrics. * For exporters like Prometheus, which rely on the single writer assumption, use a dedicated pipeline with a single `spanmetricsconnector` instance More context is available in [GitHub issue #21101](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/21101). ### About `resource_metrics_key_attributes` The `resource_metrics_key_attributes` setting are used to build the key map that determines how metrics are grouped. If this field is left empty, the connector will use **all** available attributes to compute the resource metric hash. To avoid problems, be cautious when choosing which attributes to include. Avoid attributes that: * **Change frequently** – such as `request_id`, `timestamp`, or `trace_id`. These increase cardinality and create excessive metric streams. * **Are shared across all sources** – values like `true`, `default`, or `team:backend` offer no uniqueness and can lead to multiple writers sharing the same stream. * **Are optional or inconsistently applied** – if an attribute is only present in some spans, this can fragment metric streams (e.g., one stream with the attribute and one without). Instead, use attributes that are stable, present in all spans, and meaningfully distinguish each stream. Good examples include `cluster_id`, `region`, or `deployment_environment`. ## Troubleshooting span metrics high cardinality High cardinality issues in span metrics commonly manifest in APM dashboards as an excessive number of service operations with non-unique names. Examples include URIs with unique identifiers (e.g., `GET /product/1YMWWN1N4O`) or HTTP parameters with random values (e.g., `GET /?_ga=GA1.2.569539246.1760114706`). These patterns render operation lists difficult to interpret and ineffective for monitoring purposes. This issue stems from violations of [OpenTelemetry semantic conventions](https://opentelemetry.io/docs/specs/semconv/), which require span names to have low cardinality (e.g. [HTTP span name specs](https://opentelemetry.io/docs/specs/semconv/http/http-spans/#name)). Beyond degrading APM interfaces with numerous non-meaningful operation names, this problem leads to metric time series explosion, resulting in significant performance degradation and increased costs. The span metrics connector provides an optional circuit breaker through the `aggregation_cardinality_limit` attribute (disabled by default) to mitigate cardinality explosion. While this feature addresses performance and cost concerns, it does not resolve the underlying issue of semantically meaningless operation names. ### Fixing high cardinality span name issues The ideal long-term solution is to modify the OpenTelemetry instrumentation code to comply with semantic conventions, preventing the generation of non-compliant high cardinality span names. However, deploying updated instrumentation libraries can be time-consuming, often requiring an immediate interim solution to restore observability backend functionality. #### Addressing high cardinality span names in the ingestion pipeline An effective short-term solution is to implement a span sanitization layer within the observability ingestion pipeline. This can be achieved by using the OpenTelemetry Collector Transform Processor's [`set_semconv_span_name()` function](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor#set_semconv_span_name) immediately before the Span Metrics Connector to enforce semantic conventions on span names.
Simple example OpenTelemetry Collector configuration to prevent span metrics cardinality explosion: ```yaml theme={null} receivers: otlp: ... processors: transform/sanitize_spans: error_mode: ignore trace_statements: # Sanitize all span names to prevent span metrics cardinality explosion # caused by non-compliant high cardinality span names - set_semconv_span_name("1.37.0") ... connectors: span_metrics: exporters: otlp_http/observability-backend: ... service: pipelines: traces: receivers: [otlp] processors: [transform/sanitize_spans, ...] exporters: [otlp_http/observability-backend, span_metrics] metrics: receivers: [otlp, span_metrics] processors: [...] exporters: [otlp_http/observability-backend] # ... ```
Aggressive span name sanitization may be overly restrictive for instrumentations with incomplete resource attributes. For instance, HTTP service operations may be reduced to generic names like `GET` and `POST` when HTTP spans lack the `http.route` attribute. This information loss can impact the monitoring of critical business operations. To preserve operation granularity, you can manually set the `http.route` attribute when detailed operation names are required. The missing `http.route` value can typically be derived through pattern matching on other span attributes such as `http.target` or `url.full`. Example OpenTelemetry Collector configuration that prevents cardinality explosion while preserving meaningful operation names on a service `webshop/frontend`: ```yaml theme={null} receivers: otlp: ... processors: transform/sanitize_spans: # Sanitize spans to prevent span metrics cardinality explosion caused by # non-compliant high cardinality span names: # 1. Fix incomplete semconv of critical operation spans to keep meaningful # span metrics operation names, adding missing `http.route` and # `http.request.method`. # 2. Sanitize all span names, note that http server spans lacking # `http.route` will default to operations `GET`, `POST`, etc. error_mode: ignore trace_statements: # 1. Fix incomplete semconv on the critical http operations of the `frontend` service - context: span conditions: - span.kind == SPAN_KIND_SERVER and resource.attributes["service.name"] == "frontend" and resource.attributes["service.namespace"] == "webshop" and span.attributes["http.route"] == nil statements: - set(span.attributes["http.route"], "/api/checkout") where IsMatch(span.attributes["http.target"], "\\/api\\/checkout") # e.g. # /api/checkout - set(span.attributes["http.route"], "/api/products/{productId}") where IsMatch(span.attributes["http.target"], "\\/api\\/products\\/.*") # e.g. /api/products/1YMWWN1N4O # 1. Fix incomplete semconv on the critical http operations of other services... # 2. Sanitize all span names to prevent span metrics cardinality explosion. # Unsanitized span names, when different, are kept in the `unsanitized_span_name` attribute - context: span statements: - set_semconv_span_name("1.37.0", "unsanitized_span_name") ... connectors: span_metrics: exporters: otlp_http/observability-backend: ... service: pipelines: traces: receivers: [otlp] processors: [transform/sanitize_spans, ...] exporters: [otlp_http/observability-backend, span_metrics] metrics: receivers: [otlp, span_metrics] processors: [...] exporters: [otlp_http/observability-backend] # ... ``` #### Addressing high cardinality span names in the instrumentation code The preferred long-term solution is to ensure span names and attributes comply with [OpenTelemetry Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/) directly in the instrumentation code. Custom web frameworks are a common source of high cardinality span names. While default OpenTelemetry instrumentation (e.g., Java Servlet) may assign generic span names like `GET /my-web-fwk/*`, your framework has access to more specific routing information. By overwriting span attributes in your framework code, you can create compliant, low-cardinality span names that preserve operational granularity. **Example: Custom Web Framework in Java** Consider a custom web framework that intercepts the generic route `/my-web-fwk/*` and dispatches requests like `/my-web-fwk/product/123456ABCD` or `/my-web-fwk/user/john.doe`. The default Java Servlet instrumentation produces vague span names (`GET /my-web-fwk/*`), while directly using request URIs creates high cardinality (`GET /my-web-fwk/product/123456ABCD`). The solution is to override span attributes with templated route patterns like `/my-web-fwk/product/{productId}` or `/my-web-fwk/user/{userId}`: ```java theme={null} @WebServlet(urlPatterns = "/my-web-fwk/*") public class MyWebFrameworkServlet extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Default Servlet instrumentation sets vague span names: `GET /my-web-fwk/*` (and `http.route=/my-web-fwk/*`) // Using the request URI directly would cause high cardinality and violate semantic conventions // Instead, use the framework's low-cardinality routing information below // Example routing logic String uri = request.getRequestURI(); MyWebOperation myWebOperation = getWebOperation(uri); // Fix span details to add details while complying with semantic conventions and maintaining low cardinality String httpRoute = "/my-web-fwk/" + myWebOperation.getSubHttpRoute(); Span.current().setAttribute(HttpAttributes.HTTP_ROUTE, httpRoute); Span.current().updateName(request.getMethod() + " " + httpRoute); // execute the web operation myWebOperation.execute(request, response); } ... } ``` ## Configuration ### Example Configuration ```yaml theme={null} # default configuration span_metrics/default: # default configuration with explicit buckets histogram span_metrics/default_explicit_histogram: histogram: explicit: # configuration with all possible parameters span_metrics/full: histogram: unit: "s" explicit: buckets: [ 10ms, 100ms, 250ms ] exemplars: enabled: true resource_metrics_cache_size: 1600 # Additional list of dimensions on top of: # - service.name # - span.name # - span.kind # - status.code dimensions: # If the span is missing http.method, the connector will insert # the http.method dimension with value 'GET'. - name: http.method default: GET # If a default is not provided, the http.status_code dimension will be omitted # if the span does not contain http.status_code. - name: http.status_code # The aggregation temporality of the generated metrics. # Default: "AGGREGATION_TEMPORALITY_CUMULATIVE" aggregation_temporality: "AGGREGATION_TEMPORALITY_DELTA" # The period on which all metrics (whose dimension keys remain in cache) will be emitted. # Default: 60s. metrics_flush_interval: 30s # default configuration with exponential buckets histogram span_metrics/exponential_histogram: histogram: exponential: max_size: 10 # invalid histogram configuration span_metrics/exponential_and_explicit_histogram: histogram: exponential: max_size: 10 explicit: buckets: [ 10ms, 100ms, 250ms ] span_metrics/invalid_histogram_unit: histogram: unit: "h" span_metrics/invalid_metrics_expiration: metrics_expiration: -20s span_metrics/series_expiration: series_expiration: 5m span_metrics/invalid_series_expiration: series_expiration: -20s # exemplars enabled span_metrics/exemplars_enabled: exemplars: enabled: true # exemplars enabled with max per datapoint configured span_metrics/exemplars_enabled_with_max_per_datapoint: exemplars: enabled: true max_per_data_point: 10 # resource metrics key attributes filter span_metrics/resource_metrics_key_attributes: resource_metrics_key_attributes: - service.name - telemetry.sdk.language - telemetry.sdk.name span_metrics/custom_delta_timestamp_cache_size: aggregation_temporality: "AGGREGATION_TEMPORALITY_DELTA" metric_timestamp_cache_size: 123 span_metrics/invalid_delta_timestamp_cache_size: aggregation_temporality: "AGGREGATION_TEMPORALITY_DELTA" metric_timestamp_cache_size: 0 span_metrics/default_delta_timestamp_cache_size: aggregation_temporality: "AGGREGATION_TEMPORALITY_DELTA" span_metrics/separate_calls_and_duration_dimensions: histogram: dimensions: - name: http.status_code dimensions: - name: http.method default: GET calls_dimensions: - name: http.url # Dimensions list mixing explicit names with a glob pattern. span_metrics/dimensions_with_globs: dimensions: - name: http.method default: GET - glob: db.* ``` *** *Last generated: 2026-08-03* # Sum Source: https://otel.fyi/components/connector/sumconnector OpenTelemetry connector for Sum # Sum Connector ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@greatestusername](https://github.com/greatestusername), [@shalper2](https://github.com/shalper2), [@crobert-1](https://github.com/crobert-1) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/sumconnector) ## Overview The `sum` connector can be used to sum attribute values from spans, span events, metrics, data points, and log records. ## Configuration If you are not already familiar with connectors, you may find it helpful to first visit the [Connectors README](https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md). ### Basic configuration This example configuration will sum numerical values found within the attribute `attribute.with.numerical.value` of any span telemetry routed to the connector. It will then output a metric time series with the name `my.example.metric.name` with those summed values. Note: Values found within an attribute will be converted into a float regardless of their original type before being summed and output as a metric value. Non-convertible strings will be dropped and not included. ```yaml theme={null} receivers: foo: connectors: sum: spans: my.example.metric.name: source_attribute: attribute.with.numerical.value exporters: bar: service: pipelines: metrics/sum: receivers: [sum] exporters: [bar] traces: receivers: [foo] exporters: [sum] ``` #### Required Settings The sum connector has three required configuration settings and numerous optional settings * Telemetry type: Nested below the `sum:` connector declaration. Declared as `spans:` in the [Basic Example](#basic-configuration). * Can be any of `spans`, `spanevents`, `datapoints`, or `logs`. * For metrics use `datapoints` * For traces use `spans` or `spanevents` * Metric name: Nested below the telemetry type; this is the metric name the sum connector will output summed values to. Declared as `my.example.metric.name` in the [Basic Example](#basic-configuration) * `source_attribute`: A specific attribute to search for within the source telemetry being fed to the connector. This attribute is where the connector will look for numerical values to sum into the output metric value. Declared as `attribute.with.numerical.value` in the [Basic Example](#basic-configuration) #### Optional Settings * `conditions`: [OTTL syntax](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/pkg/ottl/LANGUAGE.md) can be used to provide conditions for processing incoming telemetry. Conditions are ORed together, so if any condition is met the attribute's value will be included in the resulting sum. Conditions support OTTL path context names (e.g. `span.attributes["x"]`, `resource.attributes["x"]`, `log.attributes["x"]`, `metric.name`). Paths without an explicit context are interpreted in the context of the enclosing block. It is recommended to switch to the new syntax to avoid breaking changes in the future. * `attributes`: Declaration of attributes to include. Any of these attributes found will generate a separate sum for each set of unique combination of attribute values and output as its own datapoint in the metric time series. * `key`: (required for `attributes`) the attribute name to match against * `default_value`: (optional for `attributes`) a default value for the attribute when no matches are found. The `default_value` value can be of type string, integer, or float. ### Detailed Example Configuration This example declares that the `sum` connector is going to be ingesting `logs` and creating an output metric named `checkout.total` with numerical values found in the `source_attribute` `total.payment`. It provides a condition to check that the attribute `total.payment` is not `NULL`. It also checks any incoming log telemetry for values present in the attribute `payment.processor` and creates a datapoint within the metric time series for each unique value. Any logs without values in `payment.processor` will be included in a datapoint with the `default_value` of `unspecified_processor`. ```yaml theme={null} receivers: foo: connectors: sum: logs: checkout.total: source_attribute: total.payment conditions: - attributes["total.payment"] != "NULL" attributes: - key: payment.processor default_value: unspecified_processor exporters: bar: service: pipelines: metrics/sum: receivers: [sum] exporters: [bar] logs: receivers: [foo] exporters: [sum] ``` **Note for Log to Metrics:** If your logs contain all values in their `body` rather than in attributes (E.G. JSON payload) use a transform processor in your pipeline to upsert [parsed key/value pairs](https://github.com/open-telemetry/opentelemetry-log-collection/tree/main/docs/operators) (in this case from JSON) into attributes attached to the log. ```yaml theme={null} processors: transform/logs: log_statements: - context: log statements: - merge_maps(attributes, ParseJSON(body), "upsert") ``` [Connectors README]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/connector/README.md ## Configuration ### Example Configuration ```yaml theme={null} sum: sum/custom_description: spans: my.span.sum: description: My span record sum. source_attribute: my.attribute spanevents: my.spanevent.sum: description: My spanevent sum. source_attribute: my.attribute metrics: my.metric.sum: description: My metric sum. source_attribute: my.attribute datapoints: my.datapoint.sum: description: My datapoint sum. source_attribute: my.attribute logs: my.logrecord.sum: description: My log sum. source_attribute: my.attribute sum/custom_metric: spans: my.span.sum: source_attribute: my.attribute spanevents: my.spanevent.sum: source_attribute: my.attribute metrics: my.metric.sum: source_attribute: my.attribute datapoints: my.datapoint.sum: source_attribute: my.attribute logs: my.logrecord.sum: source_attribute: my.attribute sum/condition: spans: my.span.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-s") spanevents: my.spanevent.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-e") metrics: my.metric.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-m") datapoints: my.datapoint.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-d") logs: my.logrecord.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-l") sum/multiple_condition: spans: my.span.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-s") - IsMatch(resource.attributes["foo"], "bar-s") spanevents: my.spanevent.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-e") - IsMatch(resource.attributes["foo"], "bar-e") metrics: my.metric.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-m") - IsMatch(resource.attributes["foo"], "bar-m") datapoints: my.datapoint.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-d") - IsMatch(resource.attributes["foo"], "bar-d") logs: my.logrecord.sum: source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-l") - IsMatch(resource.attributes["foo"], "bar-l") sum/attribute: spans: my.span.sum: source_attribute: my.attribute attributes: - key: env spanevents: my.spanevent.sum: source_attribute: my.attribute attributes: - key: env metrics: my.metric.sum: source_attribute: my.attribute # Metrics do not have attributes. datapoints: my.datapoint.sum: source_attribute: my.attribute attributes: - key: env logs: my.logrecord.sum: source_attribute: my.attribute attributes: - key: env sum/multiple_metrics: spans: my.span.sum: description: My span sum. source_attribute: my.attribute limited.span.sum: description: Limited span sum. source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-s") attributes: - key: env - key: component default_value: other spanevents: my.spanevent.sum: description: My span event sum. source_attribute: my.attribute limited.spanevent.sum: description: Limited span event sum. source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-e") attributes: - key: env - key: component default_value: other metrics: my.metric.sum: description: My metric sum. source_attribute: my.attribute limited.metric.sum: description: Limited metric sum. source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-m") datapoints: my.datapoint.sum: description: My data point sum. source_attribute: my.attribute limited.datapoint.sum: description: Limited data point sum. source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-d") attributes: - key: env - key: component default_value: other logs: my.logrecord.sum: description: My log record sum. source_attribute: my.attribute limited.logrecord.sum: description: Limited log record sum. source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-l") attributes: - key: env - key: component default_value: other ``` *** *Last generated: 2026-08-03* # Exporters Source: https://otel.fyi/components/exporter/_index OpenTelemetry Exporters components # Alertmanager Source: https://otel.fyi/components/exporter/alertmanagerexporter OpenTelemetry exporter for Alertmanager # Alertmanager Exporter ![Status](https://img.shields.io/badge/status-development-orange) **Maintainers:** [@sokoide](https://github.com/sokoide), [@mcube8](https://github.com/mcube8) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/alertmanagerexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-development-blue) ![Traces](https://img.shields.io/badge/traces-development-orange) ## Overview Exports OTEL Events (SpanEvent in Tracing added by AddEvent API and Log Records) as Alerts to [Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/) back-end to notify Errors or Change events. Supported pipeline types: traces, logs ## Getting Started The following settings are required: * `endpoint`: Alertmanager endpoint to send events * `severity`: Default severity for Alerts The following settings are optional: * `timeout` `sending_queue` and `retry_on_failure` settings as provided by [Exporter Helper](https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/exporterhelper#configuration). * [HTTP settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confighttp/README.md) * [TLS and mTLS settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configtls/README.md) * `generator_url` is the source of the alerts to be used in Alertmanager's payload. The default value is "opentelemetry-collector", and can be set to the URL of the opentelemetry collector. * `severity_attribute` is the SpanEvent or LogRecord Attribute name which can be used instead of default severity string in Alert payload. e.g.: If `severity_attribute` is set to "foo" and the SpanEvent or LogRecord has an attribute called foo, foo's attribute value will be used as the severity value for that particular Alert generated from the SpanEvent or LogRecord. * `api_version` is the API version of [Alertmanager](https://prometheus.io/docs/alerting/latest/clients/). By default the value is set to "v2" and can be overridden to "v1" if using an older version of Alertmanager. * `event_labels` is the list of Event or LogRecord Attributes that will be captured as Labels in the Alert payload if value exists. Example config: ```yaml theme={null} exporters: alertmanager: alertmanager/2: endpoint: "https://a.new.alertmanager.target:9093" severity: "debug" severity_attribute: "foo" api_version: "v2" event_labels: ["foo", "bar"] tls: cert_file: /var/lib/mycert.pem key_file: /var/lib/key.pem timeout: 10s sending_queue: enabled: true num_consumers: 2 queue_size: 10 retry_on_failure: enabled: true initial_interval: 10s max_interval: 60s max_elapsed_time: 10m generator_url: "opentelemetry-collector" ``` ## Configuration ### Example Configuration ```yaml theme={null} alertmanager: alertmanager/2: endpoint: "a.new.alertmanager.target:9093" generator_url: "opentelemetry-collector" severity: "info" severity_attribute: "foo" tls: ca_file: /var/lib/mycert.pem timeout: 10s sending_queue: enabled: true num_consumers: 2 queue_size: 10 retry_on_failure: enabled: true initial_interval: 10s max_interval: 60s max_elapsed_time: 10m headers: "can you have a . here?": "F0000000-0000-0000-0000-000000000000" header1: "234" another: "somevalue" ``` *** *Last generated: 2026-08-03* # Alibabacloudlogservice Source: https://otel.fyi/components/exporter/alibabacloudlogserviceexporter OpenTelemetry exporter for Alibabacloudlogservice # Alibabacloudlogservice Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@vyagh](https://github.com/vyagh) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/alibabacloudlogserviceexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-beta-blue) ![Metrics](https://img.shields.io/badge/metrics-beta-green) ![Traces](https://img.shields.io/badge/traces-beta-orange) ## Overview This exporter supports sending OpenTelemetry data to [LogService](https://www.alibabacloud.com/product/log-service). * `endpoint` (required): LogService's [Endpoint](https://www.alibabacloud.com/help/doc-detail/29008.htm). * `project` (required): LogService's Project Name. * `logstore` (required): LogService's store Name. For metrics data, you should use metric store. * `access_key_id` (optional): AlibabaCloud access key id. * `access_key_secret` (optional): AlibabaCloud access key secret. * `security_token` (optional): AlibabaCloud security token for STS credentials. * `ecs_ram_role` (optional): set AlibabaCLoud ECS ram role if you are using ACK. * `token_file_path` (optional): Set token file path if you are using ACK. # Example: ## Simple Trace Data ```yaml theme={null} receivers: examplereceiver: exporters: alibabacloud_logservice: endpoint: "cn-hangzhou.log.aliyuncs.com" project: "demo-project" logstore: "traces-store" access_key_id: "access-key-id" access_key_secret: "access-key-secret" service: pipelines: traces: receivers: [examplereceiver] exporters: [alibabacloud_logservice] ``` ## All Telemetry Data If you are using OpenTelemetry Collector to collect different types of telemetry data, you should send to different LogService's store. ```yaml theme={null} receivers: examplereceiver: exporters: alibabacloud_logservice/logs: endpoint: "cn-hangzhou.log.aliyuncs.com" project: "demo-project" logstore: "logs-store" access_key_id: "access-key-id" access_key_secret: "access-key-secret" alibabacloud_logservice/metrics: endpoint: "cn-hangzhou.log.aliyuncs.com" project: "demo-project" logstore: "metrics-store" access_key_id: "access-key-id" access_key_secret: "access-key-secret" alibabacloud_logservice/traces: endpoint: "cn-hangzhou.log.aliyuncs.com" project: "demo-project" logstore: "traces-store" access_key_id: "access-key-id" access_key_secret: "access-key-secret" service: pipelines: traces: receivers: [examplereceiver] exporters: [alibabacloud_logservice/traces] logs: receivers: [examplereceiver] exporters: [alibabacloud_logservice/logs] metrics: receivers: [examplereceiver] exporters: [alibabacloud_logservice/metrics] ``` ## Configuration ### Example Configuration ```yaml theme={null} alibabacloud_logservice: endpoint: "cn-hangzhou.log.aliyuncs.com" alibabacloud_logservice/2: endpoint: "cn-hangzhou.log.aliyuncs.com" project: "demo-project" logstore: "demo-logstore" access_key_id: "test-id" access_key_secret: "test-secret" security_token: "test-token" ``` *** *Last generated: 2026-08-03* # Awscloudwatchlogs Source: https://otel.fyi/components/exporter/awscloudwatchlogsexporter OpenTelemetry exporter for Awscloudwatchlogs # Awscloudwatchlogs Exporter ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@yaten2302](https://github.com/yaten2302) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/awscloudwatchlogsexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-alpha-blue) ## Overview AWS CloudWatch Logs Exporter sends logs data to AWS [CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html). AWS credentials are retrieved from the [default credential chain](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials). NOTE: OpenTelemetry Logging support is experimental, hence this exporter is subject to change. ## Configuration The following settings are required: * `log_group_name`: The group name of the CloudWatch Logs. If it does not exist it will be created automatically. It supports several placeholder names. One valid example is `/aws/metrics/{ClusterName}`. It will search for ClusterName (or aws.ecs.cluster.name) resource attribute in the metrics data and replace with the actual cluster name. If none of them are found in the resource attribute map, \{ClusterName} will be replaced by undefined. Similar way, for the \{TaskId}, it searches for TaskId (or aws.ecs.task.id) key in the resource attribute map. For \{NodeName}, it searches for NodeName (or k8s.node.name) * List of valid placeholders: * `{ClusterName}`: `aws.ecs.cluster.name` * `{TaskId}`: `aws.ecs.task.id` * `{NodeName}`: `k8s.node.name` * `{PodName}`: `pod` * `{ServiceName}`: `service.name` * `{ContainerInstanceId}`: `aws.ecs.container.instance.id` * `{TaskDefinitionFamily}`: `aws.ecs.task.family` * `{InstanceId}`: `service.instance.id` * `{FaasName}`: `faas.name` * `{FaasVersion}`: `faas.version` * `log_stream_name`: The stream name of the CloudWatch Logs. If it does not exist it will be created automatically. It supports the same placeholders as `log_group_name` The following settings can be optionally configured: * `region`: The AWS region where the log stream is in. Region must be specified if it is not already set in the default credential chain. * `endpoint`: The CloudWatch Logs service endpoint which the requests are forwarded to. [See the CloudWatch Logs endpoints](https://docs.aws.amazon.com/general/latest/gr/cwl_region.html) for a list. * `log_retention`: LogRetention is the option to set the log retention policy for only newly created CloudWatch Log Groups. Defaults to Never Expire if not specified or set to 0. Possible values for retention in days are 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 2192, 2557, 2922, 3288, or 3653. * `tags`: Tags is the option to set tags for the CloudWatch Log Group. If specified, please add at most 50 tags. Input is a string to string map like so: \{ 'key': 'value' }. Keys must be between 1-128 characters and follow the regex pattern: `^([\p{L}\p{Z}\p{N}_.:/=+\-@]+)$`(alphanumerics, whitespace, and \_.:/=+-!). Values must be between 1-256 characters and follow the regex pattern: `^([\p{L}\p{Z}\p{N}_.:/=+\-@]\*)$`(alphanumerics, whitespace, and \_.:/=+-!). [Link to tagging restrictions](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html#:~:text=Required%3A%20Yes-,tags,-The%20key%2Dvalue) * `raw_log`: Boolean default false. If set to true, only the log message will be exported to CloudWatch Logs. This needs to be set to true for [EMF logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html). * `role_arn`: IAM role to upload logs to a different account. * `external_id`: Shared identitier used when assuming an IAM role in an external AWS account. [See AWS IAM Guide](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html#id_roles_third-party_external-id) * `sending_queue`: [Parameters for the sending queue](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md), where you can control parallelism and the size of the sending buffer. Obs.: this component will always have a sending queue enabled. * `num_consumers`: Number of consumers that will consume from the sending queue. This parameter controls how many consumers will consume from the sending queue in parallel. * `queue_size`: Maximum number of batches kept in memory before dropping; ignored if enabled is false ### Examples Simplest configuration: ```yaml theme={null} exporters: awscloudwatchlogs: log_group_name: "testing-logs" log_stream_name: "testing-integrations-stream" ``` Example configuration for EMF logs: ```yaml theme={null} exporters: awscloudwatchlogs: log_group_name: "testing-logs-emf" log_stream_name: "testing-integrations-stream-emf" raw_log: true region: "us-east-1" endpoint: "logs.us-east-1.amazonaws.com" log_retention: 365 tags: { "sampleKey": "sampleValue" } ``` ## Additional Notes * If the log group and/or log stream are specified in an EMF log, that EMF log will be exported to that log group and/or log stream (i.e. ignores the log group and log stream defined in the configuration) * The log group and log stream will also be created automatically if they do not already exist. * Example of an EMF log with log group and log stream: ```json theme={null} { "_aws": { "Timestamp": 1574109732004, "LogGroupName": "Foo", "LogStreamName": "Bar", "CloudWatchMetrics": [ { "Namespace": "MyApp", "Dimensions": [["Operation"]], "Metrics": [ { "Name": "ProcessingLatency", "Unit": "Milliseconds", "StorageResolution": 60 } ] } ] }, "Operation": "Aggregator", "ProcessingLatency": 100 } ``` * Resource ARNs (Amazon Resource Name (ARN) of the AWS resource running the collector) are currently not supported with the CloudWatch Logs Exporter. ## Configuration ### Example Configuration ```yaml theme={null} awscloudwatchlogs/e1-defaults: log_group_name: "test-1" log_stream_name: "testing" awscloudwatchlogs/e2-no-retries-short-queue: log_group_name: "test-2" log_stream_name: "testing" sending_queue: queue_size: 2 retry_on_failure: enabled: false awscloudwatchlogs/invalid_queue_setting: log_group_name: "test-4" log_stream_name: "testing" sending_queue: enabled: false num_consumers: 2 awscloudwatchlogs/invalid_queue_size: log_group_name: "test-3" log_stream_name: "testing" sending_queue: queue_size: 0 awscloudwatchlogs/invalid_num_consumers: log_group_name: "test-3" log_stream_name: "testing" sending_queue: num_consumers: 0 awscloudwatchlogs/invalid_required_field_stream: log_group_name: "test-1" awscloudwatchlogs/invalid_required_field_group: log_stream_name: "testing" ``` *** *Last generated: 2026-08-03* # Awsemf Source: https://otel.fyi/components/exporter/awsemfexporter OpenTelemetry exporter for Awsemf # Awsemf Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@Aneurysm9](https://github.com/Aneurysm9), [@mxiamxia](https://github.com/mxiamxia) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/awsemfexporter) ## Supported Telemetry ![Metrics](https://img.shields.io/badge/metrics-beta-green) ## Overview This exporter converts OpenTelemetry metrics to [AWS CloudWatch Embedded Metric Format(EMF)](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html) and then sends them directly to CloudWatch Logs using the [PutLogEvents](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html) API. ## Data Conversion Convert OpenTelemetry `Int64DataPoints`, `DoubleDataPoints`, `SummaryDataPoints` metrics datapoints into CloudWatch `EMF` structured log formats and send it to CloudWatch. Logs and Metrics will be displayed in CloudWatch console. NaN, Inf values are not supported by CloudWatch EMF and will be dropped by the exporter. ## Exporter Configuration The following exporter configuration parameters are supported. | Name | Description | Default | | :------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | `log_group_name` | Customized log group name which supports `{ClusterName}` and `{TaskId}` placeholders. One valid example is `/aws/metrics/{ClusterName}`. It will search for `ClusterName` (or `aws.ecs.cluster.name`) resource attribute in the metrics data and replace with the actual cluster name. If none of them are found in the resource attribute map, `{ClusterName}` will be replaced by `undefined`. Similar way, for the `{TaskId}`, it searches for `TaskId` (or `aws.ecs.task.id`) key in the resource attribute map. For `{NodeName}`, it searches for `NodeName` (or `k8s.node.name`) | "/metrics/default" | | `log_stream_name` | Customized log stream name which supports `{TaskId}`, `{ClusterName}`, `{NodeName}`, `{ContainerInstanceId}`, and `{TaskDefinitionFamily}` placeholders. One valid example is `{TaskId}`. It will search for `TaskId` (or `aws.ecs.task.id`) resource attribute in the metrics data and replace with the actual task id. If none of them are found in the resource attribute map, `{TaskId}` will be replaced by `undefined`. Similarly, for the `{TaskDefinitionFamily}`, it searches for `TaskDefinitionFamily` (or `aws.ecs.task.family`). For the `{ClusterName}`, it searches for `ClusterName` (or `aws.ecs.cluster.name`). For `{NodeName}`, it searches for `NodeName` (or `k8s.node.name`). For `{ContainerInstanceId}`, it searches for `ContainerInstanceId` (or `aws.ecs.container.instance.id`). (Note: ContainerInstanceId (or `aws.ecs.container.instance.id`) only works for AWS ECS EC2 launch type. | "otel-stream" | | `log_retention` | LogRetention is the option to set the log retention policy for only newly created CloudWatch Log Groups. Defaults to Never Expire if not specified or set to 0. Possible values for retention in days are 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 2192, 2557, 2922, 3288, or 3653. | "Never Expire" | | `tags` | Tags is the option to set tags for the CloudWatch Log Group. If specified, please add at most 50 tags. Input is a string to string map like so: \{ 'key': 'value' }. Keys must be between 1-128 characters and follow the regex pattern: `^([\p{L}\p{Z}\p{N}_.:/=+\-@]+)$`(alphanumerics, whitespace, and \_.:/=+-!). Values must be between 1-256 characters and follow the regex pattern: `^([\p{L}\p{Z}\p{N}_.:/=+\-@]*)$`(alphanumerics, whitespace, and \_.:/=+-!). [Link to tagging restrictions](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html#:~:text=Required%3A%20Yes-,tags,-The%20key%2Dvalue) | No tags set | | `namespace` | Customized CloudWatch metrics namespace | "default" | | `endpoint` | Optionally override the default CloudWatch service endpoint. | | | `no_verify_ssl` | Enable or disable TLS certificate verification. | false | | `proxy_address` | Upload Structured Logs to AWS CloudWatch through a proxy. | | | `region` | Send Structured Logs to AWS CloudWatch in a specific region. If this field is not present in config, environment variable "AWS\_REGION" can then be used to set region. | determined by metadata | | `role_arn` | IAM role to upload segments to a different account. | | | `external_id` | Shared identitier used when assuming an IAM role in an external AWS account. | | | `max_retries` | Maximum number of retries before abandoning an attempt to post data. | 1 | | `dimension_rollup_option` | DimensionRollupOption is the option for metrics dimension rollup. Three options are available: `NoDimensionRollup`, `SingleDimensionRollupOnly` and `ZeroAndSingleDimensionRollup`. The default value is `ZeroAndSingleDimensionRollup`. Enabling feature gate `awsemf.nodimrollupdefault` will set default to `NoDimensionRollup`. | "ZeroAndSingleDimensionRollup" (Enable both zero dimension rollup and single dimension rollup) | | `resource_to_telemetry_conversion` | "resource\_to\_telemetry\_conversion" is the option for converting resource attributes to telemetry attributes. It has only one config option- `enabled`. For metrics, if `enabled=true`, all the resource attributes will be converted to metric labels by default. See `Resource Attributes to Metric Labels` section below for examples. | `enabled=false` | | `output_destination` | "output\_destination" is an option to specify the EMFExporter output. Currently, two options are available. "cloudwatch" or "stdout" | `cloudwatch` | | `detailed_metrics` | Retain detailed datapoint values in exported metrics (e.g instead of exporting a quantile as a statistical value, preserve the quantile's population) | `false` | | `parse_json_encoded_attr_values` | List of attribute keys whose corresponding values are JSON-encoded strings and will be converted to JSON structures in emf logs. For example, the attribute string value "\{\\"x\\":5,\\"y\\":6}" will be converted to a json object: `{"x": 5, "y": 6}` | \[ ] | | [`metric_declarations`](#metric_declaration) | List of rules for filtering exported metrics and their dimensions. | \[ ] | | [`metric_descriptors`](#metric_descriptor) | List of rules for inserting or updating metric descriptors. | \[ ] | | `retain_initial_value_of_delta_metric` | This option specifies how the first value of a metric is handled. AWS EMF expects metric values to only contain deltas to the previous value. In the default case the first received value is therefor not sent to AWS but only used as a baseline for follow up changes to this metric. This is fine for high throughput metrics with stable labels (e.g. `requests{code=200}`). In this case it does not matter if the first value of this metric is discarded. However when your metric describes infrequent events or events with high label cardinality, then the exporter in default configuration would still drop the first occurrence of this metric. With this configuration value set to `true` the first value of all metrics will instead be send to AWS. | false | ### metric\_declaration A metric\_declaration section characterizes a rule to be used to set dimensions for exported metrics, filtered by the incoming metrics' labels and metric names. | Name | Description | Default | | :--------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | `dimensions` | List of dimension sets to be exported. Dimension sets that include dimensions that are not labels are ignored. Use empty dimension set `[]` for metrics without labels. | \[\[ ]] | | `metric_name_selectors` | List of regex strings to filter metric names by. | | | [`label_matchers`](#label_matcher) | (Optional) list of label matching rules to filter metrics by their labels. This rule is applied to any metric that matches any of the label matchers. | \[ ] | #### label\_matcher A label\_matcher section defines a matching rule against the labels of the incoming metric. Only metrics that match the rules will be used by the surrounding `metric_declaration`. | Name | Description | Default | | :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | `label_names` | List of label names to filter by. Their corresponding values are concatenated using the separator and matched against the configured regular expression. | | | `separator` | (Optional) separator placed between concatenated label values. | ";" | | `regex` | Regex string to be matched against concatenated label values. | | ### metric\_descriptor A metric descriptor section allows the schema of a metric to be overwritten before sending out to the CloudWatch backend service. Currently, we only support unit override. | Name | Description | Default | | :------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | | `metric_name` | The name of the metric to be overwritten. | | | `unit` | The overwritten value of unit. The [MetricDatum](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html) contains a full list of supported unit values. | | | `overwrite` | `true` if the schema should be overwritten with the given specification, otherwise it will only be configured if empty. | false | ## AWS Credential Configuration This exporter follows default credential resolution for the [aws-sdk-go](https://docs.aws.amazon.com/sdk-for-go/api/index.html). Follow the [guidelines](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html) for the credential configuration. ## Metric Attributes By setting attributes on your metrics you can change how individual metrics are sent to CloudWatch. Attributes can be set in code or using components like the [Attribute Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/attributesprocessor). The AWS EMF Exporter will interpret the following metric attributes to change how it publishes metrics to CloudWatch: | Attribute Name | Description | Default | | :--------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | | `aws.emf.storage_resolution` | This attribute should be set to an integer value of `1` or `60`. When sending the metric value to CloudWatch use the specified storage resolution value. CloudWatch currently supports a storage resolution of `1` or `60` to indicate 1 second or 60 second resolution. | `aws.emf.storage_resolution = 60` | ## Configuration Examples ### Resource Attributes to Metric Labels `resource_to_telemetry_conversion` option can be enabled to convert all the resource attributes to metric labels. By default, this option is disabled. Users need to set `enabled=true` to opt-in. See the config example below. ```yaml theme={null} exporters: awsemf: region: 'us-west-2' resource_to_telemetry_conversion: enabled: true ``` ### Metric Declaration The following is an example of how to use `metric_declaration` to select what metrics should be exported. ```yaml theme={null} exporters: awsemf: region: 'us-west-2' output_destination: stdout dimension_rollup_option: "NoDimensionRollup" metric_declarations: - dimensions: [[]] metric_name_selectors: # Metric without label - "^node_load15$" - dimensions: [[device, fstype], []] metric_name_selectors: - "^node_filesystem_readonly$" ``` ## Configuration ### Example Configuration ```yaml theme={null} awsemf: awsemf/1: region: 'us-west-2' role_arn: "arn:aws:iam::123456789:role/monitoring-EKS-NodeInstanceRole" detailed_metrics: false version: "1" awsemf/resource_attr_to_label: resource_to_telemetry_conversion: enabled: true awsemf/metric_descriptors: metric_descriptors: - metric_name: memcached_current_items unit: Count overwrite: true ``` *** *Last generated: 2026-08-03* # Awskinesis Source: https://otel.fyi/components/exporter/awskinesisexporter OpenTelemetry exporter for Awskinesis # Awskinesis Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@Aneurysm9](https://github.com/Aneurysm9), [@MovieStoreGuy](https://github.com/MovieStoreGuy) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/awskinesisexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-beta-blue) ![Metrics](https://img.shields.io/badge/metrics-beta-green) ![Traces](https://img.shields.io/badge/traces-beta-orange) ## Overview The kinesis exporter currently exports dynamic encodings to the configured kinesis stream. The exporter relies heavily on the kinesis.PutRecords api to reduce network I/O and reduces records into smallest atomic representation to avoid hitting the hard limits placed on Records (No greater than 1Mb). This producer will block until the operation is done to allow for retryable and queued data to help during high loads. The following settings are required: * `aws` * `stream_name` (no default): The name of the Kinesis stream to export to. The following settings can be optionally configured: * `aws` * `kinesis_endpoint` (no default) * `region` (default = us-west-2): the region that the kinesis stream is deployed in * `role` (no default): The role to be used in order to send data to the kinesis stream * `encoding` * `name` (default = otlp): defines the export type to be used to send to kinesis (available is `otlp_proto`, `otlp_json`, `zipkin_proto`, `zipkin_json`, `jaeger_proto`) * **Note** : `otlp_json` is considered experimental and *should not* be used for production environments. * `compression` (default = none): allows to set the compression type (defaults BestSpeed for all) before forwarding to kinesis (available is `flate`, `gzip`, `zlib` or `none`) * `max_records_per_batch` (default = 500, PutRecords limit): The number of records that can be batched together then sent to kinesis. * `max_record_size` (default = 1Mb, PutRecord(s) limit on record size): The max allowed size that can be exported to kinesis * `timeout` (default = 5s): Is the timeout for every attempt to send data to the backend. * `retry_on_failure` * `enabled` (default = true) * `initial_interval` (default = 5s): Time to wait after the first failure before retrying; ignored if `enabled` is `false` * `max_interval` (default = 30s): Is the upper bound on backoff; ignored if `enabled` is `false` * `max_elapsed_time` (default = 120s): Is the maximum amount of time spent trying to send a batch; ignored if `enabled` is `false` * `sending_queue` * `enabled` (default = true) * `num_consumers` (default = 10): Number of consumers that dequeue batches; ignored if `enabled` is `false` * `queue_size` (default = 1000): Maximum number of batches kept in memory before dropping data; ignored if `enabled` is `false`; User should calculate this as `num_seconds * requests_per_second` where: * `num_seconds` is the number of seconds to buffer in case of a backend outage * `requests_per_second` is the average number of requests per seconds. Example Configuration: ```yaml theme={null} exporters: awskinesis: aws: stream_name: raw-trace-stream region: us-east-1 role: arn:test-role ``` ## Configuration ### Example Configuration ```yaml theme={null} awskinesis/default: awskinesis: max_records_per_batch: 10 max_record_size: 1000 aws: stream_name: test-stream region: mars-1 role: arn:test-role kinesis_endpoint: awskinesis.mars-1.aws.galactic retry_on_failure: enabled: false encoding: name: otlp-proto ``` *** *Last generated: 2026-08-03* # Awss3 Source: https://otel.fyi/components/exporter/awss3exporter OpenTelemetry exporter for Awss3 # Awss3 Exporter ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@atoulme](https://github.com/atoulme), [@pdelewski](https://github.com/pdelewski), [@Erog38](https://github.com/Erog38) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/awss3exporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-alpha-blue) ![Metrics](https://img.shields.io/badge/metrics-alpha-green) ![Traces](https://img.shields.io/badge/traces-alpha-orange) ## Overview ## Schema supported This exporter targets to support proto/json format. ## Exporter Configuration The following exporter configuration parameters are supported. | Name | Description | Default | | :------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | | `region` | AWS region. | "us-east-1" | | `s3_bucket` | S3 bucket | | | `s3_base_prefix` | root prefix for the S3 key applied to all files. | | | `s3_prefix` | prefix for the S3 key that can be overridden dynamically by `resource_attrs_to_s3` parameter. | | | `s3_partition_format` | filepath formatting for the partition; See [strftime](https://www.man7.org/linux/man-pages/man3/strftime.3.html) for format specification. | "year=%Y/month=%m/day=%d/hour=%H/minute=%M" | | `s3_partition_timezone` | timezone used to format partition | Local | | `role_arn` | the Role ARN to be assumed | | | `file_prefix` | file prefix defined by user | | | `marshaler` | marshaler used to produce output data | `otlp_json` | | `encoding` | Encoding extension to use to marshal data. Overrides the `marshaler` configuration option if set. | | | `encoding_file_extension` | file format extension suffix when using the `encoding` configuration option. May be left empty for no suffix to be appended. | | | `endpoint` | (REST API endpoint) overrides the endpoint used by the exporter instead of constructing it from `region` and `s3_bucket` | | | `storage_class` | [S3 storageclass](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.html) | STANDARD | | `acl` | [S3 Object Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl) | none (does not set by default) | | `s3_force_path_style` | [set this to `true` to force the request to use path-style addressing](http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html) | false | | `disable_ssl` | set this to `true` to disable SSL when sending requests | false | | `compression` | should the file be compressed | none | | `sending_queue` | [exporters common queuing](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md) | disabled | | `timeout` | [exporters common timeout](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md) | 5s | | `resource_attrs_to_s3` | determines the mapping of S3 configuration values to resource attribute values for uploading operations. | | | `retry_mode` | The retryer implementation, the supported values are "standard", "adaptive" and "nop". "nop" will set the retryer as `aws.NopRetryer`, which effectively disable the retry. | standard | | `retry_max_attempts` | The max number of attempts for retrying a request if the `retry_mode` is set. Setting max attempts to 0 will allow the SDK to retry all retryable errors until the request succeeds, or a non-retryable error is returned. | 3 | | `retry_max_backoff` | the max backoff delay that can occur before retrying a request if `retry_mode` is set | 20s | | `unique_key_func_name` | Name of the function to use for generating a unique portion of the key name, defaults to a random integer. Only supported value is `uuidv7`. | | | `retry_on_failure` | see [Retry on Failure](https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/exporterhelper#retry-on-failure) for the full set of available options. | | ### Marshaler Marshaler determines the format of data sent to AWS S3. Currently, the following marshalers are implemented: * `otlp_json` (default): the [OpenTelemetry Protocol format](https://github.com/open-telemetry/opentelemetry-proto), represented as json. * `otlp_proto`: the [OpenTelemetry Protocol format](https://github.com/open-telemetry/opentelemetry-proto), represented as Protocol Buffers. A single protobuf message is written into each object. * `sumo_ic`: the [Sumo Logic Installed Collector Archive format](https://help.sumologic.com/docs/manage/data-archiving/archive/). * \_sourceCategory, \_sourceHost, and \_sourceName is needed ```yaml theme={null} resource/add_source_category: attributes: - action: insert key: _sourceCategory value: "value" - action: insert key: _sourceHost value: "value" - action: insert key: _sourceName value: "value" ``` **This format is supported only for logs.** * `body`: export the log body as string. **This format is supported only for logs.** ### Encoding Encoding overrides marshaler if present and sets to use an encoding extension defined in the collector configuration. See [https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/encoding](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/encoding). ### Compression * `none` (default): No compression will be applied * `gzip`: Files will be compressed with gzip. * `zstd`: Files will be compressed with zstd. ### resource\_attrs\_to\_s3 * `s3_bucket`: Defines which resource attribute's value should be used as the S3 bucket. When this option is set, it dynamically overrides `s3uploader/s3_bucket`. If the specified resource attribute exists in the data,\ its value will be used as the bucket; otherwise, `s3uploader/s3_bucket` will serve as the fallback. * `s3_prefix`: Defines which resource attribute's value should be used as the S3 prefix. When this option is set, it dynamically overrides `s3uploader/s3_prefix`. If the specified resource attribute exists in the data,\ its value will be used as the prefix; otherwise, `s3uploader/s3_prefix` will serve as the fallback. Following example configuration defines to store output in 'eu-central' region and bucket named 'databucket'. ```yaml theme={null} exporters: awss3: s3uploader: region: 'eu-central-1' s3_bucket: 'databucket' s3_prefix: 'metric' # Optional (disabled by default) sending_queue: enabled: true num_consumers: 10 queue_size: 100 # Optional (5s by default) timeout: 20s ``` Logs and traces will be stored inside 'databucket' in the following path format. ```console theme={null} metric/year=YYYY/month=MM/day=DD/hour=HH/minute=mm ``` ## Partition Formatting By setting the `s3_partition_format` option, users can specify the file path for their logs. See the [strftime](https://www.man7.org/linux/man-pages/man3/strftime.3.html) reference for more formatting options. ```yaml theme={null} exporters: awss3: s3uploader: region: 'eu-central-1' s3_bucket: 'databucket' s3_prefix: 'metric' s3_partition_format: '%Y/%m/%d/%H/%M' ``` In this case, logs and traces would be stored in the following path format. ```console theme={null} metric/YYYY/MM/DD/HH/mm ``` Optionally along with `s3_partition_format` you can provide `s3_partition_timezone` as name from IANA Time Zone database to change default local timezone to custom, for example `UTC` or `Europe/London`. ## Base Path Configuration The `s3_base_prefix` option allows you to specify a root path inside the bucket that is not overridden by `resource_attrs_to_s3`. If provided, `s3_prefix` will be appended to this base path. ```yaml theme={null} exporters: awss3: s3uploader: region: 'eu-central-1' s3_bucket: 'databucket' s3_base_prefix: 'environment/prod' s3_prefix: 'metric' s3_partition_format: '%Y/%m/%d/%H/%M' ``` In this case, logs and traces would be stored in the following path format. ```console theme={null} environment/prod/metric/YYYY/MM/DD/HH/mm ``` ## Data routing based on resource attributes When `resource_attrs_to_s3/s3_bucket` or `resource_attrs_to_s3/s3_prefix` is configured, the S3 bucket and/or prefix are dynamically derived from specified resource attributes in your data. If the attribute values are unavailable, the bucket and prefix will fall back to the values defined in `s3uploader/s3_bucket` and `s3uploader/s3_prefix` respectively. ```yaml theme={null} exporters: awss3: s3uploader: region: 'eu-central-1' s3_bucket: 'databucket' s3_prefix: 'metric' s3_partition_format: '%Y/%m/%d/%H/%M' resource_attrs_to_s3: s3_bucket: "com.awss3.bucket" s3_prefix: "com.awss3.prefix" ``` In this case, metrics, logs and traces would be stored in the following path format examples: ```console theme={null} bucket1/prefix1/YYYY/MM/DD/HH/mm bucket2/foo-prefix/YYYY/MM/DD/HH/mm bucket3/prefix-bar/YYYY/MM/DD/HH/mm databucket/metric/YYYY/MM/DD/HH/mm ... ``` ## Base Path with Resource Attributes When using both `s3_base_prefix` and `resource_attrs_to_s3/s3_prefix`, the `s3_base_prefix` is always used while `s3_prefix` can be dynamically overridden by resource attributes. ```yaml theme={null} exporters: awss3: s3uploader: region: 'eu-central-1' s3_bucket: 'databucket' s3_base_prefix: 'environment/prod' s3_prefix: 'default-metric' s3_partition_format: '%Y/%m/%d/%H/%M' resource_attrs_to_s3: s3_prefix: "com.awss3.prefix" ``` In this configuration: * **Base Prefix**: `environment/prod` (always included) * **Prefix**: Dynamically set from resource attribute `com.awss3.prefix` if available, otherwise falls back to `default-metric` **Path format examples:** ```console theme={null} # When resource attribute com.awss3.prefix = "service-a/metrics" environment/prod/service-a/metrics/YYYY/MM/DD/HH/mm # When resource attribute com.awss3.prefix = "service-b/logs" environment/prod/service-b/logs/YYYY/MM/DD/HH/mm # When resource attribute is unavailable (fallback) environment/prod/default-metric/YYYY/MM/DD/HH/mm ``` This allows you to maintain consistent organizational structure (via base path) while dynamically routing different data types or services to specific subdirectories. ## Retry Standard is the default retryer implementation used by service clients. See the [retry](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/retry) package documentation for details on what errors are considered as retryable by the standard retryer implementation. See also the [aws-sdk-go reference](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/configure-retries-timeouts.html) for more information. ```yaml theme={null} exporters: awss3: s3uploader: region: 'eu-central-1' s3_bucket: 'databucket' s3_prefix: 'metric' retry_mode: "standard" retry_max_attempts: 5 retry_max_backoff: "30s" ``` ## AWS Credential Configuration This exporter follows default credential resolution for the [aws-sdk-go](https://docs.aws.amazon.com/sdk-for-go/api/index.html). Follow the [guidelines](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html) for the credential configuration. ### OpenTelemetry Collector Helm Chart for Kubernetes For example, when using OpenTelemetry Collector Helm Chart you could use `extraEnvs` in the values.yaml. ```yaml theme={null} extraEnvs: - name: AWS_ACCESS_KEY_ID value: "< YOUR AWS ACCESS KEY >" - name: AWS_SECRET_ACCESS_KEY value: "< YOUR AWS SECRET ACCESS KEY >" ``` ## Configuration ### Example Configuration ```yaml theme={null} receivers: nop: exporters: awss3: sending_queue: enabled: true num_consumers: 23 queue_size: 42 timeout: 8 s3uploader: region: 'us-east-1' s3_bucket: 'foo' s3_prefix: 'bar' s3_partition_format: 'year=%Y/month=%m/day=%d/hour=%H/minute=%M' s3_partition_timezone: 'Europe/London' endpoint: "http://endpoint.com" retry_on_failure: enabled: true randomization_factor: 0.3 processors: nop: service: pipelines: traces: receivers: [nop] processors: [nop] exporters: [awss3] ``` *** *Last generated: 2026-08-03* # Awsxray Source: https://otel.fyi/components/exporter/awsxrayexporter OpenTelemetry exporter for Awsxray # Awsxray Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@wangzlei](https://github.com/wangzlei), [@srprash](https://github.com/srprash) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/awsxrayexporter) ## Supported Telemetry ![Traces](https://img.shields.io/badge/traces-beta-orange) ## Overview This exporter converts OpenTelemetry spans to [AWS X-Ray Segment Documents](https://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html) and then sends them directly to X-Ray using the [PutTraceSegments](https://docs.aws.amazon.com/xray/latest/api/API_PutTraceSegments.html) API. ## Data Conversion Trace IDs and Span IDs are expected to be originally generated by either AWS API Gateway or AWS ALB and propagated by them using the `X-Amzn-Trace-Id` HTTP header. However, other generation sources are supported by replacing fully-random Trace IDs with X-Ray formatted Trace IDs where necessary: > AWS X-Ray IDs in binary are 128 bits, the same size as W3C Trace Context IDs but the string is formatted to > “1-\{8 digit hex}-\{24 digit hex}“. For example, The W3C format trace ID “4bf92f3577b34da6a3ce929d0e0e4736” is > converted to the X-Ray format trace ID “1-4bf92f35-77b34da6a3ce929d0e0e4736". The `http` object is populated when the `component` attribute value is `grpc` as well as `http`. Other synchronous call types should also result in the `http` object being populated. ## AWS Specific Attributes The following AWS-specific Span attributes are supported in addition to the standard names and values defined in the OpenTelemetry Semantic Conventions. | Attribute name | Notes and examples | Required? | | :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | | `aws.operation` | The name of the API action invoked against an AWS service or resource. | No | | `aws.account_id` | The AWS account number if accessing resource in different account. | No | | `aws.region` | The AWS region if accessing resource in different region from app. | No | | `aws.request_id` | AWS-generated unique identifier for the request. | No | | `aws.queue_url` | For operations on an Amazon SQS queue, the queue's URL. | No | | `aws.table_name` | For operations on a DynamoDB table, the name of the table. | No | | `aws.xray.annotations` | The attribute is a slice(list) attribute that contains each of the string keys. If found on the span, the `awsxrayexporter` will use them in addition to the `indexed_attributes` configuration field when categorizing which attributes to index. This can be configured with `"aws.xray.annotations"=["key1", "key2"]` (Java example: `span.setAttribute(stringArrayKey("aws.xray.annotations"), List.of("key1", "key2"))`) | No | Any of these values supplied are used to populate the `aws` object in addition to any relevant data supplied by the Span Resource object. X-Ray uses this data to generate inferred segments for the remote APIs. ## Exporter Configuration The following exporter configuration parameters are supported. They mirror and have the same effect as the comparable AWS X-Ray Daemon configuration values. | Name | Description | Default | | :--------------------------- | :----------------------------------------------------------------------------------------------------------------- | ------- | | `num_workers` | Maximum number of concurrent calls to AWS X-Ray to upload documents. | 8 | | `endpoint` | Optionally override the default X-Ray service endpoint. | | | `request_timeout_seconds` | Number of seconds before timing out a request. | 30 | | `max_retries` | Maximun number of attempts to post a batch before failing. | 2 | | `no_verify_ssl` | Enable or disable TLS certificate verification. | false | | `proxy_address` | Upload segments to AWS X-Ray through a proxy. | | | `region` | Send segments to AWS X-Ray service in a specific region. | | | `local_mode` | Local mode to skip EC2 instance metadata check. | false | | `resource_arn` | Amazon Resource Name (ARN) of the AWS resource running the collector. | | | `role_arn` | IAM role to upload segments to a different account. | | | `external_id` | Shared identitier used when assuming an IAM role in an external AWS account. | | | `indexed_attributes` | List of attribute names to be converted to X-Ray annotations. | | | `index_all_attributes` | Enable or disable conversion of all OpenTelemetry attributes to X-Ray annotations. | false | | `aws_log_groups` | List of log group names for CloudWatch. | \[] | | `telemetry.enabled` | Whether telemetry collection is enabled at all. | false | | `telemetry.include_metadata` | Whether to include metadata in the telemetry (InstanceID, Hostname, ResourceARN) | false | | `telemetry.contributors` | List of X-Ray component IDs contributing to the telemetry (ex. for multiple X-Ray receivers: awsxray/1, awsxray/2) | | | `telemetry.hostname` | Sets the Hostname included in the telemetry. | | | `telemetry.instance_id` | Sets the InstanceID included in the telemetry. | | | `telemetry.resource_arn` | Sets the Amazon Resource Name (ARN) included in the telemetry. | | ## Traces and logs correlation AWS X-Ray can be integrated with CloudWatch Logs to correlate traces with logs. For this integration to work, the X-Ray segments must have the AWS Property `cloudwatch_logs` set. This property is set using the AWS X-Ray exporter with the following values that are evaluated in this order: 1. `aws.log.group.arns` resource attribute. 2. `aws.log.group.names` resource attribute. 3. `aws_log_groups` configuration property. In the case of multiple values are defined, the value with higher precedence will be used to set the `cloudwatch_logs` AWS Property. `aws.log.group.arns` and `aws.log.group.names` are slice resource attributes that can be set programmatically. Alternatively those resource attributes can be set using the [`OTEL_RESOURCE_ATTRIBUTES` environment variable](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#specifying-resource-information-via-an-environment-variable). To set multiple log group names /log group arns, you can use `&` to separate them. For example, 3 log groups `log-group1`, `log-group2`, and `log-group3` are set in the following command: ``` export OTEL_RESOURCE_ATTRIBUTES="aws.log.group.names=log-group1&log-group2&log-group3" ``` ## AWS Credential Configuration This exporter follows default credential resolution for the [aws-sdk-go](https://docs.aws.amazon.com/sdk-for-go/api/index.html). Follow the [guidelines](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html) for the credential configuration. [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [AWS]: https://aws-otel.github.io/docs/getting-started/x-ray#configuring-the-aws-x-ray-exporter ## Configuration ### Example Configuration ```yaml theme={null} awsxray: awsxray/customname: region: eu-west-1 resource_arn: "arn:aws:ec2:us-east1:123456789:instance/i-293hiuhe0u" role_arn: "arn:aws:iam::123456789:role/monitoring-EKS-NodeInstanceRole" indexed_attributes: [ "indexed_attr_0", "indexed_attr_1" ] aws_log_groups: ["group1", "group2"] request_timeout_seconds: 120 ``` *** *Last generated: 2026-08-03* # Azureblob Source: https://otel.fyi/components/exporter/azureblobexporter OpenTelemetry exporter for Azureblob # Azureblob Exporter ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@hgaol](https://github.com/hgaol), [@MovieStoreGuy](https://github.com/MovieStoreGuy) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/azureblobexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-alpha-blue) ![Metrics](https://img.shields.io/badge/metrics-alpha-green) ![Traces](https://img.shields.io/badge/traces-alpha-orange) ## Overview ## Configuration The following settings are required: * url: Must be specified if auth type is not connection\_string. If auth type is connection\_string, it's optional or will be override by the auth.connection\_string. Azure storage account endpoint. This setting might be replaced with `endpoint` for future. e.g. https\://``.blob.core.windows.net/ * auth (no default): Authentication method for exporter to ingest data. * type (no default): Authentication type for exporter. supported values are: connection\_string, service\_principal, system\_managed\_identity, user\_managed\_identity and workload\_identity. * tenand\_id: Tenand Id for the client, only needed when type is service\_principal and workload\_identity. * client\_id: Client Id for the auth, only needed when type is service\_principal, user\_managed\_identity and workload\_identity. * client\_secret: Secret for the client, only needed when type is service\_principal. * connection\_string: Connection string to the endpoint. Only needed for connection\_string auth type. Once provided, it'll **override** the `url` parameter to the storage account. * federated\_token\_file: The path of the projected service account token file, only needed when type is workload\_identity. The following settings can be optionally configured and have default values: * container: container for metrics, logs and traces. A container organizes a set of blobs, similar to a directory in a file system. More details can refer [this](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction#containers). * metrics (default `metrics`): container to store metrics. default value is `metrics`. * logs (default `logs`): container to store logs. default value is `logs`. * traces (default `traces`): container to store traces. default value is `traces`. * blob\_name\_format: the final blob name will be blob\_name * template\_enabled (default `false`): enables Go template parsing for blob name formats. If parsing fails, it will not throw an error but will log a warning and continue formatting the blob name using other rules. * metrics\_format (default `2006/01/02/metrics_15_04_05.json`): blob name format. The date format follows constants in Golang, refer [here](https://go.dev/src/time/format.go). * logs\_format (default `2006/01/02/logs_15_04_05.json`): blob name format. * traces\_format (default `2006/01/02/traces_15_04_05.json`): blob name format. * timezone (default `""`): Timezone for blob name formatting. Local time is used if empty. Must be a valid IANA timezone identifier accepted by Golang's [`time.LoadLocation`](https://pkg.go.dev/time#LoadLocation), such as `UTC` or `America/New_York`. * serial\_num\_enabled (default `true`): toggles whether a random serial number is appended to the blob name. * serial\_num\_range (default `10000`): a range of random number to be appended after blob\_name. e.g. `blob_name_{serial_num}`. the number will be in `[0, serial_num_range)`. * serial\_num\_before\_extension (default `false`): places the serial number before the file extension if there is one. e.g `blob_name_{serial_num}.json` instead of `blob_name.json_{serial_num}` * time\_parser\_enabled (default `true`): controls whether the exporter interprets the format string as a Go time layout. When `false`, values such as `2006` or `15_04_05` are treated as literal text. * time\_parser\_ranges (default `nil`): limits time formatting to specific parts of the blob name. When not set (nil), the entire blob name is time-formatted if `time_parser_enabled` is `true`. Provide a list of character ranges like `["0-10", "15-25"]` to only apply time formatting within those positions. For example, if your blob name is `prefix/2006/01/02/file.json` and you set `time_parser_ranges: ["7-17"]`, only the `2006/01/02` portion will be replaced with actual date values, while `prefix/` and `/file.json` remain unchanged. This is helpful when your blob name contains patterns like `2006` that you want to keep as literal text. * compression (default `""`): sets the algorithm used to process the payload before uploading to Azure Blob Storage. Valid values are `gzip`, `zstd`, or no value set (uncompressed). The appropriate extension (`.gz` or `.zst`) is automatically appended to the blob name. * format (default `json`): `json` or `proto`. which present otel json or otel protobuf format, the file extension will be `json` or `pb`. * encodings (default using encoding specified in `format`, which is `json`): if specified, uses the encoding extension to encode telemetry data. Overrides format. * logs (default `nil`): encoding component id. * metrics (default `nil`): encoding component id. * traces (default `nil`): encoding component id. * append\_blob: configures append blob behavior. When enabled, telemetry data is appended to a single blob instead of creating new blobs. This can be useful for aggregating data or reducing the number of blobs created. * enabled (default `false`): determines whether to use append blob mode. * separator (default `\n`): string to insert between appended data blocks. * `retry_on_failure` * `enabled` (default = true) * `initial_interval` (default = 5s): Time to wait after the first failure before retrying; ignored if `enabled` is `false` * `max_interval` (default = 30s): Is the upper bound on backoff; ignored if `enabled` is `false` * `max_elapsed_time` (default = 120s): Is the maximum amount of time spent trying to send a batch; ignored if `enabled` is `false` ### Blob Name Templates When `template_enabled` is `true`, you can use Go templates in `metrics_format`, `logs_format`, and `traces_format` to create dynamic blob names based on telemetry data. The root object for the template is the telemetry data itself (`pmetric.Metrics`, `plog.Logs`, or `ptrace.Traces`). The following template functions are available: | Function | Description | Example | | ----------------------- | ------------------------------------------------------------- | ------------------------------------------------ | | `getResourceMetricAttr` | Gets a resource attribute from metrics data. | `{{ getResourceMetricAttr . 0 "service.name" }}` | | `getResourceLogAttr` | Gets a resource attribute from logs data. | `{{ getResourceLogAttr . 0 "service.name" }}` | | `getResourceSpanAttr` | Gets a resource attribute from traces data. | `{{ getResourceSpanAttr . 0 "service.name" }}` | | `getScopeMetricAttr` | Gets a scope attribute from metrics data. | `{{ getScopeMetricAttr . 0 0 "scope.name" }}` | | `getScopeLogAttr` | Gets a scope attribute from logs data. | `{{ getScopeLogAttr . 0 0 "scope.name" }}` | | `getScopeSpanAttr` | Gets a scope attribute from traces data. | `{{ getScopeSpanAttr . 0 0 "scope.name" }}` | | `getMetric` | Gets a metric object. You can chain to access its fields. | `{{ (getMetric . 0 0 0).Name }}` | | `getLogRecord` | Gets a log record object. You can chain to access its fields. | `{{ (getLogRecord . 0 0 0).TraceID }}` | | `getSpan` | Gets a span object. You can chain to access its fields. | `{{ (getSpan . 0 0 0).Name }}` | An example configuration is provided as follows: ```yaml theme={null} extensions: zpages: endpoint: localhost:55679 text_encoding: encoding: utf8 marshaling_separator: "\n" unmarshaling_separator: "\r?\n" exporter: azure_blob/1: url: "https://.blob.core.windows.net/" container: logs: "logs" metrics: "metrics" traces: "traces" blob_name_format: template_enabled: true metrics_format: `{{ getResourceMetricAttr . 0 "service.name" }}/2006/01/02/metrics.json` logs_format: `{{ getScopeLogAttr . 0 0 "scope.name" }}/2006/01/02/logs.json` traces_format: `{{ (getSpan . 0 0 0).Name }}/2006/01/02/traces.json` serial_num_enabled: true time_parser_enabled: true auth: type: "connection_string" connection_string: "DefaultEndpointsProtocol=https;AccountName=;AccountKey=;EndpointSuffix=core.windows.net" encodings: logs: text_encoding append_blob: enabled: true separator: "\n" compression: gzip # or "zstd" or leave unset for no compression ``` ### Append Blob When `append_blob` is enabled: * The exporter will create append blobs instead of block blobs * New data will be appended to existing blobs rather than creating new ones * The configured separator will be inserted between data blocks * If the blob doesn't exist, it will be created automatically ## Configuration ### Example Configuration ```yaml theme={null} azure_blob/sp: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "service_principal" tenant_id: "e4b5a5f0-3d6a-4b1c-9e2f-7c8a1b8f2c3d" client_id: "e4b5a5f0-3d6a-4b1c-9e2f-7c8a1b8f2c3d" client_secret: "e4b5a5f0-3d6a-4b1c-9e2f-7c8a1b8f2c3d" container: metrics: "test" logs: "test" traces: "test" azure_blob/smi: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "system_managed_identity" format: "proto" container: metrics: "test" logs: "test" traces: "test" azure_blob/umi: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "user_managed_identity" client_id: "e4b5a5f0-3d6a-4b1c-9e2f-7c8a1b8f2c3d" container: metrics: "test" logs: "test" traces: "test" azure_blob/conn-string: # for connection string auth, no need to specify url, because it's already included in connection string auth: type: "connection_string" connection_string: "DefaultEndpointsProtocol=https;AccountName=fakeaccount;AccountKey=ZmFrZWtleQ==;EndpointSuffix=core.windows.net" container: metrics: "test" logs: "test" traces: "test" azure_blob/wif: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "workload_identity" client_id: "e4b5a5f0-3d6a-4b1c-9e2f-7c8a1b8f2c3d" tenant_id: "e4b5a5f0-3d6a-4b1c-9e2f-7c8a1b8f2c3d" federated_token_file: "/path/to/federated/token/file" container: metrics: "test" logs: "test" traces: "test" azure_blob/queue: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "system_managed_identity" sending_queue: enabled: true num_consumers: 10 queue_size: 100 container: metrics: "test" logs: "test" traces: "test" azure_blob/err1: auth: type: "system_managed_identity" azure_blob/err2: auth: type: "connection_string" azure_blob/err3: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "service_principal" client_id: "e4b5a5f0-3d6a-4b1c-9e2f-7c8a1b8f2c3d" client_secret: "" azure_blob/err4: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "user_managed_identity" azure_blob/err5: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "system_managed_identity" format: "custom" azure_blob/err6: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "workload_identity" client_id: "e4b5a5f0-3d6a-4b1c-9e2f-7c8a1b8f2c3d" tenant_id: "e4b5a5f0-3d6a-4b1c-9e2f-7c8a1b8f2c3d" azure_blob/err-compression: url: "https://fakeaccount.blob.core.windows.net/" auth: type: "connection_string" connection_string: "DefaultEndpointsProtocol=https;AccountName=fakeaccount;AccountKey=ZmFrZWtleQ==;EndpointSuffix=core.windows.net" compression: "foo" ``` *** *Last generated: 2026-08-03* # Azuredataexplorer Source: https://otel.fyi/components/exporter/azuredataexplorerexporter OpenTelemetry exporter for Azuredataexplorer # Azuredataexplorer Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@ag-ramachandran](https://github.com/ag-ramachandran) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/azuredataexplorerexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-beta-blue) ![Metrics](https://img.shields.io/badge/metrics-beta-green) ![Traces](https://img.shields.io/badge/traces-beta-orange) ## Overview This exporter sends metrics, logs and trace data to [Azure Data Explorer](https://docs.microsoft.com/en-us/azure/data-explorer), [Azure Synapse Data Explorer](https://docs.microsoft.com/en-us/azure/synapse-analytics/data-explorer/data-explorer-overview) and [Real time analytics in Fabric](https://learn.microsoft.com/en-us/fabric/real-time-analytics/overview) ## Configuration The following settings are required: * `cluster_uri` (no default): The cluster name of the provisioned ADX cluster to ingest the data. One authentication method is required: * Service principal: * `application_id` (no default): The client id to connect to the cluster and ingest data. * `application_key` (no default): The cluster secret corresponding to the client id. * `tenant_id` (no default): The tenant id where the application\_id is referenced from. * Managed identity: * `managed_identity_id` (no default): The managed identity id to authenticate with. Set to "system" for system-assigned managed identity. Set the MI client ID (GUID) for user-assigned managed identity. * Default authentication: * `use_azure_auth` (default: false): Set to true to use the Azure [default authentication](https://learn.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication?tabs=bash#2-authenticate-with-azure). The following settings can be optionally configured and have default values: > Note that the database tables are expected to be created upfront before the exporter is in operation , the definition of these are in the section [Database and Table definition scripts](#database-and-table-definition-scripts) * `db_name` (default = "oteldb"): The ADX database where the tables are present to ingest the data. * `metrics_table_name` (default = OTELMetrics): The target table in the database `db_name` that stores exported metric data. * `logs_table_name` (default = OTELLogs): The target table in the database `db_name` that stores exported logs data. * `traces_table_name` (default = OTELTraces): The target table in the database `db_name` that stores exported traces data. Optionally the following table mappings can be specified if the data needs to be mapped to a different table on ADX. This uses json [table mapping](https://docs.microsoft.com/azure/data-explorer/kusto/management/mappings#json-mapping) that can be used to map [attributes](#attribute-mapping) to target tables * `metrics_table_json_mapping` (optional, no default): The table mapping name to be used for the table `db_name`.`metrics_table_name` * `logs_table_json_mapping` (optional, no default): The table mapping name to be used for the table `db_name`.`logs_table_name` * `traces_table_json_mapping` (optional, no default): The table mapping name to be used for the table `db_name`.`traces_table_name` * `ingestion_type` (possible values=`queued` / `managed`, default = queued): ADX ingest can happen in managed [streaming](https://docs.microsoft.com/azure/data-explorer/kusto/management/streamingingestionpolicy) or [queued](https://docs.microsoft.com/azure/data-explorer/kusto/management/batchingpolicy) modes. > Note: [Streaming ingestion](https://docs.microsoft.com/azure/data-explorer/ingest-data-streaming?tabs=azure-portal%2Ccsharp) has to be enabled on ADX \[configure the ADX cluster] in case of `streaming` option. Refer the query below to check if streaming is enabled ```kql theme={null} .show database policy streamingingestion ``` An example configuration is provided as follows: ```yaml theme={null} exporters: azuredataexplorer: # Kusto cluster uri cluster_uri: "https://CLUSTER.kusto.windows.net" # Client ID application_id: "f80da32c-108c-415c-a19e-643f461a677a" # The client secret for the client application_key: "xx-xx-xx-xx" # The tenant tenant_id: "21ff9e36-fbaa-43c8-98ba-00431ea10bc3" # A managed identity id to authenticate with. # Set to "system" for system-assigned managed identity. # Set the MI client ID (GUID) for user-assigned managed identity. managed_identity_id: "z80da32c-108c-415c-a19e-643f461a677a" # Database for the logs db_name: "oteldb" # Metric table name metrics_table_name: "OTELMetrics" # Log table name logs_table_name: "OTELLogs" # Traces table traces_table_name: "OTELTraces" # Metric table mapping name metrics_table_json_mapping: "otelmetrics_mapping" # Log table mapping name logs_table_json_mapping: "otellogs_mapping" # Traces mapping table traces_table_json_mapping: "oteltraces_mapping" # Type of ingestion managed or queued ingestion_type : "managed" #other available exporter helper options, see more here: https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md # timeout: 10s # sending_queue: # enabled: true # num_consumers: 2 # queue_size: 10 # retry_on_failure: # enabled: true # initial_interval: 10s # max_interval: 60s # max_elapsed_time: 10m ``` ## Attribute mapping This exporter maps OpenTelemetry [trace](https://opentelemetry.io/docs/reference/specification/trace/sdk/), [metric](https://opentelemetry.io/docs/reference/specification/metrics/sdk/) and [log](https://opentelemetry.io/docs/reference/specification/logs/data-model/) attributes to specific structures in the ADX tables. These can then be extended by usage of [update policies](https://docs.microsoft.com/azure/data-explorer/kusto/management/updatepolicy) in ADX if needed ### Traces | ADX Table column | Description / OpenTelemetry attribute | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | TraceId | A valid trace identifier is a 16-byte array with at least one non-zero byte. | | SpanId | A valid span identifier is an 8-byte array with at least one non-zero byte. | | ParentId | A parent spanId, for the current span | | SpanName | The span name | | SpanStatus | [Status Code](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status) of the Span. | | SpanStatusMessage | [Status Message](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status) of the Span | | SpanKind | [SpanKind](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spankind) describes the relationship between the Span, its parents, and its children in a Trace | | StartTime | A start timestamp | | EndTime | An end timestamp | | TraceAttributes | Custom metric [attributes](https://opentelemetry.io/docs/reference/specification/common/#attribute) set from the application. Also contains the [instrumentation scope](https://opentelemetry.io/docs/reference/specification/common/#attribute) name and version | | ResourceAttributes | The resource attributes JSON map as specified in open telemetry [resource semantics](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/) | | Events | A list of timestamped [Events](https://opentelemetry.io/docs/reference/specification/trace/api/#add-events) | | Links | A list of [Links](https://opentelemetry.io/docs/reference/specification/trace/api/#specifying-links) to other Spans | ### Metrics | ADX Table column | Description / OpenTelemetry attribute | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Timestamp | The timestamp of the datapoint | | MetricName | The name of the datapoint | | MetricType | The type / datapoint type of the metric (e.g. Sum, Histogram, Gauge etc.) | | MetricUnit | Unit of measure of the metric | | MetricDescription | Description about the metric | | MetricValue | The metric value measured for the datapoint | | MetricAttributes | Custom metric [attributes](https://opentelemetry.io/docs/reference/specification/common/#attribute) set from the application. Also contains the [instrumentation scope](https://opentelemetry.io/docs/reference/specification/common/#attribute) name and version | | Host | The host.name extracted from [Host resource semantics](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/host/). If empty , the hostname of the exporter is used | | ResourceAttributes | The resource attributes JSON map as specified in open telemetry [resource semantics](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/) | ### Logs | ADX Table column | Description / OpenTelemetry attribute | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Timestamp | The timestamp of the datapoint | | ObservedTimestamp | Time when the event was observed. | | TraceId | Request trace id. | | SpanId | Request span id. | | SeverityText | The severity text (also known as log level) | | SeverityNumber | [Numerical value](https://opentelemetry.io/docs/reference/specification/logs/data-model/#field-severitynumber) of the severity. | | Body | The body of the log record. | | LogsAttributes | Custom metric [attributes](https://opentelemetry.io/docs/reference/specification/common/#attribute) set from the application. Also contains the [instrumentation scope](https://opentelemetry.io/docs/reference/specification/common/#attribute) name and version | | ResourceAttributes | The resource attributes JSON map as specified in open telemetry [resource semantics](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/) | ### Database and Table definition scripts The following tables need to be created in the database specified in the configuration. ```kql theme={null} .create-merge table (Timestamp:datetime, ObservedTimestamp:datetime, TraceID:string, SpanID:string, SeverityText:string, SeverityNumber:int, Body:string, ResourceAttributes:dynamic, LogsAttributes:dynamic) .create-merge table (Timestamp:datetime, MetricName:string, MetricType:string, MetricUnit:string, MetricDescription:string, MetricValue:real, Host:string, ResourceAttributes:dynamic,MetricAttributes:dynamic) .create-merge table (TraceID:string, SpanID:string, ParentID:string, SpanName:string, SpanStatus:string, SpanKind:string, StartTime:datetime, EndTime:datetime, ResourceAttributes:dynamic, TraceAttributes:dynamic, Events:dynamic, Links:dynamic) // This is an optional column to store the status code and message as a dynamic field. This augments the status field with Status code and status message .alter-merge table (SpanStatusMessage:string) //Enable streaming ingestion( for managed streaming) for the created tables using .alter table policy streamingingestion enable ``` ### Optional configurations/Enhancements suggestions * Using update policies , the collected data can further be processed as per application need. The following is an example where histogram metrics are exported to a histo specific table (buckets and aggregates) ```kql theme={null} .create table HistoBucketData (Timestamp: datetime, MetricName: string , MetricType: string , Value: double, LE: double, Host: string , ResourceAttributes: dynamic, MetricAttributes: dynamic ) .create function with ( docstring = "Histo bucket processing function", folder = "UpdatePolicyFunctions") ExtractHistoColumns() { OTELMetrics | where MetricType == 'Histogram' and MetricName has "_bucket" | extend f=parse_json(MetricAttributes) | extend le=todouble(f.le) | extend M_name=replace_string(MetricName, '_bucket','') | project Timestamp, MetricName=M_name, MetricType, MetricValue, LE=le, Host, ResourceAttributes, MetricAttributes } .alter table HistoBucketData policy update @'[{ "IsEnabled": true, "Source": "OTELMetrics","Query": "ExtractHistoColumns()", "IsTransactional": false, "PropagateIngestionProperties": false}]' //Below code creates a table which only contains count and sum values of Histogram metric type and attaches an update policy to it .create table HistoData (Timestamp: datetime, MetricName: string , MetricType: string , Count: double, Sum: double, Host: string , ResourceAttributes: dynamic, MetricAttributes: dynamic) .create function with ( docstring = "Histo sum count processing function", folder = "UpdatePolicyFunctions") ExtractHistoCountColumns() { OTELMetrics | where MetricType =='Histogram' | where MetricName has "_count" | extend Count=MetricValue | extend M_name=replace_string(MetricName, '_bucket','') | join kind=inner (OTELMetrics | where MetricType =='Histogram' | where MetricName has "_sum" | project Sum = MetricValue , Timestamp) on Timestamp | project Timestamp, MetricName=M_name, MetricType, Count, Sum, Host, ResourceAttributes, MetricAttributes } .alter table HistoData policy update @'[{ "IsEnabled": true, "Source": "RawMetricsData","Query": "ExtractHistoCountColumns()", "IsTransactional": false, "PropagateIngestionProperties": false}]' ``` ### OpenTelemetry Exporter Helper Configurations The ADX exporter now includes support for OpenTelemetry exporter helper configurations. This feature allows you to leverage the exporter helper capabilities(retries, timeout etc.) provided natively by Otel. Read more about the [exporterhelper](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md). Please note that this configuration is not enabled by default. To utilize the OpenTelemetry exporter helper, you will need to add it manually to the configuration. #### Example Configuration ````yaml theme={null} timeout: 10s sending_queue: enabled: true num_consumers: 2 queue_size: 10 retry_on_failure: enabled: true initial_interval: 10s max_interval: 60s max_elapsed_time: 10m ## Configuration ### Example Configuration ```yaml azuredataexplorer: # Kusto cluster uri cluster_uri: "https://CLUSTER.kusto.windows.net" # Client ID application_id: "f80da32c-108c-415c-a19e-643f461a677a" # The client secret for the client application_key: "xx-xx-xx-xx" # The tenant tenant_id: "21ff9e36-fbaa-43c8-98ba-00431ea10bc3" # database for the logs db_name: "oteldb" # raw metric table name metrics_table_name: "OTELMetrics" # raw log table name logs_table_name: "OTELLogs" # raw traces table traces_table_name: "OTELTraces" # type of ingestion managed or queued ingestion_type: "managed" azuredataexplorer/2: # Kusto cluster uri cluster_uri: "https://CLUSTER.kusto.windows.net" # Client ID application_id: "" # The client secret for the client application_key: "xx-xx-xx-xx" # The tenant tenant_id: "21ff9e36-fbaa-43c8-98ba-00431ea10bc3" # database for the logs db_name: "oteldb" # raw metric table name metrics_table_name: "OTELMetrics" # raw log table name logs_table_name: "OTELLogs" # raw traces table traces_table_name: "OTELTraces" # type of ingestion managed or queued ingestion_type: "" # Additional config for error tests azuredataexplorer/3: # Kusto cluster uri cluster_uri: "https://CLUSTER.kusto.windows.net" # Client ID application_id: "f80da32c-108c-415c-a19e-643f461a677a" # The client secret for the client application_key: "xx-xx-xx-xx" # The tenant tenant_id: "21ff9e36-fbaa-43c8-98ba-00431ea10bc3" # database for the logs db_name: "oteldb" # raw metric table name metrics_table_name: "OTELMetrics" # raw log table name logs_table_name: "OTELLogs" # raw traces table traces_table_name: "OTELTraces" # type of ingestion is invalid ingestion_type: "streaming" azuredataexplorer/4: # Kusto cluster uri cluster_uri: "https://CLUSTER.kusto.windows.net" # managed identity id managed_identity_id: "bf61f0ec-1f01-11ee-be56-0242ac120002" # database for the logs db_name: "oteldb" # raw metric table name metrics_table_name: "OTELMetrics" # raw log table name logs_table_name: "OTELLogs" # raw traces table traces_table_name: "OTELTraces" # type of ingestion managed or queued ingestion_type: "managed" azuredataexplorer/5: # Kusto cluster uri cluster_uri: "https://CLUSTER.kusto.windows.net" # managed identity id managed_identity_id: "managed_identity_id" # database for the logs db_name: "oteldb" # raw metric table name metrics_table_name: "OTELMetrics" # raw log table name logs_table_name: "OTELLogs" # raw traces table traces_table_name: "OTELTraces" # type of ingestion managed or queued ingestion_type: "managed" azuredataexplorer/6: # Kusto cluster uri cluster_uri: "https://CLUSTER.kusto.windows.net" # managed identity id managed_identity_id: "system" # database for the logs db_name: "oteldb" # raw metric table name metrics_table_name: "OTELMetrics" # raw log table name logs_table_name: "OTELLogs" # raw traces table traces_table_name: "OTELTraces" # type of ingestion managed or queued ingestion_type: "managed" azuredataexplorer/7: # Kusto cluster uri cluster_uri: "" # managed identity id managed_identity_id: "system" # database for the logs db_name: "oteldb" # raw metric table name metrics_table_name: "OTELMetrics" # raw log table name logs_table_name: "OTELLogs" # raw traces table traces_table_name: "OTELTraces" # type of ingestion managed or queued ingestion_type: "managed" azuredataexplorer/8: # Kusto cluster uri cluster_uri: "https://CLUSTER.kusto.windows.net" # Client ID application_id: "f80da32c-108c-415c-a19e-643f461a677a" # The client secret for the client application_key: "xx-xx-xx-xx" # The tenant tenant_id: "21ff9e36-fbaa-43c8-98ba-00431ea10bc3" # database for the logs db_name: "oteldb" # raw metric table name metrics_table_name: "OTELMetrics" # raw log table name logs_table_name: "OTELLogs" # raw traces table traces_table_name: "OTELTraces" # type of ingestion managed or queued ingestion_type: "managed" #export helper options timeout: 10s sending_queue: enabled: true num_consumers: 2 queue_size: 10 retry_on_failure: enabled: true initial_interval: 10s max_interval: 60s max_elapsed_time: 10m azuredataexplorer/9: # Kusto cluster uri cluster_uri: "https://CLUSTER.kusto.windows.net" # weather to use the default azure auth use_azure_auth: true ```` *** *Last generated: 2026-08-03* # Azuremonitor Source: https://otel.fyi/components/exporter/azuremonitorexporter OpenTelemetry exporter for Azuremonitor # Azuremonitor Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@pcwiese](https://github.com/pcwiese), [@hgaol](https://github.com/hgaol) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/azuremonitorexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-beta-blue) ![Metrics](https://img.shields.io/badge/metrics-beta-green) ![Traces](https://img.shields.io/badge/traces-beta-orange) ## Overview This exporter sends logs, traces and metrics to [Azure Monitor](https://docs.microsoft.com/azure/azure-monitor/). ## Configuration To configure the Azure Monitor Exporter, you must specify one of the following settings: * `connection_string` (recommended): The Azure Application Insights Connection String is required to send telemetry data to the monitoring service. It is the recommended method for configuring the exporter, aligning with Azure Monitor's best practices. If you need guidance on creating Azure resources, please refer to the step-by-step guides to [Create an Application Insights resource](https://docs.microsoft.com/azure/azure-monitor/app/create-new-resource) and [find your connection string](https://docs.microsoft.com/azure/azure-monitor/app/sdk-connection-string?tabs=net#find-your-connection-string). * `instrumentation_key`: Application Insights instrumentation key, which can be found in the Application Insights resource in the Azure Portal. While it is currently supported, its use is discouraged and it is slated for deprecation. It is highly encouraged to use the `connection_string` setting for new configurations and migrate existing configurations to use the `connection_string` as soon as possible. ### Environment Variable Support In addition to the above configuration options, the Azure Monitor Exporter now supports setting the connection string via the `APPLICATIONINSIGHTS_CONNECTION_STRING` environment variable. This method is particularly useful for cloud or containerized environments where managing configuration through environment variables is standard practice. **Note:** If both the environment variable and the `connection_string` configuration option are provided, the environment variable takes precedence. ### Configuration Options **Important**: Only one of `connection_string` or `instrumentation_key` should be specified in your configuration. If both are provided, `connection_string` will be used as the priority setting. The following settings can be optionally configured: * `endpoint` (default = `https://dc.services.visualstudio.com/v2/track`): The endpoint URL where data will be submitted. While this option remains available, it is important to note that the use of the `connection_string` is recommended, as it encompasses the endpoint information. The direct configuration of the `endpoint` is considered to be on a deprecation path. * `maxbatchsize` (default = 1024): The maximum number of telemetry items that can be submitted in each request. If this many items are buffered, the buffer will be flushed before `maxbatchinterval` expires. * `maxbatchinterval` (default = 10s): The maximum time to wait before sending a batch of telemetry. * `spaneventsenabled` (default = false): Enables export of span events. * `sending_queue` * `enabled` (default = false) * `num_consumers` (default = 10): Number of consumers that dequeue batches; ignored if `enabled` is `false` * `queue_size` (default = 1000): Maximum number of batches kept in memory before data; ignored if `enabled` is `false` * `storage` (default = `none`): When set, enables persistence and uses the component specified as a storage extension for the persistent queue * `shutdown_timeout` (default = 1s): Timeout to wait for graceful shutdown. Once exceeded, the component will shut down forcibly, dropping any element in queue. * `custom_events_enabled` (default = `false`): Enables export log record to custom events when there's attribute `microsoft.custom_event.name` or `APPLICATION_INSIGHTS_EVENT_MARKER_ATTRIBUTE`. ### Tag mappings (alpha) The optional `tag_mappings:` block overrides how selected Application Insights envelope tags are populated from OpenTelemetry resource attributes. Each field takes an ordered list of sources; the first one that resolves to a non-empty string wins. A source entry is interpreted as: * a **resource attribute key** when it contains a `.` (e.g. `service.instance.id`, `host.name`) * a **string literal terminal default** when it does not contain a `.` (e.g. `unknown-instance`) Defaults preserve the historical hardcoded behavior — when a field is unset, zero-config users see no change. | Mapping key | Application Insights tag | Default | | --------------------- | ------------------------ | ----------------------- | | `cloud_role_instance` | `ai.cloud.roleInstance` | `[service.instance.id]` | | `application_version` | `ai.application.ver` | `[service.version]` | > The `cloud_role_name` tag (`ai.cloud.role`) is not yet configurable; its hardcoded `service.namespace`/`service.name` concatenation continues to apply. Example — Azure Container Apps, where `service.instance.id` is set to a random uuid and operators want the revision/replica hostname instead: ```yaml theme={null} exporters: azuremonitor: connection_string: "InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://ingestion.azuremonitor.com/" tag_mappings: cloud_role_instance: [host.name, service.instance.id, unknown-instance] ``` Validation rejects an explicitly empty array (`cloud_role_instance: []`) at startup. The feature is alpha and the schema may evolve. Example: ```yaml theme={null} # It is highly recommended to use the connection string which includes the InstrumentationKey and IngestionEndpoint # This is the preferred method over using 'instrumentation_key' alone. exporters: azuremonitor: connection_string: "InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://ingestion.azuremonitor.com/" ``` (or) ```yaml theme={null} # Legacy Configuration: # The use of 'instrumentation_key' alone is not recommended and will be deprecated in the future. It is advised to use the connection_string instead. # This example is provided primarily for existing configurations that have not yet transitioned to the connection string. exporters: azuremonitor: instrumentation_key: b1cd0778-85fc-4677-a3fa-79d3c23e0efd ``` Example using environment variable: Ensure `APPLICATIONINSIGHTS_CONNECTION_STRING` is set in your environment, then configure the exporter without specifying a connection string or instrumentation key: ```yaml theme={null} exporters: azuremonitor: ``` ## Attribute mapping ### Traces This exporter maps OpenTelemetry trace data to [Application Insights data model](https://docs.microsoft.com/azure/azure-monitor/app/data-model-dependency-telemetry) using the following schema. The OpenTelemetry SpanKind determines the Application Insights telemetry type. | OpenTelemetry SpanKind | Application Insights telemetry type | | -------------------------------- | ----------------------------------- | | `CLIENT`, `PRODUCER`, `INTERNAL` | Dependency | | `SERVER`, `CONSUMER` | Request | The exporter follows the semantic conventions to fill the Application Insights specific telemetry properties. The following table shows a basic mapping. | Application Insights property | OpenTelemetry attribute | Default | | ----------------------------- | ----------------------------------------------------- | --------- | | Request.Name | `http.method`, `http.route` or `rpc.system` | span name | | Request.Url | `http.scheme`, `http.host`, `http.target` | | | Request.Source | `http.client_ip` or `net.peer.name` | | | Request.ResponseCode | `http.status_code` or `status_code` | `"0"` | | Request.Success | `http.status_code` or `status_code` | `true` | | Dependency.Name | `http.method`, `http.route` | span name | | Dependency.Data | `http.url` or span name or `db.statement` | | | Dependency.Type | `"HTTP"` or `rpc.system` or `db.system` or `"InProc"` | | | Dependency.Target | host of `http.url` or `net.peer.name` | | | Dependency.ResultCode | `http.status_code` or `status_code` | `"0"` | | Dependency.Success | `http.status_code` or `status_code` | `true` | The exact mapping can be found in [trace\_to\_envelope.go](trace_to_envelope.go). All attributes are also mapped to custom properties if they are booleans or strings and to custom measurements if they are ints or doubles. All links are mapped to property `_MS.links` with JSON array string. #### Span Events Span events are optionally saved to the Application Insights `traces` table. Exception events are saved to the Application Insights `exception` table. ### Logs This exporter saves log records to Application Insights `traces` table. [TraceId](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-traceid) is mapped to `operation_id` column and [SpanId](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-spanid) is mapped to `operation_parentId` column. #### Custom Events When `custom_events_enabled` = `true`, azure monitor exporter will export log record to custom events when there's attribute `microsoft.custom_event.name` or `APPLICATION_INSIGHTS_EVENT_MARKER_ATTRIBUTE`. #### Exceptions This exporter saves exception records to Application Insights `exceptions` table when log records indicate an exception [specification](https://opentelemetry.io/docs/specs/otel/trace/exceptions/). When `exception_events_enabled` = `true`, azure monitor exporter will export log records to exceptions when either one of `exception.message` or `exception.type` attributes are set. ### Metrics This exporter saves metrics to Application Insights `customMetrics` table. ## AAD/Entra Authentication Details of how to use the Azure Monitor Exporter with AAD/Entra based identities can be found in the [Authentication](AUTHENTICATION.md) page. ## Configuration ### Example Configuration ```yaml theme={null} azuremonitor: azuremonitor/2: # endpoint is the uri used to communicate with Azure Monitor endpoint: "https://dc.services.visualstudio.com/v2/track" # instrumentation_key is the unique identifier for your Application Insights resource instrumentation_key: 00000000-0000-0000-0000-000000000000 # connection string specifies Application Insights InstrumentationKey and IngestionEndpoint connection_string: InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://ingestion.azuremonitor.com/ # maxbatchsize is the maximum number of items that can be queued before calling to the configured endpoint maxbatchsize: 100 # maxbatchinterval is the maximum time to wait before calling the configured endpoint. maxbatchinterval: 10s # shutdown channel timeout shutdown_timeout: 2s sending_queue: # queue_size is the maximum number of items that can be queued before dropping data queue_size: 1000 enabled: true num_consumers: 10 storage: disk azuremonitor/tag_mappings: connection_string: InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://ingestion.azuremonitor.com/ tag_mappings: cloud_role_instance: [host.name, service.instance.id, unknown-instance] application_version: [service.version] disk/3: ``` *** *Last generated: 2026-08-03* # Bmchelix Source: https://otel.fyi/components/exporter/bmchelixexporter OpenTelemetry exporter for Bmchelix # Bmchelix Exporter ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@bertysentry](https://github.com/bertysentry), [@NassimBtk](https://github.com/NassimBtk), [@MovieStoreGuy](https://github.com/MovieStoreGuy) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/bmchelixexporter) ## Supported Telemetry ![Metrics](https://img.shields.io/badge/metrics-alpha-green) ## Overview > **Note:** The exporter type has been renamed from `bmchelix` to `bmc_helix` to follow the > snake\_case naming convention. The old name `bmchelix` is preserved as a deprecated alias and > will continue to work, but a deprecation warning will be logged at startup. Please update your > configuration to use `bmc_helix:`. This exporter supports sending metrics to [BMC Helix Operations Management](https://docs.bmc.com/xwiki/bin/view/IT-Operations-Management/Operations-Management/BMC-Helix-Operations-Management/bhom261/Getting-started/Product-overview/) through its [metric ingestion REST API](https://docs.bmc.com/docs/helixoperationsmanagement/244/en/metric-operation-management-endpoints-in-the-rest-api-1392780044.html). ## Getting Started The following settings are **required**: * `endpoint`: is the *BMC Helix Portal URL* of your environment, at **onbmc.com** for a BMC Helix SaaS tenant (e.g., `https://company.onbmc.com`), or your own Helix Portal URL for an on-prem instance. * `api_key`: API key to authenticate the exporter. Connect to BMC Helix Operations Management, go to the Administration > Repository page, and click on the Copy API Key button to get your API Key. Alternatively, it is recommended to create and use a dedicated [authentication key for external integration](https://docs.bmc.com/xwiki/bin/view/Helix-Common-Services/BMC-Helix-Portal/BMC-Helix-Portal/helixportal261/Administering/Using-API-keys-for-external-integrations/). Example: ```yaml theme={null} exporters: bmc_helix/helix1: endpoint: https://company.onbmc.com api_key: sending_queue: batch: ``` ### Optional Settings The following settings can be **optionally configured**: * `timeout`: (default = `10s`) Timeout for requests made to the BMC Helix. * `enrich_metric_with_attributes`: (default = `true`) When enabled, creates enriched metrics by appending datapoint attribute values to the metric name. This provides more detailed identification in BMC Helix Operations Management but increases metric cardinality. Set to `false` to reduce the number of unique metric series. * `retry_on_failure` [details here](https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/exporterhelper#configuration) * `enabled` (default = true) * `initial_interval` (default = 5s) Time to wait after the first failure before retrying; ignored if `enabled` is false. * `max_interval` (default = 30s) The upper bound on backoff; ignored if `enabled` is false. * `max_elapsed_time` (default = 300s) The maximum amount of time spent trying to send a batch; ignored if `enabled` is false. If set to 0, the retries are never stopped. Example: ```yaml theme={null} exporters: bmc_helix/helix2: endpoint: https://company.onbmc.com api_key: timeout: 20s enrich_metric_with_attributes: false sending_queue: batch: retry_on_failure: enabled: true initial_interval: 5s max_interval: 1m max_elapsed_time: 8m ``` *** ## Setting Required Attributes for Metrics To ensure metrics are correctly populated in BMC Helix, the following attributes must be set either at the *Resource* level, or at the *Metric* level: * `entityName`: Unique identifier for the entity. Used as display name if `instanceName` is missing. * `entityTypeId`: Type identifier for the entity. * `instanceName`: Display name of the entity. > **Note:** If `entityName` or `entityTypeId` is missing, the metric will not be exported. To ensure the necessary attributes are present, it is recommended to leverage the [transform processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor) with [OTTL](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl), and include it in the configuration of the telemetry pipeline. The minimal pipeline most often looks like: `OTEL metrics --> (memory limit) --> transform processor --> bmc_helix exporter`. ### Transformer Example for Hardware Metrics You can use the following OpenTelemetry Transformation Language (OTTL) configuration to map these attributes dynamically: ```yaml theme={null} transform/hw_to_helix: # Apply transformations to all metrics metric_statements: - context: datapoint statements: # Create a new attribute 'entityName' with the value of 'id' - set(attributes["entityName"], attributes["id"]) where attributes["id"] != nil # Create a new attribute 'instanceName' with the value of 'name' - set(attributes["instanceName"], attributes["name"]) where attributes["name"] != nil - context: datapoint conditions: - IsMatch(metric.name, ".*\\.agent\\..*") statements: - set(attributes["entityName"], attributes["host.id"]) where attributes["host.id"] != nil - set(attributes["instanceName"], attributes["service.name"]) where attributes["service.name"] != nil - set(attributes["entityTypeId"], "agent") - context: datapoint statements: # Mapping entityTypeId based on metric names and attributes - set(attributes["entityTypeId"], "connector") where IsMatch(metric.name, ".*\\.connector\\..*") - set(attributes["entityTypeId"], "host") where IsMatch(metric.name, ".*\\.host\\..*") or attributes["hw.type"] == "host" - set(attributes["entityTypeId"], "battery") where IsMatch(metric.name, "hw\\.battery\\..*") or attributes["hw.type"] == "battery" - set(attributes["entityTypeId"], "blade") where IsMatch(metric.name, "hw\\.blade\\..*") or attributes["hw.type"] == "blade" - set(attributes["entityTypeId"], "cpu") where IsMatch(metric.name, "hw\\.cpu\\..*") or attributes["hw.type"] == "cpu" - set(attributes["entityTypeId"], "disk_controller") where IsMatch(metric.name, "hw\\.disk_controller\\..*") or attributes["hw.type"] == "disk_controller" - set(attributes["entityTypeId"], "enclosure") where IsMatch(metric.name, "hw\\.enclosure\\..*") or attributes["hw.type"] == "enclosure" - set(attributes["entityTypeId"], "fan") where IsMatch(metric.name, "hw\\.fan\\..*") or attributes["hw.type"] == "fan" - set(attributes["entityTypeId"], "gpu") where IsMatch(metric.name, "hw\\.gpu\\..*") or attributes["hw.type"] == "gpu" - set(attributes["entityTypeId"], "led") where IsMatch(metric.name, "hw\\.led\\..*") or attributes["hw.type"] == "led" - set(attributes["entityTypeId"], "logical_disk") where IsMatch(metric.name, "hw\\.logical_disk\\..*") or attributes["hw.type"] == "logical_disk" - set(attributes["entityTypeId"], "lun") where IsMatch(metric.name, "hw\\.lun\\..*") or attributes["hw.type"] == "lun" - set(attributes["entityTypeId"], "memory") where IsMatch(metric.name, "hw\\.memory\\..*") or attributes["hw.type"] == "memory" - set(attributes["entityTypeId"], "network") where IsMatch(metric.name, "hw\\.network\\..*") or attributes["hw.type"] == "network" - set(attributes["entityTypeId"], "other_device") where IsMatch(metric.name, "hw\\.other_device\\..*") or attributes["hw.type"] == "other_device" - set(attributes["entityTypeId"], "physical_disk") where IsMatch(metric.name, "hw\\.physical_disk\\..*") or attributes["hw.type"] == "physical_disk" - set(attributes["entityTypeId"], "power_supply") where IsMatch(metric.name, "hw\\.power_supply\\..*") or attributes["hw.type"] == "power_supply" - set(attributes["entityTypeId"], "robotics") where IsMatch(metric.name, "hw\\.robotics\\..*") or attributes["hw.type"] == "robotics" - set(attributes["entityTypeId"], "tape_drive") where IsMatch(metric.name, "hw\\.tape_drive\\..*") or attributes["hw.type"] == "tape_drive" - set(attributes["entityTypeId"], "temperature") where IsMatch(metric.name, "hw\\.temperature.*") or attributes["hw.type"] == "temperature" - set(attributes["entityTypeId"], "vm") where IsMatch(metric.name, "hw\\.vm\\..*") or attributes["hw.type"] == "vm" - set(attributes["entityTypeId"], "voltage") where IsMatch(metric.name, "hw\\.voltage.*") or attributes["hw.type"] == "voltage" ``` This transformer dynamically sets the attributes required for BMC Helix based on metric names and resource attributes. ## Configuration ### Example Configuration ```yaml theme={null} bmc_helix/helix1: endpoint: https://helix1:8080 api_key: api_key enrich_metric_with_attributes: true bmc_helix/helix2: endpoint: https://helix2:8080 api_key: api_key timeout: 20s enrich_metric_with_attributes: true retry_on_failure: enabled: true initial_interval: 5s max_interval: 1m max_elapsed_time: 8m ``` *** *Last generated: 2026-08-03* # Cassandra Source: https://otel.fyi/components/exporter/cassandraexporter OpenTelemetry exporter for Cassandra # Cassandra Exporter ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@atoulme](https://github.com/atoulme), [@emreyalvac](https://github.com/emreyalvac) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/cassandraexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-alpha-blue) ![Traces](https://img.shields.io/badge/traces-alpha-orange) ## Overview ## Configuration options The following settings can be optionally configured: * `dsn` The Cassandra server DSN (Data Source Name), for example `127.0.0.1`. reference: [github.com/apache/cassandra-gocql-driver/v2](https://github.com/apache/cassandra-gocql-driver/) * `port` (default = 9042): The Cassandra server port * `timeout` (default = 10s): The Cassandra server connection timeout * `keyspace` (default = otel): The keyspace name. * `trace_table` (default = otel\_spans): The table name for traces. * `replication` (default = class: SimpleStrategy, replication\_factor: 1): The strategy of replication. [https://cassandra.apache.org/doc/4.1/cassandra/architecture/dynamo.html#replication-strategy](https://cassandra.apache.org/doc/4.1/cassandra/architecture/dynamo.html#replication-strategy) * `compression` (default = LZ4Compressor): [https://cassandra.apache.org/doc/4.0/cassandra/operating/compression.html](https://cassandra.apache.org/doc/4.0/cassandra/operating/compression.html) * `auth` (default = username: "", password: "") Authorization for the Cassandra. ## Example ```yaml theme={null} exporters: cassandra: dsn: 127.0.0.1 port: 9042 timeout: 10s keyspace: "otel" trace_table: "otel_spans" replication: class: "SimpleStrategy" replication_factor: 1 compression: algorithm: "ZstdCompressor" auth: username: "your-username" password: "your-password" ``` ## Configuration ### Example Configuration ```yaml theme={null} cassandra: dsn: 127.0.0.1 keyspace: "otel" trace_table: "otel_spans" timeout: 10s logs_table: "otel_logs" replication: class: "SimpleStrategy" replication_factor: 1 compression: algorithm: "LZ4Compressor" ``` *** *Last generated: 2026-08-03* # ClickHouse Source: https://otel.fyi/components/exporter/clickhouseexporter OpenTelemetry exporter for ClickHouse # ClickHouse Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@hanjm](https://github.com/hanjm), [@Frapschen](https://github.com/Frapschen), [@SpencerTorres](https://github.com/SpencerTorres) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/clickhouseexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-beta-blue) ![Metrics](https://img.shields.io/badge/metrics-alpha-green) ![Traces](https://img.shields.io/badge/traces-beta-orange) ## Overview This exporter supports sending OpenTelemetry data to [ClickHouse](https://clickhouse.com/). > ClickHouse is an open-source, high performance columnar OLAP database management system for real-time analytics using > SQL. > Throughput can be measured in rows per second or megabytes per second. > If the data is placed in the page cache, a query that is not too complex is processed on modern hardware at a speed of > approximately 2-10 GB/s of uncompressed data on a single server. > If 10 bytes of columns are extracted, the speed is expected to be around 100-200 million rows per second. Note: **Batching Recommendation** For optimal performance, [ClickHouse recommends](https://clickhouse.com/docs/en/introduction/performance/#performance-when-inserting-data) inserting data in large batches: > We recommend inserting data in packets of at least 5000 rows, or no more than a single request per second. When inserting to a MergeTree table from a tab-separated dump, the insertion speed can be from 50 to 200 MB/s. To achieve this natively, enable batching within the exporter's `sending_queue` configuration. You do not need to add the external `batch` processor to your collector pipeline. Relying on the exporter's internal batching is the recommended approach to avoid data-loss issues associated with the external processor. Enable it by adding a `batch` block inside `sending_queue`: ```yaml theme={null} exporters: clickhouse: endpoint: tcp://127.0.0.1:9000 sending_queue: # num_consumers controls how many batches are inserted into ClickHouse # concurrently. num_consumers: 10 batch: min_size: 5000 # rows per INSERT (items sizer); tune to your workload flush_timeout: 5s # flush a partial batch after this delay ``` If you are migrating from a pipeline that uses the standalone `batch` processor, remove `batch` from the pipeline's `processors` list and configure `sending_queue.batch` instead. For durability across restarts, also set `sending_queue.storage` to a [storage extension](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/storage/filestorage) so queued batches survive a crash (at-least-once delivery). ## Visualization Tools #### Official ClickHouse Plugin for Grafana The official [ClickHouse Datasource for Grafana](https://grafana.com/grafana/plugins/grafana-clickhouse-datasource/) contains features that integrate directly with this exporter. You can view associated [logs](https://clickhouse.com/docs/en/integrations/grafana/query-builder#logs) and [traces](https://clickhouse.com/docs/en/integrations/grafana/query-builder#traces), as well as visualize other queries such as tables and time series graphs. Learn [how to configure the OpenTelemetry integration](https://clickhouse.com/docs/en/integrations/grafana/config#opentelemetry). #### Altinity's ClickHouse Plugin for Grafana If the official plugin doesn't meet your needs, you can try the [Altinity plugin for ClickHouse](https://grafana.com/grafana/plugins/vertamedia-clickhouse-datasource/), which also supports a wide range of features. ### Logs * Get log severity count time series. ```sql theme={null} SELECT toDateTime(toStartOfInterval(Timestamp, INTERVAL 60 second)) as time, SeverityText, count() as count FROM otel_logs WHERE toStartOfFiveMinutes(Timestamp) >= toStartOfFiveMinutes(NOW() - INTERVAL 1 HOUR) AND Timestamp >= NOW() - INTERVAL 1 HOUR GROUP BY SeverityText, time ORDER BY time; ``` The default logs table is ordered by `(toStartOfFiveMinutes(Timestamp), ServiceName, Timestamp)`. For time range queries, filter on both `toStartOfFiveMinutes(Timestamp)` and `Timestamp`, and order by the tuple `(toStartOfFiveMinutes(Timestamp), Timestamp)` to use the primary key's read-in-order optimization. Apply `toStartOfFiveMinutes` to the range bound as well (e.g. `toStartOfFiveMinutes(NOW() - INTERVAL 1 HOUR)`) so the time bucket bounds are not truncated off the scan. * Find any log. ```sql theme={null} SELECT Timestamp as log_time, Body FROM otel_logs WHERE toStartOfFiveMinutes(Timestamp) >= toStartOfFiveMinutes(NOW() - INTERVAL 1 HOUR) AND Timestamp >= NOW() - INTERVAL 1 HOUR ORDER BY (toStartOfFiveMinutes(Timestamp), Timestamp) DESC LIMIT 100; ``` * Find log with specific service. ```sql theme={null} SELECT Timestamp as log_time, Body FROM otel_logs WHERE ServiceName = 'clickhouse-exporter' AND toStartOfFiveMinutes(Timestamp) >= toStartOfFiveMinutes(NOW() - INTERVAL 1 HOUR) AND Timestamp >= NOW() - INTERVAL 1 HOUR ORDER BY (toStartOfFiveMinutes(Timestamp), Timestamp) DESC LIMIT 100; ``` * Find log with specific attribute. ```sql theme={null} SELECT Timestamp as log_time, Body FROM otel_logs WHERE LogAttributes['container_name'] = '/example_flog_1' AND toStartOfFiveMinutes(Timestamp) >= toStartOfFiveMinutes(NOW() - INTERVAL 1 HOUR) AND Timestamp >= NOW() - INTERVAL 1 HOUR ORDER BY (toStartOfFiveMinutes(Timestamp), Timestamp) DESC LIMIT 100; ``` * Find log with body contain string token. ```sql theme={null} SELECT Timestamp as log_time, Body FROM otel_logs WHERE hasToken(Body, 'http') AND toStartOfFiveMinutes(Timestamp) >= toStartOfFiveMinutes(NOW() - INTERVAL 1 HOUR) AND Timestamp >= NOW() - INTERVAL 1 HOUR ORDER BY (toStartOfFiveMinutes(Timestamp), Timestamp) DESC LIMIT 100; ``` * Find log with body contain string. ```sql theme={null} SELECT Timestamp as log_time, Body FROM otel_logs WHERE Body like '%http%' AND toStartOfFiveMinutes(Timestamp) >= toStartOfFiveMinutes(NOW() - INTERVAL 1 HOUR) AND Timestamp >= NOW() - INTERVAL 1 HOUR ORDER BY (toStartOfFiveMinutes(Timestamp), Timestamp) DESC LIMIT 100; ``` * Find log with body regexp match string. ```sql theme={null} SELECT Timestamp as log_time, Body FROM otel_logs WHERE match(Body, 'http') AND toStartOfFiveMinutes(Timestamp) >= toStartOfFiveMinutes(NOW() - INTERVAL 1 HOUR) AND Timestamp >= NOW() - INTERVAL 1 HOUR ORDER BY (toStartOfFiveMinutes(Timestamp), Timestamp) DESC LIMIT 100; ``` * Find log with body json extract. ```sql theme={null} SELECT Timestamp as log_time, Body FROM otel_logs WHERE JSONExtractFloat(Body, 'bytes') > 1000 AND toStartOfFiveMinutes(Timestamp) >= toStartOfFiveMinutes(NOW() - INTERVAL 1 HOUR) AND Timestamp >= NOW() - INTERVAL 1 HOUR ORDER BY (toStartOfFiveMinutes(Timestamp), Timestamp) DESC LIMIT 100; ``` ### Traces * Find spans with specific attribute. ```sql theme={null} SELECT Timestamp, TraceId, SpanId, ParentSpanId, SpanName, SpanKind, ServiceName, Duration, StatusCode, StatusMessage, toString(SpanAttributes), toString(ResourceAttributes), toString(Events.Name), toString(Links.TraceId) FROM otel_traces WHERE ServiceName = 'clickhouse-exporter' AND SpanAttributes['peer.service'] = 'telemetrygen-server' AND Timestamp >= NOW() - INTERVAL 1 HOUR Limit 100; ``` * Find traces with traceID (using time primary index and TraceID skip index). ```sql theme={null} WITH '391dae938234560b16bb63f51501cb6f' as trace_id, (SELECT min(Start) FROM otel_traces_trace_id_ts WHERE TraceId = trace_id) as start, (SELECT max(End) + 1 FROM otel_traces_trace_id_ts WHERE TraceId = trace_id) as end SELECT Timestamp, TraceId, SpanId, ParentSpanId, SpanName, SpanKind, ServiceName, Duration, StatusCode, StatusMessage, toString(SpanAttributes), toString(ResourceAttributes), toString(Events.Name), toString(Links.TraceId) FROM otel_traces WHERE TraceId = trace_id AND Timestamp >= start AND Timestamp <= end Limit 100; ``` * Find spans is error. ```sql theme={null} SELECT Timestamp, TraceId, SpanId, ParentSpanId, SpanName, SpanKind, ServiceName, Duration, StatusCode, StatusMessage, toString(SpanAttributes), toString(ResourceAttributes), toString(Events.Name), toString(Links.TraceId) FROM otel_traces WHERE ServiceName = 'clickhouse-exporter' AND StatusCode = 'Error' AND Timestamp >= NOW() - INTERVAL 1 HOUR Limit 100; ``` * Find slow spans. ```sql theme={null} SELECT Timestamp, TraceId, SpanId, ParentSpanId, SpanName, SpanKind, ServiceName, Duration, StatusCode, StatusMessage, toString(SpanAttributes), toString(ResourceAttributes), toString(Events.Name), toString(Links.TraceId) FROM otel_traces WHERE ServiceName = 'clickhouse-exporter' AND Duration > 1 * 1e9 AND Timestamp >= NOW() - INTERVAL 1 HOUR Limit 100; ``` ### Metrics Metrics data is stored in different clickhouse tables depending on their types. The tables will have a suffix to distinguish which type of metrics data is stored. | Metrics Type | Metrics Table | | --------------------- | ------------------------ | | sum | \_sum | | gauge | \_gauge | | histogram | \_histogram | | exponential histogram | \_exponential\_histogram | | summary | \_summary | Before you make a metrics query, you need to know the type of metric you wish to use. If your metrics come from Prometheus(or someone else uses OpenMetrics protocol), you also need to know the [compatibility](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/compatibility/prometheus_and_openmetrics.md#prometheus-and-openmetrics-compatibility) between Prometheus(OpenMetrics) and OTLP Metrics. * Find a sum metrics with name ```sql theme={null} select TimeUnix,MetricName,Attributes,Value from otel_metrics_sum where MetricName='calls' limit 100 ``` * Find a sum metrics with name, attribute. ```sql theme={null} select TimeUnix,MetricName,Attributes,Value from otel_metrics_sum where MetricName='calls' and Attributes['service_name']='featureflagservice' limit 100 ``` The OTLP Metrics [define two type value for one datapoint](https://github.com/open-telemetry/opentelemetry-proto/blob/main/opentelemetry/proto/metrics/v1/metrics.proto#L358), clickhouse only use one value of float64 to store them. ### Profiles > \[!IMPORTANT] > Profiles support is at `development` stability. The OpenTelemetry profiling signal itself is > pre-GA (the OTLP profiles protocol is in `v1development`), so the schema and behavior may change > in a backwards-incompatible way. To send profiles through a collector pipeline you must enable the > `service.profilesSupport` feature gate (`--feature-gates=+service.profilesSupport`). > > **The profiles table requires ClickHouse 26.2 or newer.** It always uses `text` (full-text-search) > indexes and does not fall back to `bloom_filter` on older server versions. If you manage the schema > yourself (`create_schema: false`), you can adapt the DDL for an older version. Profiles are stored as one denormalized row per OTLP `Sample`. The interned `ProfilesDictionary` (strings, functions, locations, mappings, links, attributes) is resolved at write time so each row is self-contained and can be queried without joins. ## Performance Guide A single ClickHouse instance with 32 CPU cores and 128 GB RAM can handle around 20 TB (20 Billion) logs per day, the data compression ratio is 7 \~ 11, the compressed data store in disk is 1.8 TB \~ 2.85 TB, add more clickhouse node to cluster can increase linearly. The otel-collector with `otlp receiver/clickhouse tcp exporter` (with `sending_queue` batching enabled) can process around 40k/s logs entry per CPU cores, add more collector node can increase linearly. ### Reading a shared table by a resource attribute The default schemas order primarily by time and `ServiceName`, and store resource-level labels (for example a `tenant` or `namespace` attribute) in the `ResourceAttributes` map rather than in the sort key. A skip index on the map values lets a query that filters on a single attribute value prune granules, but because every value shares the same time-partitioned parts, a wide time-range read filtered to one value still scans granules that also contain other values' rows — the filter is applied after the granule is read. For a low-cardinality attribute this is negligible. If you query a shared table by a *high-cardinality* attribute (for example one tenant out of hundreds or thousands, each reading concurrently), that shared-parts scan can become the read bottleneck. In that case, set [`create_schema: false`](#schema-management) and manage the DDL yourself so the attribute participates in the primary key — for example by adding it early in `ORDER BY` or via a projection — accepting that this diverges from the default schema. ## Configuration options The following settings are required: * `endpoint` (no default): The ClickHouse server address, support multi host with port, for example: * tcp protocol `tcp://addr1:port,tcp://addr2:port` or TLS `tcp://addr1:port,addr2:port?secure=true` * http protocol `http://addr1:port,addr2:port` or https `https://addr1:port,addr2:port` * clickhouse protocol `clickhouse://addr1:port,addr2:port` or TLS `clickhouse://addr1:port,addr2:port?secure=true` When multiple endpoints are provided, the driver handles load balancing and automatic failover. By default, it uses `in_order` strategy (tries endpoints in the order specified). Alternatively, use `connection_open_strategy=round_robin` (distributes connections evenly) or `connection_open_strategy=random` (randomly selects endpoints) in `connection_params`. See [connection\_open\_strategy documentation](https://pkg.go.dev/github.com/ClickHouse/clickhouse-go/v2#readme-connection-strategy). Many other ClickHouse specific options can be configured through query parameters e.g. `addr?dial_timeout=5s&compress=lz4`. For a full list of options see the [ClickHouse driver documentation](https://pkg.go.dev/github.com/ClickHouse/clickhouse-go/v2#readme-connection-settings-reference) Connection options: * `username` (default = ): The authentication username. * `password` (default = ): The authentication password. * `ttl` (default = 0): The data time-to-live example 30m, 48h. Also, 0 means no ttl. * `database` (default = default): The database name. Overrides the database defined in `endpoint` when this setting is not equal to `default`. * `connection_params` (default = \{}). Extra connection parameters with map format. Query parameters provided in `endpoint` will be individually overwritten if present in this map. Parameters can be either driver parameters (e.g., `connection_open_strategy`, `max_open_conns`) that control client-side behavior, or ClickHouse session settings (e.g., `max_execution_time`) that are passed to the server. See the [driver parameters list](https://pkg.go.dev/github.com/ClickHouse/clickhouse-go/v2#Options) for recognized driver options; all others are treated as session settings. * `create_schema` (default = true): When set to true, will run DDL to create the database and tables. (See [schema management](#schema-management)) * `compress` (default = lz4): Controls the compression algorithm. Valid options: `none` (disabled), `zstd`, `lz4` (default), `gzip`, `deflate`, `br`, `true` (lz4). Ignored if `compress` is set in the `endpoint` or `connection_params`. * `async_insert` (default = true): Enables [async inserts](https://clickhouse.com/docs/en/optimize/asynchronous-inserts). Ignored if async inserts are configured in the `endpoint` or `connection_params`. Async inserts may still be overridden server-side. * `tls` Advanced TLS configuration (See [TLS](#tls)). Additional DSN features: The underlying `clickhouse-go` module offers additional configuration. These can be set in the exporter's `endpoint` or `connection_params` config values. * `client_info_product` Must be in `productName/version` format with comma separated entries. By default the exporter will append its binary build information. You can use this information to track the origin of `INSERT` statements in the `system.query_log` table. ClickHouse tables: * `logs_table_name` (default = otel\_logs): The table name for logs. * `traces_table_name` (default = otel\_traces): The table name for traces. * `profiles_table_name` (default = otel\_profiles): The table name for profiles. * `metrics_tables` * `gauge` * `name` (default = "otel\_metrics\_gauge") * `sum` * `name` (default = "otel\_metrics\_sum") * `summary` * `name` (default = "otel\_metrics\_summary") * `histogram` * `name` (default = "otel\_metrics\_histogram") * `exponential_histogram` * `name` (default = "otel\_metrics\_exp\_histogram") Cluster definition: * `cluster_name` (default = ): Optional. If present, will include `ON CLUSTER cluster_name` when creating tables. Table engine: * `table_engine` * `name` (default = MergeTree) * `params` (default = ) Modifies `ENGINE` definition when table is created. If not set then `ENGINE` defaults to `MergeTree()`. Can be combined with `cluster_name` to enable [replication for fault tolerance](https://clickhouse.com/docs/en/architecture/replication). Processing: * `timeout` (default = 5s): The timeout for every attempt to send data to the backend. * `sending_queue` * `enabled` (default = true) * `num_consumers` (default = 10): Number of concurrent consumers that dequeue and insert data into ClickHouse. Enabling `batch` does not reduce this parallelism, only the (cheap) queue reader becomes single-threaded, while inserts still run on up to `num_consumers` workers. Ignored if `enabled` is `false`. * `queue_size` (default = 1000): Maximum size of the queue, measured in `sizer` units. Data is dropped when the queue is full unless `block_on_overflow` is enabled. * `sizer` (default = `requests`): How `queue_size` is measured. One of `requests`, `items`, or `bytes`. * `block_on_overflow` (default = false): If `true`, waits for space when the queue is full instead of dropping data (applies backpressure to the pipeline). * `storage` (default = none): Name of a [storage extension](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/storage/filestorage) for a persistent, crash-safe queue. When unset, the queue is in-memory and is lost on restart. * `batch` (disabled by default): Batches data inside the sending queue. Add an empty `batch: {}` to enable it with the defaults below. This replaces the standalone `batch` processor; see the batching recommendation near the top of this document. * `flush_timeout` (default = 200ms): Time after which a batch is sent regardless of size. * `min_size` (default = 8192): Minimum batch size before it is sent, in `batch.sizer` units. * `max_size` (default = 0): Maximum batch size; `0` means no limit. When set, larger batches are split, and it must be `>= min_size`. * `sizer` (default = `items`): How batch size is measured. One of `items` or `bytes` (not `requests`). If unset, inherits `sending_queue.sizer`. * `retry_on_failure` * `enabled` (default = true) * `initial_interval` (default = 5s): The Time to wait after the first failure before retrying; ignored if `enabled` is `false` * `max_interval` (default = 30s): The upper bound on backoff; ignored if `enabled` is `false` * `max_elapsed_time` (default = 300s): The maximum amount of time spent trying to send a batch; ignored if `enabled` is `false` ## TLS The exporter supports TLS. To enable TLS, you must specify the `secure=true` query parameter in the `endpoint` URL or use the `https` scheme. You may also use certificate authentication with the `tls` setting: ```yaml theme={null} exporters: clickhouse: endpoint: . . . tls: insecure: false insecure_skip_verify: false ca_file: CAroot.crt cert_file: client.crt key_file: client.key ``` The available `tls` options are inherited from [OpenTelemetry's TLS config structure](https://pkg.go.dev/go.opentelemetry.io/collector/config/configtls#ClientConfig), more options are available than shown in this example. ## Schema management By default, the exporter will create the database and tables under the names defined in the config. This is fine for simple deployments, but for production workloads, it is recommended that you manage your own schema by setting `create_schema` to `false` in the config. This prevents each exporter process from racing to create the database and tables, and makes it easier to upgrade the exporter in the future. In this mode, the only SQL sent to your server will be for `INSERT` statements. The default DDL used by the exporter can be found in `internal/sqltemplates`. Be sure to customize the indexes, TTL, and partitioning to fit your deployment. Column names and types must be the same to preserve compatibility with the exporter's `INSERT` statements. As long as the column names/types match the `INSERT` statement, you can create whatever kind of table you want. See [ClickHouse's LogHouse](https://clickhouse.com/blog/building-a-logging-platform-with-clickhouse-and-saving-millions-over-datadog#schema) as an example of this flexibility. ### Upgrading existing tables Sometimes new columns are added to the exporter in a backwards compatible way. The exporter runs a `DESC TABLE` command on startup to determine which of these new columns are available on the table schema. If you already have tables created by a previous version of the exporter, you will need to add these new columns manually. Here is an example of a command you can use to update your existing table (adjust database and table names as needed): ```sql theme={null} ALTER TABLE otel.otel_logs ADD COLUMN IF NOT EXISTS EventName String CODEC(ZSTD(1)); ``` To find the newest columns available check the `internal/sqltemplates` folder. The `CREATE TABLE` statements will always have the latest columns. In some cases the table changes will not be backwards compatible. Be sure to check the changelog for breaking changes before upgrading your collector. ### Optional table upgrades As mentioned in the previous section, the exporter is able to detect which columns are present on the schema for backwards compatibility. Here are some columns you can add to your table to update the schema: ```sql theme={null} -- EventName ALTER TABLE otel.otel_logs ADD COLUMN IF NOT EXISTS EventName String CODEC(ZSTD(1)); -- JSON tables only. These 3 columns are part of one feature, you must add all 3 at once. ALTER TABLE otel.otel_logs ADD COLUMN IF NOT EXISTS ResourceAttributesKeys Array(LowCardinality(String)) CODEC(ZSTD(1)), ADD COLUMN IF NOT EXISTS ScopeAttributesKeys Array(LowCardinality(String)) CODEC(ZSTD(1)), ADD COLUMN IF NOT EXISTS LogAttributesKeys Array(LowCardinality(String)) CODEC(ZSTD(1)), -- Optional indices ADD INDEX IF NOT EXISTS idx_res_attr_keys ResourceAttributesKeys TYPE bloom_filter(0.01) GRANULARITY 1, ADD INDEX IF NOT EXISTS idx_scope_attr_keys ScopeAttributesKeys TYPE bloom_filter(0.01) GRANULARITY 1, ADD INDEX IF NOT EXISTS idx_log_attr_keys LogAttributesKeys TYPE bloom_filter(0.01) GRANULARITY 1; -- JSON tables only. These 2 columns are part of one feature, you must add all 2 at once. ALTER TABLE otel.otel_traces ADD COLUMN IF NOT EXISTS ResourceAttributesKeys Array(LowCardinality(String)) CODEC(ZSTD(1)), ADD COLUMN IF NOT EXISTS SpanAttributesKeys Array(LowCardinality(String)) CODEC(ZSTD(1)), -- Optional indices ADD INDEX IF NOT EXISTS idx_res_attr_keys ResourceAttributesKeys TYPE bloom_filter(0.01) GRANULARITY 1, ADD INDEX IF NOT EXISTS idx_span_attr_keys SpanAttributesKeys TYPE bloom_filter(0.01) GRANULARITY 1; ``` ## Example Config This example shows how to configure the exporter to send data to a ClickHouse server. It uses the native protocol without TLS. The exporter will create the database and tables if they don't exist. The data is stored for 72 hours (3 days). ```yaml theme={null} receivers: examplereceiver: exporters: clickhouse: endpoint: tcp://127.0.0.1:9000?dial_timeout=10s database: otel async_insert: true ttl: 72h compress: lz4 create_schema: true logs_table_name: otel_logs traces_table_name: otel_traces timeout: 5s metrics_tables: gauge: name: "otel_metrics_gauge" sum: name: "otel_metrics_sum" summary: name: "otel_metrics_summary" histogram: name: "otel_metrics_histogram" exponential_histogram: name: "otel_metrics_exp_histogram" retry_on_failure: enabled: true initial_interval: 5s max_interval: 30s max_elapsed_time: 300s # cluster_name: my_cluster # table_engine: # name: ReplicatedMergeTree # params: service: pipelines: logs: receivers: [ examplereceiver ] exporters: [ clickhouse ] ``` ## Experimental JSON support JSON column types can be enabled per-exporter using the `json` config option: ```yaml theme={null} exporters: clickhouse: endpoint: clickhouse://localhost:9000?enable_json_type=1 json: true ``` Previously, the `clickhouse.json` feature gate was used to enable JSON for all ClickHouse exporter instances. This feature gate is now deprecated. Use the `json` config option instead, which allows per-pipeline control. You may also need to add `enable_json_type=1` to your endpoint or `connection_params`. DDL has been updated, but feel free to tune the schema as needed. DDL can be found in the `internal/sqltemplates` package. All `Map` columns have been replaced with `JSON`. ClickHouse v25+ is recommended for reliable JSON support. ## Contributing Before contributing, review the contribution guidelines in [CONTRIBUTING.md](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/CONTRIBUTING.md). #### Integration tests Integration tests can be run with the following command (includes unit tests): ```sh theme={null} go test -tags integration ``` *Note: Make sure integration tests pass after making changes to SQL.* ## Configuration ### Example Configuration ```yaml theme={null} clickhouse: endpoint: clickhouse://127.0.0.1:9000 clickhouse/full: endpoint: clickhouse://127.0.0.1:9000 username: foo password: bar database: otel ttl: 72h logs_table_name: otel_logs traces_table_name: otel_traces timeout: 5s tls: cert_file: client.crt key_file: client.key retry_on_failure: enabled: true initial_interval: 5s max_interval: 30s max_elapsed_time: 300s sending_queue: queue_size: 100 storage: file_storage/clickhouse metrics_tables: gauge: name: "otel_metrics_custom_gauge" sum: name: "otel_metrics_custom_sum" summary: name: "otel_metrics_custom_summary" histogram: name: "otel_metrics_custom_histogram" exponential_histogram: name: "otel_metrics_custom_exp_histogram" clickhouse/batch: endpoint: clickhouse://127.0.0.1:9000 sending_queue: batch: min_size: 5000 max_size: 10000 flush_timeout: 5s clickhouse/json: endpoint: clickhouse://127.0.0.1:9000 json: true clickhouse/invalid-endpoint: endpoint: 127.0.0.1:9000 clickhouse/table-engine-empty: endpoint: clickhouse://127.0.0.1:9000 clickhouse/table-engine-name-only: endpoint: clickhouse://127.0.0.1:9000 table_engine: name: ReplicatedReplacingMergeTree clickhouse/table-engine-full: endpoint: clickhouse://127.0.0.1:9000 table_engine: name: ReplicatedReplacingMergeTree params: "'/clickhouse/tables/{shard}/table_name', '{replica}', ver" clickhouse/table-engine-params-only: endpoint: clickhouse://127.0.0.1:9000 table_engine: params: "whatever" ``` *** *Last generated: 2026-08-03* # Coralogix Source: https://otel.fyi/components/exporter/coralogixexporter OpenTelemetry exporter for Coralogix # Coralogix Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@povilasv](https://github.com/povilasv), [@iblancasa](https://github.com/iblancasa), [@douglascamata](https://github.com/douglascamata) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/coralogixexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-beta-blue) ![Metrics](https://img.shields.io/badge/metrics-beta-green) ![Traces](https://img.shields.io/badge/traces-beta-orange) ## Overview The Coralogix exporter sends traces, metrics and logs to [Coralogix](https://coralogix.com/). > Please review the Collector's [security > documentation](https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md), > which contains recommendations on securing sensitive information such as the > API key required by this exporter. ## Configuration Example configuration: ```yaml theme={null} exporters: coralogix: # The Coralogix domain domain: "coralogix.com" # Your Coralogix private key is sensitive private_key: "xxx" # (Optional) Protocol to use for communication: "grpc" (default) or "http" protocol: "grpc" # (Optional) Ordered list of Resource attributes that are used for Coralogix # AppName and SubSystem values. The first non-empty Resource attribute is used. # Example: application_name_attributes: ["k8s.namespace.name", "service.namespace"] # Example: subsystem_name_attributes: ["k8s.deployment.name", "k8s.daemonset.name", "service.name"] application_name_attributes: - "service.namespace" subsystem_name_attributes: - "service.name" # Traces, Metrics and Logs emitted by this OpenTelemetry exporter # are tagged in Coralogix with the default application and subsystem constants. application_name: "MyBusinessEnvironment" subsystem_name: "MyBusinessSystem" # (Optional) Configure the sending queue for batching capabilities sending_queue: sizer: bytes batch: min_size: 4194304 max_size: 8388608 # (Optional) Timeout is the timeout for every attempt to send data to the backend. timeout: 30s # (Optional) Use AWS PrivateLink for private connectivity. When true, data is sent to # ingress.private.. See "Coralogix's Domain" section below for details. # private_link: true ``` ### Transport Protocol The Coralogix exporter supports two transport protocols: * **gRPC** (default): Uses gRPC for efficient binary communication * **HTTP**: Uses HTTP with protobuf encoding, useful for proxy support or environments where gRPC is restricted To use HTTP protocol: ```yaml theme={null} exporters: coralogix: protocol: "http" domain: "coralogix.com" ``` #### Using HTTP Protocol with Proxy When using HTTP protocol, you can configure proxy settings: ```yaml theme={null} exporters: coralogix: protocol: "http" domain: "coralogix.com" private_key: "xxx" application_name: "MyApp" subsystem_name: "MySubsystem" domain_settings: proxy_url: "http://proxy.example.com:8080" timeout: 30s ``` **Notes**: * Proxy support (`proxy_url`) is only available when using the HTTP protocol. gRPC protocol does not support this setting. * Signal-specific settings (logs, traces, metrics) take precedence over `domain_settings`. * **The profiles signal is not supported when using HTTP protocol**. Use gRPC protocol (default) if you need to send profiles data. ```` ### Compression By default, the Coralogix exporter uses gzip compression. Alternatively, you can use zstd compression, for example: ```yaml exporters: coralogix: domain_settings: compression: "zstd" ```` ### v0.76.0 Coralogix Domain Since v0.76.0 you can specify Coralogix domain in the configuration file instead of specifying different endpoints for traces, metrics and logs. For example, the configuration below, can be replaced with domain field: Old configuration: ```yaml theme={null} exporters: coralogix: traces: endpoint: "ingress.coralogix.com:443" metrics: endpoint: "ingress.coralogix.com:443" logs: endpoint: "ingress.coralogix.com:443" ``` New configuration with domain field: ```yaml theme={null} exporters: coralogix: domain: "coralogix.com" ``` ### Coralogix's Domain Depending on your region and, you might need to use a different domain. For an up-to-date list of domains, please refer to [the official Coralogix's Domain documentation](https://coralogix.com/docs/user-guides/account-management/account-settings/coralogix-domain/#domains). Additionally, Coralogix supports AWS PrivateLink, which provides private connectivity between virtual private clouds (VPCs), supported AWS services, and your on-premises networks without exposing your traffic to the public internet. For an up-to-date list of AWS PrivateLink domains, please refer to [Coralogix's official AWS PrivateLink documentation](https://coralogix.com/docs/integrations/aws/aws-privatelink/aws-privatelink/#privatelink-endpoints). To automatically use the PrivateLink endpoint that corresponds to the configured domain, you can set the `private_link` configuration field to `true`. For example: ```yaml theme={null} exporters: coralogix: domain: "eu2.coralogix.com" private_link: true ``` ### Application and SubSystem attributes v0.62.0 release of OpenTelemetry Collector allows you to map Application name and Subsystem name to Resource attributes. You need to set `application_name_attributes` and `subsystem_name_attributes` fields with a list of potential Resource attributes for the AppName and Subsystem values. The first not-empty Resource attribute is going to be used. If multiple resource attributes are available, **the order of the attributes in the list determines their priority.** ### Kubernetes attributes When using OpenTelemetry Collector with [k8sattribute](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/k8sattributesprocessor) processor, you can use attributes coming from Kubernetes, such as `k8s.namespace.name` or `k8s.deployment.name`. The following example shows recommended list of attributes: ```yaml theme={null} exporters: coralogix: domain: "coralogix.com" application_name_attributes: - "k8s.namespace.name" - "service.namespace" subsystem_name_attributes: - "k8s.deployment.name" - "k8s.statefulset.name" - "k8s.daemonset.name" - "k8s.cronjob.name" - "service.name" ``` ### Host Attributes OpenTelemetry Collector [Resource Detection](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor) processor can discover Host Resource attributes, such as `host.name` and provide Resource attributes using environment variables, which can be used for setting AppName and SubSystem fields in Coralogix. Example: ```yaml theme={null} processors: resource_detection/system: detectors: ["system", "env"] system: hostname_sources: ["os"] ``` And setting environment variable such as: ``` OTEL_RESOURCE_ATTRIBUTES="env=production" ``` You can configure Coralogix Exporter: ```yaml theme={null} exporters: coralogix: domain: "coralogix.com" application_name_attributes: - "env" subsystem_name_attributes: - "host.name" ``` ### EC2 Attributes OpenTelemetry Collector [Resource Detection](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor) processor can discover EC2 Resource attributes, such as EC2 tags as resource attributes. Example: ```yaml theme={null} processors: resource_detection/ec2: detectors: ["ec2"] ec2: # A list of regex's to match tag keys to add as resource attributes can be specified tags: - ^ec2.tag.name$ - ^ec2.tag.subsystem$ ``` ***NOTE:*** In order to fetch EC2 tags, the IAM role assigned to the EC2 instance must have a policy that includes the `ec2:DescribeTags` permission. ```json theme={null} \{ "Version": "2012-10-17", "Statement": [ \{ "Sid": "VisualEditor0", "Effect": "Allow", "Action": "ec2:DescribeTags", "Resource": "*" \} ] \} ``` You can configure Coralogix Exporter: ```yaml theme={null} exporters: coralogix: domain: "coralogix.com" application_name_attributes: - "ec2.tag.name" subsystem_name_attributes: - "ec2.tag.subsystem" ``` ### Custom Attributes You can combine and create custom Resource attributes using [transform](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor) processor. For example: ```yaml theme={null} processors: transform: error_mode: ignore log_statements: - context: resource statements: - set(attributes["applicationName"], Concat(["development-environment", attributes["k8s.namespace.name"]], "-")) ``` Then you can use the custom Resource attribute in Coralogix exporter: ```yaml theme={null} exporters: coralogix: domain: "coralogix.com" application_name_attributes: - "applicationName" subsystem_name_attributes: - "host.name" ``` ### Exporting to multiple teams based on attributes You can export the signals based on your business logic (attributes) to different Coralogix teams. To achieve this, you'll need to use the [`filter`](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/filterprocessor/README.md) processor and setup one pipeline per team. You can setup your `filter` processors as following (example with metrics): ```yaml theme={null} processors: filter/teamA: metrics: datapoint: - 'attributes["your_label"] != "teamA"' filter/teamB: metrics: datapoint: - 'attributes["your_label"] != "teamB"' ``` This configuration ensures separate processor per each team. Any data points without an attribute for a particular team will be dropped from exporting. Secondly, set up an individual exporter per each team: ```yaml theme={null} exporters: coralogix/teamA: metrics: endpoint: "otel-metrics.coralogix.com:443" private_key: `` application_name: "MyBusinessEnvironment" subsystem_name: "MyBusinessSystem" coralogix/teamB: metrics: endpoint: "otel-metrics.coralogix.com:443" private_key: `` application_name: "MyBusinessEnvironment" subsystem_name: "MyBusinessSystem" ``` Finally, join each processor and exporter (and any other components you wish) in the pipelines. Here is an example with a Prometheus receiver: ```yaml theme={null} service: pipelines: metrics/1: receivers: [prometheus] processors: [filter/teamA] exporters: [coralogix/teamA] metrics/2: receivers: [prometheus] processors: [filter/teamB] exporters: [coralogix/teamB] ``` ### Custom application and subsystem name You can pass custom application and subsystem name via the following resource attributes: * `cx.subsystem.name` * `cx.application.name` For example: ```yaml theme={null} receivers: file_log/nginx: include: - '/tmp/tmp.log' include_file_path: true include_file_name: false start_at: end resource: cx.subsystem.name: nginx file_log/access-log: include: - '/tmp/access.log' include_file_path: true include_file_name: false resource: cx.subsystem.name: access-log exporters: coralogix: domain: 'coralogix.com' private_key: "XXX" application_name: 'app_name' timeout: 30s service: pipelines: logs: receivers: [file_log/nginx, file_log/access-log] exporters: [coralogix] ``` ## Warnings ### Authentication issues in v0.127.0 Version 0.127.0 introduced a regression in the Coralogix exporter. As a consequence, it requires an updated authentication configuration to ensure proper telemetry data transmission to Coralogix. If you're using this version, please modify your configuration to include the authentication headers as shown below: ```yaml theme={null} coralogix: traces: headers: "Authorization": "Bearer $\{env:CORALOGIX_PRIVATE_KEY\}" metrics: headers: "Authorization": "Bearer $\{env:CORALOGIX_PRIVATE_KEY\}" logs: headers: "Authorization": "Bearer $\{env:CORALOGIX_PRIVATE_KEY\}" ``` This configuration ensures proper authentication with the Coralogix backend. Prior versions (v0.126.0 and earlier) and subsequent versions (v0.128.0 and later) are not affected by this authentication issue. ### Need help? Our world-class customer success team is available 24/7 to walk you through the setup for this exporter and answer any questions that may come up. Feel free to reach out to us **via our in-app chat** or by sending us an email to [support@coralogix.com](mailto:support@coralogix.com). ## Configuration ### Example Configuration ```yaml theme={null} coralogix: traces: endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:4317" private_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" application_name: "APP_NAME" # Deprecated: [v0.47.0] SubSystem will remove in the next version subsystem_name: "SUBSYSTEM_NAME" timeout: 5s coralogix/trace: endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:4317" private_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" application_name: "APP_NAME" # Deprecated: [v0.47.0] SubSystem will remove in the next version subsystem_name: "SUBSYSTEM_NAME" timeout: 5s coralogix/all: traces: endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:4317" metrics: endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:4317" logs: endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:4317" application_name_attributes: - "service.namespace" - "k8s.namespace.name" subsystem_name_attributes: - "service.name" - "k8s.deployment.name" - "k8s.statefulset.name" - "k8s.daemonset.name" - "k8s.cronjob.name" - "k8s.job.name" - "k8s.container.name" private_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" application_name: "APP_NAME" subsystem_name: "SUBSYSTEM_NAME" timeout: 5s coralogix/domain: domain: "coralogix.com" application_name_attributes: - "service.namespace" subsystem_name_attributes: - "service.name" private_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" application_name: "APP_NAME" subsystem_name: "SUBSYSTEM_NAME" timeout: 5s coralogix/domain_endpoints: domain: "coralogix.com" traces: endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:4317" metrics: endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:4317" logs: endpoint: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:4317" application_name_attributes: - "service.namespace" subsystem_name_attributes: - "service.name" private_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" application_name: "APP_NAME" subsystem_name: "SUBSYSTEM_NAME" timeout: 5s coralogix/http_protocol: protocol: "http" domain: "coralogix.com" application_name_attributes: - "service.namespace" subsystem_name_attributes: - "service.name" private_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" application_name: "APP_NAME" subsystem_name: "SUBSYSTEM_NAME" timeout: 5s ``` *** *Last generated: 2026-08-03* # Datadog Source: https://otel.fyi/components/exporter/datadogexporter OpenTelemetry exporter for Datadog # Datadog Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@mx-psi](https://github.com/mx-psi), [@dineshg13](https://github.com/dineshg13), [@liustanley](https://github.com/liustanley), [@songy23](https://github.com/songy23), [@mackjmr](https://github.com/mackjmr), [@jade-guiton-dd](https://github.com/jade-guiton-dd), [@IbraheemA](https://github.com/IbraheemA) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/datadogexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-beta-blue) ![Metrics](https://img.shields.io/badge/metrics-beta-green) ![Traces](https://img.shields.io/badge/traces-beta-orange) ## Overview > Please review the Collector's [security documentation](https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/security-best-practices.md), which contains recommendations on securing sensitive information such as the API key required by this exporter. > The Datadog Exporter now skips APM stats computation by default. It is recommended to only use the [Datadog Connector](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/datadogconnector) in order to compute APM stats. > To temporarily revert to the previous behavior, disable the `exporter.datadogexporter.DisableAPMStats` feature gate. Example: `otelcol --config=config.yaml --feature-gates=-exporter.datadogexporter.DisableAPMStats` Find the full configs of Datadog exporter and their usage in [collector.yaml](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/datadogexporter/examples/collector.yaml). More example configs can be found in the [official documentation](https://docs.datadoghq.com/opentelemetry/setup/collector_exporter/). ## FAQs ### Why am I getting errors 413 - Request Entity Too Large, how do I fix it? This error indicates the payload size sent by the Datadog exporter exceeds the size limit (see previous examples [https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/16834](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/16834), [https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/17566](https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/17566)). This is usually caused by the pipeline batching too many telemetry data before sending to the Datadog API intake. To fix that, prefer using the Datadog exporter `sending_queue::batch` section instead of the batch processor: ```yaml theme={null} exporters: datadog: api: key: ${env:DD_API_KEY} sending_queue: batch: min_size: 10 max_size: 100 flush_timeout: 10s ``` If you are using the batch processor instead, try lowering `send_batch_size` and `send_batch_max_size` in your config. You might want to have a separate batch processor dedicated for datadog exporter if other exporters expect a larger batch size, e.g. ``` processors: batch: # To be used by other exporters timeout: 1s # Default value for send_batch_size is 8192 batch/datadog: send_batch_max_size: 100 send_batch_size: 10 timeout: 10s ... service: pipelines: metrics: receivers: ... processors: [batch/datadog] exporters: [datadog] ``` The exact values for `send_batch_size` and `send_batch_max_size` depends on your specific workload. Also note that, Datadog intake has different payload size limits for the 3 signal types: * Trace intake: 3.2MB * Log intake: [https://docs.datadoghq.com/api/latest/logs/](https://docs.datadoghq.com/api/latest/logs/) * Metrics V2 intake: [https://docs.datadoghq.com/api/latest/metrics/#submit-metrics](https://docs.datadoghq.com/api/latest/metrics/#submit-metrics) ### Fall back to the Zorkian metric client with feature gate Support for Zorkian is now deprecated, please use the metrics export serializer. See [https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.122.0](https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.122.0) and #37930 for more info about Metrics Export Serializer. ### Remap OTel’s service.name attribute to service for logs **NOTE** this workaround is only needed when feature gate `exporter.datadogexporter.UseLogsAgentExporter` is disabled. This feature gate is enabled by default starting v0.108.0. For Datadog Exporter versions 0.83.0 - v0.107.0, the `service` field of OTel logs is populated as [OTel semantic convention](https://opentelemetry.io/docs/specs/semconv/resource/#service) `service.name`. However, `service.name` is not one of the default [service attributes](https://docs.datadoghq.com/logs/log_configuration/pipelines/?tab=service#service-attribute) in Datadog’s log preprocessing. To get the service field correctly populated in your logs, you can specify service.name to be the source of a log’s service by setting a [log service remapper processor](https://docs.datadoghq.com/logs/log_configuration/pipelines/?tab=service#service-attribute). [beta]: https://github.com/open-telemetry/opentelemetry-collector#beta [alpha]: https://github.com/open-telemetry/opentelemetry-collector#alpha [contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib [AWS]: https://aws-otel.github.io/docs/partners/datadog ### How to add custom log source In order to add a custom source to your OTLP logs, set resource attribute `datadog.log.source`. This feature requires `exporter.datadogexporter.UseLogsAgentExporter` feature flag to be enabled (now enabled by default). Example: ``` processors: transform/logs: log_statements: - context: resource statements: - set(attributes["datadog.log.source"], "otel") ``` ### My Collector K8s pod is getting rebooted on startup when I don't manually set a hostname under `exporters::datadog::hostname` This is due to a bug with underlying hostname detection blocking the `health_check` extension from responding to liveness/readiness probes on startup. To fix, either set `hostname_detection_timeout` to be less than the pod/daemonset `livenessProbe: failureThreshold * periodSeconds` so that the timeout for hostname detection on startup takes less time than the control plane waits before restarting the pod, or leave `hostname_detection_timeout` at the default `25s` value and double-check the `livenessProbe` and `readinessProbe` settings and ensure that the control plane will in fact wait long enough for startup to complete before restarting the pod. Hostname detection is currently required to initialize the Datadog Exporter, unless a hostname is specified manually under `hostname`. ## Configuration ### Example Configuration ```yaml theme={null} datadog/api: hostname: customhostname api: key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa site: datadoghq.eu fail_on_invalid_key: true traces: span_name_remappings: "old_name1": "new_name1" "old_name2": "new_name2" span_name_as_resource_name: true trace_buffer: 10 datadog/api2: hostname: customhostname host_metadata: tags: [example:tag] api: key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa site: datadoghq.eu metrics: endpoint: https://api.datadoghq.test traces: span_name_remappings: "old_name3": "new_name3" "old_name4": "new_name4" endpoint: https://trace.agent.datadoghq.test logs: endpoint: https://http-intake.logs.datadoghq.test datadog/default: api: key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ``` *** *Last generated: 2026-08-03* # Dataset Source: https://otel.fyi/components/exporter/datasetexporter OpenTelemetry exporter for Dataset # Dataset Exporter ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@atoulme](https://github.com/atoulme), [@martin-majlis-s1](https://github.com/martin-majlis-s1), [@zdaratom-s1](https://github.com/zdaratom-s1), [@tomaz-s1](https://github.com/tomaz-s1) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/datasetexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-alpha-blue) ![Traces](https://img.shields.io/badge/traces-alpha-orange) ## Overview This exporter sends logs to [DataSet](https://www.dataset.com/). See the [Getting Started](https://app.scalyr.com/help/getting-started) guide. ## Configuration ### Required Settings * `dataset_url` (no default): The URL of the DataSet API that ingests the data. Most likely [https://app.scalyr.com](https://app.scalyr.com). * `api_key` (no default): The "Log Write" API Key required to use API. Instructions how to get [API key](https://app.scalyr.com/help/api-keys). If you do not want to specify `api_key` in the file, you can use the [builtin functionality](https://opentelemetry.io/docs/collector/configuration/#configuration-environment-variables) and use `api_key: ${env:DATASET_API_KEY}`. ### Server Host Settings Specifying the server host is crucial for ensuring the correct functionality of DataSet. DataSet expects the server host value to be provided in the `serverHost` attribute. If the server host value is stored in a different attribute, you can use the [resourceprocessor](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/resourceprocessor/README.md) or [attributesprocessor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/attributesprocessor) to copy it into the `serverHost` attribute. You can also utilize the `server_host` settings (described below) to populate the serverHost attribute with different values. The process of populating the serverHost attribute works as follows: * If the `serverHost` attribute is specified and not empty in the log or trace, then it is used. * If the `serverHost` attribute is specified and not empty in the [resource](https://opentelemetry.io/docs/specs/otel/resource/sdk/), then it is used. * If the `host.name` attribute is specified and not empty in the [resource](https://opentelemetry.io/docs/specs/otel/resource/sdk/), then it is used. * If the `server_host.server_host` setting is specified and not empty, then it is used. * If `server_host.use_host_name` setting is set to `true`, the `hostname` of the node is used. Make sure to provide the appropriate server host value in the `serverHost` attribute to ensure the proper functionality of DataSet and accurate handling of events. ### Optional Settings * `debug` (default = false): Adds `session_key` to the server fields. It's useful for debugging throughput issues. * `buffer`: * `max_lifetime` (default = 5s): The maximum delay between sending batches from the same session. * `purge_older_than` (default = 30s): The maximum delay between receiving data for the same session after which resources associated with it are purged. * `group_by` (default = \[]): The list of attributes based on which events should be grouped. They are moved from the event attributes to the session info and shown as server fields in the UI. * `retry_initial_interval` (default = 5s): Time to wait after the first failure before retrying. * `retry_max_interval` (default = 30s): Is the upper bound on backoff. * `retry_max_elapsed_time` (default = 300s): Is the maximum amount of time spent trying to send a buffer. * `retry_shutdown_timeout` (default = 30s): The maximum time for which it will try to send data to the DataSet during shutdown. This value should be shorter than container's grace period. * `max_parallel_outgoing` (default = 100): The maximum number of parallel outgoing requests. * `logs`: * `export_resource_info_on_event` (default = false): Include LogRecord resource information (if available) on the DataSet event. * `export_resource_prefix` (default = 'resource.attributes.'): A prefix string for the resource, if `export_resource_info_on_event` is enabled. * `export_scope_info_on_event` (default = true): Include LogRecord scope information (if available) on the DataSet event. * `export_scope_prefix` (default = 'scope.attributes.'): A prefix string for the scope, if `export_scope_info_on_event` is enabled. * `export_separator` (default = '.'): The separator to add between keys when flattening nested structures (maps, arrays). * `export_distinguishing_suffix` (default = '\_'): A suffix string to resolve naming collisions when flattening. * `decompose_complex_message_field` (default = false): Decompose complex body / message field types (e.g. a maps, arrays) into separate fields. * `decomposed_complex_message_prefix` (default = 'body.map.'): A prefix string to use when a complex message is decomposed. * `traces`: * `export_separator` (default = '.'): The separator to add between keys when flattening nested structures (maps, arrays). * `export_distinguishing_suffix` (default = '\_'): A suffix string to resolve naming collisions when flattening. * `server_host`: * `server_host` (default = ''): Specifies the server host to be used for the events. * `use_hostname` (default = true): Determines whether the `hostname` of the node should be used as the server host for the events. When set to `true`, the node's `hostname` is automatically used. * `retry_on_failure`: See [retry\_on\_failure](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md) * `sending_queue`: See [sending\_queue](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md) * `timeout`: See [timeout](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md) ### Attributes Enabled attributes are exported in the order: 1. Log properties 2. Body 3. Resource attributes 4. Scope attributes 5. Log attributes If there is a name conflict, the `export_distinguishing_suffix` value is appended to the later attribute's name. If the `export_distinguishing_suffix` value is an empty string, then the value from the last attribute is used. #### Example Example LogRecord: ``` Log - body: - b: 1 - x: "b" - resource: - r: 2 - x: "r" - scope: - s: 3 - x: "s" - attribute: - a: 4 - x: "a" - map: - m1: 5 - m2: 6 ``` Then the event will look like: * Default settings for `logs`: * Event: ``` - message: "{\"b\": 1, \"x\": \"b\"}" - scope.attributes.s: 3 - scope.attributes.x: "s" - a: 4 - x: "a" - map.m1: 5 - map.m2: 6 ``` * Everything enabled: * Configuration: ``` logs: export_resource_info_on_event: true export_resource_prefix: "r." export_scope_info_on_event: true export_scope_prefix: "s." decompose_complex_message_field: true decomposed_complex_message_prefix: "m." export_separator: "-" export_distinguishing_suffix: "_" ``` * Event: ``` - message: "{\"b\": 1, \"x\": \"b\"}" - m.b: 1 - m.x: "b" - r.r: 2 - r.x: "r" - s.s: 3 - s.x: "s" - a: 4 - x: "a" - map-m1: 5 - map-m2: 6 ``` * Everything enabled, prefixes are empty strings: * Configuration: ``` logs: export_resource_info_on_event: true export_resource_prefix: "" export_scope_info_on_event: true export_scope_prefix: "" decompose_complex_message_field: true decomposed_complex_message_prefix: "" export_separator: "-" export_distinguishing_suffix: "_" ``` * Event: ``` - message: "{\"b\": 1, \"x\": \"b\"}" - b: 1 - x: "b" - r: 2 - x_: "r" - s: 3 - x__: "s" - a: 4 - x___: "a" - map-m1: 5 - map-m2: 6 ``` * Everything enabled, prefixes are empty strings, suffix is empty string: * Configuration: ``` logs: export_resource_info_on_event: true export_resource_prefix: "" export_scope_info_on_event: true export_scope_prefix: "" decompose_complex_message_field: true decomposed_complex_message_prefix: "" export_separator: "-" export_distinguishing_suffix: "" ``` * Event: ``` - message: "{\"b\": 1, \"x\": \"b\"}" - b: 1 - r: 2 - s: 3 - a: 4 - x: "a" - map-m1: 5 - map-m2: 6 ``` Field names can have `.` dots, `_` underscores, and `-` hyphens. You must escape slashes in Search and PowerQueries. For example, search the field name `app.kubernetes.io/component` as `app.kubernetes.io\/component`. ### Example ```yaml theme={null} processors: attributes: - key: serverHost action: insert from_attribute: container_id resource: attributes: - key: serverHost from_attribute: node_id action: insert exporters: dataset/logs: # DataSet API URL, https://app.eu.scalyr.com for DataSet EU instance dataset_url: https://app.scalyr.com # API Key api_key: your_api_key buffer: # Send buffer to the API at least every 5s max_lifetime: 5s # Group data based on these attributes group_by: - container_id # try to send data to the DataSet for at most 30s during shutdown retry_shutdown_timeout: 30s server_host: # If the serverHost attribute is not specified or empty, # use the value from the env variable SERVER_HOST server_host: ${env:SERVER_HOST} # If server_host is not set, use the hostname value use_hostname: true sending_queue: # Enable batching batch: dataset/traces: # DataSet API URL, https://app.eu.scalyr.com for DataSet EU instance dataset_url: https://app.scalyr.com # API Key api_key: your_api_key buffer: max_lifetime: 15s group_by: - resource_service.instance.id sending_queue: # Enable batching batch: service: pipelines: logs: receivers: [otlp] processors: [attributes] # add dataset among your exporters exporters: [dataset/logs] traces: receivers: [otlp] # add dataset among your exporters exporters: [dataset/traces] ``` ### Handling `serverHost` Attribute Based on the given configuration and scenarios, here's the expected behavior: 1. Resource: `{'node_id:' 'node-pay-01', 'host.name': 'host-pay-01'}`, Log: `{'container_id': 'cont-pay-01'}`, Env: `SERVER_HOST='server-pay-01'`, Hostname: `ip-172-31-27-19` * Since the attribute `container_id` is set, `attributesprocessor` will copy this value to the `serverHost`. * Used `serverHost` will be `cont-pay-01`. 2. Resource: `{'node_id': 'node-pay-01', 'host.name': 'host-pay-01'}`, Log: `{'attribute.foo': 'Bar'}`, Env: `SERVER_HOST='server-pay-01'`, Hostname: `ip-172-31-27-19` * Since the resource attribute `node_id` is set, `resourceprocessor` will copy this value to the `serverHost`. * Used `serverHost` will be `node-pay-01`. 3. Resource: `{'host.name': 'host-pay-01'}`, Log: `{'attribute.foo': 'Bar'}`, Env: `SERVER_HOST='server-pay-01'`, Hostname: `ip-172-31-27-19` * Since the resource attribute `host.name` is set, it will be used. * Used `serverHost` will be `host-pay-01`. 4. Resource: `{}`, Log: `{'attribute.foo': 'Bar'}`, Env: `SERVER_HOST='server-pay-01'`, Hostname: `ip-172-31-27-19` * Since the attribute `container_id` is not set, the value from the environmental variable `SERVER_HOST` will be copied to the `serverHost`. * Used `serverHost` will be `server-pay-01`. 5. Resource: `{}`, Log: `{'attribute.foo': 'Bar'}`, Env: `SERVER_HOST=''`, Hostname: `ip-172-31-27-19` * Since the attribute `container_id` is not set and the environmental variable `SERVER_HOST` is empty, the `hostname` of the node (`ip-172-31-27-19`) will be used as the fallback value for `serverHost`. * Used `serverHost` will be `ip-172-31-27-19`. ## Metrics To enable metrics you have to: 1. Run collector with enabled feature gate `telemetry.useOtelForInternalMetrics`. This can be done by executing it with one additional parameter - `--feature-gates=telemetry.useOtelForInternalMetrics`. 2. Enable metrics scraping as part of the configuration and add receiver into services: ```yaml theme={null} receivers: prometheus: config: scrape_configs: - job_name: 'otel-collector' scrape_interval: 5s static_configs: - targets: ['0.0.0.0:8888'] ... service: pipelines: metrics: # add prometheus among metrics receivers receivers: [prometheus] exporters: [otlp_http/prometheus, debug] ``` ### Available Metrics Available metrics contain `dataset` in their name. There are counters related to the number of processed events (`events`), buffers (`buffer`), sessions (`sessions`), and transferred bytes (`bytes`). There are also histograms related to response times (`responseTime`) and payload size (`payloadSize`). There are several counters related to events/buffers: * `enqueued` - the number of received entities * `processed` - the number of entities that were accepted by the next layer * `dropped` - the number of entities that were not accepted by the next layer * `broken` - the number of entities that were somehow corrupted during processing (should be 0) The number of entities, that are still in the queue can be computed as `enqueued - (processed + dropped + broken)`. ## Configuration ### Example Configuration ```yaml theme={null} dataset/minimal: dataset_url: https://app.scalyr.com api_key: key-minimal dataset/lib: dataset_url: https://app.eu.scalyr.com api_key: key-lib buffer: max_lifetime: 345ms group_by: - attributes.container_id - attributes.log.file.path dataset/full: dataset_url: https://app.scalyr.com api_key: key-full debug: true buffer: max_lifetime: 3456ms purge_older_than: 78s group_by: - body.map.kubernetes.pod_id - body.map.kubernetes.docker_id - body.map.stream retry_initial_interval: 21s retry_max_interval: 22s retry_max_elapsed_time: 23s retry_shutdown_timeout: 24s max_parallel_outgoing: 25 logs: export_resource_info_on_event: true export_resource_prefix: "_resource_" export_scope_info_on_event: true export_scope_prefix: "_scope_" export_separator: "_X_" export_distinguishing_suffix: "_L_" decompose_complex_message_field: true decomposed_complex_message_prefix: "_body_" traces: export_separator: "_Y_" export_distinguishing_suffix: "_T_" server_host: use_hostname: false server_host: "server-host" retry_on_failure: enabled: true initial_interval: 11 randomization_factor: 0.113 multiplier: 11.6 max_interval: 12 max_elapsed_time: 13 sending_queue: enabled: true num_consumers: 14 queue_size: 15 timeout: timeout: 16 ``` *** *Last generated: 2026-08-03* # Doris Source: https://otel.fyi/components/exporter/dorisexporter OpenTelemetry exporter for Doris # Doris Exporter ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@atoulme](https://github.com/atoulme), [@joker-star-l](https://github.com/joker-star-l) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/dorisexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-alpha-blue) ![Metrics](https://img.shields.io/badge/metrics-alpha-green) ![Traces](https://img.shields.io/badge/traces-alpha-orange) ## Overview This exporter supports sending traces, metrics, and logs data to [Apache Doris](https://doris.apache.org/) (version >= 2.1.1). ## Configuration The following configuration options are supported: * `endpoint` The http stream load address. * `database` (default = otel) The database name. * `username` The authentication username. * `password` The authentication password. * `table` * `logs` (default = otel\_logs) The table name for logs. * `traces` (default = otel\_traces) The table name for traces. * `metrics` (default = otel\_metrics) The table name for metrics. * `create_schema` (default = true) Whether databases and tables are created automatically in doris. * `mysql_endpoint` The mysql protocol address of doris. Only use to create the schema; ignored if `create_schema` is false. * `history_days` (default = 0) Data older than these days will be deleted; ignored if `create_schema` is false. If set to 0, historical data will not be deleted. * `create_history_days` (default = 0) The number of days in the history partition that was created when the table was created; ignored if `create_schema` is false. If `history_days` is not 0, `create_history_days` needs to be less than or equal to `history_days`. * `replication_num` (default = 1) The number of replicas of the table; ignored if `create_schema` is false. * `timezone` (default is the time zone of the opentelemetry collector if IANA Time Zone Database is found, else is UTC) The time zone of doris, e.g. Asia/Shanghai. * `log_response` (default = false) Whether to log the response of doris stream load. * `label_prefix` (default = open\_telemetry) the prefix of the label in doris stream load. The final generated label is \{label\_prefix}\{db}\{table}\{yyyyMMddHHmmss}\{uuid}. * `headers` (default is empty map) The headers of doris stream load. Details: [header parameters](https://doris.apache.org/docs/data-operate/import/import-way/stream-load-manual#load-configuration-parameters) and [group commit](https://doris.apache.org/docs/data-operate/import/group-commit-manual#stream-load). * `log_progress_interval` (default = 10) The interval, in seconds, between statistical logs. When it is less than or equal to 0, the statistical log is not printed. * `sending_queue` [details here](https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/exporterhelper#configuration) * `enabled` (default = true) * `num_consumers` (default = 10) Number of consumers that dequeue batches; ignored if `enabled` is false. * `queue_size` (default = 1000) Maximum number of batches kept in memory before dropping; ignored if `enabled` is false. * `retry_on_failure` [details here](https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/exporterhelper#configuration) * `enabled` (default = true) * `initial_interval` (default = 5s) Time to wait after the first failure before retrying; ignored if `enabled` is false. * `max_interval` (default = 30s) The upper bound on backoff; ignored if `enabled` is false. * `max_elapsed_time` (default = 300s) The maximum amount of time spent trying to send a batch; ignored if `enabled` is false. If set to 0, the retries are never stopped. The Doris exporter supports common [HTTP Configuration Settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confighttp/README.md#http-configuration-settings), except for compression (all requests are uncompressed). As a consequence of supporting [confighttp](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confighttp/README.md#http-configuration-settings), the Doris exporter also supports common [TLS Configuration Settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configtls/README.md#tls-configuration-settings). The Doris exporter sets `timeout` (HTTP request timeout) to 60s by default. All other defaults are as defined by [confighttp](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confighttp/README.md#http-configuration-settings). Example: ```yaml theme={null} exporters: doris: endpoint: http://localhost:8030 database: otel username: admin password: admin table: logs: otel_logs traces: otel_traces metrics: otel_metrics create_schema: true mysql_endpoint: localhost:9030 history_days: 0 create_history_days: 0 replication_num: 1 timezone: Asia/Shanghai timeout: 5s sending_queue: enabled: true num_consumers: 10 queue_size: 1000 retry_on_failure: enabled: true initial_interval: 5s max_interval: 30s max_elapsed_time: 300s ``` ## Notes 1. Time Zone The Doris exporter uses IANA Time Zone Database (known as tzdata) to handle time zones, so make sure tzdata is on your system. For example, when you use docker, you should add option `-v your/path/to/tzdata:/usr/share/zoneinfo` when running the container. ## Configuration ### Example Configuration ```yaml theme={null} doris: endpoint: http://localhost:8030 mysql_endpoint: localhost:9030 doris/full: endpoint: http://localhost:8030 database: otel username: admin password: admin table: logs: otel_logs traces: otel_traces metrics: otel_metrics create_schema: true mysql_endpoint: localhost:9030 history_days: 0 create_history_days: 0 replication_num: 2 timezone: Asia/Shanghai timeout: 5s label_prefix: otel log_response: true headers: max_filter_ratio: "0.1" strict_mode: "true" group_commit: "async_mode" log_progress_interval: 5 sending_queue: enabled: true num_consumers: 10 queue_size: 1000 retry_on_failure: enabled: true initial_interval: 5s max_interval: 30s max_elapsed_time: 300s ``` *** *Last generated: 2026-08-03* # Elasticsearch Source: https://otel.fyi/components/exporter/elasticsearchexporter OpenTelemetry exporter for Elasticsearch # Elasticsearch Exporter ![Status](https://img.shields.io/badge/status-beta-yellow) **Available in:** `contrib` **Maintainers:** [@JaredTan95](https://github.com/JaredTan95), [@blakerouse](https://github.com/blakerouse), [@carsonip](https://github.com/carsonip), [@lahsivjar](https://github.com/lahsivjar) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/elasticsearchexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-beta-blue) ![Metrics](https://img.shields.io/badge/metrics-development-green) ![Traces](https://img.shields.io/badge/traces-beta-orange) ## Overview This exporter supports sending logs, metrics, traces and profiles to [Elasticsearch](https://www.elastic.co/elasticsearch). The Exporter is API-compatible with Elasticsearch 7.17.x, 8.x, and 9.x. Certain features of the exporter, such as the `otel` mapping mode, may require newer versions of Elasticsearch. Limited effort will be made to support EOL versions of Elasticsearch -- see [https://www.elastic.co/support/eol](https://www.elastic.co/support/eol). ## Configuration options Exactly one of the following settings is required: * `endpoint` (no default): The target Elasticsearch URL to which data will be sent (e.g. `https://elasticsearch:9200`) * `endpoints` (no default): A list of Elasticsearch URLs to which data will be sent, attempted in round-robin order * `cloudid` (no default): The [Elastic Cloud ID](https://www.elastic.co/guide/en/cloud/current/ec-cloud-id.html) of the Elastic Cloud Cluster to which data will be sent (e.g. `foo:YmFyLmNsb3VkLmVzLmlvJGFiYzEyMyRkZWY0NTY=`) When the above settings are missing, `endpoints` will default to the comma-separated `ELASTICSEARCH_URL` environment variable. Elasticsearch credentials may be configured via [Authentication configuration][configauth] settings. As a shortcut, the following settings are also supported: * `user` (optional): Username used for HTTP Basic Authentication. * `password` (optional): Password used for HTTP Basic Authentication. * `api_key` (optional): [Elasticsearch API Key] in "encoded" format (e.g. `VFR2WU41VUJIbG9SbGJUdVFrMFk6NVVhVDE3SDlSQS0wM1Rxb24xdXFldw==`). Example: ```yaml theme={null} exporters: elasticsearch: endpoint: https://elastic.example.com:9200 auth: authenticator: basicauth extensions: basicauth: client_auth: username: elastic password: changeme ······ service: extensions: [basicauth] pipelines: logs: receivers: [otlp] exporters: [elasticsearch] traces: receivers: [otlp] exporters: [elasticsearch] ``` ## Advanced configuration ### HTTP settings The Elasticsearch exporter supports common [HTTP Configuration Settings][confighttp]. Gzip compression is enabled by default. To disable compression, set `compression` to `none`. Default Compression Level is set to 1 (gzip.BestSpeed). As a consequence of supporting [confighttp], the Elasticsearch exporter also supports common [TLS Configuration Settings][configtls]. ```yaml theme={null} timeout: 90s ``` The Elasticsearch exporter sets `timeout` (HTTP request timeout) to 90s by default. Note that this is per request and is independent between HTTP request retries. All other defaults are as defined by [confighttp]. ### Queuing and batching The Elasticsearch exporter supports the common [`sending_queue` settings][exporterhelper] which supports both queueing and batching. The default sending queue is configured to do async batching with the following configuration: ```yaml theme={null} sending_queue: enabled: true sizer: requests num_consumers: 10 queue_size: 10 batch: flush_timeout: 10s min_size: 1e+6 // 1MB max_size: 5e+6 // 5MB sizer: bytes ``` The default configurations are chosen to be closer to the defaults with the exporter's previous inbuilt batching feature. The [`exporterhelper` documentation][exporterhelper] provides more details on the `sending_queue` settings. ### Elasticsearch document routing Documents are statically or dynamically routed to the target index / data stream in the following order. The first routing mode that applies will be used. 1. "Static mode": Route to `logs_index` for log records, `metrics_index` for data points and `traces_index` for spans, if these configs are not empty respectively. [^3] 2. "Dynamic - Index attribute mode": Route to index name specified in `elasticsearch.index` attribute (precedence: log record / data point / span attribute > scope attribute > resource attribute) if the attribute exists. [^3] 3. "Dynamic - Data stream routing mode": Route to data stream constructed from `${data_stream.type}-${data_stream.dataset}-${data_stream.namespace}`, where `data_stream.type` is `logs` for log records, `metrics` for data points, and `traces` for spans, and is static. [^3] In a special case with `mapping::mode: bodymap`, `data_stream.type` field (valid values: `logs`, `metrics`, `traces`, `profiles`, `synthetics`) can be dynamically set from attributes. The resulting documents will contain the corresponding `data_stream.*` fields, see restrictions applied to [Data Stream Fields](https://www.elastic.co/guide/en/ecs/current/ecs-data_stream.html). 1. `data_stream.dataset` or `data_stream.namespace` in attributes (precedence: log record / data point / span attribute > scope attribute > resource attribute) 2. Otherwise, if a scope attribute with the name `encoding.format` exists and contains a string value, `data_stream.dataset` will be set to this value. Note that while enabled by default, this behaviour is considered experimental. Some encoding extensions set this field (e.g. [awslogsencodingextension](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/extension/encoding/awslogsencodingextension)), but it is not yet part of Semantic Conventions. There is the potential that the name of this routing field evolves as the [discussion progresses in SemConv](https://github.com/open-telemetry/semantic-conventions/issues/2854). 3. Otherwise, if scope name matches regex `/receiver/(\w*receiver)` or `/connector/(\w*connector)`, `data_stream.dataset` will be capture group #1 4. Otherwise, `data_stream.dataset` falls back to `generic` and `data_stream.namespace` falls back to `default`. [^3]: See additional handling in [Document routing exceptions for OTel data mode](#document-routing-exceptions-for-otel-data-mode) This can be customised through the following settings: * `logs_index` (optional): The [index] or [data stream] name to publish logs (and span events in OTel mapping mode) to. `logs_index` should be empty unless all logs should be sent to the same index. * `logs_dynamic_index` (optional): uses resource, scope, or log record attributes to dynamically construct index name. * `enabled`(DEPRECATED): No-op. Documents are now always routed dynamically unless `logs_index` is not empty. Will be removed in a future version. * `metrics_index` (optional): The [index] or [data stream] name to publish metrics to. `metrics_index` should be empty unless all metrics should be sent to the same index. Note that metrics support is currently in development. * `metrics_dynamic_index` (optional): uses resource, scope or data point attributes to dynamically construct index name. * `enabled`(DEPRECATED): No-op. Documents are now always routed dynamically unless `metrics_index` is not empty. Will be removed in a future version. * `traces_index` (optional): The [index] or [data stream] name to publish traces to. `traces_index` should be empty unless all traces should be sent to the same index. * `traces_dynamic_index` (optional): uses resource, scope, or span attributes to dynamically construct index name. * `enabled`(DEPRECATED): No-op. Documents are now always routed dynamically unless `traces_index` is not empty. Will be removed in a future version. * `logstash_format` (optional): Logstash format compatibility. Logs, metrics and traces can be written into an index in Logstash format. * `enabled`(default=false): Enable/disable Logstash format compatibility. When `logstash_format::enabled` is `true`, the index name is composed using the above dynamic routing rules as prefix and the date as suffix, e.g: If the computed index name is `logs-generic-default`, the resulting index will be `logs-generic-default-YYYY.MM.DD`. The last string appended belongs to the date when the data is being generated. * `prefix_separator`(default=`-`): Set a separator between logstash\_prefix and date. * `date_format`(default=`%Y.%m.%d`): Time format (based on strftime) to generate the second part of the Index name. * `logs_dynamic_id` (optional): Dynamically determines the document ID to be used in Elasticsearch based on a log record attribute. * `enabled`(default=false): Enable/Disable dynamic ID for log records. If `elasticsearch.document_id` exists and is not an empty string in the log record attributes, it will be used as the document ID. Otherwise, the document ID will be generated by Elasticsearch. The attribute `elasticsearch.document_id` is removed from the final document when the `otel` mapping mode is used. See [Setting a document id dynamically](#setting-a-document-id-dynamically). * `traces_dynamic_id` (optional): Dynamically determines the document ID to be used in Elasticsearch based on a span attribute. * `enabled`(default=false): Enable/Disable dynamic ID for spans. If `elasticsearch.document_id` exists and is not an empty string in the span attributes, it will be used as the document ID. For span events, this only applies when using `otel` mapping mode (where span events are stored as separate documents). Otherwise, the document ID will be generated by Elasticsearch. The attribute `elasticsearch.document_id` is removed from the final document when the `otel` mapping mode is used. See [Setting a document id dynamically](#setting-a-document-id-dynamically). #### Document routing exceptions for OTel data mode In OTel mapping mode (`mapping::mode: otel`), there is special handling in addition to the above document routing rules in [Elasticsearch document routing](#elasticsearch-document-routing). The order to determine the routing mode is the same as [Elasticsearch document routing](#elasticsearch-document-routing). 1. "Static mode": Span events are separate documents routed to `logs_index` if non-empty. 2. "Dynamic - Index attribute mode": Span events are separate documents routed using attribute `elasticsearch.index` (precedence: span event attribute > scope attribute > resource attribute) if the attribute exists. 3. "Dynamic - Data stream routing mode": * For all documents, `data_stream.dataset` will always be appended with `.otel`. * A special case to (3)(1) in [Elasticsearch document routing](#elasticsearch-document-routing), span events are separate documents that have `data_stream.type: logs` and are routed using data stream attributes (precedence: span event attribute > scope attribute > resource attribute) ### Elasticsearch document mapping The Elasticsearch exporter supports several document schemas and preprocessing behaviours, which may be configured through the following settings: * `mapping`: * `mode` (DEPRECATED): The mapping mode if supplied via config file is ignored. Use the `X-Elastic-Mapping-Mode` client metadata key or the `elastic.mapping.mode` scope attribute instead. If not specified via these methods, the default mapping mode is `otel`. * `allowed_modes` (defaults to all mapping modes): A list of allowed mapping modes. If `otel` is included in the list, it is used as the default mapping mode. Otherwise, the first entry in the list is used as the default. The mapping mode can be controlled via the client metadata key `X-Elastic-Mapping-Mode`, e.g. via HTTP headers, gRPC metadata. It is possible to restrict which mapping modes may be requested by configuring `mapping::allowed_modes`, which defaults to all mapping modes. Keep in mind that not all processors or exporter configurations will maintain client metadata. The mapping mode can also be controlled via the scope attribute `elastic.mapping.mode`. If specified, this takes precedence over the `X-Elastic-Mapping-Mode` client metadata. If any scope has an invalid mapping mode, the exporter will reject the entire batch. The attribute will be excluded from the final document. Valid mapping modes are: * `none` * `ecs` * `otel` * `raw` * `bodymap` See below for a description of each mapping mode. #### Migration: Setting mapping mode via scope attribute Since the `mapping::mode` config option is deprecated, use the following method to set the mapping mode: **Use scope attribute via transform processor** This approach sets the `elastic.mapping.mode` scope attribute on the telemetry data. ```yaml theme={null} processors: transform: log_statements: - context: scope statements: - set(attributes["elastic.mapping.mode"], "otel") trace_statements: - context: scope statements: - set(attributes["elastic.mapping.mode"], "otel") metric_statements: - context: scope statements: - set(attributes["elastic.mapping.mode"], "otel") exporters: elasticsearch: endpoint: https://elasticsearch:9200 service: pipelines: logs: receivers: [otlp] processors: [transform] exporters: [elasticsearch] ``` > \[!NOTE] > The scope attribute `elastic.mapping.mode` takes precedence over the `X-Elastic-Mapping-Mode` client metadata. > The attribute will be excluded from the final document sent to Elasticsearch. > \[!NOTE] > `otel` and `ecs` mapping modes require Elasticsearch 8.12 or above[^1]. > `otel` mode works best with Elasticsearch 8.16 or above[^2]. [^1]: as OTel and ECS mapping modes rely on the `require_data_stream` bulk action metadata, available since Elasticsearch 8.12 [^2]: Elasticsearch 8.16 contains a built-in `otel-data` plugin #### OTel mapping mode The default and recommended "OTel-native" mapping mode. In `otel` mapping mode, the Elasticsearch Exporter stores documents in Elastic's preferred "OTel-native" schema. In this mapping mode, documents use the original attribute names and closely follows the event structure from the OTLP events. There is special treatment for the following attributes: `data_stream.type`, `data_stream.dataset`, and `data_stream.namespace`. Instead of serializing these values under the `*attributes.*` namespace, they are put at the root of the document, to conform with the conventions of the data stream naming scheme that maps these as `constant_keyword` fields. `data_stream.dataset` will always be appended with `.otel` if [dynamic data stream routing mode](#elasticsearch-document-routing) is active. Span events are stored in separate documents. They will be routed with `data_stream.type` set to `logs` if [dynamic data stream routing mode](#elasticsearch-document-routing) is active. Attribute `elasticsearch.index` will be removed from the final document if exists. | Signal | Supported | | -------- | -------------------- | | Logs | :white\_check\_mark: | | Traces | :white\_check\_mark: | | Metrics | :white\_check\_mark: | | Profiles | :white\_check\_mark: | #### ECS mapping mode > \[!WARNING] > The ECS mode mapping mode is currently undergoing changes, and its behaviour is unstable. In `ecs` mapping mode, the Elasticsearch Exporter maps fields from [OpenTelemetry Semantic Conventions][SemConv] (version 1.22.0) to [Elastic Common Schema][ECS] where possible. This mode may be used for compatibility with existing dashboards that work with ECS. | Signal | `ecs` | | -------- | -------------------- | | Logs | :white\_check\_mark: | | Traces | :white\_check\_mark: | | Metrics | :white\_check\_mark: | | Profiles | :no\_entry\_sign: | In ECS mapping mode, span events are extracted as separate ECS-formatted log documents following the APM data stream convention: * Span events named `exception` with `exception.type` or `exception.message` present are routed to `logs-apm.error-`. * All other span events are routed to `logs-apm.app.-`. #### Bodymap mapping mode > \[!WARNING] > The Bodymap mode mapping mode is currently undergoing changes, and its behaviour is unstable. In `bodymap` mapping mode, the Elasticsearch Exporter supports only logs and will take the "body" of a log record as the exact content of the Elasticsearch document without any transformation. This mapping mode is intended for use cases where the client wishes to have complete control over the Elasticsearch document structure. | Signal | `bodymap` | | -------- | -------------------- | | Logs | :white\_check\_mark: | | Traces | :no\_entry\_sign: | | Metrics | :no\_entry\_sign: | | Profiles | :no\_entry\_sign: | #### Default (none) mapping mode In the `none` mapping mode the Elasticsearch Exporter produces documents with the original field names of from the OTLP data structures. | Signal | `none` | | -------- | -------------------- | | Logs | :white\_check\_mark: | | Traces | :white\_check\_mark: | | Metrics | :no\_entry\_sign: | | Profiles | :no\_entry\_sign: | #### Raw mapping mode The `raw` mapping mode is identical to `none`, except for two differences: * In `none` mode attributes are mapped with an `Attributes.` prefix, while in `raw` mode they are not. * In `none` mode span events are mapped with an `Events.` prefix, while in `raw` mode they are not. | Signal | `raw ` | | -------- | -------------------- | | Logs | :white\_check\_mark: | | Traces | :white\_check\_mark: | | Metrics | :no\_entry\_sign: | | Profiles | :no\_entry\_sign: | ### Elasticsearch ingest pipeline Documents may be optionally passed through an [Elasticsearch Ingest pipeline] prior to indexing. This can be configured through the following settings: * `pipeline` (optional): ID of an [Elasticsearch Ingest pipeline] used for processing documents published by the exporter. * `logs_dynamic_pipeline` (optional): Dynamically determines the ingest pipeline to be used in Elasticsearch based on attributes in the log signal. * `enabled`(default=false): Enable/Disable dynamic pipeline. If `elasticsearch.ingest_pipeline` attribute exists in the log record attributes and is not an empty string, it will be used as the Elasticsearch ingest pipeline. This currently only applies to the log signal. The attribute `elasticsearch.ingest_pipeline` is removed from the final document when the `otel` mapping mode is used. ### Elasticsearch bulk indexing The Elasticsearch exporter uses the [Elasticsearch Bulk API] for indexing documents. The behaviour of this bulk indexing can be configured with the following settings: * `num_workers` (DEPRECATED, use `sending_queue::num_consumers` instead): This config is deprecated and will be used to configure `sending_queue::num_consumers` if `sending_queue::num_consumers` is not explicitly defined. Number of workers publishing bulk requests concurrently. * `flush` (DEPRECATED, use `sending_queue` instead): This config is deprecated and will be used to configure different options for `sending_queue` if `sending_queue` options are not explicitly defined. Event bulk indexer buffer flush settings * `bytes` (DEPRECATED, use `sending_queue::batch::max_size` instead): This config is deprecated and will be used to configure `sending_queue::batch::max_size` if `sending_queue::batch::max_size` is not explicitly defined. See the `sending_queue::batch::max_size` for more details. * `interval` (DEPRECATED, use `sending_queue::batch::flush_timeout` instead): This config is deprecated and will be used to configure `sending_queue::batch::flush_timeout` if `sending_queue::batch::flush_timeout` is not explicitly defined. See the `sending_queue::batch::flush_timeout` for more details. * `retry`: Elasticsearch bulk request retry settings * `enabled` (default=true): Enable/Disable request retry on error. Failed requests are retried with exponential backoff. * `max_requests` (DEPRECATED, use retry::max\_retries instead): Number of HTTP request retries including the initial attempt. If used, `retry::max_retries` will be set to `max_requests - 1`. * `max_retries` (default=2): Number of HTTP request retries. To disable retries, set `retry::enabled` to `false` instead of setting `max_retries` to `0`. * `initial_interval` (default=100ms): Initial waiting time if a HTTP request failed. * `max_interval` (default=1m): Max waiting time if a HTTP request failed. * `retry_on_status` (default=\[429]): Status codes that trigger request level retries. To avoid duplicates, it defaults to `[429]`. * `retry_on_document_status` (default=same as `retry_on_status`): Status codes that trigger document level retries for failed documents in successful bulk HTTP responses. Set to `[]` to disable document level retries by status code while keeping request level retries configured through `retry_on_status`. * `sending_queue`: Configures the queueing and batching behaviour. Below are the defaults (which may vary from standard defaults), for full configuration check the [`exporterhelper` docs][exporterhelper]. * `enabled` (default=true): Enable queueing and batching behaviour. * `num_consumers` (default=10): Number of consumers that dequeue batches. * `wait_for_result` (default=false): If `true`, blocks incoming requests until processed. * `block_on_overflow` (default=false): If `true`, blocks the request until the queue has space. * `sizer` (default=requests): Measure queueing by requests. * `queue_size` (default=10): Maximum size the queue can accept. * `batch`: * `flush_timeout` (default=10s): Time after which batch is exported irrespective of other settings. * `sizer` (default=bytes): Size batches by bytes. Note that bytes here are based on the pdata model and not on the NDJSON docs that will constitute the bulk indexer requests. To address this discrepancy, the bulk indexers could also flush when their size exceeds the configured max\_size due to size of pdata model being smaller than their corresponding NDJSON encoding. * `min_size` (default=1MB): Min size of the batch. * `max_size` (default=5MB): Max size of the batch. This value should be much lower than [Elasticsearch's `http.max_content_length`](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html#http-settings) config to avoid HTTP 413 Entity Too Large error. It is recommended to keep this value under 5MB. #### Bulk indexing error response With Elasticsearch 8.18+, a new [query parameter `include_source_on_error`](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-bulk#operation-bulk-include_source_on_error) allows users to receive the source document in the error response, if there were any parsing errors in the bulk request. In the exporter, the equivalent configuration is also named `include_source_on_error`. * `include_source_on_error`: * `true`: Enables bulk index responses to include source document on error. Requires Elasticsearch 8.18+. WARNING: the exporter may log error responses containing request payload, causing potential sensitive data to be exposed in logs. * `false`: Disables including source document on bulk index error responses. Requires Elasticsearch 8.18+. * `null` (default): Backward-compatible option for older Elasticsearch versions. By default, the error reason is discarded from bulk index responses entirely, i.e. only error type is returned. ### Elasticsearch node discovery The Elasticsearch Exporter will regularly check Elasticsearch for available nodes. Newly discovered nodes will automatically be used for load balancing. Settings related to node discovery are: * `discover`: * `on_start` (optional): If enabled the exporter queries Elasticsearch for all known nodes in the cluster on startup. * `interval` (optional): Interval to update the list of Elasticsearch nodes. Node discovery can be disabled by setting `discover.interval` to 0. ### Telemetry settings The Elasticsearch Exporter's own telemetry settings for testing and debugging purposes. ⚠️ This is experimental and may change at any time. * `telemetry`: * `log_request_body` (default=false): Logs Elasticsearch client request body as a field in a log line at DEBUG level. It requires `service::telemetry::logs::level` to be set to `debug`. WARNING: Enabling this config may expose sensitive data. * `log_response_body` (default=false): Logs Elasticsearch client response body as a field in a log line at DEBUG level. It requires `service::telemetry::logs::level` to be set to `debug`. WARNING: Enabling this config may expose sensitive data. * `log_failed_docs_input` (default=false): Include the input (action line and document line) causing indexing error under `input` field in a log line at DEBUG level. It requires `service::telemetry::logs::level` to be set to `debug`. WARNING: Enabling this config may expose sensitive data. * `log_failed_docs_input_rate_limit` (default="1s"): Rate limiting of logs emitted by `log_failed_docs_input` config, e.g. "1s" means roughly 1 log line per second. A zero or negative value disables rate limiting. ### Metadata keys Metadata keys are a list of client metadata keys that the exporter uses to partition batches when `sending_queue` is enabled with batching support and enrich internal telemetry. ⚠️ This is experimental and may change at any time. * `metadata_keys` (optional): List of metadata keys that will be used to partition the data into batches if [sending\_queue][exporterhelper] is enabled with batching support. With batching enabled only these metadata keys are guaranteed to be propagated. The keys will also be used to enrich the exporter's internal telemetry if defined. The keys are extracted from the client metadata available via the context and added to the internal telemetry as attributes. NOTE: The metadata keys are converted to lower case as key lookups for client metadata is case insensitive. This means that the metric produced by internal telemetry will also have the attribute in lower case. ## Exporting metrics Metrics support is currently in development. The metric types supported are: * Gauge * Sum * Histogram (Delta temporality only) * Exponential histogram (Delta temporality only) * Summary ### Metrics dynamic templates For metrics, the exporter sends **per-document `dynamic_templates`** with each bulk index action so that Elasticsearch can apply the correct mapping to metric fields. It uses the [bulk API `dynamic_templates` parameter](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-bulk): > A map from the full name of fields to the name of dynamic templates. It defaults to an empty map. If a name matches a dynamic template, that template will be applied regardless of other match predicates defined in the template. If a field is already defined in the mapping, then this parameter won't be used. The index template must define dynamic templates whose names match the values sent by the exporter. Behavior depends on the mapping mode: | Mapping mode | Field path in document | Template names sent | Notes | | ------------ | ----------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **OTel** | `metrics.` | `histogram`, `summary`, `gauge_double`, `gauge_long`, `counter_double`, `counter_long` | The OTel data plugin defines more specific templates. | | **ECS** | `metric.` | `histogram_metrics`, `summary_metrics`, `double_metrics` | Relies on core templates in [metrics@mappings](https://github.com/elastic/elasticsearch/blob/8.15/x-pack/plugin/core/template-resources/src/main/resources/metrics%40mappings.json). Intended to match the [APM metrics ingest pipeline](https://github.com/elastic/elasticsearch/blob/b34960a2b450869aee2866e91c647e0026dd6953/x-pack/plugin/apm-data/src/main/resources/ingest-pipelines/metrics-apm%40pipeline.yaml). | * **OTel**: Each metric is written under the `metrics` object; the bulk action maps full field names (e.g. `metrics.my_metric`) to one of the OTel template names above based on metric type (histogram, summary, gauge, or counter) and value type. * **ECS**: Each metric is written as a top-level field `metric.`; the bulk action maps that field name to one of the ECS/APM template names (`histogram_metrics`, `summary_metrics`, or `double_metrics` for gauges and counters). ### Bulk Response Filter Path The Elasticsearch bulk API accepts a [filter\_path](https://www.elastic.co/docs/reference/elasticsearch/rest-apis/common-options#common-options-response-filtering) parameter. This can be used to reduce the response returned by Elasticsearch. The exporter uses a default `filter_path` that is set by the [go-docappender](https://github.com/elastic/go-docappender). The default is currently `items.*._index,items.*.status,items.*.failure_store,items.*.error.type,items.*.error.reason` and is defined by the `DefaultFilterPath` in the [go-docappnder](https://github.com/elastic/go-docappender) package. If you want to change the `filter_path` you may do so by setting `bulk_response_filter_path` to the desired string in the configuration. > \[!NOTE] > If `items.*._index.items` is not in the BulkResponseFilterPath than for any failed documents, the exporter will not be able to log the index to which the document was being written to. > \[!NOTE] > If `items.*._index.items` is not in the BulkResponseFilterPath than the exporter will log rejection of duplicates to ".profiling-stackframes" which were previously suppressed. ## Exporting profiles Profiles support is currently in development, and should not be used in production. Profiles only support the OTel mapping mode. Example: ```yaml theme={null} exporters: elasticsearch: endpoint: https://elastic.example.com:9200 mapping: mode: otel ``` > \[!IMPORTANT] > For the Elasticsearch Exporter to be able to export Profiles data, Universal Profiling needs to be installed in the database. > See [the Universal Profiling getting started documentation](https://www.elastic.co/guide/en/observability/current/profiling-get-started.html) > You will need to use the Elasticsearch endpoint, with an [Elasticsearch API key](https://www.elastic.co/guide/en/kibana/current/api-keys.html). [confighttp]: https://github.com/open-telemetry/opentelemetry-collector/tree/main/config/confighttp/README.md#http-configuration-settings [configtls]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configtls/README.md#tls-configuration-settings [configauth]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configauth/README.md#authentication-configuration [exporterhelper]: https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md [Elasticsearch Ingest pipeline]: https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest.html [Elasticsearch Bulk API]: https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html [Elasticsearch API Key]: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html [index]: https://www.elastic.co/guide/en/elasticsearch/reference/current/indices.html [data stream]: https://www.elastic.co/guide/en/elasticsearch/reference/current/data-streams.html [ecs]: https://www.elastic.co/guide/en/ecs/current/index.html [SemConv]: https://github.com/open-telemetry/semantic-conventions ## ECS Mapping `elasticsearchexporter` follows ECS mapping defined here: [https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model-appendix.md#elastic-common-schema](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model-appendix.md#elastic-common-schema) When `mode` is set to `ecs`, `elasticsearchexporter` performs conversions for resource-level and record-level (log or trace) attributes from their Semantic Conventions (SemConv) names to equivalent Elastic Common Schema (ECS) names. If the target ECS field name is specified as an empty string (`""`), the converter will neither convert the SemConv key to the equivalent ECS name nor pass through the SemConv key as-is to become the ECS name. When "Preserved" is true, the attribute will be preserved in the payload and duplicated as mapped to its ECS equivalent. When more than one SemConv attribute maps to the same ECS attribute, the converter will map all attributes to the same ECS name. This is mean to support backwards compatibility for SemConv attributes that have been renamed/deprecated. The value of the last-mapped attribute will take precedence. It is recommended to enrich events using the [elasticapmprocessor](https://github.com/elastic/opentelemetry-collector-components/tree/main/processor/elasticapmprocessor) to ensure index documents contain all required Elastic fields to power the Kibana UI. ### Resource attribute mapping | Semantic Convention Name | ECS Name | Preserve | Skip if exists | | --------------------------- | --------------------------- | -------- | -------------- | | client.address | client.ip | false | false | | cloud.platform | cloud.service.name | false | false | | container.image.tags | container.image.tag | false | false | | deployment.environment | service.environment | false | false | | deployment.environment.name | service.environment | false | false | | faas.instance | faas.id | false | false | | faas.trigger | faas.trigger.type | false | false | | host.arch | host.architecture | false | false | | host.hostname | host.hostname | true | true | | k8s.cluster.name | orchestrator.cluster.name | false | false | | k8s.container.name | kubernetes.container.name | false | false | | k8s.cronjob.name | kubernetes.cronjob.name | false | false | | k8s.daemonset.name | kubernetes.daemonset.name | false | false | | k8s.deployment.name | kubernetes.deployment.name | false | false | | k8s.job.name | kubernetes.job.name | false | false | | k8s.namespace.name | kubernetes.namespace | false | false | | k8s.node.name | kubernetes.node.name | false | false | | k8s.pod.name | kubernetes.pod.name | false | false | | k8s.pod.uid | kubernetes.pod.uid | false | false | | k8s.replicaset.name | kubernetes.replicaset.name | false | false | | k8s.statefulset.name | kubernetes.statefulset.name | false | false | | os.description | host.os.full | false | false | | os.name | host.os.name | false | false | | os.type | host.os.platform | false | false | | os.version | host.os.version | false | false | | process.command\_line | process.args | false | false | | process.executable.name | process.title | false | false | | process.executable.path | process.executable | false | false | | process.parent.pid | process.parent.pid | false | false | | process.runtime.name | service.runtime.name | false | false | | process.runtime.version | service.runtime.version | false | false | | service.instance.id | service.node.name | false | false | | source.address | source.ip | false | false | | telemetry.distro.name | "" | false | false | | telemetry.distro.version | "" | false | false | | telemetry.sdk.language | service.language.name | false | false | | telemetry.sdk.name | "" | false | false | | telemetry.sdk.version | service.language.version | false | false | ### Log record attribute mapping | Semantic Convention Name | ECS Name | Preserve | | ------------------------ | --------------------------------- | -------- | | event.name | event.action | false | | exception.message | error.message | false | | exception.stacktrace | error.stacktrace | false | | exception.type | error.type | false | | exception.escaped | event.error.exception.handled | false | | http.response.body.size | http.response.encoded\_body\_size | false | ### Span attribute mapping | Semantic Convention Name | ECS Name | Preserve | | ------------------------ | --------------------------------- | -------- | | db.system | span.db.type | false | | db.namespace | span.db.instance | false | | db.query.text | span.db.statement | false | | http.response.body.size | http.response.encoded\_body\_size | false | ### Compound Mapping There are ECS fields that are not mapped easily 1 to 1 but require more advanced logic. #### `host.name` and `host.hostname` Maintains the SemConv Value `host.name` as ECS Value `host.name` and maps it to ECS Value `host.hostname`, if this does not already exist. #### `@timestamp` In case the record contains `timestamp`, this value is used. Otherwise, the `observed timestamp` is used. ## Setting a document id dynamically The `logs_dynamic_id` and `traces_dynamic_id` settings allow users to set the document ID dynamically based on log record, span, or span event attributes. Besides the ability to control the document ID, these settings also work as a deduplication mechanism, as Elasticsearch will refuse to index a document with the same ID. For logs, the log record attribute `elasticsearch.document_id` can be set explicitly by a processor based on the log record. For traces, the span attribute `elasticsearch.document_id` (or span event attribute for span events) can be set explicitly by a processor based on the span or span event. As an example, the `transform` processor can create this attribute dynamically for logs: ```yaml theme={null} processors: transform/es-doc-id: error_mode: ignore log_statements: - context: log condition: attributes["event_name"] != null && attributes["event_creation_time"] != null statements: - set(attributes["elasticsearch.document_id"], Concat(["log", attributes["event_name"], attributes["event_creation_time"], "-")) ``` For traces, you can use the `transform` processor to set the document ID based on trace and span IDs to ensure uniqueness: ```yaml theme={null} exporters: elasticsearch: mapping: mode: otel # Required for span events to be separate documents traces_dynamic_id: enabled: true processors: transform/es-doc-id-traces: error_mode: ignore trace_statements: - context: span statements: # Set ID for spans - set(attributes["elasticsearch.document_id"], Concat([trace_id.string, span_id.string], "-")) - context: spanevent statements: # Set ID for span events (only works in otel mapping mode) - set(attributes["elasticsearch.document_id"], Concat([trace_id.string, span_id.string, name], "-")) ``` **Note**: Span events are only stored as separate documents in `otel` mapping mode. In other mapping modes (ecs, bodymap, raw), span events are embedded within the span document and will not have separate document IDs. ## Known issues ### version\_conflict\_engine\_exception Symptom: `elasticsearchexporter` logs an error "failed to index document" with `error.type` "version\_conflict\_engine\_exception" and `error.reason` containing "version conflict, document already exists". This happens when the target data stream is a TSDB metrics data stream (e.g. using OTel mapping mode sending to a 8.16+ Elasticsearch, or ECS mapping mode sending to system integration data streams). Elasticsearch [Time Series Data Streams](https://www.elastic.co/guide/en/elasticsearch/reference/current/tsds.html) requires that there must only be one document per timestamp with the same dimensions. The purpose is to avoid duplicate data when re-trying a batch of metrics that were previously sent but failed to be indexed. The dimensions are mostly made up of resource attributes, scope attributes, scope name, attributes, and the unit. The exporter can only group metrics with the same dimensions into the same document if they arrive in the same batch. To ensure metrics are not dropped even if they arrive in different batches in the exporter, the exporter adds a fingerprint of the metric names to the document in the `otel` mapping mode. Note that this functionality requires both * minimum Elasticsearch Exporter version 0.121.0 * minimum Elasticsearch version 8.17.6, 8.18.1, 8.19.0, 9.0.1, or 9.1.0 If you are on an earlier version of Elasticsearch, either update your cluster or install this custom component template: ```shell theme={null} PUT _component_template/metrics-otel@custom { "template": { "mappings": { "properties": { "_metric_names_hash": { "type": "keyword", "time_series_dimension": true } } } } } ``` After installing this component template, if you've previously ingested data, you'll need to wait until the old index of the time series data stream reaches its `end_time`. This can take up to 30 minutes by default. See [time series index look-ahead time](https://www.elastic.co/docs/reference/elasticsearch/index-settings/time-series) for more information. While in most situations, this error is just a sign that Elasticsearch's duplicate detection is working as intended, the data may be classified as a duplicate while it was not. This implies data is lost. 1. If the data is not sent in `otel` mapping mode to `metrics-*.otel-*` data streams, the metrics name fingerprint is not applied. This can happen for OTel host and k8s metrics that the [`elasticinframetricsprocessor`](https://github.com/elastic/opentelemetry-collector-components/tree/main/processor/elasticinframetricsprocessor) has translated to the format the host and k8s dashboards in Kibana can consume. If these metrics arrive in the `elasticsearchexporter` in different batches, they will not be grouped to the same document. This can cause the `version_conflict_engine_exception` error. Try to remove the `batchprocessor` from the pipeline (or set `send_batch_max_size: 0`) to ensure metrics are not split into different batches. This gives the exporter the opportunity to group all related metrics into the same document. 2. Otherwise, check your metrics pipeline setup for misconfiguration that causes an actual violation of the [single writer principle](https://opentelemetry.io/docs/specs/otel/metrics/data-model/#single-writer). This means that the same metric with the same dimensions is sent from multiple sources, which is not allowed in the OTel metrics data model. ### flush failed (400) illegal\_argument\_exception Symptom: bulk indexer logs an error that indicates "bulk indexer flush error" with bulk request returning HTTP 400 and an error type of `illegal_argument_exception`, similar to the following. ``` error elasticsearchexporter@v0.120.1/bulkindexer.go:343 bulk indexer flush error { "otelcol.component.id": "elasticsearch", "otelcol.component.kind": "Exporter", "otelcol.signal": "logs", "error": "flush failed (400): {\"error\":{\"type\":\"illegal_argument_exception\",\"caused_by\":{}}}" } ``` In this scenario, Elasticsearch may reject the bulk request because the `require_data_stream` bulk action metadata is not supported. This may happen when you use [OTel mapping mode](#otel-mapping-mode) (the default mapping mode from v0.122.0, or explicitly by configuring `mapping::mode: otel`) or [ECS mapping mode](#ecs-mapping-mode), and send data to Elasticsearch version \< 8.12. To resolve this, upgrade Elasticsearch to 8.12+; for OTel mapping mode, 8.16+ is recommended. Alternatively, try other mapping modes, but the document structure will be different. ### "dropping cumulative temporality histogram" and "dropping cumulative temporality exponential histogram" Symptom: `elasticsearchexporter` logs a warning `dropping cumulative temporarily histogram` similar to: ``` warn elasticsearchexporter@v0.132.0/exporter.go:340 validation errors { "resource": { "service.instance.id": "33ffe7e8-e944-4f92-8fce-9094f4b61d1d", "service.name": "./elastic-agent", "service.version": "9.1.5" }, "otelcol.component.id": "elasticsearch/otel", "otelcol.component.kind": "exporter", "otelcol.signal": "metrics", "error": "dropping cumulative temporality histogram \"http.client.request.duration\"" } ``` This issue occurs because Elasticsearch does not support **cumulative temporality** for histograms. As a workaround, you can either: * Export histogram metrics using **delta temporality**, or * Apply a `cumulativetodelta` processor. For more details, see [Metrics data ingestion](https://www.elastic.co/docs/reference/opentelemetry/compatibility/limitations#metrics-data-ingestion). ## Attributes | Attribute Name | Description | Type | Values | | --------------------------- | -------------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------ | | `error.type` | The type of error that occurred when processing the documents. | string | | | `failure_store` | The status of the failure store. | string | `unknown`, `not_enabled`, `used`, `failed` | | `http.response.status_code` | HTTP status code. | int | | | `outcome` | The operation outcome. | string | `success`, `failed_client`, `failed_server`, `timeout`, `too_many`, `failure_store`, `internal_server_error` | ## Configuration ### Example Configuration ```yaml theme={null} elasticsearch: endpoints: [https://elastic.example.com:9200] elasticsearch/trace: tls: insecure: false endpoints: [https://elastic.example.com:9200] timeout: 2m headers: myheader: test traces_index: trace_index traces_dynamic_index: enabled: false logs_dynamic_index: enabled: false metrics_dynamic_index: enabled: false pipeline: mypipeline user: elastic password: search api_key: AvFsEiPs== discover: on_start: true retry: max_retries: 5 retry_on_status: - 429 - 500 elasticsearch/metric: tls: insecure: false endpoints: [http://localhost:9200] metrics_index: my_metric_index traces_dynamic_index: enabled: false logs_dynamic_index: enabled: false metrics_dynamic_index: enabled: false timeout: 2m headers: myheader: test pipeline: mypipeline user: elastic password: search api_key: AvFsEiPs== discover: on_start: true retry: max_retries: 5 retry_on_status: - 429 - 500 elasticsearch/log: tls: insecure: false endpoints: [http://localhost:9200] logs_index: my_log_index traces_dynamic_index: enabled: false logs_dynamic_index: enabled: false metrics_dynamic_index: enabled: false timeout: 2m headers: myheader: test pipeline: mypipeline user: elastic password: search api_key: AvFsEiPs== discover: on_start: true retry: max_retries: 5 retry_on_status: - 429 - 500 elasticsearch/logstash_format: endpoints: [http://localhost:9200] logstash_format: enabled: true elasticsearch/raw: endpoints: [http://localhost:9200] mapping: mode: raw elasticsearch/cloudid: cloudid: foo:YmFyLmNsb3VkLmVzLmlvJGFiYzEyMyRkZWY0NTY= elasticsearch/confighttp_endpoint: endpoint: https://elastic.example.com:9200 elasticsearch/compression_none: endpoint: https://elastic.example.com:9200 compression: none elasticsearch/compression_gzip: endpoint: https://elastic.example.com:9200 compression: gzip elasticsearch/include_source_on_error: endpoint: https://elastic.example.com:9200 include_source_on_error: true elasticsearch/metadata_keys: endpoint: https://elastic.example.com:9200 metadata_keys: - x-test-1 - x-test-2 elasticsearch/sendingqueue_disabled: endpoint: https://elastic.example.com:9200 sending_queue: enabled: false elasticsearch/sendingqueue_enabled: endpoint: https://elastic.example.com:9200 sending_queue: enabled: true sizer: requests num_consumers: 100 batch: flush_timeout: 1s sizer: items min_size: 1000 max_size: 5000 elasticsearch/backward_compat_for_deprecated_cfgs/new_config_takes_priority: endpoint: https://elastic.example.com:9200 # Should be ignored and left as-is num_workers: 11 flush: interval: 11s bytes: 1001 # Should take precedence sending_queue: enabled: true sizer: requests num_consumers: 111 batch: flush_timeout: 111s max_size: 1_000_001 sizer: bytes elasticsearch/backward_compat_for_deprecated_cfgs/fallback_to_old_cfg: endpoint: https://elastic.example.com:9200 # Should be used to set sending_queue config num_workers: 11 flush: interval: 11s bytes: 1_000_001 sending_queue: enabled: true sizer: requests batch: sizer: bytes elasticsearch/suppress_conflict_errors: endpoint: https://elastic.example.com:9200 suppress_conflict_errors: true elasticsearch/retry_on_document_status: endpoint: https://elastic.example.com:9200 retry: retry_on_status: [429, 500] retry_on_document_status: [400, 409] elasticsearch/retry_on_document_status_empty: endpoint: https://elastic.example.com:9200 retry: retry_on_status: [429, 500] retry_on_document_status: [] ``` *** *Last generated: 2026-08-03* # Faro Source: https://otel.fyi/components/exporter/faroexporter OpenTelemetry exporter for Faro # Faro Exporter ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `contrib` **Maintainers:** [@dehaansa](https://github.com/dehaansa), [@rlankfo](https://github.com/rlankfo), [@mar4uk](https://github.com/mar4uk) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/faroexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-alpha-blue) ![Traces](https://img.shields.io/badge/traces-alpha-orange) ## Overview The Faro exporter sends telemetry data to a [Faro](https://grafana.com/oss/faro/) endpoint. ## Configuration The following settings are required: * `endpoint` (no default): The URL to send telemetry data to (e.g., [https://faro.example.com/collect](https://faro.example.com/collect)). The following settings can be optionally configured: * `sending_queue` * `enabled` (default = true) * `num_consumers` (default = 10) * `queue_size` (default = 1000) * `retry_on_failure` * `enabled` (default = true) * `initial_interval` (default = 5s): Time to wait after the first failure before retrying. * `max_interval` (default = 30s): Upper bound on backoff. * `max_elapsed_time` (default = 300s): Maximum amount of time spent trying to send a batch. * `timeout` (default = 5s): HTTP request timeout when sending data. * `read_buffer_size` (default = 0): Size of the buffer used to read the response body. * `write_buffer_size` (default = 512 KiB): Size of the buffer used to write the request body. * `headers` (default = `{}`): Additional headers to send with the request. * `compression` (default = none): Compression method to use for the request body. Supported values: `none`, `gzip`. Example: ```yaml theme={null} exporters: faro: endpoint: https://faro.example.com/collect timeout: 10s headers: X-API-Key: "my-api-key" ``` The full list of settings exposed for this exporter are documented [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/faroexporter/config.go) with detailed sample configurations [here](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/faroexporter/testdata/config.yaml). ## Getting Started The following settings are required: * `endpoint` (no default): URL to which the exporter is going to send Faro telemetry data. For example: `https://faro.example.com/collect`. To use TLS, specify `https://` as the protocol scheme in the URL passed to the `endpoint` property. See [Advanced Configuration](#advanced-configuration) for more TLS options. Example: ```yaml theme={null} exporters: faro: endpoint: "https://faro.example.com/collect" faro/tlsnoverify: endpoint: "https://faro.example.com/collect" tls: insecure_skip_verify: true ``` ## Advanced Configuration Several helper files are leveraged to provide additional capabilities automatically: * [HTTP client settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confighttp/README.md#client-configuration) * [TLS and mTLS settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configtls/README.md) * [Queuing, retry and timeout settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md) ## Configuration ### Example Configuration ```yaml theme={null} receivers: nop: processors: nop: exporters: faro: endpoint: https://faro.example.com/collect timeout: 10s headers: X-API-Key: "my-api-key" faro/with_queue_settings: endpoint: https://faro.example.com/collect sending_queue: enabled: true num_consumers: 2 queue_size: 10 faro/with_retry_settings: endpoint: https://faro.example.com/collect retry_on_failure: enabled: true initial_interval: 10s max_interval: 60s max_elapsed_time: 10m faro/with_compression: endpoint: https://faro.example.com/collect compression: gzip service: pipelines: traces: receivers: [nop] processors: [nop] exporters: [faro] metrics: receivers: [nop] processors: [nop] exporters: [faro] logs: receivers: [nop] processors: [nop] exporters: [faro] ``` *** *Last generated: 2026-08-03* # File Source: https://otel.fyi/components/exporter/fileexporter OpenTelemetry exporter for File # File Exporter ![Status](https://img.shields.io/badge/status-alpha-red) **Available in:** `core`, `contrib`, `k8s` **Maintainers:** [@paulojmdias](https://github.com/paulojmdias) **Source:** [opentelemetry-collector-contrib](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/fileexporter) ## Supported Telemetry ![Logs](https://img.shields.io/badge/logs-alpha-blue) ![Metrics](https://img.shields.io/badge/metrics-alpha-green) ![Traces](https://img.shields.io/badge/traces-alpha-orange) ## Overview Writes telemetry data to files on disk. Use the [OTLP JSON File receiver](../../receiver/otlpjsonfilereceiver/README.md) to read the data back into the collector (as long as the data was exported using OTLP JSON format). Exporter supports the following features: * Support for writing pipeline data to a file. * Support for rotation of telemetry files. * Support for compressing the telemetry data before exporting. * Support for writing into multiple files, where the file path is determined by a resource attribute. Please note that there is no guarantee that exact field names will remain stable. The official [opentelemetry-collector-contrib container](https://hub.docker.com/r/otel/opentelemetry-collector-contrib/tags#!) does not have a writable filesystem by default since it's built on the `scratch` layer. As such, you will need to create a writable directory for the path. You could do this by [mounting a volume](https://docs.docker.com/storage/volumes/#choose-the--v-or---mount-flag) with flags such as `rw` or `rwZ`. On Linux, and given a `otel-collector-config.yaml` with a `file` exporter whose path is prefixed with `/file-exporter`, ```bash theme={null} mkdir --mode o+rwx file-exporter # z is an SELinux construct that is ignored on other systems docker run -v "./file-exporter:/file-exporter:rwz" -v "otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml" otel/opentelemetry-collector-contrib:latest ``` Note this same syntax for volumes will work with docker-compose. You could also modify the base image and manually build your own container to have a writeable directory or change the runas uid if needed, but this is more involved. ## Configuration options: The following settings are required: * `path` \[no default]: where to write information. The following settings are optional: * `rotation` settings to rotate telemetry files. * max\_megabytes: \[default: 100]: the maximum size in megabytes of the telemetry file before it is rotated. * max\_days: \[no default (unlimited)]: the maximum number of days to retain telemetry files based on the timestamp encoded in their filename. * max\_backups: \[default: 100]: the maximum number of old telemetry files to retain. * localtime : \[default: false (use UTC)] whether or not the timestamps in backup files is formatted according to the host's local time. * `format`\[default: json]: define the data format of encoded telemetry data. The setting can be overridden with `proto`. * `encoding`\[default: none]: if specified, uses an encoding extension to encode telemetry data. Overrides `format`. * `append`\[default: `false`] defines whether append to the file (`true`) or truncate (`false`). If `append: true` is set then setting `rotation` is currently not supported. * `compression`\[no default]: the compression algorithm used when exporting telemetry data to file. Supported compression algorithms:`zstd` * `compression_params` * `level` (default = 0): the compression level used when exporting telemetry data. * The following are valid combinations of `compression` and `level`: * `zstd` * SpeedFastest: `1` * SpeedDefault: `3` * SpeedBetterCompression: `6` * SpeedBestCompression: `11` * `flush_interval`\[default: 1s]: `time.Duration` interval between flushes. See [time.ParseDuration](https://pkg.go.dev/time#ParseDuration) for valid formats. NOTE: a value without unit is in nanoseconds and `flush_interval` is ignored and writes are not buffered if `rotation` is set. * `create_directory`\[default: false]: when set, the exporter will create the parent directory of the configured `path` if it does not exist. * `directory_permissions`\[default: 0755]: file mode (octal string) used when creating directories, minus the process umask. This also applies to directories created by `group_by`. * `group_by` enables writing to separate files based on a resource attribute. * enabled: \[default: false] enables group\_by. * resource\_attribute: \[default: fileexporter.path\_segment]: specifies the name of the resource attribute that contains the path segment of the file to write to. The final path will be the `path` config value, with the `*` replaced with the value of this resource attribute. * max\_open\_files: \[default: 100]: specifies the maximum number of open file descriptors for the output files. ## File Rotation Telemetry data is exported to a single file by default. `fileexporter` only enables file rotation when the user specifies `rotation:` in the config. However, if specified, related default settings would apply. Telemetry is first written to a file that exactly matches the `path` setting. When the file size exceeds `max_megabytes` or age exceeds `max_days`, the file will be rotated. When a file is rotated, **it is renamed by putting the current time in a timestamp** in the name immediately before the file's extension (or the end of the filename if there's no extension). **A new telemetry file will be created at the original `path`.** For example, if your `path` is `data.json` and rotation is triggered, this file will be renamed to `data-2022-09-14T05-02-14.173.json`, and a new telemetry file created with `data.json` ## File Compression Telemetry data is compressed according to the `compression` setting. `fileexporter` does not compress data by default. > \[!NOTE] > An alpha feature gate `exporter.file.nativeCompression` is available that switches from > per-message compression to native file-level compression, producing standard `.zst` files > compatible with tools like `zstd -d`. See [Feature Gates](documentation.md) for details. Currently, `fileexporter` support the `zstd` compression algorithm, and we will support more compression algorithms in the future. ## File Format Telemetry data is encoded according to the `format` setting and then written to the file. When `format` is json and `compression` is none , telemetry data is written to file in JSON format. Each line in the file is a JSON object. Otherwise, when using `proto` format or any kind of encoding, each encoded object is preceded by 4 bytes (an unsigned 32 bit integer) which represent the number of bytes contained in the encoded object.When we need read the messages back in, we read the size, then read the bytes into a separate buffer, then parse from that buffer. ## Group by attribute By specifying `group_by.resource_attribute` in the config, the exporter will determine a filepath for each telemetry record, by substituting the value of the resource attribute into the `path` configuration value. The final path is guaranteed to start with the prefix part of the `path` config value (the part before the `*` character). For example if `path` is "/data/\*.json", and the resource attribute value is "../etc/my\_config", then the final path will be sanitized to "/data/etc/my\_config.json". The final path can contain path separators (`/`). The exporter will create missing directories recursively (similarly to `mkdir -p`). Grouping by attribute currently only supports a **single** **resource** attribute. If you would like to use multiple attributes, please use [Transform processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor) create a routing key. If you would like to use a non-resource level (eg: Log/Metric/DataPoint) attribute, please use [Group by Attributes processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/groupbyattrsprocessor) first. ## Example: ```yaml theme={null} exporters: file/no_rotation: path: ./foo file/rotation_with_default_settings: path: ./foo rotation: file/rotation_with_custom_settings: path: ./foo rotation: max_megabytes: 10 max_days: 3 max_backups: 3 localtime: true format: proto compression: zstd compression_params: level: 6 file/flush_every_5_seconds: path: ./foo flush_interval: 5 ``` ## Get Started in an existing cluster We will follow the [documentation](https://opentelemetry.io/docs/k8s-operator/) to first install the operator in an existing cluster and then create an OpenTelemetry Collector (otelcol) instance, mounting an additional volume under `/data` under which the file exporter will write `metrics.json`: ```shell theme={null} kubectl apply -f - < Alternatives If you obtained OS-specific packages or built your own binary in step 1, you'll need to follow the appropriate conventions for running the collector. 5. **Gather telemetry.** Run an application that can submit OTLP-formatted metrics and traces, and configure it to send them to `127.0.0.1:4317` (for gRPC) or `127.0.0.1:55681` (for HTTP).
Alternatives * Set up the host metrics receiver, which will gather telemetry from the host without needing an external application to submit telemetry. * Set up an application-specific receiver, such as the Nginx receiver, and run the corresponding application. * Set up a receiver for some other protocol (such Prometheus, StatsD, Zipkin or Jaeger), and run an application that speaks one of those protocols.
6. **View telemetry in GCP.** Use the GCP [metrics explorer](https://console.cloud.google.com/monitoring/metrics-explorer) and [trace overview](https://console.cloud.google.com/traces) to view your newly submitted telemetry. ## Configuration reference The following configuration options are supported: * `project` (default = Fetch from Credentials): GCP project identifier. * `destination_project_quota` (optional, default = false): Counts quota against the project to which the data is sent (as opposed to the project associated with the Collector's service account. For example, when setting `project_id` or using [multi-project export](#multi-project-exporting). * `user_agent` (default = `collector description/version os/arch`, i.e. `opentelemetry-collector-contrib/v0.139.0 linux/amd64`): Override the user agent string sent on requests to Cloud Monitoring (currently only applies to metrics). Specify `{{version}}` to include the application version number. * `timeout` (default = `12s`) The timeout for requests to Google Cloud Platform APIs, specified in Go Time Duration format. * `impersonate` (optional): Configuration for service account impersonation * `target_principal`: TargetPrincipal is the email address of the service account to impersonate. * `subject`: (optional) Subject is the sub field of a JWT. This field should only be set if you wish to impersonate as a user. This feature is useful when using domain wide delegation. * `delegates`: (default = \[]) Delegates are the service account email addresses in a delegation chain. Each service account must be granted roles/iam.serviceAccountTokenCreator on the next service account in the chain. * `metric` (optional): Configuration for sending metrics to Google Cloud Monitoring. * `prefix` (default = `workload.googleapis.com`): The prefix to add to metrics. * `endpoint` (default = `monitoring.googleapis.com`): Endpoint where metric data is going to be sent to. * `use_insecure` (default = false): If true, disables gRPC client transport security. Only has effect if Endpoint is not "". * `compression` (optional, supported values: \[`gzip`]): Compression format for Metrics gRPC requests. Defaults to no compression. * `grpc_pool_size` (optional): Sets the size of the connection pool in the GCP client. Defaults to a single connection. * `known_domains` (default = \[googleapis.com, kubernetes.io, istio.io, knative.dev]): If a metric belongs to one of these domains it does not get a prefix. * `skip_create_descriptor` (default = false): If set to true, do not send metric descriptors to Google Cloud Monitoring. * `instrumentation_library_labels` (default = true): If true, the exporter will copy the OTLP `InstrumentationScope.Name` to a label `instrumentation_source` and `InstrumentationScope.Version` to a label `instrumentation_version` labels on metrics. * `service_resource_labels` (default = true): If true, the exporter will copy the Semantic Conventions `service.name`, `service.namespace`, and `service.instance.id` from OTLP Resource Attributes into the Google Cloud Monitoring timeseries metric labels. These labels will be the same as the Semantic Conventions with `.` replaced by `_`. * `create_metric_descriptor_buffer_size` (default = 10): Buffer size for the channel which asynchronously calls CreateMetricDescriptor. * `resource_filters` (default = \[]): If provided, resource attributes matching any filter will be included in metric labels. Can be defined by `prefix`, `regex`, or `prefix` AND `regex`. * `prefix`: Match resource keys by prefix. * `regex`: Match resource keys by regex. * `cumulative_normalization` (default = true): If true, normalizes cumulative metrics without start times or with explicit reset points by subtracting subsequent points from the initial point. It is enabled by default. Since it caches starting points, it may result in increased memory usage. * `sum_of_squared_deviation` (default = false): If true, enables calculation of an estimated sum of squared deviation. It is an estimate, and is not exact. * `create_service_timeseries` (default = false): If true, this will send all timeseries using `CreateServiceTimeSeries`. Implicitly, this sets `skip_create_descriptor` to true. * `experimental_wal` (default = \[]): If provided, enables use of a write ahead log for time series requests. * `directory` (default = `./`): Path to local directory for WAL file. * `max_backoff` (default = `1h`): Max duration to retry requests on network errors (`UNAVAILABLE` or `DEADLINE_EXCEEDED`). * `trace` (optional): Configuration for sending traces to Google Cloud Trace. * `endpoint` (default = `cloudtrace.googleapis.com`): Endpoint where trace data is going to be sent to. * `use_insecure` (default = false): If true, disables gRPC client transport security. Only has effect if Endpoint is not "". * `grpc_pool_size` (optional): Sets the size of the connection pool in the GCP client. Defaults to a single connection. * `attribute_mappings` (optional): AttributeMappings determines how to map from OpenTelemetry attribute keys to Google Cloud Trace keys. By default, it changes `http` and `service` keys so that they appear more prominently in the UI. * `key`: The OpenTelemetry attribute key * `replacement`: The replacement attribute sent to Google Cloud Trace * `log` (optional): Configuration for sending logs to Google Cloud Logging. * `endpoint` (default = `logging.googleapis.com`): Endpoint where log data is going to be sent to. * `use_insecure` (default = false): If true, disables gRPC client transport security. Only has effect if Endpoint is not "". * `compression` (optional, Supported values: \[`gzip`]): Compression format for Logs gRPC requests. Defaults to no compression. * `grpc_pool_size` (optional): Sets the size of the connection pool in the GCP client. Defaults to a single connection. * `default_log_name` (optional): Defines a default name for log entries. If left unset, and a log entry does not have the `gcp.log_name` attribute set, the exporter will return an error processing that entry. * `resource_filters` (default = \[]): If provided, Resource Attributes matching any filter will be included in log entry labels. Can be defined by `prefix`, `regex`, or `prefix` AND `regex`. * `prefix`: Match resource keys by prefix. * `regex`: Match resource keys by regex. * `sending_queue` (optional): Configuration for how to buffer data before sending. Note: The `sending_queue` is provided (and documented) by the [Exporter Helper](https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter/exporterhelper#sending-queue) Beyond standard YAML configuration as outlined in the section above, exporters that leverage the net/http package (all do today) also respect the following proxy environment variables: * HTTP\_PROXY * HTTPS\_PROXY * NO\_PROXY If set at Collector start time then exporters, regardless of protocol, will or will not proxy traffic as defined by these environment variables. ### Monitored Resources For metrics and logs, this exporter maps the OpenTelemetry Resource to a Google Cloud [Logging](https://cloud.google.com/logging/docs/api/v2/resource-list) or [Monitoring](https://cloud.google.com/monitoring/api/resources) Monitored Resource. The complete mapping logic can be found in [resourcemapping.go](https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/main/internal/resourcemapping/resourcemapping.go). That may be the most helpful reference if you want to map to a specific monitored resource. #### On GCP If running on GCP, using the GCP resource detector, as shown above, will populate the resource attributes required to map to the appropriate monitored resource. #### Off GCP If you are not running on GCP, you still need to choose a [GCP zone or region](https://cloud.google.com/compute/docs/regions-zones) to send telemetry to by setting `cloud.availability_zone` or `cloud.region`. In addition, you should use the detector associated with other cloud providers, if applicable. If running on Kubernetes, it is recommended to additionally set `k8s.pod.name`, `k8s.namespace.name`, and `k8s.container.name` using the `k8sattributes` processor. If you are getting "duplicate timeseries encountered" errors, it is likely because you are missing a required resource attribute, causing a metric from two different instances of an application to end up with the same monitored resource. ### Preventing metric label collisions The metrics exporter can add metric labels to timeseries, such as when setting `metric.service_resource_labels`, `metric.instrumentation_library_labels` (both on by default), or when using `metric.resource_filters` to convert resource attributes to metric labels. However, if your metrics already contain any of these labels they will fail to export to Google Cloud with a `Duplicate label key encountered` error. Such labels from the default features above include: * `service_name` * `service_namespace` * `service_instance_id` * `instrumentation_source` * `instrumentation_version` *(Note that these are the sanitized versions of OpenTelemetry attributes, with `.` replaced by `_` to be compatible with Cloud Monitoring. For example, `service_name` comes from the [`service.name` resource attribute](https://github.com/open-telemetry/opentelemetry-specification/blob/dc78006c12d9767fd2e35b691706c7572a76fd43/specification/resource/semantic_conventions/README.md#service).)* To prevent this, it's recommended to use the [transform processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/c7bd50ce773e66be327ef7618775a884a774e5d1/processor/transformprocessor) in your collector config to rename existing metric labels to preserve them, for example: ```yaml theme={null} processors: transform: metric_statements: - context: datapoint statements: - set(attributes["exported_service_name"], attributes["service_name"]) - delete_key(attributes, "service_name") - set(attributes["exported_service_namespace"], attributes["service_namespace"]) - delete_key(attributes, "service_namespace") - set(attributes["exported_service_instance_id"], attributes["service_instance_id"]) - delete_key(attributes, "service_instance_id") - set(attributes["exported_instrumentation_source"], attributes["instrumentation_source"]) - delete_key(attributes, "instrumentation_source") - set(attributes["exported_instrumentation_version"], attributes["instrumentation_version"]) - delete_key(attributes, "instrumentation_version") ``` **Note** It is not recommended to use these transformations with the googlecloud exporter in a logging or trace pipeline. The same method can be used for any resource attributes being filtered to metric labels, or metric labels which might collide with the GCP monitored resource used with resource detection. Keep in mind that your conflicting attributes may contain dots instead of underscores (eg, `service.name`), but these will still collide once all attributes are normalized to metric labels. In this case you will need to update the collector config above appropriately. ### Logging Example The logging exporter processes OpenTelemetry log entries and exports them to GCP Cloud Logging. Logs can be collected using one of the opentelemetry-collector-contrib log receivers, such as the [filelogreceiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/filelogreceiver). Log entries must contain any Cloud Logging-specific fields as a matching OpenTelemetry attribute (as shown in examples from the [logs data model](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#google-cloud-logging)). These attributes can be parsed using the various [log operators](../../pkg/stanza/docs/operators/README.md#what-operators-are-available) available upstream. For example, the following config parses the [HTTPRequest field](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#HttpRequest) from Apache log entries saved in `/var/log/apache.log`. It also parses out the `timestamp` and inserts a non-default `log_name` attribute and GCP [MonitoredResource](https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource) attribute. ```yaml theme={null} receivers: file_log: include: [ /var/log/apache.log ] start_at: beginning operators: - id: http_request_parser type: regex_parser regex: '(?m)^(?P[^ ]*) (?P[^ ]*) (?P[^ ]*) \[(?P