mirror of
https://github.com/hanzoai/telemetry.git
synced 2026-10-30 20:01:49 +00:00
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description the `writeexponentialhistogramdatapoints` function in the debug exporter’s normal verbosity mode previously had todo placeholder and did not print any bucket data. this change implements the missing bucket display. each bucket is now printed as `leX=Y`, where `X` is the computed upper bound and `Y` is the bucket count. for positive buckets, the upper bound is calculated as `exp((index+1) * factor)`, and for negative buckets as `-exp(index * factor)`, where `factor = math.Ldexp(math.Ln2, -scale)`. negative buckets are listed from most-negative to least-negative, and the zero bucket is printed as `zero=N` when its count is non-zero. <!-- Issue number if applicable --> #### Link to tracking issue Fixes #10463 <!--Describe what testing was performed and which tests were added.--> #### Testing <!--Describe the documentation added.--> #### Documentation No documentation changes required. <!--Please delete paragraphs that you did not use before submitting.--> --------- Signed-off-by: arpit529srivastava <[email protected]>
212 lines
7.7 KiB
Go
212 lines
7.7 KiB
Go
// Copyright The OpenTelemetry Authors
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package normal
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"go.opentelemetry.io/collector/pdata/pmetric"
|
|
)
|
|
|
|
func TestMarshalMetrics(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input pmetric.Metrics
|
|
expected string
|
|
}{
|
|
{
|
|
name: "empty metrics",
|
|
input: pmetric.NewMetrics(),
|
|
expected: "",
|
|
},
|
|
{
|
|
name: "sum data point",
|
|
input: func() pmetric.Metrics {
|
|
metrics := pmetric.NewMetrics()
|
|
metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
|
|
metric.SetName("system.cpu.time")
|
|
dataPoint := metric.SetEmptySum().DataPoints().AppendEmpty()
|
|
dataPoint.SetDoubleValue(123.456)
|
|
dataPoint.Attributes().PutStr("state", "user")
|
|
dataPoint.Attributes().PutStr("cpu", "0")
|
|
return metrics
|
|
}(),
|
|
expected: `ResourceMetrics #0
|
|
ScopeMetrics #0
|
|
system.cpu.time{state=user,cpu=0} 123.456
|
|
`,
|
|
},
|
|
{
|
|
name: "data point with resource and scope attributes",
|
|
input: func() pmetric.Metrics {
|
|
metrics := pmetric.NewMetrics()
|
|
resourceMetrics := metrics.ResourceMetrics().AppendEmpty()
|
|
resourceMetrics.SetSchemaUrl("https://opentelemetry.io/resource-schema-url")
|
|
resourceMetrics.Resource().Attributes().PutStr("resourceKey1", "resourceValue1")
|
|
resourceMetrics.Resource().Attributes().PutBool("resourceKey2", false)
|
|
scopeMetrics := resourceMetrics.ScopeMetrics().AppendEmpty()
|
|
scopeMetrics.SetSchemaUrl("http://opentelemetry.io/scope-schema-url")
|
|
scopeMetrics.Scope().SetName("scope-name")
|
|
scopeMetrics.Scope().SetVersion("1.2.3")
|
|
scopeMetrics.Scope().Attributes().PutStr("scopeKey1", "scopeValue1")
|
|
scopeMetrics.Scope().Attributes().PutBool("scopeKey2", true)
|
|
metric := scopeMetrics.Metrics().AppendEmpty()
|
|
metric.SetName("system.cpu.time")
|
|
dataPoint := metric.SetEmptySum().DataPoints().AppendEmpty()
|
|
dataPoint.SetDoubleValue(123.456)
|
|
dataPoint.Attributes().PutStr("state", "user")
|
|
dataPoint.Attributes().PutStr("cpu", "0")
|
|
return metrics
|
|
}(),
|
|
expected: `ResourceMetrics #0 [https://opentelemetry.io/resource-schema-url] resourceKey1=resourceValue1 resourceKey2=false
|
|
ScopeMetrics #0 [email protected] [http://opentelemetry.io/scope-schema-url] scopeKey1=scopeValue1 scopeKey2=true
|
|
system.cpu.time{state=user,cpu=0} 123.456
|
|
`,
|
|
},
|
|
{
|
|
name: "gauge data point",
|
|
input: func() pmetric.Metrics {
|
|
metrics := pmetric.NewMetrics()
|
|
metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
|
|
metric.SetName("system.cpu.utilization")
|
|
dataPoint := metric.SetEmptyGauge().DataPoints().AppendEmpty()
|
|
dataPoint.SetDoubleValue(78.901234567)
|
|
dataPoint.Attributes().PutStr("state", "free")
|
|
dataPoint.Attributes().PutStr("cpu", "8")
|
|
return metrics
|
|
}(),
|
|
expected: `ResourceMetrics #0
|
|
ScopeMetrics #0
|
|
system.cpu.utilization{state=free,cpu=8} 78.901234567
|
|
`,
|
|
},
|
|
{
|
|
name: "histogram",
|
|
input: func() pmetric.Metrics {
|
|
metrics := pmetric.NewMetrics()
|
|
metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
|
|
metric.SetName("http.server.request.duration")
|
|
dataPoint := metric.SetEmptyHistogram().DataPoints().AppendEmpty()
|
|
dataPoint.Attributes().PutInt("http.response.status_code", 200)
|
|
dataPoint.Attributes().PutStr("http.request.method", "GET")
|
|
dataPoint.ExplicitBounds().FromRaw([]float64{0.125, 0.5, 1, 3})
|
|
dataPoint.BucketCounts().FromRaw([]uint64{1324, 13, 0, 2, 1})
|
|
dataPoint.SetCount(1340)
|
|
dataPoint.SetSum(99.573)
|
|
dataPoint.SetMin(0.017)
|
|
dataPoint.SetMax(8.13)
|
|
return metrics
|
|
}(),
|
|
expected: `ResourceMetrics #0
|
|
ScopeMetrics #0
|
|
http.server.request.duration{http.response.status_code=200,http.request.method=GET} count=1340 sum=99.573 min=0.017 max=8.13 le0.125=1324 le0.5=13 le1=0 le3=2 1
|
|
`,
|
|
},
|
|
{
|
|
name: "exponential histogram without buckets",
|
|
input: func() pmetric.Metrics {
|
|
metrics := pmetric.NewMetrics()
|
|
metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
|
|
metric.SetName("http.server.request.duration")
|
|
dataPoint := metric.SetEmptyExponentialHistogram().DataPoints().AppendEmpty()
|
|
dataPoint.Attributes().PutInt("http.response.status_code", 200)
|
|
dataPoint.Attributes().PutStr("http.request.method", "GET")
|
|
dataPoint.SetCount(1340)
|
|
dataPoint.SetSum(99.573)
|
|
dataPoint.SetMin(0.017)
|
|
dataPoint.SetMax(8.13)
|
|
return metrics
|
|
}(),
|
|
expected: `ResourceMetrics #0
|
|
ScopeMetrics #0
|
|
http.server.request.duration{http.response.status_code=200,http.request.method=GET} count=1340 sum=99.573 min=0.017 max=8.13
|
|
`,
|
|
},
|
|
{
|
|
name: "exponential histogram with buckets",
|
|
input: func() pmetric.Metrics {
|
|
metrics := pmetric.NewMetrics()
|
|
metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
|
|
metric.SetName("http.server.request.duration")
|
|
dataPoint := metric.SetEmptyExponentialHistogram().DataPoints().AppendEmpty()
|
|
dataPoint.Attributes().PutInt("http.response.status_code", 200)
|
|
dataPoint.Attributes().PutStr("http.request.method", "GET")
|
|
dataPoint.SetCount(1340)
|
|
dataPoint.SetSum(99.573)
|
|
dataPoint.SetMin(0.017)
|
|
dataPoint.SetMax(8.13)
|
|
dataPoint.SetScale(3)
|
|
dataPoint.SetZeroCount(3)
|
|
dataPoint.Negative().SetOffset(-2)
|
|
dataPoint.Negative().BucketCounts().FromRaw([]uint64{10, 20})
|
|
dataPoint.Positive().SetOffset(1)
|
|
dataPoint.Positive().BucketCounts().FromRaw([]uint64{40, 50, 60})
|
|
return metrics
|
|
}(),
|
|
expected: func() string {
|
|
f := math.Ldexp(math.Ln2, -3)
|
|
return fmt.Sprintf("ResourceMetrics #0\nScopeMetrics #0\n"+
|
|
"http.server.request.duration{http.response.status_code=200,http.request.method=GET}"+
|
|
" count=1340 sum=99.573 min=0.017 max=8.13"+
|
|
" le%v=20 le%v=10 zero=3 le%v=40 le%v=50 le%v=60\n",
|
|
-math.Exp(-1*f), -math.Exp(-2*f),
|
|
math.Exp(2*f), math.Exp(3*f), math.Exp(4*f))
|
|
}(),
|
|
},
|
|
{
|
|
name: "exponential histogram with positive buckets only",
|
|
input: func() pmetric.Metrics {
|
|
metrics := pmetric.NewMetrics()
|
|
metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
|
|
metric.SetName("latency")
|
|
dataPoint := metric.SetEmptyExponentialHistogram().DataPoints().AppendEmpty()
|
|
dataPoint.SetCount(2)
|
|
dataPoint.SetScale(1)
|
|
dataPoint.Positive().SetOffset(1)
|
|
dataPoint.Positive().BucketCounts().FromRaw([]uint64{1, 1})
|
|
return metrics
|
|
}(),
|
|
expected: func() string {
|
|
f := math.Ldexp(math.Ln2, -1)
|
|
return fmt.Sprintf("ResourceMetrics #0\nScopeMetrics #0\n"+
|
|
"latency{} count=2 le%v=1 le%v=1\n",
|
|
math.Exp(2*f), math.Exp(3*f))
|
|
}(),
|
|
},
|
|
{
|
|
name: "summary",
|
|
input: func() pmetric.Metrics {
|
|
metrics := pmetric.NewMetrics()
|
|
metric := metrics.ResourceMetrics().AppendEmpty().ScopeMetrics().AppendEmpty().Metrics().AppendEmpty()
|
|
metric.SetName("summary")
|
|
dataPoint := metric.SetEmptySummary().DataPoints().AppendEmpty()
|
|
dataPoint.Attributes().PutInt("http.response.status_code", 200)
|
|
dataPoint.Attributes().PutStr("http.request.method", "GET")
|
|
dataPoint.SetCount(1340)
|
|
dataPoint.SetSum(99.573)
|
|
quantile := dataPoint.QuantileValues().AppendEmpty()
|
|
quantile.SetQuantile(0.01)
|
|
quantile.SetValue(15)
|
|
return metrics
|
|
}(),
|
|
expected: `ResourceMetrics #0
|
|
ScopeMetrics #0
|
|
summary{http.response.status_code=200,http.request.method=GET} count=1340 sum=99.573000 q0.01=15
|
|
`,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
output, err := NewNormalMetricsMarshaler().MarshalMetrics(tt.input)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.expected, string(output))
|
|
})
|
|
}
|
|
}
|