Skip to content

Commit 681d35f

Browse files
authored
Merge branch 'main' into codeboten/fix-close-response
2 parents e915a7b + a96a3d6 commit 681d35f

File tree

10 files changed

+103
-93
lines changed

10 files changed

+103
-93
lines changed

.github/workflows/fossa.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
steps:
1515
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
1616

17-
- uses: fossas/fossa-action@93a52ecf7c3ac7eb40f5de77fd69b1a19524de94 # v1.5.0
17+
- uses: fossas/fossa-action@c0a7d013f84c8ee5e910593186598625513cc1e4 # v1.6.0
1818
with:
1919
api-key: ${{secrets.FOSSA_API_KEY}}
2020
team: OpenTelemetry

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
- Fix user agent in OTLP HTTP metrics exporter
11+
([#4475](https://github.com/open-telemetry/opentelemetry-python/pull/4475))
12+
- Improve performance of baggage operations
13+
([#4466](https://github.com/open-telemetry/opentelemetry-python/pull/4466))
14+
- sdk: remove duplicated constant definitions for `environment_variables`
15+
([#4491](https://github.com/open-telemetry/opentelemetry-python/pull/4491))
16+
- api: Revert record `BaseException` change in `trace_api.use_span()`
17+
([#4494](https://github.com/open-telemetry/opentelemetry-python/pull/4494))
18+
1019
## Version 1.31.0/0.52b0 (2025-03-12)
1120

1221
- semantic-conventions: Bump to 1.31.0
1322
([#4471](https://github.com/open-telemetry/opentelemetry-python/pull/4471))
1423
- Add type annotations to context's attach & detach
1524
([#4346](https://github.com/open-telemetry/opentelemetry-python/pull/4346))
1625
- Fix OTLP encoders missing instrumentation scope schema url and attributes
17-
([#4359](https://github.com/open-telemetry/opentelemetry-python/pull/4359))
26+
([#4359](https://github.com/open-telemetry/opentelemetry-python/pull/4359))
1827
- prometheus-exporter: fix labels out of place for data points with different
1928
attribute sets
2029
([#4413](https://github.com/open-telemetry/opentelemetry-python/pull/4413))

docs/examples/fork-process-model/flask-uwsgi/requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ click==8.1.7
22
Flask==2.3.3
33
googleapis-common-protos==1.52.0
44
grpcio==1.56.2
5-
gunicorn==22.0.0
65
itsdangerous==2.1.2
7-
Jinja2==3.1.5
6+
Jinja2==3.1.6
87
MarkupSafe==2.1.3
98
opentelemetry-api==1.20.0
109
opentelemetry-exporter-otlp==1.20.0

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@
4040
from opentelemetry.exporter.otlp.proto.common.metrics_encoder import (
4141
encode_metrics,
4242
)
43-
from opentelemetry.exporter.otlp.proto.http import Compression
43+
from opentelemetry.exporter.otlp.proto.http import (
44+
_OTLP_HTTP_HEADERS,
45+
Compression,
46+
)
4447
from opentelemetry.proto.collector.metrics.v1.metrics_service_pb2 import ( # noqa: F401
4548
ExportMetricsServiceRequest,
4649
)
@@ -152,9 +155,7 @@ def __init__(
152155
self._compression = compression or _compression_from_env()
153156
self._session = session or requests.Session()
154157
self._session.headers.update(self._headers)
155-
self._session.headers.update(
156-
{"Content-Type": "application/x-protobuf"}
157-
)
158+
self._session.headers.update(_OTLP_HTTP_HEADERS)
158159
if self._compression is not Compression.NoCompression:
159160
self._session.headers.update(
160161
{"Content-Encoding": self._compression.value}

exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
DEFAULT_TIMEOUT,
3333
OTLPMetricExporter,
3434
)
35+
from opentelemetry.exporter.otlp.proto.http.version import __version__
3536
from opentelemetry.sdk.environment_variables import (
3637
OTEL_EXPORTER_OTLP_CERTIFICATE,
3738
OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE,
@@ -124,6 +125,15 @@ def test_constructor_default(self):
124125
self.assertIs(exporter._compression, DEFAULT_COMPRESSION)
125126
self.assertEqual(exporter._headers, {})
126127
self.assertIsInstance(exporter._session, Session)
128+
self.assertIn("User-Agent", exporter._session.headers)
129+
self.assertEqual(
130+
exporter._session.headers.get("Content-Type"),
131+
"application/x-protobuf",
132+
)
133+
self.assertEqual(
134+
exporter._session.headers.get("User-Agent"),
135+
"OTel-OTLP-Exporter-Python/" + __version__,
136+
)
127137

128138
@patch.dict(
129139
"os.environ",

opentelemetry-api/src/opentelemetry/baggage/__init__.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from logging import getLogger
1616
from re import compile
1717
from types import MappingProxyType
18-
from typing import Mapping, Optional
18+
from typing import Dict, Mapping, Optional
1919

2020
from opentelemetry.context import create_key, get_value, set_value
2121
from opentelemetry.context.context import Context
@@ -44,10 +44,7 @@ def get_all(
4444
Returns:
4545
The name/value pairs in the Baggage
4646
"""
47-
baggage = get_value(_BAGGAGE_KEY, context=context)
48-
if isinstance(baggage, dict):
49-
return MappingProxyType(baggage)
50-
return MappingProxyType({})
47+
return MappingProxyType(_get_baggage_value(context=context))
5148

5249

5350
def get_baggage(
@@ -64,7 +61,7 @@ def get_baggage(
6461
The value associated with the given name, or null if the given name is
6562
not present.
6663
"""
67-
return get_all(context=context).get(name)
64+
return _get_baggage_value(context=context).get(name)
6865

6966

7067
def set_baggage(
@@ -80,7 +77,7 @@ def set_baggage(
8077
Returns:
8178
A Context with the value updated
8279
"""
83-
baggage = dict(get_all(context=context))
80+
baggage = _get_baggage_value(context=context).copy()
8481
baggage[name] = value
8582
return set_value(_BAGGAGE_KEY, baggage, context=context)
8683

@@ -95,7 +92,7 @@ def remove_baggage(name: str, context: Optional[Context] = None) -> Context:
9592
Returns:
9693
A Context with the name/value removed
9794
"""
98-
baggage = dict(get_all(context=context))
95+
baggage = _get_baggage_value(context=context).copy()
9996
baggage.pop(name, None)
10097

10198
return set_value(_BAGGAGE_KEY, baggage, context=context)
@@ -113,6 +110,13 @@ def clear(context: Optional[Context] = None) -> Context:
113110
return set_value(_BAGGAGE_KEY, {}, context=context)
114111

115112

113+
def _get_baggage_value(context: Optional[Context] = None) -> Dict[str, object]:
114+
baggage = get_value(_BAGGAGE_KEY, context=context)
115+
if isinstance(baggage, dict):
116+
return baggage
117+
return {}
118+
119+
116120
def _is_valid_key(name: str) -> bool:
117121
return _KEY_PATTERN.fullmatch(str(name)) is not None
118122

opentelemetry-api/src/opentelemetry/trace/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,10 @@ def use_span(
588588
finally:
589589
context_api.detach(token)
590590

591-
except BaseException as exc: # pylint: disable=broad-exception-caught
591+
# Record only exceptions that inherit Exception class but not BaseException, because
592+
# classes that directly inherit BaseException are not technically errors, e.g. GeneratorExit.
593+
# See https://github.com/open-telemetry/opentelemetry-python/issues/4484
594+
except Exception as exc: # pylint: disable=broad-exception-caught
592595
if isinstance(span, Span) and span.is_recording():
593596
# Record the exception as an event
594597
if record_exception:

opentelemetry-api/tests/trace/test_globals.py

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
# Copyright The OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
115
import unittest
216
from unittest.mock import Mock, patch
317

@@ -13,7 +27,12 @@ class SpanTest(trace.NonRecordingSpan):
1327
recorded_status = Status(status_code=StatusCode.UNSET)
1428

1529
def set_status(self, status, description=None):
16-
self.recorded_status = status
30+
if isinstance(status, Status):
31+
self.recorded_status = status
32+
else:
33+
self.recorded_status = Status(
34+
status_code=status, description=description
35+
)
1736

1837
def end(self, end_time=None):
1938
self.has_ended = True
@@ -133,18 +152,6 @@ class TestUseSpanException(Exception):
133152

134153
self.assertEqual(test_span.recorded_exception, exception)
135154

136-
def test_use_span_base_exception(self):
137-
class TestUseSpanBaseException(BaseException):
138-
pass
139-
140-
test_span = SpanTest(trace.INVALID_SPAN_CONTEXT)
141-
exception = TestUseSpanBaseException("test exception")
142-
with self.assertRaises(TestUseSpanBaseException):
143-
with trace.use_span(test_span):
144-
raise exception
145-
146-
self.assertEqual(test_span.recorded_exception, exception)
147-
148155
def test_use_span_set_status(self):
149156
class TestUseSpanException(Exception):
150157
pass
@@ -155,10 +162,33 @@ class TestUseSpanException(Exception):
155162
raise TestUseSpanException("test error")
156163

157164
self.assertEqual(
158-
test_span.recorded_status.status_code, # type: ignore[reportAttributeAccessIssue]
165+
test_span.recorded_status.status_code,
159166
StatusCode.ERROR,
160167
)
161168
self.assertEqual(
162-
test_span.recorded_status.description, # type: ignore[reportAttributeAccessIssue]
169+
test_span.recorded_status.description,
163170
"TestUseSpanException: test error",
164171
)
172+
173+
def test_use_span_base_exceptions(self):
174+
base_exception_classes = [
175+
BaseException,
176+
GeneratorExit,
177+
SystemExit,
178+
KeyboardInterrupt,
179+
]
180+
181+
for exc_cls in base_exception_classes:
182+
with self.subTest(exc=exc_cls.__name__):
183+
test_span = SpanTest(trace.INVALID_SPAN_CONTEXT)
184+
185+
with self.assertRaises(exc_cls):
186+
with trace.use_span(test_span):
187+
raise exc_cls()
188+
189+
self.assertEqual(
190+
test_span.recorded_status.status_code,
191+
StatusCode.UNSET,
192+
)
193+
self.assertIsNone(test_span.recorded_status.description)
194+
self.assertIsNone(test_span.recorded_exception)

opentelemetry-sdk/src/opentelemetry/sdk/environment_variables/__init__.py

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -565,25 +565,6 @@
565565
Default: False
566566
"""
567567

568-
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT"
569-
"""
570-
.. envvar:: OTEL_EXPORTER_OTLP_METRICS_ENDPOINT
571-
572-
The :envvar:`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` target to which the metric exporter is going to send spans.
573-
The endpoint MUST be a valid URL host, and MAY contain a scheme (http or https), port and path.
574-
A scheme of https indicates a secure connection and takes precedence over this configuration setting.
575-
"""
576-
577-
OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE = (
578-
"OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE"
579-
)
580-
"""
581-
.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE
582-
583-
The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE` stores the path to the certificate file for
584-
TLS credentials of gRPC client for metrics. Should only be used for a secure connection for metrics.
585-
"""
586-
587568
OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE = "OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE"
588569
"""
589570
.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE
@@ -592,22 +573,6 @@
592573
TLS credentials of gRPC client for logs. Should only be used for a secure connection for logs.
593574
"""
594575

595-
OTEL_EXPORTER_OTLP_METRICS_HEADERS = "OTEL_EXPORTER_OTLP_METRICS_HEADERS"
596-
"""
597-
.. envvar:: OTEL_EXPORTER_OTLP_METRICS_HEADERS
598-
599-
The :envvar:`OTEL_EXPORTER_OTLP_METRICS_HEADERS` contains the key-value pairs to be used as headers for metrics
600-
associated with gRPC or HTTP requests.
601-
"""
602-
603-
OTEL_EXPORTER_OTLP_METRICS_TIMEOUT = "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT"
604-
"""
605-
.. envvar:: OTEL_EXPORTER_OTLP_METRICS_TIMEOUT
606-
607-
The :envvar:`OTEL_EXPORTER_OTLP_METRICS_TIMEOUT` is the maximum time the OTLP exporter will
608-
wait for each batch export for metrics.
609-
"""
610-
611576
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT = "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT"
612577
"""
613578
.. envvar:: OTEL_EXPORTER_OTLP_LOGS_TIMEOUT
@@ -616,16 +581,6 @@
616581
wait for each batch export for logs.
617582
"""
618583

619-
OTEL_EXPORTER_OTLP_METRICS_COMPRESSION = (
620-
"OTEL_EXPORTER_OTLP_METRICS_COMPRESSION"
621-
)
622-
"""
623-
.. envvar:: OTEL_EXPORTER_OTLP_METRICS_COMPRESSION
624-
625-
Same as :envvar:`OTEL_EXPORTER_OTLP_COMPRESSION` but only for the metric
626-
exporter. If both are present, this takes higher precedence.
627-
"""
628-
629584
OTEL_EXPORTER_JAEGER_CERTIFICATE = "OTEL_EXPORTER_JAEGER_CERTIFICATE"
630585
"""
631586
.. envvar:: OTEL_EXPORTER_JAEGER_CERTIFICATE
@@ -714,13 +669,6 @@
714669
The :envvar:`OTEL_METRIC_EXPORT_TIMEOUT` is the maximum allowed time (in milliseconds) to export data.
715670
"""
716671

717-
OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY = "OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY"
718-
"""
719-
.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY
720-
721-
The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY` is the clients private key to use in mTLS communication in PEM format.
722-
"""
723-
724672
OTEL_METRICS_EXEMPLAR_FILTER = "OTEL_METRICS_EXEMPLAR_FILTER"
725673
"""
726674
.. envvar:: OTEL_METRICS_EXEMPLAR_FILTER
@@ -737,15 +685,6 @@
737685
The :envvar:`OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` is the default aggregation to use for histogram instruments.
738686
"""
739687

740-
OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE = (
741-
"OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE"
742-
)
743-
"""
744-
.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE
745-
746-
The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE` is the client certificate/chain trust for clients private key to use in mTLS communication in PEM format.
747-
"""
748-
749688
OTEL_EXPERIMENTAL_RESOURCE_DETECTORS = "OTEL_EXPERIMENTAL_RESOURCE_DETECTORS"
750689
"""
751690
.. envvar:: OTEL_EXPERIMENTAL_RESOURCE_DETECTORS

pyproject.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,24 @@ pythonVersion = "3.8"
103103
include = [
104104
"opentelemetry-semantic-conventions",
105105
"opentelemetry-api",
106+
"opentelemetry-sdk",
107+
]
108+
109+
exclude = [
110+
"opentelemetry-sdk/tests",
111+
"opentelemetry-sdk/src/opentelemetry/sdk/_configuration",
112+
"opentelemetry-sdk/src/opentelemetry/sdk/_events",
113+
"opentelemetry-sdk/src/opentelemetry/sdk/_logs",
114+
"opentelemetry-sdk/src/opentelemetry/sdk/error_handler",
115+
"opentelemetry-sdk/src/opentelemetry/sdk/resources",
116+
"opentelemetry-sdk/src/opentelemetry/sdk/metrics",
117+
"opentelemetry-sdk/src/opentelemetry/sdk/trace",
118+
"opentelemetry-sdk/src/opentelemetry/sdk/util",
119+
"opentelemetry-sdk/benchmarks",
106120
]
107121

108122
# When packages are correct typed add them to the strict list
109123
strict = [
110124
"opentelemetry-semantic-conventions",
125+
"opentelemetry-sdk/src/opentelemetry/sdk/environment_variables",
111126
]

0 commit comments

Comments
 (0)