Skip to content

Commit 2a4eab4

Browse files
author
NN
committed
Add encoding option to encoding ids
1 parent 200c274 commit 2a4eab4

File tree

9 files changed

+147
-58
lines changed

9 files changed

+147
-58
lines changed

exporter/opentelemetry-exporter-otlp-json-common/src/opentelemetry/exporter/otlp/json/common/__init__.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,3 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
15-
16-
from opentelemetry.exporter.otlp.json.common.version import __version__
17-
18-
__all__ = ["__version__"]

exporter/opentelemetry-exporter-otlp-json-common/src/opentelemetry/exporter/otlp/json/common/_internal/_log_encoder/__init__.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,20 @@
2121
from opentelemetry.sdk._logs import LogData
2222
from opentelemetry.sdk.resources import Resource
2323
from opentelemetry.sdk.util.instrumentation import InstrumentationScope
24+
from opentelemetry.exporter.otlp.json.common._internal.encoder_utils import encode_id
25+
from opentelemetry.exporter.otlp.json.common.encoding import IdEncoding
2426

25-
26-
def encode_logs(logs_data: Sequence[LogData]) -> Dict[str, Any]:
27+
def encode_logs(
28+
logs_data: Sequence[LogData],
29+
id_encoding: Optional[IdEncoding] = None) -> Dict[str, Any]:
2730
"""Encodes logs in the OTLP JSON format.
2831
2932
Returns:
3033
A dict representing the logs in OTLP JSON format as specified in the
3134
OpenTelemetry Protocol and ProtoJSON format.
3235
"""
36+
id_encoding = id_encoding or IdEncoding.BASE64
37+
3338
# Group logs by resource
3439
resource_logs = {}
3540
for log_data in logs_data:
@@ -65,7 +70,7 @@ def encode_logs(logs_data: Sequence[LogData]) -> Dict[str, Any]:
6570

6671
# Add log record to the appropriate scope
6772
scope_logs[scope_key]["logRecords"].append(
68-
_encode_log_record(log_data)
73+
_encode_log_record(log_data, id_encoding)
6974
)
7075

7176
# Convert dictionaries to lists for JSON output
@@ -124,7 +129,9 @@ def _encode_instrumentation_scope(
124129
}
125130

126131

127-
def _encode_log_record(log_data: LogData) -> Dict[str, Any]:
132+
def _encode_log_record(
133+
log_data: LogData,
134+
id_encoding: IdEncoding) -> Dict[str, Any]:
128135
"""Encodes a log record into OTLP JSON format."""
129136
log_record = log_data.log_record
130137

@@ -147,12 +154,10 @@ def _encode_log_record(log_data: LogData) -> Dict[str, Any]:
147154

148155
# Handle trace context if present
149156
if log_record.trace_id:
150-
trace_id_bytes = log_record.trace_id.to_bytes(16, "big")
151-
result["traceId"] = base64.b64encode(trace_id_bytes).decode("ascii")
157+
result["traceId"] = encode_id(id_encoding, log_record.trace_id, 16)
152158

153159
if log_record.span_id:
154-
span_id_bytes = log_record.span_id.to_bytes(8, "big")
155-
result["spanId"] = base64.b64encode(span_id_bytes).decode("ascii")
160+
result["spanId"] = encode_id(id_encoding, log_record.span_id, 8)
156161

157162
if (
158163
hasattr(log_record, "trace_flags")

exporter/opentelemetry-exporter-otlp-json-common/src/opentelemetry/exporter/otlp/json/common/_internal/encoder_utils.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,40 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
15+
import base64
16+
from opentelemetry.exporter.otlp.json.common.encoding import IdEncoding
17+
18+
19+
def encode_id(id_encoding: IdEncoding, the_id: int, size: int) -> str:
20+
if id_encoding == IdEncoding.BASE64:
21+
return encode_to_base64(the_id, size)
22+
elif id_encoding == IdEncoding.HEX:
23+
return encode_to_hex(the_id, size)
24+
else:
25+
raise ValueError(f"Unsupported encoding: {id_encoding}")
26+
27+
28+
def encode_to_base64(the_id: int, size: int) -> str:
29+
"""
30+
Encodes an integer as to a base64 string of a specified size.
31+
"""
32+
if the_id < 0:
33+
raise ValueError("The ID must be a non-negative integer.")
34+
if size < 0:
35+
raise ValueError("Size must be a non-negative integer.")
36+
37+
the_id_bytes = the_id.to_bytes(size, "big")
38+
return base64.b64encode(the_id_bytes).decode("ascii")
39+
40+
41+
def encode_to_hex(the_id: int, size: int) -> str:
42+
"""
43+
Encodes an integer to a hex string of a specified size.
44+
"""
45+
if the_id < 0:
46+
raise ValueError("The ID must be a non-negative integer.")
47+
if size < 0:
48+
raise ValueError("Size must be a non-negative integer.")
49+
50+
return hex(the_id)[2:].zfill(size * 2)

exporter/opentelemetry-exporter-otlp-json-common/src/opentelemetry/exporter/otlp/json/common/_internal/metrics_encoder/__init__.py

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
)
5252
from opentelemetry.sdk.resources import Resource
5353
from opentelemetry.sdk.util.instrumentation import InstrumentationScope
54+
from opentelemetry.exporter.otlp.json.common._internal.encoder_utils import encode_id
55+
from opentelemetry.exporter.otlp.json.common.encoding import IdEncoding
5456

