Skip to content

Commit 4277f76

Browse files
committed
Optimize and fix geo attribute serialization
1 parent a99c3fc commit 4277f76

File tree

2 files changed

+44
-55
lines changed

2 files changed

+44
-55
lines changed

exporter/elasticsearchexporter/pdata_serializer.go

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -289,33 +289,37 @@ func writeAttributes(v *json.Visitor, attributes pcommon.Map, stringifyMapValues
289289
if attributes.Len() == 0 {
290290
return
291291
}
292-
geoAttributes := mergeGeolocation(attributes)
292+
293293
_ = v.OnKey("attributes")
294294
_ = v.OnObjectStart(-1, structform.AnyType)
295295
attributes.Range(func(k string, val pcommon.Value) bool {
296296
switch k {
297297
case dataStreamType, dataStreamDataset, dataStreamNamespace, mappingHintsAttrKey:
298298
return true
299299
}
300-
if strings.HasSuffix(k, ".geo.location.lat") || strings.HasSuffix(k, ".geo.location.lon") {
300+
if isGeoAttribute(k, val) {
301301
return true
302302
}
303303
_ = v.OnKey(k)
304304
writeValue(v, val, stringifyMapValues)
305305
return true
306306
})
307-
geoAttributes.Range(func(k string, val pcommon.Value) bool {
308-
_ = v.OnKey(k)
309-
writeValue(v, val, stringifyMapValues)
310-
return true
311-
})
307+
writeGeolocationAttributes(v, attributes)
312308
_ = v.OnObjectFinished()
313309
}
314310

315-
// mergeGeolocation returns a new map that to merges all `geo.location.{lon,lat}`,
316-
// and namespaced `*.geo.location.{lon,lat}` attributes from the provided map to unnamespaced and namespaced `geo.location`.
317-
// This is to match the geo_point type in Elasticsearch.
318-
func mergeGeolocation(attributes pcommon.Map) pcommon.Map {
311+
func isGeoAttribute(k string, val pcommon.Value) bool {
312+
if val.Type() != pcommon.ValueTypeDouble {
313+
return false
314+
}
315+
switch k {
316+
case "geo.location.lat", "geo.location.lon":
317+
return true
318+
}
319+
return strings.HasSuffix(k, ".geo.location.lat") || strings.HasSuffix(k, ".geo.location.lon")
320+
}
321+
322+
func writeGeolocationAttributes(v *json.Visitor, attributes pcommon.Map) {
319323
const (
320324
lonKey = "geo.location.lon"
321325
latKey = "geo.location.lat"
@@ -362,28 +366,27 @@ func mergeGeolocation(attributes pcommon.Map) pcommon.Map {
362366
return true
363367
})
364368

365-
geoAttributes := pcommon.NewMap()
366369
for prefix, geo := range prefixToGeo {
367370
if geo.lonSet && geo.latSet {
368371
key := prefix + mergedKey
369372
// Geopoint expressed as an array with the format: [lon, lat]
370-
s := geoAttributes.PutEmptySlice(key)
371-
s.EnsureCapacity(2)
372-
s.AppendEmpty().SetDouble(geo.lon)
373-
s.AppendEmpty().SetDouble(geo.lat)
373+
_ = v.OnKey(key)
374+
_ = v.OnArrayStart(-1, structform.AnyType)
375+
_ = v.OnFloat64(geo.lon)
376+
_ = v.OnFloat64(geo.lat)
377+
_ = v.OnArrayFinished()
374378
continue
375379
}
376380
// Place the attributes back if lon and lat are not present together
377381
if geo.lonSet {
378-
key := prefix + lonKey
379-
geoAttributes.PutDouble(key, geo.lon)
382+
_ = v.OnKey(prefix + lonKey)
383+
_ = v.OnFloat64(geo.lon)
380384
}
381385
if geo.latSet {
382-
key := prefix + latKey
383-
geoAttributes.PutDouble(key, geo.lat)
386+
_ = v.OnKey(prefix + latKey)
387+
_ = v.OnFloat64(geo.lat)
384388
}
385389
}
386-
return geoAttributes
387390
}
388391

389392
func writeMap(v *json.Visitor, m pcommon.Map, stringifyMapValues bool) {

exporter/elasticsearchexporter/pdata_serializer_test.go

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"testing"
1111

1212
"github.com/stretchr/testify/assert"
13-
"github.com/stretchr/testify/require"
1413
"go.opentelemetry.io/collector/pdata/pcommon"
1514
"go.opentelemetry.io/collector/pdata/plog"
1615
"go.opentelemetry.io/collector/pdata/pmetric"
@@ -117,9 +116,17 @@ func TestSerializeLog(t *testing.T) {
117116
{
118117
name: "geo attributes",
119118
logCustomizer: func(_ pcommon.Resource, _ pcommon.InstrumentationScope, record plog.LogRecord) {
120-
record.Attributes().PutDouble("foo.geo.location.lon", 1)
121-
record.Attributes().PutDouble("foo.geo.location.lat", 2)
122-
record.Attributes().PutDouble("bar.geo.location.lat", 3)
119+
record.Attributes().PutDouble("geo.location.lon", 1.1)
120+
record.Attributes().PutDouble("geo.location.lat", 2.2)
121+
record.Attributes().PutDouble("foo.bar.geo.location.lon", 3.3)
122+
record.Attributes().PutDouble("foo.bar.geo.location.lat", 4.4)
123+
record.Attributes().PutDouble("a.geo.location.lon", 5.5)
124+
record.Attributes().PutDouble("b.geo.location.lat", 6.6)
125+
record.Attributes().PutDouble("unrelatedgeo.location.lon", 7.7)
126+
record.Attributes().PutDouble("unrelatedgeo.location.lat", 8.8)
127+
record.Attributes().PutDouble("d", 9.9)
128+
record.Attributes().PutStr("e.geo.location.lon", "foo")
129+
record.Attributes().PutStr("e.geo.location.lat", "bar")
123130
},
124131
wantErr: false,
125132
expected: map[string]any{
@@ -129,8 +136,15 @@ func TestSerializeLog(t *testing.T) {
129136
"resource": map[string]any{},
130137
"scope": map[string]any{},
131138
"attributes": map[string]any{
132-
"foo.geo.location": []any{json.Number("1.0"), json.Number("2.0")},
133-
"bar.geo.location.lat": json.Number("3.0"),
139+
"geo.location": []any{json.Number("1.1"), json.Number("2.2")},
140+
"foo.bar.geo.location": []any{json.Number("3.3"), json.Number("4.4")},
141+
"a.geo.location.lon": json.Number("5.5"),
142+
"b.geo.location.lat": json.Number("6.6"),
143+
"unrelatedgeo.location.lon": json.Number("7.7"),
144+
"unrelatedgeo.location.lat": json.Number("8.8"),
145+
"d": json.Number("9.9"),
146+
"e.geo.location.lon": "foo",
147+
"e.geo.location.lat": "bar",
134148
},
135149
},
136150
},
@@ -202,31 +216,3 @@ func TestSerializeMetricsConflict(t *testing.T) {
202216
},
203217
}, result, eventAsJSON)
204218
}
205-
206-
func TestMergeGeolocation(t *testing.T) {
207-
attributes := map[string]any{
208-
"geo.location.lon": 1.1,
209-
"geo.location.lat": 2.2,
210-
"foo.bar.geo.location.lon": 3.3,
211-
"foo.bar.geo.location.lat": 4.4,
212-
"a.geo.location.lon": 5.5,
213-
"b.geo.location.lat": 6.6,
214-
"unrelatedgeo.location.lon": 7.7,
215-
"unrelatedgeo.location.lat": 8.8,
216-
"d": 9.9,
217-
"e.geo.location.lon": "foo",
218-
"e.geo.location.lat": "bar",
219-
}
220-
wantAttributes := map[string]any{
221-
"a.geo.location.lon": 5.5,
222-
"b.geo.location.lat": 6.6,
223-
"geo.location": []any{1.1, 2.2},
224-
"foo.bar.geo.location": []any{3.3, 4.4},
225-
}
226-
input := pcommon.NewMap()
227-
err := input.FromRaw(attributes)
228-
require.NoError(t, err)
229-
output := mergeGeolocation(input)
230-
after := output.AsRaw()
231-
assert.Equal(t, wantAttributes, after)
232-
}

0 commit comments

Comments
 (0)