Skip to content

stdoutmetric exporter observability#7492

Merged
dmathieu merged 78 commits intoopen-telemetry:mainfrom
mahendrabishnoi2:stdoutmetric-auto-instrumentation
Dec 15, 2025
Merged

stdoutmetric exporter observability#7492
dmathieu merged 78 commits intoopen-telemetry:mainfrom
mahendrabishnoi2:stdoutmetric-auto-instrumentation

Conversation

@mahendrabishnoi2
Copy link
Copy Markdown
Member

@mahendrabishnoi2 mahendrabishnoi2 commented Oct 11, 2025

Fixes #7014

This PR adds support for below self observability metrics for stdoutmetric exporter

  • otel.sdk.exporter.metric_data_point.inflight
  • otel.sdk.exporter.metric_data_point.exported
  • otel.sdk.exporter.operation.duration

These metrics are experimental and hence behind a feature flag OTEL_GO_X_OBSERVABILITY.
Definition of above metrics is available at https://github.com/open-telemetry/semantic-conventions/blob/v1.36.0/docs/otel/sdk-metrics.md

Observability Implementation Checklist

Observability Implementation Checklist

Based on the project Observability guidelines, ensure the following are completed:

Environment Variable Activation

  • Observability features are disabled by default
  • Features are activated through the OTEL_GO_X_OBSERVABILITY environment variable
  • Use consistent pattern with x.Observability.Enabled() check 1
  • Follow established experimental feature pattern 23

Encapsulation

  • Instrumentation is encapsulated within a dedicated struct (e.g., Instrumentation)
  • Instrumentation is not mixed into the instrumented component
  • Instrumentation code is in its own file or package if complex/reused
  • Instrumentation setup doesn't bloat the main component code

Initialization

  • Initialization is only done when observability is enabled
  • Setup is explicit and side-effect free
  • Return errors from initialization when appropriate
  • Use the global Meter provider (e.g., otel.GetMeterProvider())
  • Include proper meter configuration with:
    • Instrumentation package name is used for the Meter
    • Instrumentation version (e.g. Version)
    • Schema URL (e.g. SchemaURL)

Performance

  • Little to no overhead when observability is disabled
  • Expensive operations are only executed when observability is enabled
  • When enabled, instrumentation code paths are optimized to reduce allocation/computation overhead

Attribute and Option Allocation Management

  • Use sync.Pool for attribute slices and options with dynamic attributes
  • Pool objects are properly reset before returning to pool
  • Pools are scoped for maximum efficiency while ensuring correctness

Caching

  • Static attribute sets known at compile time are pre-computed and cached
  • Common attribute combinations use lookup tables/maps

Benchmarking

  • Benchmarks provided for all instrumentation code
  • Benchmark scenarios include both enabled and disabled observability
  • Benchmark results show impact on allocs/op, B/op, and ns/op (use b.ReportAllocs() in benchmarks)

Error Handling and Robustness

  • Errors are reported back to caller when possible
  • Partial failures are handled gracefully
  • Use partially initialized components when available
  • Return errors to caller instead of only using otel.Handle()
  • Use otel.Handle() only when component cannot report error to user

