in exporter/collector/googlemanagedprometheus/extra_metrics.go [268:382]
func (c Config) addScopeInfoMetric(m pmetric.Metrics) {
if !c.ExtraMetricsConfig.EnableScopeInfo {
return
}
ids := make(map[scopeID]struct{})
rms := m.ResourceMetrics()
for i := 0; i < rms.Len(); i++ {
rm := rms.At(i)
getResourceAttr := func(attr string) string {
if v, ok := rm.Resource().Attributes().Get(attr); ok {
return v.AsString()
}
return ""
}
sms := rm.ScopeMetrics()
for j := 0; j < sms.Len(); j++ {
sm := sms.At(j)
// If not present, skip this scope
if len(sm.Scope().Name()) == 0 && len(sm.Scope().Version()) == 0 {
continue
}
// Keep track of the most recent time in this scope's metrics
// Use that time for the timestamp of the new metric
latestTime := time.Time{}
for k := 0; k < sm.Metrics().Len(); k++ {
metric := sm.Metrics().At(k)
switch metric.Type() {
case pmetric.MetricTypeSum:
sum := metric.Sum()
points := sum.DataPoints()
for x := 0; x < points.Len(); x++ {
point := points.At(x)
point.Attributes().PutStr("otel_scope_name", sm.Scope().Name())
point.Attributes().PutStr("otel_scope_version", sm.Scope().Version())
if latestTime.Before(points.At(x).Timestamp().AsTime()) {
latestTime = points.At(x).Timestamp().AsTime()
}
}
case pmetric.MetricTypeGauge:
gauge := metric.Gauge()
points := gauge.DataPoints()
for x := 0; x < points.Len(); x++ {
point := points.At(x)
point.Attributes().PutStr("otel_scope_name", sm.Scope().Name())
point.Attributes().PutStr("otel_scope_version", sm.Scope().Version())
if latestTime.Before(points.At(x).Timestamp().AsTime()) {
latestTime = points.At(x).Timestamp().AsTime()
}
}
case pmetric.MetricTypeSummary:
summary := metric.Summary()
points := summary.DataPoints()
for x := 0; x < points.Len(); x++ {
point := points.At(x)
point.Attributes().PutStr("otel_scope_name", sm.Scope().Name())
point.Attributes().PutStr("otel_scope_version", sm.Scope().Version())
if latestTime.Before(points.At(x).Timestamp().AsTime()) {
latestTime = points.At(x).Timestamp().AsTime()
}
}
case pmetric.MetricTypeHistogram:
hist := metric.Histogram()
points := hist.DataPoints()
for x := 0; x < points.Len(); x++ {
point := points.At(x)
point.Attributes().PutStr("otel_scope_name", sm.Scope().Name())
point.Attributes().PutStr("otel_scope_version", sm.Scope().Version())
if latestTime.Before(points.At(x).Timestamp().AsTime()) {
latestTime = points.At(x).Timestamp().AsTime()
}
}
case pmetric.MetricTypeExponentialHistogram:
eh := metric.ExponentialHistogram()
points := eh.DataPoints()
for x := 0; x < points.Len(); x++ {
point := points.At(x)
point.Attributes().PutStr("otel_scope_name", sm.Scope().Name())
point.Attributes().PutStr("otel_scope_version", sm.Scope().Version())
if latestTime.Before(points.At(x).Timestamp().AsTime()) {
latestTime = points.At(x).Timestamp().AsTime()
}
}
}
}
id := scopeID{
resource: resourceID{
serviceName: getResourceAttr(semconv.AttributeServiceName),
serviceNamespace: getResourceAttr(semconv.AttributeServiceNamespace),
serviceInstanceID: getResourceAttr(semconv.AttributeServiceInstanceID),
},
name: sm.Scope().Name(),
version: sm.Scope().Version(),
}
if _, ok := ids[id]; ok {
// We've already added a scope with the same ID before, so skip this one.
continue
}
ids[id] = struct{}{}
// Add otel_scope_info metric
scopeInfoMetric := sm.Metrics().AppendEmpty()
scopeInfoMetric.SetName("otel_scope_info")
dataPoint := scopeInfoMetric.SetEmptyGauge().DataPoints().AppendEmpty()
dataPoint.SetIntValue(1)
sm.Scope().Attributes().Range(func(k string, v pcommon.Value) bool {
dataPoint.Attributes().PutStr(k, v.AsString())
return true
})
dataPoint.Attributes().PutStr("otel_scope_name", sm.Scope().Name())
dataPoint.Attributes().PutStr("otel_scope_version", sm.Scope().Version())
dataPoint.SetTimestamp(pcommon.NewTimestampFromTime(latestTime))
}
}
}