Skip to content

Commit 7bc2652

Browse files
[exporter/elasticsearch] Update ecs mode encoder semconv attributes (#43807)
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue. Ex. Adding a feature - Explain what this achieves.--> #### Description - Add new sem conv resource attributes to the ecs mode encoder - Add new sem conv record attributes to the ecs mode log and span encoders * I created a separate [issue](#43806) to update the otel version since some attributes added in this PR are not present in v1.22.0 <!-- Issue number (e.g. #1234) or full URL to issue, if applicable. --> #### Link to tracking issue Fixes #43805 <!--Describe what testing was performed and which tests were added.--> #### Testing - Updated unit test - Setup a local collector with the elasticsearch exporter to validate indexed documents
1 parent ab2df27 commit 7bc2652

File tree

3 files changed

+120
-10
lines changed

3 files changed

+120
-10
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. receiver/filelog)
7+
component: exporter/elasticsearch
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Update Elasticsearch exporter ECS mapping mode encoder semantic convention mappings
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [43805]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [user]

exporter/elasticsearchexporter/model.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,18 @@ var resourceAttrsConversionMap = map[string]string{
4242
string(semconv.ContainerImageTagsKey): "container.image.tag",
4343
string(semconv.HostNameKey): "host.hostname",
4444
string(semconv.HostArchKey): "host.architecture",
45+
string(semconv.ProcessParentPIDKey): "process.parent.pid",
46+
string(semconv.ProcessExecutableNameKey): "process.title",
4547
string(semconv.ProcessExecutablePathKey): "process.executable",
48+
string(semconv.ProcessCommandLineKey): "process.args",
4649
string(semconv.ProcessRuntimeNameKey): "service.runtime.name",
4750
string(semconv.ProcessRuntimeVersionKey): "service.runtime.version",
4851
string(semconv.OSNameKey): "host.os.name",
4952
string(semconv.OSTypeKey): "host.os.platform",
5053
string(semconv.OSDescriptionKey): "host.os.full",
5154
string(semconv.OSVersionKey): "host.os.version",
55+
string(semconv.ClientAddressKey): "client.ip",
56+
string(semconv.SourceAddressKey): "source.ip",
5257
string(semconv.K8SDeploymentNameKey): "kubernetes.deployment.name",
5358
string(semconv.K8SNamespaceNameKey): "kubernetes.namespace",
5459
string(semconv.K8SNodeNameKey): "kubernetes.node.name",
@@ -61,6 +66,8 @@ var resourceAttrsConversionMap = map[string]string{
6166
string(semconv.K8SDaemonSetNameKey): "kubernetes.daemonset.name",
6267
string(semconv.K8SContainerNameKey): "kubernetes.container.name",
6368
string(semconv.K8SClusterNameKey): "orchestrator.cluster.name",
69+
string(semconv.FaaSInstanceKey): "faas.id",
70+
string(semconv.FaaSTriggerKey): "faas.trigger.type",
6471
}
6572

6673
// resourceAttrsToPreserve contains conventions that should be preserved in ECS mode.
@@ -199,11 +206,12 @@ func (ecsModeEncoder) encodeLog(
199206

200207
// Finally, try to map record-level attributes to ECS fields.
201208
recordAttrsConversionMap := map[string]string{
202-
"event.name": "event.action",
203-
string(semconv.ExceptionMessageKey): "error.message",
204-
string(semconv.ExceptionStacktraceKey): "error.stacktrace",
205-
string(semconv.ExceptionTypeKey): "error.type",
206-
string(semconv.ExceptionEscapedKey): "event.error.exception.handled",
209+
"event.name": "event.action",
210+
string(semconv.ExceptionMessageKey): "error.message",
211+
string(semconv.ExceptionStacktraceKey): "error.stacktrace",
212+
string(semconv.ExceptionTypeKey): "error.type",
213+
string(semconv.ExceptionEscapedKey): "event.error.exception.handled",
214+
string(semconv.HTTPResponseBodySizeKey): "http.response.encoded_body_size",
207215
}
208216
encodeAttributesECSMode(&document, record.Attributes(), recordAttrsConversionMap, resourceAttrsToPreserve)
209217
addDataStreamAttributes(&document, "", idx)
@@ -247,7 +255,12 @@ func (ecsModeEncoder) encodeSpan(
247255

248256
// Finally, try to map record-level attributes to ECS fields.
249257
spanAttrsConversionMap := map[string]string{
250-
// None at the moment
258+
string(semconv.MessagingDestinationNameKey): "span.message.queue.name",
259+
"messaging.operation.name": "span.action",
260+
string(semconv.DBSystemKey): "span.db.type",
261+
"db.namespace": "span.db.instance",
262+
"db.query.text": "span.db.statement",
263+
string(semconv.HTTPResponseBodySizeKey): "http.response.encoded_body_size",
251264
}
252265

253266
// Handle special cases.

exporter/elasticsearchexporter/model_test.go

Lines changed: 74 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,20 @@ func TestEncodeSpanECSMode(t *testing.T) {
458458
string(semconv.ServiceInstanceIDKey): "23",
459459
string(semconv.ServiceNameKey): "some-service",
460460
string(semconv.ServiceVersionKey): "env-version-1234",
461+
string(semconv.ProcessParentPIDKey): "42",
462+
string(semconv.ProcessExecutableNameKey): "node",
463+
string(semconv.ClientAddressKey): "12.53.12.1",
464+
string(semconv.SourceAddressKey): "12.53.12.1",
465+
string(semconv.FaaSInstanceKey): "arn:aws:lambda:us-east-2:123456789012:function:custom-runtime",
466+
string(semconv.FaaSTriggerKey): "api-gateway",
461467
})
462468
require.NoError(t, err)
463469

470+
// add slice attributes
471+
processCommandLineSlice := resource.Attributes().PutEmptySlice(string(semconv.ProcessCommandLineKey))
472+
err = processCommandLineSlice.FromRaw([]any{"node", "app.js"})
473+
require.NoError(t, err)
474+
464475
scope := pcommon.NewInstrumentationScope()
465476

466477
traces := ptrace.NewTraces()
@@ -470,6 +481,16 @@ func TestEncodeSpanECSMode(t *testing.T) {
470481
scope.CopyTo(scopeSpans.Scope())
471482

472483
span := scopeSpans.Spans().AppendEmpty()
484+
err = span.Attributes().FromRaw(map[string]any{
485+
string(semconv.MessagingDestinationNameKey): "users_queue",
486+
"messaging.operation.name": "receive",
487+
string(semconv.DBSystemKey): "sql",
488+
"db.namespace": "users",
489+
"db.query.text": "SELECT * FROM users WHERE user_id=?",
490+
string(semconv.HTTPResponseBodySizeKey): "http.response.encoded_body_size",
491+
})
492+
require.NoError(t, err)
493+
473494
span.SetName("client span")
474495
span.SetSpanID([8]byte{0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26})
475496
span.SetTraceID([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1})
@@ -509,6 +530,15 @@ func TestEncodeSpanECSMode(t *testing.T) {
509530
"span": {
510531
"id": "1920212223242526",
511532
"name": "client span",
533+
"action": "receive",
534+
"db": {
535+
"instance": "users",
536+
"statement": "SELECT * FROM users WHERE user_id=?",
537+
"type": "sql"
538+
},
539+
"message": {
540+
"queue": { "name": "users_queue" }
541+
},
512542
"links": [
513543
{
514544
"span_id": "1112131415161718",
@@ -539,6 +569,26 @@ func TestEncodeSpanECSMode(t *testing.T) {
539569
"name": "23"
540570
},
541571
"version": "env-version-1234"
572+
},
573+
"process": {
574+
"parent": { "pid": "42" },
575+
"title": "node",
576+
"args" : ["node", "app.js"]
577+
},
578+
"client": {
579+
"ip": "12.53.12.1"
580+
},
581+
"source": {
582+
"ip": "12.53.12.1"
583+
},
584+
"faas": {
585+
"id" : "arn:aws:lambda:us-east-2:123456789012:function:custom-runtime",
586+
"trigger": { "type": "api-gateway" }
587+
},
588+
"http": {
589+
"response": {
590+
"encoded_body_size": "http.response.encoded_body_size"
591+
}
542592
}
543593
}`, buf.String())
544594
}
@@ -591,6 +641,12 @@ func TestEncodeLogECSMode(t *testing.T) {
591641
string(semconv.K8SDaemonSetNameKey): "daemonset.name",
592642
string(semconv.K8SContainerNameKey): "container.name",
593643
string(semconv.K8SClusterNameKey): "cluster.name",
644+
string(semconv.ProcessParentPIDKey): "42",
645+
string(semconv.ProcessExecutableNameKey): "node",
646+
string(semconv.ClientAddressKey): "12.53.12.1",
647+
string(semconv.SourceAddressKey): "12.53.12.1",
648+
string(semconv.FaaSInstanceKey): "arn:aws:lambda:us-east-2:123456789012:function:custom-runtime",
649+
string(semconv.FaaSTriggerKey): "api-gateway",
594650
})
595651
require.NoError(t, err)
596652

@@ -602,7 +658,8 @@ func TestEncodeLogECSMode(t *testing.T) {
602658

603659
record := plog.NewLogRecord()
604660
err = record.Attributes().FromRaw(map[string]any{
605-
"event.name": "user-password-change",
661+
"event.name": "user-password-change",
662+
string(semconv.HTTPResponseBodySizeKey): 1024,
606663
})
607664
require.NoError(t, err)
608665
observedTimestamp := pcommon.Timestamp(1710273641123456789)
@@ -655,8 +712,10 @@ func TestEncodeLogECSMode(t *testing.T) {
655712
},
656713
"process": {
657714
"pid": 9833,
658-
"command_line": "/usr/bin/ssh -l user 10.0.0.16",
659-
"executable": "/usr/bin/ssh"
715+
"args": "/usr/bin/ssh -l user 10.0.0.16",
716+
"executable": "/usr/bin/ssh",
717+
"parent": { "pid": "42" },
718+
"title": "node"
660719
},
661720
"service": {
662721
"name": "foo.bar",
@@ -676,6 +735,7 @@ func TestEncodeLogECSMode(t *testing.T) {
676735
"manufacturer": "Samsung"
677736
},
678737
"event": {"action": "user-password-change"},
738+
"http": { "response": {"encoded_body_size": 1024 }} ,
679739
"kubernetes": {
680740
"namespace": "default",
681741
"node": {"name": "node-1"},
@@ -691,7 +751,17 @@ func TestEncodeLogECSMode(t *testing.T) {
691751
"daemonset": {"name": "daemonset.name"},
692752
"container": {"name": "container.name"}
693753
},
694-
"orchestrator": {"cluster": {"name": "cluster.name"}}
754+
"orchestrator": {"cluster": {"name": "cluster.name"}},
755+
"client": {
756+
"ip": "12.53.12.1"
757+
},
758+
"source": {
759+
"ip": "12.53.12.1"
760+
},
761+
"faas": {
762+
"id" : "arn:aws:lambda:us-east-2:123456789012:function:custom-runtime",
763+
"trigger": { "type": "api-gateway" }
764+
}
695765
}`, buf.String())
696766
}
697767

0 commit comments

Comments
 (0)