Skip to content

Commit

Permalink
[enrichments] Add more enrichments for spans (#77)
Browse files Browse the repository at this point in the history
* Add transaction.id enrichment
* Add processor.event enrichment
* Add event.success_count enrichment
* Add {transaction, span}.duration.us enrichment
  • Loading branch information
lahsivjar authored Aug 13, 2024
1 parent a361389 commit 619fa7b
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 68 deletions.
30 changes: 20 additions & 10 deletions enrichments/trace/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,22 @@ type ScopeConfig struct {
// ElasticTransactionConfig configures the enrichment attributes for the
// spans which are identified as elastic transaction.
type ElasticTransactionConfig struct {
Root AttributeConfig `mapstructure:"root"`
Name AttributeConfig `mapstructure:"name"`
Type AttributeConfig `mapstructure:"type"`
Result AttributeConfig `mapstructure:"result"`
EventOutcome AttributeConfig `mapstructure:"event_outcome"`
ID AttributeConfig `mapstructure:"id"`
Root AttributeConfig `mapstructure:"root"`
Name AttributeConfig `mapstructure:"name"`
ProcessorEvent AttributeConfig `mapstructure:"processor_event"`
DurationUs AttributeConfig `mapstructure:"duration_us"`
Type AttributeConfig `mapstructure:"type"`
Result AttributeConfig `mapstructure:"result"`
EventOutcome AttributeConfig `mapstructure:"event_outcome"`
}

// ElasticSpanConfig configures the enrichment attributes for the spans
// which are NOT identified as elastic transaction.
type ElasticSpanConfig struct {
Name AttributeConfig `mapstructure:"name"`
ProcessorEvent AttributeConfig `mapstructure:"processor_event"`
DurationUs AttributeConfig `mapstructure:"duration_us"`
EventOutcome AttributeConfig `mapstructure:"event_outcome"`
ServiceTarget AttributeConfig `mapstructure:"service_target"`
DestinationService AttributeConfig `mapstructure:"destination_service"`
Expand All @@ -73,14 +78,19 @@ func Enabled() Config {
ServiceFrameworkVersion: AttributeConfig{Enabled: true},
},
Transaction: ElasticTransactionConfig{
Root: AttributeConfig{Enabled: true},
Name: AttributeConfig{Enabled: true},
Type: AttributeConfig{Enabled: true},
Result: AttributeConfig{Enabled: true},
EventOutcome: AttributeConfig{Enabled: true},
ID: AttributeConfig{Enabled: true},
Root: AttributeConfig{Enabled: true},
Name: AttributeConfig{Enabled: true},
ProcessorEvent: AttributeConfig{Enabled: true},
DurationUs: AttributeConfig{Enabled: true},
Type: AttributeConfig{Enabled: true},
Result: AttributeConfig{Enabled: true},
EventOutcome: AttributeConfig{Enabled: true},
},
Span: ElasticSpanConfig{
Name: AttributeConfig{Enabled: true},
ProcessorEvent: AttributeConfig{Enabled: true},
DurationUs: AttributeConfig{Enabled: true},
EventOutcome: AttributeConfig{Enabled: true},
ServiceTarget: AttributeConfig{Enabled: true},
DestinationService: AttributeConfig{Enabled: true},
Expand Down
5 changes: 5 additions & 0 deletions enrichments/trace/internal/elastic/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@ const (
AttributeServiceFrameworkVersion = "service.framework.version"

// span attributes
AttributeProcessorEvent = "processor.event"
AttributeTransactionID = "transaction.id"
AttributeTransactionRoot = "transaction.root"
AttributeTransactionName = "transaction.name"
AttributeTransactionType = "transaction.type"
AttributeTransactionDurationUs = "transaction.duration.us"
AttributeTransactionResult = "transaction.result"
AttributeSpanName = "span.name"
AttributeEventOutcome = "event.outcome"
AttributeSuccessCount = "event.success_count"
AttributeServiceTargetType = "service.target.type"
AttributeServiceTargetName = "service.target.name"
AttributeSpanDestinationServiceResource = "span.destination.service.resource"
AttributeSpanDurationUs = "span.duration.us"
)
23 changes: 23 additions & 0 deletions enrichments/trace/internal/elastic/span.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,21 @@ func (s *spanEnrichmentContext) enrichTransaction(
span ptrace.Span,
cfg config.ElasticTransactionConfig,
) {
if cfg.ID.Enabled {
span.Attributes().PutStr(AttributeTransactionID, span.SpanID().String())
}
if cfg.Root.Enabled {
span.Attributes().PutBool(AttributeTransactionRoot, isTraceRoot(span))
}
if cfg.Name.Enabled {
span.Attributes().PutStr(AttributeTransactionName, span.Name())
}
if cfg.ProcessorEvent.Enabled {
span.Attributes().PutStr(AttributeProcessorEvent, "transaction")
}
if cfg.DurationUs.Enabled {
span.Attributes().PutInt(AttributeTransactionDurationUs, getDurationUs(span))
}
if cfg.Type.Enabled {
s.setTxnType(span)
}
Expand All @@ -185,9 +194,15 @@ func (s *spanEnrichmentContext) enrichSpan(
if cfg.Name.Enabled {
span.Attributes().PutStr(AttributeSpanName, span.Name())
}
if cfg.ProcessorEvent.Enabled {
span.Attributes().PutStr(AttributeProcessorEvent, "span")
}
if cfg.EventOutcome.Enabled {
s.setEventOutcome(span)
}
if cfg.DurationUs.Enabled {
span.Attributes().PutInt(AttributeSpanDurationUs, getDurationUs(span))
}
if cfg.ServiceTarget.Enabled {
s.setServiceTarget(span)
}
Expand Down Expand Up @@ -245,17 +260,21 @@ func (s *spanEnrichmentContext) setTxnResult(span ptrace.Span) {
func (s *spanEnrichmentContext) setEventOutcome(span ptrace.Span) {
// default to success outcome
outcome := "success"
successCount := 1
switch {
case s.spanStatusCode == ptrace.StatusCodeError:
outcome = "failure"
successCount = 0
case s.spanStatusCode == ptrace.StatusCodeOk:
// keep the default success outcome
case s.httpStatusCode >= http.StatusInternalServerError:
// TODO (lahsivjar): Handle GRPC status code? - not handled in apm-data
// TODO (lahsivjar): Move to HTTPResponseStatusCode? Backward compatibility?
outcome = "failure"
successCount = 0
}
span.Attributes().PutStr(AttributeEventOutcome, outcome)
span.Attributes().PutInt(AttributeSuccessCount, int64(successCount))
}

func (s *spanEnrichmentContext) setServiceTarget(span ptrace.Span) {
Expand Down Expand Up @@ -337,6 +356,10 @@ func (s *spanEnrichmentContext) setDestinationService(span ptrace.Span) {
}
}

func getDurationUs(span ptrace.Span) int64 {
return int64(span.EndTimestamp()-span.StartTimestamp()) / 1000
}

func isTraceRoot(span ptrace.Span) bool {
return span.ParentSpanID().IsEmpty()
}
Expand Down
Loading

0 comments on commit 619fa7b

Please sign in to comment.