Skip to content

Commit

Permalink
feat: add host.name to trace span metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
sunface committed Mar 17, 2024
1 parent c6b988e commit 284f5a7
Showing 1 changed file with 27 additions and 16 deletions.
43 changes: 27 additions & 16 deletions otel-collector/processor/xobservespanmetricsprocessor/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (

const (
serviceNameKey = conventions.AttributeServiceName
hostNameKey = conventions.AttributeHostName
operationKey = "operation" // OpenTelemetry non-standard constant.
spanKindKey = "span.kind" // OpenTelemetry non-standard constant.
statusCodeKey = "status.code" // OpenTelemetry non-standard constant.
Expand Down Expand Up @@ -70,6 +71,7 @@ type processorImp struct {
lock sync.Mutex
logger *zap.Logger
instanceID string
hostName string
config Config

metricsExporter exporter.Metrics
Expand Down Expand Up @@ -685,7 +687,7 @@ func getRemoteAddress(span ptrace.Span) (string, bool) {
return "", false
}

func (p *processorImp) aggregateMetricsForSpan(serviceName string, span ptrace.Span, resourceAttr pcommon.Map) {
func (p *processorImp) aggregateMetricsForSpan(serviceName string, hostName string, span ptrace.Span, resourceAttr pcommon.Map) {

if p.shouldSkip(serviceName, span, resourceAttr) {
p.logger.Debug("Skipping span", zap.String("span", span.Name()), zap.String("service", serviceName))
Expand All @@ -702,13 +704,13 @@ func (p *processorImp) aggregateMetricsForSpan(serviceName string, span ptrace.S
p.keyBuf.Reset()
buildKey(p.keyBuf, serviceName, span, p.dimensions, resourceAttr)
key := metricKey(p.keyBuf.String())
p.cache(serviceName, span, key, resourceAttr)
p.cache(serviceName, hostName, span, key, resourceAttr)
p.updateHistogram(key, latencyInMilliseconds, span.TraceID(), span.SpanID())

p.keyBuf.Reset()
buildKey(p.keyBuf, serviceName, span, p.callDimensions, resourceAttr)
callKey := metricKey(p.keyBuf.String())
p.callCache(serviceName, span, callKey, resourceAttr)
p.callCache(serviceName, hostName, span, callKey, resourceAttr)
p.updateCallHistogram(callKey, latencyInMilliseconds, span.TraceID(), span.SpanID())

spanAttr := span.Attributes()
Expand All @@ -722,7 +724,7 @@ func (p *processorImp) aggregateMetricsForSpan(serviceName string, span ptrace.S
extraDims := map[string]pcommon.Value{
"address": pcommon.NewValueStr(remoteAddr),
}
p.externalCallCache(serviceName, span, externalCallKey, resourceAttr, extraDims)
p.externalCallCache(serviceName, hostName, span, externalCallKey, resourceAttr, extraDims)
p.updateExternalHistogram(externalCallKey, latencyInMilliseconds, span.TraceID(), span.SpanID())
}

Expand All @@ -731,7 +733,7 @@ func (p *processorImp) aggregateMetricsForSpan(serviceName string, span ptrace.S
p.keyBuf.Reset()
buildCustomKey(p.keyBuf, serviceName, span, p.dbCallDimensions, resourceAttr, nil)
dbCallKey := metricKey(p.keyBuf.String())
p.dbCallCache(serviceName, span, dbCallKey, resourceAttr)
p.dbCallCache(serviceName, hostName, span, dbCallKey, resourceAttr)
p.updateDBHistogram(dbCallKey, latencyInMilliseconds, span.TraceID(), span.SpanID())
}
}
Expand All @@ -748,6 +750,12 @@ func (p *processorImp) aggregateMetrics(traces ptrace.Traces) {
if !ok {
continue
}
var hostName string
hostAttr, ok := resourceAttr.Get(conventions.AttributeHostName)
if ok {
hostName = hostAttr.Str()
}

resourceAttr.PutStr(xobserveID, p.instanceID)
serviceName := serviceAttr.Str()
ilsSlice := rspans.ScopeSpans()
Expand All @@ -756,7 +764,7 @@ func (p *processorImp) aggregateMetrics(traces ptrace.Traces) {
spans := ils.Spans()
for k := 0; k < spans.Len(); k++ {
span := spans.At(k)
p.aggregateMetricsForSpan(serviceName, span, resourceAttr)
p.aggregateMetricsForSpan(serviceName, hostName, span, resourceAttr)
}
}
}
Expand Down Expand Up @@ -863,10 +871,11 @@ func (p *processorImp) resetExemplarData() {
}
}

func (p *processorImp) buildDimensionKVs(serviceName string, span ptrace.Span, optionalDims []dimension, resourceAttrs pcommon.Map) pcommon.Map {
func (p *processorImp) buildDimensionKVs(serviceName string, hostName string, span ptrace.Span, optionalDims []dimension, resourceAttrs pcommon.Map) pcommon.Map {
dims := pcommon.NewMap()
dims.EnsureCapacity(4 + len(optionalDims))
dims.PutStr(serviceNameKey, serviceName)
dims.PutStr(hostNameKey, hostName)
dims.PutStr(operationKey, span.Name())
dims.PutStr(spanKindKey, SpanKindStr(span.Kind()))
dims.PutStr(statusCodeKey, StatusCodeStr(span.Status().Code()))
Expand All @@ -889,10 +898,12 @@ func (p *processorImp) buildDimensionKVs(serviceName string, span ptrace.Span, o
return dims
}

func (p *processorImp) buildCustomDimensionKVs(serviceName string, span ptrace.Span, optionalDims []dimension, resourceAttrs pcommon.Map, extraDims map[string]pcommon.Value) pcommon.Map {
func (p *processorImp) buildCustomDimensionKVs(serviceName string, hostName string, span ptrace.Span, optionalDims []dimension, resourceAttrs pcommon.Map, extraDims map[string]pcommon.Value) pcommon.Map {
dims := pcommon.NewMap()

dims.PutStr(serviceNameKey, serviceName)
dims.PutStr(hostNameKey, hostName)

for k, v := range extraDims {
v.CopyTo(dims.PutEmpty(k))
}
Expand Down Expand Up @@ -1007,43 +1018,43 @@ func getDimensionValueWithResource(d dimension, spanAttr pcommon.Map, resourceAt
// This enables a lookup of the dimension key-value map when constructing the metric like so:
//
// LabelsMap().InitFromMap(p.metricKeyToDimensions[key])
func (p *processorImp) cache(serviceName string, span ptrace.Span, k metricKey, resourceAttrs pcommon.Map) {
func (p *processorImp) cache(serviceName string, hostName string, span ptrace.Span, k metricKey, resourceAttrs pcommon.Map) {
// Use Get to ensure any existing key has its recent-ness updated.
if _, has := p.metricKeyToDimensions.Get(k); !has {
p.metricKeyToDimensions.Add(k, p.buildDimensionKVs(serviceName, span, p.dimensions, resourceAttrs))
p.metricKeyToDimensions.Add(k, p.buildDimensionKVs(serviceName, hostName, span, p.dimensions, resourceAttrs))
}
}

// callCache caches the dimension key-value map for the metricKey if there is a cache miss.
// This enables a lookup of the dimension key-value map when constructing the metric like so:
//
// LabelsMap().InitFromMap(p.callMetricKeyToDimensions[key])
func (p *processorImp) callCache(serviceName string, span ptrace.Span, k metricKey, resourceAttrs pcommon.Map) {
func (p *processorImp) callCache(serviceName string, hostName string, span ptrace.Span, k metricKey, resourceAttrs pcommon.Map) {
// Use Get to ensure any existing key has its recent-ness updated.
if _, has := p.callMetricKeyToDimensions.Get(k); !has {
p.callMetricKeyToDimensions.Add(k, p.buildDimensionKVs(serviceName, span, p.callDimensions, resourceAttrs))
p.callMetricKeyToDimensions.Add(k, p.buildDimensionKVs(serviceName, hostName, span, p.callDimensions, resourceAttrs))
}
}

// dbCallCache caches the dimension key-value map for the metricKey if there is a cache miss.
// This enables a lookup of the dimension key-value map when constructing the metric like so:
//
// LabelsMap().InitFromMap(p.dbCallMetricKeyToDimensions[key])
func (p *processorImp) dbCallCache(serviceName string, span ptrace.Span, k metricKey, resourceAttrs pcommon.Map) {
func (p *processorImp) dbCallCache(serviceName string, hostName string, span ptrace.Span, k metricKey, resourceAttrs pcommon.Map) {
// Use Get to ensure any existing key has its recent-ness updated.
if _, has := p.dbCallMetricKeyToDimensions.Get(k); !has {
p.dbCallMetricKeyToDimensions.Add(k, p.buildCustomDimensionKVs(serviceName, span, p.dbCallDimensions, resourceAttrs, nil))
p.dbCallMetricKeyToDimensions.Add(k, p.buildCustomDimensionKVs(serviceName, hostName, span, p.dbCallDimensions, resourceAttrs, nil))
}
}

// externalCallCache caches the dimension key-value map for the metricKey if there is a cache miss.
// This enables a lookup of the dimension key-value map when constructing the metric like so:
//
// LabelsMap().InitFromMap(p.externalCallMetricKeyToDimensions[key])
func (p *processorImp) externalCallCache(serviceName string, span ptrace.Span, k metricKey, resourceAttrs pcommon.Map, extraDims map[string]pcommon.Value) {
func (p *processorImp) externalCallCache(serviceName string, hostName string, span ptrace.Span, k metricKey, resourceAttrs pcommon.Map, extraDims map[string]pcommon.Value) {
// Use Get to ensure any existing key has its recent-ness updated.
if _, has := p.externalCallMetricKeyToDimensions.Get(k); !has {
p.externalCallMetricKeyToDimensions.Add(k, p.buildCustomDimensionKVs(serviceName, span, p.externalCallDimensions, resourceAttrs, extraDims))
p.externalCallMetricKeyToDimensions.Add(k, p.buildCustomDimensionKVs(serviceName, hostName, span, p.externalCallDimensions, resourceAttrs, extraDims))
}
}

Expand Down

0 comments on commit 284f5a7

Please sign in to comment.