5557
_logger = logging.getLogger(__name__)
5658

@@ -164,20 +166,25 @@ def _get_aggregation(
164166
return instrument_class_aggregation
165167

166168

167-
def encode_metrics(metrics_data: MetricsData) -> Dict[str, Any]:
169+
def encode_metrics(
170+
metrics_data: MetricsData,
171+
id_encoding: Optional[IdEncoding] = None) -> Dict[str, Any]:
168172
"""Encodes metrics in the OTLP JSON format.
169173
170174
Returns:
171175
A dict representing the metrics in OTLP JSON format as specified in the
172176
OpenTelemetry Protocol and ProtoJSON format.
173177
"""
178+
id_encoding = id_encoding or IdEncoding.BASE64
179+
174180
resource_metrics_list = []
175181

176182
for resource_metrics in metrics_data.resource_metrics:
177183
resource_metrics_dict = {
178184
"resource": _encode_resource(resource_metrics.resource),
179185
"scopeMetrics": _encode_scope_metrics(
180-
resource_metrics.scope_metrics
186+
resource_metrics.scope_metrics,
187+
id_encoding,
181188
),
182189
"schemaUrl": resource_metrics.schema_url or "",
183190
}
@@ -199,6 +206,7 @@ def _encode_resource(resource: Resource) -> Dict[str, Any]:
199206

200207
def _encode_scope_metrics(
201208
scope_metrics_list: Sequence[ScopeMetrics],
209+
id_encoding: IdEncoding,
202210
) -> List[Dict[str, Any]]:
203211
"""Encodes a list of scope metrics into OTLP JSON format."""
204212
if not scope_metrics_list:
@@ -209,7 +217,7 @@ def _encode_scope_metrics(
209217
result.append(
210218
{
211219
"scope": _encode_instrumentation_scope(scope_metrics.scope),
212-
"metrics": _encode_metrics_list(scope_metrics.metrics),
220+
"metrics": _encode_metrics_list(scope_metrics.metrics, id_encoding),
213221
"schemaUrl": scope_metrics.schema_url or "",
214222
}
215223
)
@@ -232,7 +240,7 @@ def _encode_instrumentation_scope(
232240
}
233241

234242

235-
def _encode_metrics_list(metrics: Sequence[Metric]) -> List[Dict[str, Any]]:
243+
def _encode_metrics_list(metrics: Sequence[Metric], id_encoding: IdEncoding) -> List[Dict[str, Any]]:
236244
"""Encodes a list of metrics into OTLP JSON format."""
237245
if not metrics:
238246
return []
@@ -247,14 +255,14 @@ def _encode_metrics_list(metrics: Sequence[Metric]) -> List[Dict[str, Any]]:
247255

248256
# Add data based on metric type
249257
if isinstance(metric.data, Sum):
250-
metric_dict["sum"] = _encode_sum(metric.data)
258+
metric_dict["sum"] = _encode_sum(metric.data, id_encoding)
251259
elif isinstance(metric.data, Gauge):
252-
metric_dict["gauge"] = _encode_gauge(metric.data)
260+
metric_dict["gauge"] = _encode_gauge(metric.data, id_encoding)
253261
elif isinstance(metric.data, HistogramType):
254-
metric_dict["histogram"] = _encode_histogram(metric.data)
262+
metric_dict["histogram"] = _encode_histogram(metric.data, id_encoding)
255263
elif isinstance(metric.data, ExponentialHistogram):
256264
metric_dict["exponentialHistogram"] = (
257-
_encode_exponential_histogram(metric.data)
265+
_encode_exponential_histogram(metric.data, id_encoding)
258266
)
259267
# Add other metric types as needed
260268

@@ -263,10 +271,10 @@ def _encode_metrics_list(metrics: Sequence[Metric]) -> List[Dict[str, Any]]:
263271
return result
264272

265273

266-
def _encode_sum(sum_data: Sum) -> Dict[str, Any]:
274+
def _encode_sum(sum_data: Sum, id_encoding: IdEncoding) -> Dict[str, Any]:
267275
"""Encodes a Sum metric into OTLP JSON format."""
268276
result = {
269-
"dataPoints": _encode_number_data_points(sum_data.data_points),
277+
"dataPoints": _encode_number_data_points(sum_data.data_points, id_encoding),
270278
"aggregationTemporality": _get_aggregation_temporality(
271279
sum_data.aggregation_temporality
272280
),
@@ -276,14 +284,14 @@ def _encode_sum(sum_data: Sum) -> Dict[str, Any]:
276284
return result
277285

278286

279-
def _encode_gauge(gauge_data: Gauge) -> Dict[str, Any]:
287+
def _encode_gauge(gauge_data: Gauge, id_encoding: IdEncoding) -> Dict[str, Any]:
280288
"""Encodes a Gauge metric into OTLP JSON format."""
281289
return {
282-
"dataPoints": _encode_number_data_points(gauge_data.data_points),
290+
"dataPoints": _encode_number_data_points(gauge_data.data_points, id_encoding),
283291
}
284292

285293

286-
def _encode_histogram(histogram_data: HistogramType) -> Dict[str, Any]:
294+
def _encode_histogram(histogram_data: HistogramType, id_encoding: IdEncoding) -> Dict[str, Any]:
287295
"""Encodes a Histogram metric into OTLP JSON format."""
288296
data_points = []
289297

@@ -307,7 +315,7 @@ def _encode_histogram(histogram_data: HistogramType) -> Dict[str, Any]:
307315

308316
# Optional exemplars field
309317
if hasattr(point, "exemplars") and point.exemplars:
310-
point_dict["exemplars"] = _encode_exemplars(point.exemplars)
318+
point_dict["exemplars"] = _encode_exemplars(point.exemplars, id_encoding)
311319

312320
data_points.append(point_dict)
313321

@@ -321,6 +329,7 @@ def _encode_histogram(histogram_data: HistogramType) -> Dict[str, Any]:
321329

322330
def _encode_exponential_histogram(
323331
histogram_data: ExponentialHistogram,
332+
id_encoding: IdEncoding,
324333
) -> Dict[str, Any]:
325334
"""Encodes an ExponentialHistogram metric into OTLP JSON format."""
326335
data_points = []
@@ -367,7 +376,7 @@ def _encode_exponential_histogram(
367376

368377
# Add exemplars if available
369378
if hasattr(point, "exemplars") and point.exemplars:
370-
point_dict["exemplars"] = _encode_exemplars(point.exemplars)
379+
point_dict["exemplars"] = _encode_exemplars(point.exemplars, id_encoding)
371380

372381
data_points.append(point_dict)
373382

@@ -381,6 +390,7 @@ def _encode_exponential_histogram(
381390

382391
def _encode_number_data_points(
383392
data_points: Sequence[Any],
393+
id_encoding: IdEncoding
384394
) -> List[Dict[str, Any]]:
385395
"""Encodes number data points into OTLP JSON format."""
386396
result = []
@@ -402,14 +412,14 @@ def _encode_number_data_points(
402412

403413
# Optional exemplars field
404414
if hasattr(point, "exemplars") and point.exemplars:
405-
point_dict["exemplars"] = _encode_exemplars(point.exemplars)
415+
point_dict["exemplars"] = _encode_exemplars(point.exemplars, id_encoding)
406416

407417
result.append(point_dict)
408418

409419
return result
410420

411421

412-
def _encode_exemplars(exemplars: Sequence[Any]) -> List[Dict[str, Any]]:
422+
def _encode_exemplars(exemplars: Sequence[Any], id_encoding: IdEncoding) -> List[Dict[str, Any]]:
413423
"""Encodes metric exemplars into OTLP JSON format."""
414424
result = []
415425

@@ -423,16 +433,12 @@ def _encode_exemplars(exemplars: Sequence[Any]) -> List[Dict[str, Any]]:
423433

424434
# Add trace info if available
425435
if hasattr(exemplar, "trace_id") and exemplar.trace_id:
426-
trace_id_bytes = exemplar.trace_id.to_bytes(16, "big")
427-
exemplar_dict["traceId"] = base64.b64encode(trace_id_bytes).decode(
428-
"ascii"
429-
)
436+
trace_id = encode_id(id_encoding, exemplar.trace_id, 16)
437+
exemplar_dict["traceId"] = trace_id
430438

431439
if hasattr(exemplar, "span_id") and exemplar.span_id:
432-
span_id_bytes = exemplar.span_id.to_bytes(8, "big")
433-
exemplar_dict["spanId"] = base64.b64encode(span_id_bytes).decode(
434-
"ascii"
435-
)
440+
span_id = encode_id(id_encoding, exemplar.span_id, 8)
441+
exemplar_dict["spanId"] = span_id
436442

437443
# Add value based on type
438444
if hasattr(exemplar, "value") and isinstance(exemplar.value, int):

0 commit comments

Comments
 (0)