Skip to content

Commit e909e47

Browse files
authored
Add support for target service in metric aggregation (#7924)
1 parent aa7f0f1 commit e909e47

File tree

10 files changed

+254
-41
lines changed

10 files changed

+254
-41
lines changed

apmpackage/apm/data_stream/internal_metrics/fields/fields.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,17 @@
130130
type: keyword
131131
description: |
132132
Version of the runtime used.
133+
- name: target
134+
type: group
135+
fields:
136+
- name: name
137+
type: keyword
138+
description: |
139+
Target service for which data is collected.
140+
- name: type
141+
type: keyword
142+
description: |
143+
Type of the target service for which data is collected
133144
- name: span
134145
type: group
135146
fields:

changelogs/head.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ https://github.com/elastic/apm-server/compare/8.2\...main[View commits]
2020
- For OpenTelemetry exception span events, stack traces that cannot be parsed will now be stored in `event.stack_trace` {pull}7706[7706]
2121
- Support for ingesting `service.target.type` and `service.target.name` added to intake API for spans {pull}7870[7870]
2222
- Derive `service.target.{type, name}` fields for older agents from `span.context.destination.service.resource` {pull}7925[7925]
23+
- Support `service.target.*` in metrics aggregation {pull}7924[7924]
2324

2425
[float]
2526
==== Added

docs/spec/v2/transaction.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,22 @@
756756
"unknown",
757757
null
758758
]
759+
},
760+
"service_target_name": {
761+
"description": "ServiceTargetName identifies the instance name of the target service being operated on",
762+
"type": [
763+
"null",
764+
"string"
765+
],
766+
"maxLength": 512
767+
},
768+
"service_target_type": {
769+
"description": "ServiceTargetType identifies the type of the target service being operated on e.g. 'oracle', 'rabbitmq'",
770+
"type": [
771+
"null",
772+
"string"
773+
],
774+
"maxLength": 512
759775
}
760776
}
761777
},

model/modeldecoder/v2/decoder.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,14 +270,19 @@ func mapToDroppedSpansModel(from []transactionDroppedSpanStats, tx *model.Transa
270270
if f.Outcome.IsSet() {
271271
to.Outcome = f.Outcome.Val
272272
}
273-
274273
if f.Duration.IsSet() {
275274
to.Duration.Count = f.Duration.Count.Val
276275
sum := f.Duration.Sum
277276
if sum.IsSet() {
278277
to.Duration.Sum = time.Duration(sum.Us.Val) * time.Microsecond
279278
}
280279
}
280+
if f.ServiceTargetType.IsSet() {
281+
to.ServiceTargetType = f.ServiceTargetType.Val
282+
}
283+
if f.ServiceTargetName.IsSet() {
284+
to.ServiceTargetName = f.ServiceTargetName.Val
285+
}
281286

282287
tx.DroppedSpansStats = append(tx.DroppedSpansStats, to)
283288
}

model/modeldecoder/v2/model.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,11 @@ type transactionDroppedSpanStats struct {
10281028
// DestinationServiceResource identifies the destination service resource
10291029
// being operated on. e.g. 'http://elastic.co:80', 'elasticsearch', 'rabbitmq/queue_name'.
10301030
DestinationServiceResource nullable.String `json:"destination_service_resource" validate:"maxLength=1024"`
1031+
// ServiceTargetType identifies the type of the target service being operated on
1032+
// e.g. 'oracle', 'rabbitmq'
1033+
ServiceTargetType nullable.String `json:"service_target_type" validate:"maxLength=512"`
1034+
// ServiceTargetName identifies the instance name of the target service being operated on
1035+
ServiceTargetName nullable.String `json:"service_target_name" validate:"maxLength=512"`
10311036
// Outcome of the span: success, failure, or unknown. Outcome may be one of
10321037
// a limited set of permitted values describing the success or failure of
10331038
// the span. It can be used for calculating error rates for outgoing requests.

model/modeldecoder/v2/model_generated.go

Lines changed: 9 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

model/transaction.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ func (m TransactionMark) fields() mapstr.M {
148148

149149
type DroppedSpanStats struct {
150150
DestinationServiceResource string
151+
ServiceTargetType string
152+
ServiceTargetName string
151153
Outcome string
152154
Duration AggregatedDuration
153155
}
@@ -157,6 +159,8 @@ func (stat DroppedSpanStats) fields() mapstr.M {
157159
out.maybeSetString("destination_service_resource",
158160
stat.DestinationServiceResource,
159161
)
162+
out.maybeSetString("service_target_type", stat.ServiceTargetType)
163+
out.maybeSetString("service_target_name", stat.ServiceTargetName)
160164
out.maybeSetString("outcome", stat.Outcome)
161165
out.maybeSetMapStr("duration", stat.Duration.fields())
162166
return mapstr.M(out)

systemtest/approvals/TestServiceDestinationAggregation.approved.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929
"name": "metric"
3030
},
3131
"service": {
32-
"name": "systemtest"
32+
"name": "systemtest",
33+
"target": {
34+
"type": "resource"
35+
}
3336
},
3437
"span": {
3538
"destination": {

x-pack/apm-server/aggregation/spanmetrics/aggregator.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,18 @@ func (a *Aggregator) processSpan(event *model.APMEvent) model.APMEvent {
228228
duration = time.Duration(event.Span.Composite.Sum * float64(time.Millisecond))
229229
}
230230

231-
key := makeAggregationKey(event, event.Span.DestinationService.Resource, a.config.Interval)
231+
var serviceTargetType, serviceTargetName string
232+
if event.Service.Target != nil {
233+
serviceTargetType = event.Service.Target.Type
234+
serviceTargetName = event.Service.Target.Name
235+
}
236+
key := makeAggregationKey(
237+
event,
238+
event.Span.DestinationService.Resource,
239+
serviceTargetType,
240+
serviceTargetName,
241+
a.config.Interval,
242+
)
232243
metrics := spanMetrics{
233244
count: float64(count) * event.Span.RepresentativeCount,
234245
sum: float64(duration) * event.Span.RepresentativeCount,
@@ -248,7 +259,13 @@ func (a *Aggregator) processDroppedSpanStats(event *model.APMEvent, dss model.Dr
248259
return model.APMEvent{}
249260
}
250261

251-
key := makeAggregationKey(event, dss.DestinationServiceResource, a.config.Interval)
262+
key := makeAggregationKey(
263+
event,
264+
dss.DestinationServiceResource,
265+
dss.ServiceTargetType,
266+
dss.ServiceTargetName,
267+
a.config.Interval,
268+
)
252269
metrics := spanMetrics{
253270
count: float64(dss.Duration.Count) * representativeCount,
254271
sum: float64(dss.Duration.Sum) * representativeCount,
@@ -292,12 +309,16 @@ type aggregationKey struct {
292309
serviceEnvironment string
293310
agentName string
294311

312+
// target
313+
targetType string
314+
targetName string
315+
295316
// destination
296317
resource string
297318
outcome string
298319
}
299320

300-
func makeAggregationKey(event *model.APMEvent, resource string, interval time.Duration) aggregationKey {
321+
func makeAggregationKey(event *model.APMEvent, resource, targetType, targetName string, interval time.Duration) aggregationKey {
301322
return aggregationKey{
302323
// Group metrics by time interval.
303324
timestamp: event.Timestamp.Truncate(interval),
@@ -306,6 +327,9 @@ func makeAggregationKey(event *model.APMEvent, resource string, interval time.Du
306327
serviceEnvironment: event.Service.Environment,
307328
agentName: event.Agent.Name,
308329

330+
targetType: targetType,
331+
targetName: targetName,
332+
309333
resource: resource,
310334
outcome: event.Event.Outcome,
311335
}
@@ -317,12 +341,20 @@ type spanMetrics struct {
317341
}
318342

319343
func makeMetricset(key aggregationKey, metrics spanMetrics) model.APMEvent {
344+
var target *model.ServiceTarget
345+
if key.targetName != "" || key.targetType != "" {
346+
target = &model.ServiceTarget{
347+
Type: key.targetType,
348+
Name: key.targetName,
349+
}
350+
}
320351
return model.APMEvent{
321352
Timestamp: key.timestamp,
322353
Agent: model.Agent{Name: key.agentName},
323354
Service: model.Service{
324355
Name: key.serviceName,
325356
Environment: key.serviceEnvironment,
357+
Target: target,
326358
},
327359
Event: model.Event{
328360
Outcome: key.outcome,

0 commit comments

Comments
 (0)