Context Propagation

  • Observability measurements receive the context from the function being measured (don't break context propagation by using context.Background())

Semantic Conventions Compliance

  • All metrics follow OpenTelemetry Semantic Conventions
  • Use the otelconv convenience package for metric semantic conventions
  • Component names follow semantic conventions
  • Use package path scope type as stable identifier for non-standard components
  • Component names are stable unique identifiers
  • Use global counter for uniqueness if necessary
  • Component ID counter is resettable for deterministic testing

Testing

  • Use deterministic testing with isolated state
  • Restore previous state after tests (t.Cleanup())
  • Isolate meter provider for testing
  • Use t.Setenv() for environment variable testing
  • Reset component ID counter for deterministic component names
  • Test order doesn't affect results

Footnotes

  1. https://github.com/open-telemetry/opentelemetry-go/blob/e4ab3141123d0811125a69823dbbe4d9ec5a9b8f/exporters/stdout/stdouttrace/internal/observ/instrumentation.go#L101-L103

  2. https://github.com/open-telemetry/opentelemetry-go/blob/e4ab3141123d0811125a69823dbbe4d9ec5a9b8f/exporters/stdout/stdouttrace/internal/x/x.go

  3. https://github.com/open-telemetry/opentelemetry-go/blob/e4ab3141123d0811125a69823dbbe4d9ec5a9b8f/sdk/internal/x/x.go

mahendrabishnoi2 and others added 30 commits August 4, 2025 22:18
…etrics

1. otel.sdk.exporter.metric_data_point.inflight
2. otel.sdk.exporter.metric_data_point.exported
3. otel.sdk.exporter.operation.duration
- use pool to amortize slice allocation
- pass actual context
- use t.Cleanup instead of defer in tests
- improve readability by returning without using err var
- use metricdatatest for comparision in testcase
Copy link
Copy Markdown
Member

@flc1125 flc1125 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition, we are missing a benchmark test case and its results based on the exporter.

Comment thread exporters/stdout/stdoutmetric/internal/version.go Outdated
Comment thread exporters/stdout/stdoutmetric/internal/observ/instrumentation_test.go Outdated
Comment thread exporters/stdout/stdoutmetric/internal/observ/instrumentation_test.go Outdated
@mahendrabishnoi2
Copy link
Copy Markdown
Member Author

In addition, we are missing a benchmark test case and its results based on the exporter.

I didn't get this point. This module has benchmark tests similar to others. Could you please help me in understanding exactly what's missing?

@mahendrabishnoi2
Copy link
Copy Markdown
Member Author

In addition, we are missing a benchmark test case and its results based on the exporter.

goos: darwin
goarch: arm64
pkg: go.opentelemetry.io/otel/exporters/stdout/stdoutmetric
cpu: Apple M1 Pro
                                 │ exporter.txt │
                                 │    sec/op    │
ExporterExport/Observability-8      16.38µ ± 3%
ExporterExport/NoObservability-8    15.92µ ± 1%
geomean                             16.15µ

                                 │ exporter.txt │
                                 │     B/op     │
ExporterExport/Observability-8     2.277Ki ± 0%
ExporterExport/NoObservability-8   2.277Ki ± 0%
geomean                            2.277Ki

                                 │ exporter.txt │
                                 │  allocs/op   │
ExporterExport/Observability-8       85.00 ± 0%
ExporterExport/NoObservability-8     85.00 ± 0%
geomean                              85.00

@mahendrabishnoi2
Copy link
Copy Markdown
Member Author

@open-telemetry/go-approvers sorry for the ping. Is there anything pending from me on this PR?

@MrAlias MrAlias modified the milestones: v1.39.0, v1.40.0 Dec 4, 2025
@dmathieu dmathieu merged commit c15644d into open-telemetry:main Dec 15, 2025
33 checks passed
@MrAlias MrAlias mentioned this pull request Feb 2, 2026
MrAlias added a commit that referenced this pull request Feb 2, 2026
### Added

- Add `Enabled` method to all synchronous instrument interfaces
(`Float64Counter`, `Float64UpDownCounter`, `Float64Histogram`,
`Float64Gauge`, `Int64Counter`, `Int64UpDownCounter`, `Int64Histogram`,
`Int64Gauge`,) in `go.opentelemetry.io/otel/metric`. This stabilizes the
synchronous instrument enabled feature, allowing users to check if an
instrument will process measurements before performing computationally
expensive operations. (#7763)
- Add `AlwaysRecord` sampler in `go.opentelemetry.io/otel/sdk/trace`.
(#7724)
- Add `go.opentelemetry.io/otel/semconv/v1.39.0` package. The package
contains semantic conventions from the `v1.39.0` version of the
OpenTelemetry Semantic Conventions. See the [migration
documentation](https://github.com/open-telemetry/opentelemetry-go/blob/298cbedf256b7a9ab3c21e41fc5e3e6d6e4e94aa/semconv/v1.39.0/MIGRATION.md)
for information on how to upgrade from
`go.opentelemetry.io/otel/semconv/v1.38.0.` (#7783, #7789)

### Changed

- `Exporter` in `go.opentelemetry.io/otel/exporter/prometheus` ignores
metrics with the scope `go.opentelemetry.io/contrib/bridges/prometheus`.
This prevents scrape failures when the Prometheus exporter is
misconfigured to get data from the Prometheus bridge. (#7688)
- Improve performance of concurrent histogram measurements in
`go.opentelemetry.io/otel/sdk/metric`. (#7474)
- Add experimental observability metrics in
`go.opentelemetry.io/otel/exporters/stdout/stdoutmetric`. (#7492)
- Improve the concurrent performance of `HistogramReservoir` in
`go.opentelemetry.io/otel/sdk/metric/exemplar` by 4x. (#7443)
- Improve performance of concurrent synchronous gauge measurements in
`go.opentelemetry.io/otel/sdk/metric`. (#7478)
- Improve performance of concurrent exponential histogram measurements
in `go.opentelemetry.io/otel/sdk/metric`. (#7702)
- Improve the concurrent performance of `FixedSizeReservoir` in
`go.opentelemetry.io/otel/sdk/metric/exemplar`. (#7447)
- The `rpc.grpc.status_code` attribute in the experimental metrics
emitted from
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` is
replaced with the `rpc.response.status_code` attribute to align with the
semantic conventions. (#7854)
- The `rpc.grpc.status_code` attribute in the experimental metrics
emitted from
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc` is
replaced with the `rpc.response.status_code` attribute to align with the
semantic conventions. (#7854)

### Fixed

- Fix bad log message when key-value pairs are dropped because of key
duplication in `go.opentelemetry.io/otel/sdk/log`. (#7662)
- Fix `DroppedAttributes` on `Record` in
`go.opentelemetry.io/otel/sdk/log` to not count the non-attribute
key-value pairs dropped because of key duplication. (#7662)
- Fix `SetAttributes` on `Record` in `go.opentelemetry.io/otel/sdk/log`
to not log that attributes are dropped when they are actually not
dropped. (#7662)
- `WithHostID` detector in `go.opentelemetry.io/otel/sdk/resource` to
use full path for `ioreg` command on Darwin (macOS). (#7818)
- Fix missing `request.GetBody` in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` to
correctly handle HTTP2 GOAWAY frame. (#7794)

### Deprecated

- Deprecate `go.opentelemetry.io/otel/exporters/zipkin`. For more
information, see the [OTel blog post deprecating the Zipkin
exporter](https://opentelemetry.io/blog/2025/deprecating-zipkin-exporters/).
(#7670)

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg:exporter:stdout Related to the stdout exporter package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Metrics SDK observability - stdoutmetric exporter metrics

5 participants