| Status | |
|---|---|
| Stability | development: logs, metrics, traces |
| Distributions | [] |
| Issues | |
| Code coverage | |
| Code Owners | @stu |
The exporter_creator exporter dynamically creates other exporters at runtime when observer extensions report endpoints (for example Kubernetes pods, CRDs, or JSON-defined targets). It evaluates rules against each endpoint, starts matching exporter templates with configuration expanded from endpoint data, and routes incoming logs, metrics, and traces to the right sub-exporter using resource attributes. Use it when destinations are not fixed at config time—similar to dynamic receiver wiring, but on the export side of the pipeline.
In opentelemetry-collector-contrib, receiver creator (receiver_creator) watches observers and spawns receivers from templates. Exporter creator is the same pattern for exporters: watch observers, match rules, instantiate exporters. This repository tracks the implementation from contrib’s exporter/exportercreator, published as a standalone module (github.com/stuart23/exportercreator) for custom collector builds.
exporter_creator is not included in the default core or contrib collector distributions. Build a custom binary with the OpenTelemetry Collector Builder (ocb). See the OCB documentation.
Add the module under exporters in builder-config.yaml (use a real version tag once you publish; v0.0.0 is common with a local replace during development):
exporters:
- gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.147.0
- gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.147.0
- gomod: github.com/stuart23/exportercreator v0.1.0You also need at least one observer extension in the same manifest (for example k8s_observer, jsonfile_observer) so watch_observers has something to attach to. This module depends on extension/observer from contrib; your go.mod or builder manifest often needs replace directives for contrib paths (including observer submodules such as jsonfileobserver). Copy and adapt the replaces block from builder-config.example.yaml—paths are relative to the builder output_path directory.
- Module path:
github.com/stuart23/exportercreator - Shared state: includes a copy of contrib’s
internal/sharedcomponent, which is not importable from outside the contrib module tree as a normal dependency. - Observer API: depends on a tagged
extension/observerrelease (seego.mod). Rules acceptk8s.crdandjsonfileendpoint kinds viaObserverEndpointTypeK8sCRD/ObserverEndpointTypeJSONFileso behavior stays aligned with real observers even when those kinds are not yet named constants in the observer module.
-
Observer Extensions: The exporter watches observer extensions (like
k8s_observer) for endpoint discovery events. -
Rule Matching: When endpoints are discovered, rules are evaluated to determine which exporter templates should be instantiated.
-
Dynamic Exporter Creation: Matching exporter templates are used to create sub-exporters with endpoint-specific configuration.
-
Telemetry Routing: Incoming telemetry is routed to the appropriate sub-exporter based on resource attribute matching against endpoint properties.
extensions:
k8s_observer:
observe_pods: true
exporters:
exporter_creator:
# Observer extensions to watch for endpoint discovery
watch_observers: [k8s_observer]
# Rules for routing telemetry to exporters based on resource attributes
routing:
rules:
- resource_attribute: k8s.pod.labels.app
endpoint_property: labels.app
# Fallback exporters for unmatched telemetry
default_exporters: [otlp/default]
# Exporter templates - created when endpoints match rules
exporters:
otlp/per-app:
rule: type == "pod" && labels["otel-export"] == "true"
config:
endpoint: '`labels["collector-endpoint"]`'
service:
extensions: [k8s_observer]
pipelines:
traces:
receivers: [otlp]
exporters: [exporter_creator]| Option | Type | Description |
|---|---|---|
watch_observers |
[]component.ID |
Observer extensions to watch for endpoint discovery |
routing.rules |
[]RoutingRule |
Rules for matching resource attributes to endpoint properties |
default_exporters |
[]component.ID |
Static exporters to receive unmatched telemetry |
exporters |
map[string]exporterTemplate |
Exporter templates to instantiate when rules match |
Each routing rule maps a resource attribute to an endpoint property:
| Field | Type | Description |
|---|---|---|
resource_attribute |
string |
Resource attribute key (e.g., k8s.pod.labels.app) |
endpoint_property |
string |
Endpoint property path using dot notation (e.g., labels.app, spec.region) |
| Field | Type | Description |
|---|---|---|
rule |
string |
Expression that must evaluate to true for the exporter to be created |
config |
map[string]any |
Exporter configuration (supports endpoint value expansion) |
resource_attributes |
map[string]any |
Resource attributes to associate with this exporter |
Configuration values can reference endpoint properties using backtick expressions:
config:
endpoint: '`labels["collector-endpoint"]`'
topic: '`annotations["kafka.topic"]`'go test ./...go test ./... uses the published observer module from the proxy; no local contrib checkout is required.