Skip to content

Commit feca389

Browse files
Merge upstream/main and resolve CHANGELOG.md conflict
2 parents fe4e2da + 2448295 commit feca389

File tree

41 files changed

+1361
-177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1361
-177
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414

1515
- `opentelemetry-exporter-otlp-proto-http`: Handle HTTP 413 (Payload Too Large) responses in trace and log exporters by splitting the batch in half and retrying each half recursively
1616
([#5032](https://github.com/open-telemetry/opentelemetry-python/pull/5032))
17+
- `opentelemetry-sdk`: Add shared `_parse_headers` helper for declarative config OTLP exporters
18+
([#5021](https://github.com/open-telemetry/opentelemetry-python/pull/5021))
19+
- `opentelemetry-api`: Replace a broad exception in attribute cleaning tests to satisfy pylint in the `lint-opentelemetry-api` CI job
20+
- `opentelemetry-sdk`: Add `create_resource` and `create_propagator`/`configure_propagator` to declarative file configuration, enabling Resource and propagator instantiation from config files without reading env vars
21+
([#4979](https://github.com/open-telemetry/opentelemetry-python/pull/4979))
22+
- `opentelemetry-sdk`: Map Python `CRITICAL` log level to OTel `FATAL` severity text per the specification
23+
([#4984](https://github.com/open-telemetry/opentelemetry-python/issues/4984))
1724
- `opentelemetry-sdk`: Add file configuration support with YAML/JSON loading, environment variable substitution, and schema validation against the vendored OTel config JSON schema
1825
([#4898](https://github.com/open-telemetry/opentelemetry-python/pull/4898))
1926
- Fix intermittent CI failures in `getting-started` and `tracecontext` jobs caused by GitHub git CDN SHA propagation lag by installing contrib packages from the already-checked-out local copy instead of a second git clone
@@ -38,6 +45,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3845
([#4910](https://github.com/open-telemetry/opentelemetry-python/pull/4910))
3946
- Add configurable `max_export_batch_size` to OTLP HTTP metrics exporter
4047
([#4576](https://github.com/open-telemetry/opentelemetry-python/pull/4576))
48+
- `opentelemetry-exporter-otlp-proto-http`: use consistent protobuf for export request
49+
([#5015](https://github.com/open-telemetry/opentelemetry-python/pull/5015))
50+
- `opentelemetry-sdk`: cache TracerConfig into the tracer, this changes an internal interface. Only one Tracer with the same instrumentation scope will be created
51+
([#5007](https://github.com/open-telemetry/opentelemetry-python/pull/5007))
4152

4253
## Version 1.40.0/0.61b0 (2026-03-04)
4354

docs/api/index.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
OpenTelemetry Python API
22
========================
33

4-
.. TODO: what is the API
4+
The OpenTelemetry Python API provides the core interfaces and no-op
5+
implementations for instrumenting applications with traces, metrics, and logs.
6+
It defines the abstract classes and data types that library authors and
7+
application developers use to collect telemetry data. The API is designed to be
8+
lightweight with minimal dependencies so that instrumentation libraries can
9+
depend on it without pulling in the full SDK.
10+
11+
For the concrete implementation of these interfaces, see the
12+
:doc:`OpenTelemetry Python SDK </sdk/index>`.
513

614
.. toctree::
715
:maxdepth: 1

docs/conf.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,11 +228,11 @@
228228
scm_web = "https://github.com/" + REPO + "blob/" + branch
229229

230230
# Store variables in the epilogue so they are globally available.
231-
rst_epilog = """
232-
.. |SCM_WEB| replace:: {s}
233-
.. |SCM_RAW_WEB| replace:: {sr}
234-
.. |SCM_BRANCH| replace:: {b}
235-
""".format(s=scm_web, sr=scm_raw_web, b=branch)
231+
rst_epilog = f"""
232+
.. |SCM_WEB| replace:: {scm_web}
233+
.. |SCM_RAW_WEB| replace:: {scm_raw_web}
234+
.. |SCM_BRANCH| replace:: {branch}
235+
"""
236236

237237
# used to have links to repo files
238238
extlinks = {

docs/sdk/environment_variables.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
opentelemetry.sdk.environment_variables
22
=======================================
33

4-
.. TODO: what is the SDK
4+
The OpenTelemetry Python SDK can be configured through environment variables.
5+
These variables control behaviors such as exporter selection, resource
6+
attributes, span limits, and trace sampling. They follow the conventions
7+
defined by the `OpenTelemetry specification
8+
<https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/>`_.
59

610
.. toctree::
711
:maxdepth: 1

docs/sdk/index.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
OpenTelemetry Python SDK
22
========================
33

4-
.. TODO: what is the SDK
4+
The OpenTelemetry Python SDK provides the reference implementation of the
5+
:doc:`OpenTelemetry Python API </api/index>`. It includes the concrete classes
6+
for managing and exporting traces, metrics, and logs — such as
7+
``TracerProvider``, ``MeterProvider``, span processors, metric readers, and
8+
exporters. The SDK is responsible for sampling, batching, and delivering
9+
telemetry data to backends.
10+
11+
Install the SDK in your application to configure how telemetry is collected,
12+
processed, and exported.
513

614
.. toctree::
715
:maxdepth: 1

exporter/opentelemetry-exporter-otlp-proto-common/src/opentelemetry/exporter/otlp/proto/common/_internal/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def _get_resource_data(
170170
resource_class(
171171
**{
172172
"resource": collector_resource,
173-
"scope_{}".format(name): scope_data.values(),
173+
f"scope_{name}": scope_data.values(),
174174
}
175175
)
176176
)

exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,7 @@
155155
class InvalidCompressionValueException(Exception):
156156
def __init__(self, environ_key: str, environ_value: str):
157157
super().__init__(
158-
'Invalid value "{}" for compression envvar {}'.format(
159-
environ_value, environ_key
160-
)
158+
f'Invalid value "{environ_value}" for compression envvar {environ_key}'
161159
)
162160

163161

exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
_is_retryable,
5151
_load_session_from_envvar,
5252
)
53-
from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import ( # noqa: F401
53+
from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import (
5454
ExportMetricsServiceRequest,
5555
)
5656
from opentelemetry.proto.common.v1.common_pb2 import ( # noqa: F401
@@ -60,7 +60,7 @@
6060
KeyValue,
6161
KeyValueList,
6262
)
63-
from opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2 # noqa: F401
63+
from opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2
6464
from opentelemetry.proto.resource.v1.resource_pb2 import Resource # noqa: F401
6565
from opentelemetry.proto.resource.v1.resource_pb2 import (
6666
Resource as PB2Resource,
@@ -243,18 +243,19 @@ def _export(
243243

244244
def _export_with_retries(
245245
self,
246-
serialized_data: bytes,
246+
export_request: ExportMetricsServiceRequest,
247247
deadline_sec: float,
248248
) -> MetricExportResult:
249249
"""Export serialized data with retry logic until success, non-transient error, or exponential backoff maxed out.
250250
251251
Args:
252-
serialized_data: serialized metrics data to export
252+
export_request: ExportMetricsServiceRequest object containing metrics data to export
253253
deadline_sec: timestamp deadline for the export
254254
255255
Returns:
256256
MetricExportResult: SUCCESS if export succeeded, FAILURE otherwise
257257
"""
258+
serialized_data = export_request.SerializeToString()
258259
for retry_num in range(_MAX_RETRYS):
259260
# multiplying by a random number between .8 and 1.2 introduces a +/20% jitter to each backoff.
260261
backoff_seconds = 2**retry_num * random.uniform(0.8, 1.2)
@@ -310,23 +311,21 @@ def export(
310311
_logger.warning("Exporter already shutdown, ignoring batch")
311312
return MetricExportResult.FAILURE
312313

313-
serialized_data = encode_metrics(metrics_data)
314+
export_request = encode_metrics(metrics_data)
314315
deadline_sec = time() + self._timeout
315316

316317
# If no batch size configured, export as single batch with retries as configured
317318
if self._max_export_batch_size is None:
318-
return self._export_with_retries(
319-
serialized_data.SerializeToString(), deadline_sec
320-
)
319+
return self._export_with_retries(export_request, deadline_sec)
321320

322321
# Else, export in batches of configured size
323-
split_metrics_batches = list(
324-
_split_metrics_data(serialized_data, self._max_export_batch_size)
322+
batched_export_requests = _split_metrics_data(
323+
export_request, self._max_export_batch_size
325324
)
326325

327-
for split_metrics_data in split_metrics_batches:
326+
for split_metrics_data in batched_export_requests:
328327
export_result = self._export_with_retries(
329-
split_metrics_data.SerializeToString(),
328+
split_metrics_data,
330329
deadline_sec,
331330
)
332331
if export_result != MetricExportResult.SUCCESS:
@@ -353,18 +352,18 @@ def force_flush(self, timeout_millis: float = 10_000) -> bool:
353352

354353

355354
def _split_metrics_data(
356-
metrics_data: pb2.MetricsData,
355+
metrics_data: ExportMetricsServiceRequest,
357356
max_export_batch_size: int | None = None,
358-
) -> Iterable[pb2.MetricsData]:
359-
"""Splits metrics data into several MetricsData (copies protobuf originals),
357+
) -> Iterable[ExportMetricsServiceRequest]:
358+
"""Splits metrics data into several ExportMetricsServiceRequest (copies protobuf originals),
360359
based on configured data point max export batch size.
361360
362361
Args:
363362
metrics_data: metrics object based on HTTP protocol buffer definition
364363
365364
Returns:
366-
Iterable[pb2.MetricsData]: An iterable of pb2.MetricsData objects containing
367-
pb2.ResourceMetrics, pb2.ScopeMetrics, pb2.Metrics, and data points
365+
Iterable[ExportMetricsServiceRequest]: An iterable of ExportMetricsServiceRequest objects containing
366+
ExportMetricsServiceRequest.ResourceMetrics, ExportMetricsServiceRequest.ScopeMetrics, ExportMetricsServiceRequest.Metrics, and data points
368367
"""
369368
if not max_export_batch_size:
370369
return metrics_data
@@ -430,7 +429,7 @@ def _split_metrics_data(
430429
batch_size += 1
431430

432431
if batch_size >= max_export_batch_size:
433-
yield pb2.MetricsData(
432+
yield ExportMetricsServiceRequest(
434433
resource_metrics=_get_split_resource_metrics_pb2(
435434
split_resource_metrics
436435
)
@@ -491,7 +490,7 @@ def _split_metrics_data(
491490
split_resource_metrics.pop()
492491

493492
if batch_size > 0:
494-
yield pb2.MetricsData(
493+
yield ExportMetricsServiceRequest(
495494
resource_metrics=_get_split_resource_metrics_pb2(
496495
split_resource_metrics
497496
)

0 commit comments

Comments
 (0)