Skip to content

stdoutmetric: WithoutTimestamps mutates ResourceMetrics passed to Export #8785

Description

@pellared

Description

When stdoutmetric.WithoutTimestamps is enabled, Export calls redactTimestamps on the caller-provided *metricdata.ResourceMetrics. That function replaces every metric's Data value in place with a timestamp-redacted aggregation.

The metric.Exporter contract allows the caller to reuse ResourceMetrics after Export returns. The mutation therefore strips timestamps from data subsequently used by another consumer or exporter. WithoutTimestamps originally copied the data in #3828; the in-place behavior appeared after the export interface changed to a pointer in #3853.

Environment

  • OS: Linux (the behavior is platform-independent)
  • Architecture: amd64
  • Go Version: 1.26.4
  • opentelemetry-go version: 0de413a318cb52629baefb89a1554a905e105aa3

Steps To Reproduce

Add the following test to the stdoutmetric exporter tests:

package stdoutmetric_test

import (
	"io"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"go.opentelemetry.io/otel/exporters/stdout/stdoutmetric"
	"go.opentelemetry.io/otel/sdk/metric/metricdata"
)

func TestWithoutTimestampsDoesNotMutateInput(t *testing.T) {
	start := time.Unix(1, 0).UTC()
	end := time.Unix(2, 0).UTC()
	rm := &metricdata.ResourceMetrics{
		ScopeMetrics: []metricdata.ScopeMetrics{{
			Metrics: []metricdata.Metrics{{
				Data: metricdata.Gauge[int64]{
					DataPoints: []metricdata.DataPoint[int64]{{
						StartTime: start,
						Time:      end,
						Value:     1,
					}},
				},
			}},
		}},
	}
	exp, err := stdoutmetric.New(
		stdoutmetric.WithWriter(io.Discard),
		stdoutmetric.WithoutTimestamps(),
	)
	require.NoError(t, err)

	require.NoError(t, exp.Export(t.Context(), rm))
	got := rm.ScopeMetrics[0].Metrics[0].Data.(metricdata.Gauge[int64]).DataPoints[0]
	assert.Equal(t, start, got.StartTime)
	assert.Equal(t, end, got.Time)
}

Run:

cd exporters/stdout/stdoutmetric
go test . -run '^TestWithoutTimestampsDoesNotMutateInput$' -count=1

On current main, both timestamps in the caller's data are zero after Export returns.

Expected behavior

WithoutTimestamps should redact only the encoded output. Export should leave the caller-provided ResourceMetrics unchanged.

Tip: React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:metricsPart of OpenTelemetry MetricsbugSomething isn't workingpkg:exporter:stdoutRelated to the stdout exporter package

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions