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.
Description
When
stdoutmetric.WithoutTimestampsis enabled,ExportcallsredactTimestampson the caller-provided*metricdata.ResourceMetrics. That function replaces every metric'sDatavalue in place with a timestamp-redacted aggregation.The
metric.Exportercontract allows the caller to reuseResourceMetricsafterExportreturns. The mutation therefore strips timestamps from data subsequently used by another consumer or exporter.WithoutTimestampsoriginally copied the data in #3828; the in-place behavior appeared after the export interface changed to a pointer in #3853.Environment
0de413a318cb52629baefb89a1554a905e105aa3Steps To Reproduce
Add the following test to the
stdoutmetricexporter tests:Run:
On current
main, both timestamps in the caller's data are zero afterExportreturns.Expected behavior
WithoutTimestampsshould redact only the encoded output.Exportshould leave the caller-providedResourceMetricsunchanged.Tip: React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding
+1orme too, to help us triage it. Learn more here.