-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add misc changes for metrics correctness #1453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,8 @@ import ( | |
type MetricCfg struct { | ||
// The type of metric to generate | ||
MetricDescriptorType pdata.MetricType | ||
// A prefix for every metric name | ||
MetricNamePrefix string | ||
// The number of instrumentation library metrics per resource | ||
NumILMPerResource int | ||
// The size of the MetricSlice and number of Metrics | ||
|
@@ -48,9 +50,12 @@ type MetricCfg struct { | |
StepSize uint64 | ||
} | ||
|
||
// DefaultCfg produces a MetricCfg with default values. These should be good enough to produce sane | ||
// (but boring) metrics, and can be used as a starting point for making alterations. | ||
func DefaultCfg() MetricCfg { | ||
return MetricCfg{ | ||
MetricDescriptorType: pdata.MetricTypeInt64, | ||
MetricNamePrefix: "", | ||
NumILMPerResource: 1, | ||
NumMetricsPerILM: 1, | ||
NumPtLabels: 1, | ||
|
@@ -63,11 +68,25 @@ func DefaultCfg() MetricCfg { | |
} | ||
} | ||
|
||
// DefaultMetricData produces MetricData with a default config. | ||
func DefaultMetricData() data.MetricData { | ||
return MetricDataFromCfg(DefaultCfg()) | ||
} | ||
|
||
// MetricDataFromCfg produces MetricData with the passed-in config. | ||
func MetricDataFromCfg(cfg MetricCfg) data.MetricData { | ||
return newMetricGenerator().genMetricDataFromCfg(cfg) | ||
} | ||
|
||
type metricGenerator struct { | ||
metricID int | ||
} | ||
|
||
func newMetricGenerator() *metricGenerator { | ||
return &metricGenerator{} | ||
} | ||
Comment on lines
+81
to
+87
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this whole type needed? You can just pass around metricID. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
func (g *metricGenerator) genMetricDataFromCfg(cfg MetricCfg) data.MetricData { | ||
md := data.NewMetricData() | ||
rms := md.ResourceMetrics() | ||
rms.Resize(cfg.NumResourceMetrics) | ||
|
@@ -81,27 +100,27 @@ func MetricDataFromCfg(cfg MetricCfg) data.MetricData { | |
pdata.NewAttributeValueString(fmt.Sprintf("resource-attr-val-%d", j)), | ||
) | ||
} | ||
populateIlm(cfg, rm) | ||
g.populateIlm(cfg, rm) | ||
} | ||
return md | ||
} | ||
|
||
func populateIlm(cfg MetricCfg, rm pdata.ResourceMetrics) { | ||
func (g *metricGenerator) populateIlm(cfg MetricCfg, rm pdata.ResourceMetrics) { | ||
ilms := rm.InstrumentationLibraryMetrics() | ||
ilms.Resize(cfg.NumILMPerResource) | ||
for i := 0; i < cfg.NumILMPerResource; i++ { | ||
ilm := ilms.At(i) | ||
populateMetrics(cfg, ilm) | ||
g.populateMetrics(cfg, ilm) | ||
} | ||
} | ||
|
||
func populateMetrics(cfg MetricCfg, ilm pdata.InstrumentationLibraryMetrics) { | ||
func (g *metricGenerator) populateMetrics(cfg MetricCfg, ilm pdata.InstrumentationLibraryMetrics) { | ||
metrics := ilm.Metrics() | ||
metrics.Resize(cfg.NumMetricsPerILM) | ||
for i := 0; i < cfg.NumMetricsPerILM; i++ { | ||
metric := metrics.At(i) | ||
metric.InitEmpty() | ||
populateMetricDesc(cfg, metric) | ||
g.populateMetricDesc(cfg, metric) | ||
switch cfg.MetricDescriptorType { | ||
case pdata.MetricTypeInt64, pdata.MetricTypeMonotonicInt64: | ||
populateIntPoints(cfg, metric) | ||
|
@@ -115,10 +134,11 @@ func populateMetrics(cfg MetricCfg, ilm pdata.InstrumentationLibraryMetrics) { | |
} | ||
} | ||
|
||
func populateMetricDesc(cfg MetricCfg, metric pdata.Metric) { | ||
func (g *metricGenerator) populateMetricDesc(cfg MetricCfg, metric pdata.Metric) { | ||
desc := metric.MetricDescriptor() | ||
desc.InitEmpty() | ||
desc.SetName("my-md-name") | ||
desc.SetName(fmt.Sprintf("%smetric_%d", cfg.MetricNamePrefix, g.metricID)) | ||
g.metricID++ | ||
desc.SetDescription("my-md-description") | ||
desc.SetUnit("my-md-units") | ||
desc.SetType(cfg.MetricDescriptorType) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ import ( | |
|
||
"go.uber.org/atomic" | ||
|
||
"go.opentelemetry.io/collector/consumer" | ||
"go.opentelemetry.io/collector/consumer/consumerdata" | ||
"go.opentelemetry.io/collector/consumer/pdata" | ||
"go.opentelemetry.io/collector/consumer/pdatautil" | ||
|
@@ -124,7 +125,7 @@ func (mb *MockBackend) GetStats() string { | |
|
||
// DataItemsReceived returns total number of received spans and metrics. | ||
func (mb *MockBackend) DataItemsReceived() uint64 { | ||
return mb.tc.spansReceived.Load() + mb.mc.metricsReceived.Load() | ||
return mb.tc.numSpansReceived.Load() + mb.mc.numMetricsReceived.Load() | ||
} | ||
|
||
// ClearReceivedItems clears the list of received traces and metrics. Note: counters | ||
|
@@ -172,13 +173,20 @@ func (mb *MockBackend) ConsumeMetricOld(md consumerdata.MetricsData) { | |
} | ||
} | ||
|
||
type TraceDualConsumer interface { | ||
consumer.TraceConsumer | ||
consumer.TraceConsumerOld | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you need the Old interface? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To answer this and the next question, the old interface is used by Prometheus and OpenCensus on the metrics side, and Zipkin on the tracing side. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is no longer true :) for 2 out of 3 :) |
||
} | ||
|
||
var _ TraceDualConsumer = (*MockTraceConsumer)(nil) | ||
|
||
type MockTraceConsumer struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be public? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it will be used by the test harness in the metrics package as a placeholder trace consumer. |
||
spansReceived atomic.Uint64 | ||
backend *MockBackend | ||
numSpansReceived atomic.Uint64 | ||
backend *MockBackend | ||
} | ||
|
||
func (tc *MockTraceConsumer) ConsumeTraces(_ context.Context, td pdata.Traces) error { | ||
tc.spansReceived.Add(uint64(td.SpanCount())) | ||
tc.numSpansReceived.Add(uint64(td.SpanCount())) | ||
|
||
rs := td.ResourceSpans() | ||
for i := 0; i < rs.Len(); i++ { | ||
|
@@ -214,7 +222,7 @@ func (tc *MockTraceConsumer) ConsumeTraces(_ context.Context, td pdata.Traces) e | |
} | ||
|
||
func (tc *MockTraceConsumer) ConsumeTraceData(_ context.Context, td consumerdata.TraceData) error { | ||
tc.spansReceived.Add(uint64(len(td.Spans))) | ||
tc.numSpansReceived.Add(uint64(len(td.Spans))) | ||
|
||
for _, span := range td.Spans { | ||
var spanSeqnum int64 | ||
|
@@ -243,29 +251,28 @@ func (tc *MockTraceConsumer) ConsumeTraceData(_ context.Context, td consumerdata | |
return nil | ||
} | ||
|
||
type MetricsDualConsumer interface { | ||
consumer.MetricsConsumer | ||
consumer.MetricsConsumerOld | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same. |
||
} | ||
|
||
var _ MetricsDualConsumer = (*MockMetricConsumer)(nil) | ||
|
||
type MockMetricConsumer struct { | ||
metricsReceived atomic.Uint64 | ||
backend *MockBackend | ||
numMetricsReceived atomic.Uint64 | ||
backend *MockBackend | ||
} | ||
|
||
func (mc *MockMetricConsumer) ConsumeMetrics(_ context.Context, md pdata.Metrics) error { | ||
_, dataPoints := pdatautil.MetricAndDataPointCount(md) | ||
mc.metricsReceived.Add(uint64(dataPoints)) | ||
mc.numMetricsReceived.Add(uint64(dataPoints)) | ||
mc.backend.ConsumeMetric(md) | ||
return nil | ||
} | ||
|
||
func (mc *MockMetricConsumer) ConsumeMetricsData(_ context.Context, md consumerdata.MetricsData) error { | ||
dataPoints := 0 | ||
for _, metric := range md.Metrics { | ||
for _, ts := range metric.Timeseries { | ||
dataPoints += len(ts.Points) | ||
} | ||
} | ||
|
||
mc.metricsReceived.Add(uint64(dataPoints)) | ||
|
||
_, dataPoints := pdatautil.TimeseriesAndPointCount(md) | ||
mc.numMetricsReceived.Add(uint64(dataPoints)) | ||
mc.backend.ConsumeMetricOld(md) | ||
|
||
return nil | ||
} |
Uh oh!
There was an error while loading. Please reload this page.