Skip to content

Commit 95da33b

Browse files
authored
Merge branch 'main' into main
2 parents eede7b6 + 3015950 commit 95da33b

File tree

6 files changed

+60
-33
lines changed

6 files changed

+60
-33
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. 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: Increase metric grouping hash and _metric_names_hash from 32 bit to 64 bit to reduce collisions and chance of consequent data loss.
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: [41208]
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: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,19 +1290,19 @@ func TestExporterMetrics(t *testing.T) {
12901290
expected := []itemRequest{
12911291
{
12921292
Action: []byte(`{"create":{"_index":"metrics-generic.otel-default","dynamic_templates":{"metrics.metric.foo":"histogram"}}}`),
1293-
Document: []byte(`{"@timestamp":"0.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"metric.foo":{"counts":[1,2,3,4],"values":[0.5,1.5,2.5,3.0]}},"resource":{},"scope":{},"_metric_names_hash":"f7fdad9f"}`),
1293+
Document: []byte(`{"@timestamp":"0.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"metric.foo":{"counts":[1,2,3,4],"values":[0.5,1.5,2.5,3.0]}},"resource":{},"scope":{},"_metric_names_hash":"b23939f78dc5f649"}`),
12941294
},
12951295
{
12961296
Action: []byte(`{"create":{"_index":"metrics-generic.otel-default","dynamic_templates":{"metrics.metric.foo":"histogram"}}}`),
1297-
Document: []byte(`{"@timestamp":"3600000.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"metric.foo":{"counts":[4,5,6,7],"values":[2.0,4.5,5.5,6.0]}},"resource":{},"scope":{},"_metric_names_hash":"f7fdad9f"}`),
1297+
Document: []byte(`{"@timestamp":"3600000.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"metric.foo":{"counts":[4,5,6,7],"values":[2.0,4.5,5.5,6.0]}},"resource":{},"scope":{},"_metric_names_hash":"b23939f78dc5f649"}`),
12981298
},
12991299
{
13001300
Action: []byte(`{"create":{"_index":"metrics-generic.otel-default","dynamic_templates":{"metrics.metric.sum":"gauge_double"}}}`),
1301-
Document: []byte(`{"@timestamp":"3600000.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"metric.sum":1.5},"resource":{},"scope":{},"start_timestamp":"7200000.0","_metric_names_hash":"6e599000"}`),
1301+
Document: []byte(`{"@timestamp":"3600000.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"metric.sum":1.5},"resource":{},"scope":{},"start_timestamp":"7200000.0","_metric_names_hash":"f4a8ac5e1b330ad6"}`),
13021302
},
13031303
{
13041304
Action: []byte(`{"create":{"_index":"metrics-generic.otel-default","dynamic_templates":{"metrics.metric.summary":"summary"}}}`),
1305-
Document: []byte(`{"@timestamp":"10800000.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"metric.summary":{"sum":1.5,"value_count":1}},"resource":{},"scope":{},"start_timestamp":"10800000.0","_metric_names_hash":"45a9e3cb"}`),
1305+
Document: []byte(`{"@timestamp":"10800000.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"metric.summary":{"sum":1.5,"value_count":1}},"resource":{},"scope":{},"start_timestamp":"10800000.0","_metric_names_hash":"2f30c89222c9d308"}`),
13061306
},
13071307
}
13081308

@@ -1371,7 +1371,7 @@ func TestExporterMetrics(t *testing.T) {
13711371
expected := []itemRequest{
13721372
{
13731373
Action: []byte(`{"create":{"_index":"metrics-generic.otel-default","dynamic_templates":{"metrics.sum":"gauge_long","metrics.summary":"summary"}}}`),
1374-
Document: []byte(`{"@timestamp":"0.0","_doc_count":10,"data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"sum":0,"summary":{"sum":1.0,"value_count":10}},"resource":{},"scope":{},"_metric_names_hash":"7dc58200"}`),
1374+
Document: []byte(`{"@timestamp":"0.0","_doc_count":10,"data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"sum":0,"summary":{"sum":1.0,"value_count":10}},"resource":{},"scope":{},"_metric_names_hash":"e446964dc8337bbb"}`),
13751375
},
13761376
}
13771377

@@ -1421,11 +1421,11 @@ func TestExporterMetrics(t *testing.T) {
14211421
expected := []itemRequest{
14221422
{
14231423
Action: []byte(`{"create":{"_index":"metrics-generic.otel-default","dynamic_templates":{"metrics.histogram.summary":"summary"}}}`),
1424-
Document: []byte(`{"@timestamp":"0.0","_doc_count":10,"data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"attributes":{},"metrics":{"histogram.summary":{"sum":1.0,"value_count":10}},"resource":{},"scope":{},"_metric_names_hash":"acbaed6b"}`),
1424+
Document: []byte(`{"@timestamp":"0.0","_doc_count":10,"data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"attributes":{},"metrics":{"histogram.summary":{"sum":1.0,"value_count":10}},"resource":{},"scope":{},"_metric_names_hash":"fcd1d6737d725996"}`),
14251425
},
14261426
{
14271427
Action: []byte(`{"create":{"_index":"metrics-generic.otel-default","dynamic_templates":{"metrics.exphistogram.summary":"summary"}}}`),
1428-
Document: []byte(`{"@timestamp":"3600000.0","_doc_count":10,"data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"attributes":{},"metrics":{"exphistogram.summary":{"sum":1.0,"value_count":10}},"resource":{},"scope":{},"_metric_names_hash":"29641c64"}`),
1428+
Document: []byte(`{"@timestamp":"3600000.0","_doc_count":10,"data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"attributes":{},"metrics":{"exphistogram.summary":{"sum":1.0,"value_count":10}},"resource":{},"scope":{},"_metric_names_hash":"6a10ca190ae63c5"}`),
14291429
},
14301430
}
14311431

@@ -1464,7 +1464,7 @@ func TestExporterMetrics(t *testing.T) {
14641464
expected := []itemRequest{
14651465
{
14661466
Action: []byte(`{"create":{"_index":"metrics-generic.otel-default","dynamic_templates":{"metrics.foo.bar":"gauge_long","metrics.foo":"gauge_long","metrics.foo.bar.baz":"gauge_long"}}}`),
1467-
Document: []byte(`{"@timestamp":"0.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"foo":0,"foo.bar":0,"foo.bar.baz":0},"resource":{},"scope":{},"_metric_names_hash":"204c382a"}`),
1467+
Document: []byte(`{"@timestamp":"0.0","data_stream":{"dataset":"generic.otel","namespace":"default","type":"metrics"},"metrics":{"foo":0,"foo.bar":0,"foo.bar.baz":0},"resource":{},"scope":{},"_metric_names_hash":"9c732a69b35274fe"}`),
14681468
},
14691469
}
14701470

exporter/elasticsearchexporter/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go 1.23.0
44

55
require (
66
github.com/cespare/xxhash v1.1.0
7+
github.com/cespare/xxhash/v2 v2.3.0
78
github.com/elastic/go-docappender/v2 v2.10.0
89
github.com/elastic/go-elasticsearch/v8 v8.18.1
910
github.com/elastic/go-freelru v0.16.0
@@ -44,7 +45,6 @@ require (
4445

4546
require (
4647
github.com/cenkalti/backoff/v5 v5.0.2 // indirect
47-
github.com/cespare/xxhash/v2 v2.3.0 // indirect
4848
github.com/cilium/ebpf v0.16.0 // indirect
4949
github.com/davecgh/go-spew v1.1.1 // indirect
5050
github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect

exporter/elasticsearchexporter/internal/metricgroup/hasher.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ package metricgroup // import "github.com/open-telemetry/opentelemetry-collector
55

66
import (
77
"encoding/binary"
8-
"hash/fnv"
98

9+
"github.com/cespare/xxhash/v2"
1010
"go.opentelemetry.io/collector/pdata/pcommon"
1111
"go.opentelemetry.io/collector/pdata/pmetric"
1212

@@ -16,9 +16,9 @@ import (
1616

1717
// HashKey is a struct for comparing data point identity.
1818
type HashKey struct {
19-
resourceHash uint32
20-
scopeHash uint32
21-
dpHash uint32
19+
resourceHash uint64
20+
scopeHash uint64
21+
dpHash uint64
2222
}
2323

2424
// DataPointHasher is an interface for hashing data points by their identity,
@@ -64,64 +64,64 @@ func (h *ECSDataPointHasher) HashKey() HashKey {
6464
v.CopyTo(merged.PutEmpty(k))
6565
}
6666

67-
hasher := fnv.New32a()
67+
hasher := xxhash.New()
6868

6969
timestampBuf := make([]byte, 8)
7070
binary.LittleEndian.PutUint64(timestampBuf, uint64(h.dp.Timestamp()))
71-
hasher.Write(timestampBuf)
71+
_, _ = hasher.Write(timestampBuf)
7272

7373
mapHashSortedExcludeReservedAttrs(hasher, merged)
7474

7575
return HashKey{
76-
dpHash: hasher.Sum32(),
76+
dpHash: hasher.Sum64(),
7777
}
7878
}
7979

8080
// OTelDataPointHasher computes a hash for each of resource, scope and data point on each Update call,
8181
// to avoid wasteful hashing and sorting on data point sharing the same resource and scope.
8282
type OTelDataPointHasher struct {
83-
resourceHash uint32
84-
scopeHash uint32
85-
dpHash uint32
83+
resourceHash uint64
84+
scopeHash uint64
85+
dpHash uint64
8686
}
8787

8888
func (h *OTelDataPointHasher) UpdateResource(resource pcommon.Resource) {
8989
// We cannot use exp/metrics/identity here because some resource fields e.g. schema url
9090
// are not dimensions and should not be part of the hash.
9191

92-
hasher := fnv.New32a()
92+
hasher := xxhash.New()
9393
// There is special handling to merge geo attributes during serialization,
9494
// but we can hash them as if they are separate now.
9595
mapHashSortedExcludeReservedAttrs(hasher, resource.Attributes(), elasticsearch.MappingHintsAttrKey)
96-
h.resourceHash = hasher.Sum32()
96+
h.resourceHash = hasher.Sum64()
9797
}
9898

9999
func (h *OTelDataPointHasher) UpdateScope(scope pcommon.InstrumentationScope) {
100-
hasher := fnv.New32a()
101-
hasher.Write([]byte(scope.Name()))
100+
hasher := xxhash.New()
101+
_, _ = hasher.Write([]byte(scope.Name()))
102102
// There is special handling to merge geo attributes during serialization,
103103
// but we can hash them as if they are separate now.
104104
mapHashSortedExcludeReservedAttrs(hasher, scope.Attributes(), elasticsearch.MappingHintsAttrKey)
105-
h.scopeHash = hasher.Sum32()
105+
h.scopeHash = hasher.Sum64()
106106
}
107107

108108
func (h *OTelDataPointHasher) UpdateDataPoint(dp datapoints.DataPoint) {
109-
hasher := fnv.New32a()
109+
hasher := xxhash.New()
110110

111111
timestampBuf := make([]byte, 8)
112112
binary.LittleEndian.PutUint64(timestampBuf, uint64(dp.Timestamp()))
113-
hasher.Write(timestampBuf)
113+
_, _ = hasher.Write(timestampBuf)
114114

115115
binary.LittleEndian.PutUint64(timestampBuf, uint64(dp.StartTimestamp()))
116-
hasher.Write(timestampBuf)
116+
_, _ = hasher.Write(timestampBuf)
117117

118-
hasher.Write([]byte(dp.Metric().Unit()))
118+
_, _ = hasher.Write([]byte(dp.Metric().Unit()))
119119

120120
// There is special handling to merge geo attributes during serialization,
121121
// but we can hash them as if they are separate now.
122122
mapHashSortedExcludeReservedAttrs(hasher, dp.Attributes(), elasticsearch.MappingHintsAttrKey)
123123

124-
h.dpHash = hasher.Sum32()
124+
h.dpHash = hasher.Sum64()
125125
}
126126

127127
func (h *OTelDataPointHasher) HashKey() HashKey {

exporter/elasticsearchexporter/internal/serializer/otelserializer/metrics.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ package otelserializer // import "github.com/open-telemetry/opentelemetry-collec
66
import (
77
"bytes"
88
"fmt"
9-
"hash/fnv"
109
"sort"
1110
"strconv"
1211

12+
"github.com/cespare/xxhash/v2"
1313
"github.com/elastic/go-structform"
1414
"github.com/elastic/go-structform/json"
1515
"go.opentelemetry.io/collector/pdata/pcommon"
@@ -92,13 +92,13 @@ func serializeDataPoints(v *json.Visitor, dataPoints []datapoints.DataPoint, val
9292
writeUIntField(v, "_doc_count", docCount)
9393
}
9494
sort.Strings(metricNames)
95-
hasher := fnv.New32a()
95+
hasher := xxhash.New()
9696
for _, name := range metricNames {
9797
_, _ = hasher.Write([]byte(name))
9898
}
9999
// workaround for https://github.com/elastic/elasticsearch/issues/99123
100100
// should use a string field to benefit from run-length encoding
101-
writeStringFieldSkipDefault(v, "_metric_names_hash", strconv.FormatUint(uint64(hasher.Sum32()), 16))
101+
writeStringFieldSkipDefault(v, "_metric_names_hash", strconv.FormatUint(hasher.Sum64(), 16))
102102

103103
return dynamicTemplates
104104
}

exporter/elasticsearchexporter/internal/serializer/otelserializer/metrics_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ func TestSerializeMetricsConflict(t *testing.T) {
5858
"metrics": map[string]any{
5959
"foo": json.Number("42"),
6060
},
61-
"_metric_names_hash": "a9f37ed7",
61+
"_metric_names_hash": "33bf00a859c4ba3f",
6262
}, result, eventAsJSON)
6363
}

0 commit comments

Comments
 (0)