Skip to content

Commit 374b96b

Browse files
authored
OTLP: add support for counters and gauges (#133702)
1 parent 0322089 commit 374b96b

File tree

13 files changed

+1217
-1
lines changed

13 files changed

+1217
-1
lines changed

server/src/main/java/org/elasticsearch/cluster/routing/TsidBuilder.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,15 @@ public class TsidBuilder {
3434
private static final int MAX_TSID_VALUE_FIELDS = 16;
3535
private final BufferedMurmur3Hasher murmur3Hasher = new BufferedMurmur3Hasher(0L);
3636

37-
private final List<Dimension> dimensions = new ArrayList<>();
37+
private final List<Dimension> dimensions;
38+
39+
public TsidBuilder() {
40+
this.dimensions = new ArrayList<>();
41+
}
42+
43+
public TsidBuilder(int size) {
44+
this.dimensions = new ArrayList<>(size);
45+
}
3846

3947
public static TsidBuilder newBuilder() {
4048
return new TsidBuilder();
@@ -281,6 +289,10 @@ private static int writeHash128(MurmurHash3.Hash128 hash128, byte[] buffer, int
281289
return index;
282290
}
283291

292+
public int size() {
293+
return dimensions.size();
294+
}
295+
284296
/**
285297
* A functional interface that describes how objects of a complex type are added to a TSID.
286298
*
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.oteldata.otlp.datapoint;
9+
10+
import io.opentelemetry.proto.common.v1.KeyValue;
11+
import io.opentelemetry.proto.metrics.v1.Metric;
12+
import io.opentelemetry.proto.metrics.v1.NumberDataPoint;
13+
14+
import java.util.List;
15+
import java.util.Set;
16+
17+
import static io.opentelemetry.proto.metrics.v1.AggregationTemporality.AGGREGATION_TEMPORALITY_CUMULATIVE;
18+
19+
/**
20+
* Represents a metrics data point in the OpenTelemetry metrics data model.
21+
* This interface defines methods to access various properties of a data point,
22+
* such as its timestamp, attributes, unit, metric name, and methods to build
23+
* the metric value in a specific format.
24+
* The reason this class is needed is that the generated classes from the
25+
* OpenTelemetry proto definitions don't implement a common interface,
26+
* which makes it difficult to handle different types of data points uniformly.
27+
*/
28+
public interface DataPoint {
29+
30+
/**
31+
* Returns the timestamp of the data point in Unix nanoseconds.
32+
*
33+
* @return the timestamp in nanoseconds
34+
*/
35+
long getTimestampUnixNano();
36+
37+
/**
38+
* Returns the start timestamp of the data point in Unix nanoseconds.
39+
* This allows detecting when a sequence of observations is unbroken.
40+
* This field indicates to consumers the start time for points with cumulative and delta temporality,
41+
* and can support correct rate calculation.
42+
*
43+
* @return the start timestamp in nanoseconds
44+
*/
45+
long getStartTimestampUnixNano();
46+
47+
/**
48+
* Returns the attributes associated with the data point.
49+
*
50+
* @return a list of key-value pairs representing the attributes
51+
*/
52+
List<KeyValue> getAttributes();
53+
54+
/**
55+
* Returns the unit of measurement for the data point.
56+
*
57+
* @return the unit as a string
58+
*/
59+
String getUnit();
60+
61+
/**
62+
* Returns the name of the metric associated with the data point.
63+
*
64+
* @return the metric name as a string
65+
*/
66+
String getMetricName();
67+
68+
/**
69+
* Returns the dynamic template name for the data point based on its type and value.
70+
* This is used to dynamically map the appropriate field type according to the data point's characteristics.
71+
*
72+
* @return the dynamic template name as a string
73+
*/
74+
String getDynamicTemplate();
75+
76+
/**
77+
* Validates whether the data point can be indexed into Elasticsearch.
78+
*
79+
* @param errors a set to collect validation error messages
80+
* @return true if the data point is valid, false otherwise
81+
*/
82+
boolean isValid(Set<String> errors);
83+
84+
record Number(NumberDataPoint dataPoint, Metric metric) implements DataPoint {
85+
86+
@Override
87+
public long getTimestampUnixNano() {
88+
return dataPoint.getTimeUnixNano();
89+
}
90+
91+
@Override
92+
public List<KeyValue> getAttributes() {
93+
return dataPoint.getAttributesList();
94+
}
95+
96+
@Override
97+
public long getStartTimestampUnixNano() {
98+
return dataPoint.getStartTimeUnixNano();
99+
}
100+
101+
@Override
102+
public String getUnit() {
103+
return metric.getUnit();
104+
}
105+
106+
@Override
107+
public String getMetricName() {
108+
return metric.getName();
109+
}
110+
111+
@Override
112+
public String getDynamicTemplate() {
113+
String type;
114+
if (metric.hasSum()
115+
// TODO add support for delta counters - for now we represent them as gauges
116+
&& metric.getSum().getAggregationTemporality() == AGGREGATION_TEMPORALITY_CUMULATIVE
117+
// TODO add support for up/down counters - for now we represent them as gauges
118+
&& metric.getSum().getIsMonotonic()) {
119+
type = "counter_";
120+
} else {
121+
type = "gauge_";
122+
}
123+
if (dataPoint.getValueCase() == NumberDataPoint.ValueCase.AS_INT) {
124+
return type + "long";
125+
} else if (dataPoint.getValueCase() == NumberDataPoint.ValueCase.AS_DOUBLE) {
126+
return type + "double";
127+
} else {
128+
return null;
129+
}
130+
}
131+
132+
@Override
133+
public boolean isValid(Set<String> errors) {
134+
return true;
135+
}
136+
}
137+
}

0 commit comments

Comments
 (0)