Skip to content

Commit 23ca652

Browse files
felixbarnycarsonip
authored andcommitted
[elasticsearchexporter] Consistently store the structured body of logs and events in otel mode (open-telemetry#37387)
The OTel community has reached a consensus that all structured data for events defined by semantic conventions should be stored in attributes (open-telemetry/semantic-conventions#1651 (comment)). The body for events may contain opaque/external data, which sounds like a job for the flattened field type. Therefore, it no longer makes sense to map the body for logs and events differently. The corresponding Elasticsearch mapping change has been merged already: elastic/elasticsearch#120547 --------- Co-authored-by: Carson Ip <[email protected]>
1 parent 0d0bf39 commit 23ca652

File tree

4 files changed

+33
-16
lines changed

4 files changed

+33
-16
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: breaking
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: elasticsearchexporter
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Consistently store the structured body of logs and events in `body.structured` in `otel` mode
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: [37387]
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/exporter_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ func TestExporterLogs(t *testing.T) {
438438
m.PutEmptyMap("inner").PutStr("foo", "bar")
439439
return vm
440440
}(),
441-
wantDocument: []byte(`{"@timestamp":"0.0","attributes":{"attr.foo":"attr.foo.value"},"data_stream":{"dataset":"attr.dataset.otel","namespace":"resource.attribute.namespace","type":"logs"},"observed_timestamp":"0.0","resource":{"attributes":{"resource.attr.foo":"resource.attr.foo.value"}},"scope":{},"body":{"flattened":{"true":true,"false":false,"inner":{"foo":"bar"}}}}`),
441+
wantDocument: []byte(`{"@timestamp":"0.0","attributes":{"attr.foo":"attr.foo.value"},"data_stream":{"dataset":"attr.dataset.otel","namespace":"resource.attribute.namespace","type":"logs"},"observed_timestamp":"0.0","resource":{"attributes":{"resource.attr.foo":"resource.attr.foo.value"}},"scope":{},"body":{"structured":{"true":true,"false":false,"inner":{"foo":"bar"}}}}`),
442442
},
443443
{
444444
body: func() pcommon.Value {
@@ -461,7 +461,7 @@ func TestExporterLogs(t *testing.T) {
461461
s.AppendEmpty().SetEmptyMap().PutStr("foo", "bar")
462462
return vs
463463
}(),
464-
wantDocument: []byte(`{"@timestamp":"0.0","attributes":{"attr.foo":"attr.foo.value"},"data_stream":{"dataset":"attr.dataset.otel","namespace":"resource.attribute.namespace","type":"logs"},"observed_timestamp":"0.0","resource":{"attributes":{"resource.attr.foo":"resource.attr.foo.value"}},"scope":{},"body":{"flattened":{"value":["foo",false,{"foo":"bar"}]}}}`),
464+
wantDocument: []byte(`{"@timestamp":"0.0","attributes":{"attr.foo":"attr.foo.value"},"data_stream":{"dataset":"attr.dataset.otel","namespace":"resource.attribute.namespace","type":"logs"},"observed_timestamp":"0.0","resource":{"attributes":{"resource.attr.foo":"resource.attr.foo.value"}},"scope":{},"body":{"structured":{"value":["foo",false,{"foo":"bar"}]}}}`),
465465
},
466466
{
467467
body: func() pcommon.Value {

exporter/elasticsearchexporter/pdata_serializer.go

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -200,17 +200,14 @@ func serializeLog(resource pcommon.Resource, resourceSchemaURL string, scope pco
200200
writeSpanIDField(v, "span_id", record.SpanID())
201201
writeAttributes(v, record.Attributes(), false)
202202
writeIntFieldSkipDefault(v, "dropped_attributes_count", int64(record.DroppedAttributesCount()))
203-
isEvent := false
204203
if record.EventName() != "" {
205-
isEvent = true
206204
writeStringFieldSkipDefault(v, "event_name", record.EventName())
207205
} else if eventNameAttr, ok := record.Attributes().Get("event.name"); ok && eventNameAttr.Str() != "" {
208-
isEvent = true
209206
writeStringFieldSkipDefault(v, "event_name", eventNameAttr.Str())
210207
}
211208
writeResource(v, resource, resourceSchemaURL, false)
212209
writeScope(v, scope, scopeSchemaURL, false)
213-
writeLogBody(v, record, isEvent)
210+
writeLogBody(v, record)
214211
_ = v.OnObjectFinished()
215212
return nil
216213
}
@@ -227,21 +224,14 @@ func writeDataStream(v *json.Visitor, idx esIndex) {
227224
_ = v.OnObjectFinished()
228225
}
229226

230-
func writeLogBody(v *json.Visitor, record plog.LogRecord, isEvent bool) {
227+
func writeLogBody(v *json.Visitor, record plog.LogRecord) {
231228
if record.Body().Type() == pcommon.ValueTypeEmpty {
232229
return
233230
}
234231
_ = v.OnKey("body")
235232
_ = v.OnObjectStart(-1, structform.AnyType)
236233

237-
// Determine if this log record is an event, as they are mapped differently
238-
// https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/events.md
239-
var bodyType string
240-
if isEvent {
241-
bodyType = "structured"
242-
} else {
243-
bodyType = "flattened"
244-
}
234+
bodyType := "structured"
245235
body := record.Body()
246236
switch body.Type() {
247237
case pcommon.ValueTypeMap:

exporter/elasticsearchexporter/pdata_serializer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func TestSerializeLog(t *testing.T) {
103103
"resource": map[string]any{},
104104
"scope": map[string]any{},
105105
"body": map[string]any{
106-
"flattened": map[string]any{
106+
"structured": map[string]any{
107107
"foo.bar": "baz",
108108
},
109109
},

0 commit comments

Comments
 (0)