odigos-opentelemetry-python 1.0.89__tar.gz → 1.0.90__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {odigos_opentelemetry_python-1.0.89/odigos_opentelemetry_python.egg-info → odigos_opentelemetry_python-1.0.90}/PKG-INFO +3 -5
- odigos_opentelemetry_python-1.0.90/initializer/__init__.py +24 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/components.py +9 -0
- odigos_opentelemetry_python-1.0.90/initializer/diagnose.py +59 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/lib_handling.py +0 -6
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/odigos_sampler.py +8 -8
- odigos_opentelemetry_python-1.0.90/initializer/version.py +1 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90/odigos_opentelemetry_python.egg-info}/PKG-INFO +3 -5
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/odigos_opentelemetry_python.egg-info/SOURCES.txt +1 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/odigos_opentelemetry_python.egg-info/requires.txt +2 -4
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/http_client.py +9 -9
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/transport.py +18 -13
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/pyproject.toml +3 -5
- odigos_opentelemetry_python-1.0.89/initializer/__init__.py +0 -22
- odigos_opentelemetry_python-1.0.89/initializer/version.py +0 -1
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/LICENSE +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/README.md +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/distro/__init__.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/distro/distro.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/distro/instrumentation_registry.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/envs.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/exit_hook.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/odigos_sampler_helpers.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/post_instrument.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/process_resource.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/schemas/__init__.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/schemas/sampling.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/odigos_opentelemetry_python.egg-info/dependency_links.txt +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/odigos_opentelemetry_python.egg-info/entry_points.txt +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/odigos_opentelemetry_python.egg-info/top_level.txt +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/__init__.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/anyvalue_pb2.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/config.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/health_status.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/opamp_pb2.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/opamp_registry.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/utils.py +0 -0
- {odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/setup.cfg +0 -0
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: odigos-opentelemetry-python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.90
|
|
4
4
|
Summary: Odigos Initializer for Python OpenTelemetry Components
|
|
5
5
|
Author-email: odigos-io <support@odigos.io>
|
|
6
6
|
Requires-Python: >=3.9
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Dist: uuid7==0.1.0
|
|
9
|
-
Requires-Dist: urllib3
|
|
10
|
-
Requires-Dist: urllib3===2.2.3
|
|
11
|
-
Requires-Dist: odigos-requests==2.32.3.dev0
|
|
9
|
+
Requires-Dist: urllib3>=2.6.3
|
|
12
10
|
Requires-Dist: zipp==3.20.2
|
|
13
11
|
Requires-Dist: idna==3.10
|
|
14
12
|
Requires-Dist: asgiref==3.8.1
|
|
15
|
-
Requires-Dist: requests==2.32.3
|
|
16
13
|
Requires-Dist: certifi==2025.1.31
|
|
17
14
|
Requires-Dist: charset-normalizer==3.4.1
|
|
18
15
|
Requires-Dist: googleapis-common-protos==1.66.0
|
|
@@ -79,4 +76,5 @@ Requires-Dist: opentelemetry-instrumentation-vertexai==2.1b0
|
|
|
79
76
|
Requires-Dist: opentelemetry-instrumentation-weaviate==0.50.1
|
|
80
77
|
Provides-Extra: test
|
|
81
78
|
Requires-Dist: pytest>=8.0; extra == "test"
|
|
79
|
+
Requires-Dist: pyyaml>=6.0; extra == "test"
|
|
82
80
|
Dynamic: license-file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from .diagnose import ODIGOS_LOGGER_NAME, OPENTELEMETRY_LOGGER_NAME, apply_log_levels_from_env
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# This is the main odigos-opentelemetry-python logger setup function.
|
|
7
|
+
# It is used by all modules within this package to ensure that all logs are captured by the same logger.
|
|
8
|
+
#
|
|
9
|
+
# Each controlled logger gets its own console handler and does not propagate to the root logger.
|
|
10
|
+
def setup_logging():
|
|
11
|
+
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
12
|
+
|
|
13
|
+
for logger_name in (ODIGOS_LOGGER_NAME, OPENTELEMETRY_LOGGER_NAME):
|
|
14
|
+
logger = logging.getLogger(logger_name)
|
|
15
|
+
handler = logging.StreamHandler()
|
|
16
|
+
handler.setFormatter(formatter)
|
|
17
|
+
logger.addHandler(handler)
|
|
18
|
+
logger.propagate = False # Prevent logs from reaching the root logger
|
|
19
|
+
|
|
20
|
+
# Apply the diagnostics log levels from environment variables for the startup window, before the first OpAMP remote config.
|
|
21
|
+
apply_log_levels_from_env()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
setup_logging()
|
{odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/components.py
RENAMED
|
@@ -54,6 +54,7 @@ from .exit_hook import ExitHooks
|
|
|
54
54
|
from .envs import set_static_otel_env
|
|
55
55
|
|
|
56
56
|
from .odigos_sampler import OdigosSampler
|
|
57
|
+
from .diagnose import apply_log_levels_from_opamp
|
|
57
58
|
|
|
58
59
|
from opamp.config import Config
|
|
59
60
|
from opamp import opamp_registry
|
|
@@ -104,6 +105,10 @@ def initialize_components(trace_exporters=False, span_processor=None):
|
|
|
104
105
|
except AttributeError:
|
|
105
106
|
initial_remote_config = None
|
|
106
107
|
|
|
108
|
+
# Let the remote config take over the diagnostics log levels from the environment variables.
|
|
109
|
+
# On the OpAMP error path container_config is None, which silences the loggers.
|
|
110
|
+
apply_log_levels_from_opamp(container_config)
|
|
111
|
+
|
|
107
112
|
handle_django_instrumentation()
|
|
108
113
|
|
|
109
114
|
auto_resource = {
|
|
@@ -275,6 +280,10 @@ def update_agent_config(conf: Config):
|
|
|
275
280
|
:return: If the `provider` is `None` or if `active_proc` is `None`, then the function will return
|
|
276
281
|
without performing any further actions.
|
|
277
282
|
"""
|
|
283
|
+
# Update the diagnostics log levels on every remote config, even before the tracer provider exists.
|
|
284
|
+
if hasattr(conf, 'container_config'):
|
|
285
|
+
apply_log_levels_from_opamp(conf.container_config)
|
|
286
|
+
|
|
278
287
|
provider = get_tracer_provider()
|
|
279
288
|
if provider is None:
|
|
280
289
|
return
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
# log level of the odigos agent itself
|
|
6
|
+
ODIGOS_LOG_LEVEL: str = "ODIGOS_LOG_LEVEL"
|
|
7
|
+
ODIGOS_LOGGER_NAME: str = "odigos"
|
|
8
|
+
# log level of the OpenTelemetry components
|
|
9
|
+
OTEL_LOG_LEVEL: str = "OTEL_LOG_LEVEL"
|
|
10
|
+
OPENTELEMETRY_LOGGER_NAME: str = "opentelemetry"
|
|
11
|
+
|
|
12
|
+
# Env var vocabulary: the OpenTelemetry standard log level words (case-insensitive).
|
|
13
|
+
_ENV_LEVEL_MAP: Dict[str, Optional[int]] = {
|
|
14
|
+
"ALL": logging.NOTSET,
|
|
15
|
+
"VERBOSE": logging.DEBUG,
|
|
16
|
+
"DEBUG": logging.DEBUG,
|
|
17
|
+
"INFO": logging.INFO,
|
|
18
|
+
"WARN": logging.WARNING,
|
|
19
|
+
"ERROR": logging.ERROR,
|
|
20
|
+
"NONE": None,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Remote config vocabulary: log level set sent by the OpAMP server.
|
|
24
|
+
# The key is optional so a missing config level (None) resolves to None, which silences the logger.
|
|
25
|
+
_CONFIG_LEVEL_MAP: Dict[Optional[str], int] = {
|
|
26
|
+
"error": logging.ERROR,
|
|
27
|
+
"warn": logging.WARNING,
|
|
28
|
+
"info": logging.INFO,
|
|
29
|
+
"debug": logging.DEBUG,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _set_logger_level(logger_name: str, level: Optional[int]) -> None:
|
|
34
|
+
logger = logging.getLogger(logger_name)
|
|
35
|
+
if level is None:
|
|
36
|
+
# No level configured for this logger, so silence it.
|
|
37
|
+
logger.disabled = True
|
|
38
|
+
else:
|
|
39
|
+
logger.disabled = False
|
|
40
|
+
logger.setLevel(level)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def apply_log_levels_from_env() -> None:
|
|
44
|
+
"""
|
|
45
|
+
This governs the startup window before the first OpAMP remote config is received.
|
|
46
|
+
An unset or unrecognized value silences the logger.
|
|
47
|
+
"""
|
|
48
|
+
_set_logger_level(ODIGOS_LOGGER_NAME, _ENV_LEVEL_MAP.get((os.getenv(ODIGOS_LOG_LEVEL) or "").upper()))
|
|
49
|
+
_set_logger_level(OPENTELEMETRY_LOGGER_NAME, _ENV_LEVEL_MAP.get((os.getenv(OTEL_LOG_LEVEL) or "").upper()))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def apply_log_levels_from_opamp(container_config: Optional[Dict[str, Any]]) -> None:
|
|
53
|
+
"""
|
|
54
|
+
Apply the log levels from the OpAMP remote container config.
|
|
55
|
+
The remote config fully overrides the environment variables: a missing level silences the logger rather than falling back to the environment.
|
|
56
|
+
"""
|
|
57
|
+
agent_diagnostics: Dict[str, Any] = (container_config or {}).get("agentDiagnostics", {}) or {}
|
|
58
|
+
_set_logger_level(ODIGOS_LOGGER_NAME, _CONFIG_LEVEL_MAP.get(agent_diagnostics.get("odigosLogLevel")))
|
|
59
|
+
_set_logger_level(OPENTELEMETRY_LOGGER_NAME, _CONFIG_LEVEL_MAP.get(agent_diagnostics.get("openTelemetryComponentsLogLevel")))
|
|
@@ -40,13 +40,7 @@ def reload_distro_modules() -> None:
|
|
|
40
40
|
'typing_extensions',
|
|
41
41
|
]
|
|
42
42
|
|
|
43
|
-
excluded_modules = ['urllib3_odigos', 'requests_odigos']
|
|
44
|
-
|
|
45
43
|
for module in list(sys.modules):
|
|
46
|
-
# Check if the module starts with any of the needed prefixes, but not with any of the excluded prefixes.
|
|
47
|
-
if any(module.startswith(prefix) for prefix in excluded_modules):
|
|
48
|
-
continue
|
|
49
|
-
|
|
50
44
|
if any(module.startswith(prefix) for prefix in needed_module_prefixes):
|
|
51
45
|
module_file = getattr(sys.modules[module], '__file__', None) # Safely get __file__
|
|
52
46
|
if module_file and ('/etc/odigos-vmagent/' in module_file or '/var/odigos/' in module_file):
|
|
@@ -71,10 +71,10 @@ class OdigosSampler(Sampler):
|
|
|
71
71
|
return SamplingResult(Decision.RECORD_AND_SAMPLE, attributes=attributes, trace_state=_get_parent_trace_state(parent_context))
|
|
72
72
|
else:
|
|
73
73
|
return SamplingResult(self._not_sampled_decision(), trace_state=_get_parent_trace_state(parent_context))
|
|
74
|
-
|
|
74
|
+
sampler_logger.debug(f'Running Should_sample a span with the following attributes: {attributes}')
|
|
75
75
|
|
|
76
76
|
if self._config is None:
|
|
77
|
-
|
|
77
|
+
sampler_logger.debug('No configuration is set, returning RECORD_AND_SAMPLE')
|
|
78
78
|
return SamplingResult(Decision.RECORD_AND_SAMPLE, attributes=attributes, trace_state=_get_parent_trace_state(parent_context))
|
|
79
79
|
|
|
80
80
|
is_dry_run: bool = self._config.get('dryRun', False)
|
|
@@ -90,7 +90,7 @@ class OdigosSampler(Sampler):
|
|
|
90
90
|
|
|
91
91
|
http_operation_sample: Optional[HeadSamplingOperationMatcher] = noisy_operation.get("operation")
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
sampler_logger.debug(f'Evaluating noisy operation: {noisy_operation}')
|
|
94
94
|
|
|
95
95
|
# No operation matcher -> rule applies workload-wide (matches every span)
|
|
96
96
|
# This supports Sampling rules that scope by sourceScopes (workload) without specific HTTP matcher
|
|
@@ -104,7 +104,7 @@ class OdigosSampler(Sampler):
|
|
|
104
104
|
if (http_client_sample := http_operation_sample.get("httpClient")) and kind == SpanKind.CLIENT:
|
|
105
105
|
matched = self._match_http_client_sample_rule(http_client_sample, attributes) or matched
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
sampler_logger.debug(f'Noisy operation matched: {matched}, percentage: {percentage_to_sample}')
|
|
108
108
|
if matched and (winning_operation is None or percentage_to_sample < winning_operation.get("percentageAtMost", 0.0)):
|
|
109
109
|
winning_operation = noisy_operation
|
|
110
110
|
|
|
@@ -120,17 +120,17 @@ class OdigosSampler(Sampler):
|
|
|
120
120
|
|
|
121
121
|
# In dry-run mode, never actually drop spans
|
|
122
122
|
if is_dry_run:
|
|
123
|
-
|
|
123
|
+
sampler_logger.debug(f'Dry run [{trace_id}] would_be_sampled={sampled} (lowest_percentage={lowest_percentage})')
|
|
124
124
|
return SamplingResult(Decision.RECORD_AND_SAMPLE, attributes=attributes, trace_state=trace_state)
|
|
125
125
|
|
|
126
126
|
if sampled:
|
|
127
|
-
|
|
127
|
+
sampler_logger.debug(f'Trace [{trace_id}] is sampled with lowest percentage {lowest_percentage}')
|
|
128
128
|
return SamplingResult(Decision.RECORD_AND_SAMPLE, attributes=attributes, trace_state=trace_state)
|
|
129
129
|
else:
|
|
130
|
-
|
|
130
|
+
sampler_logger.debug(f'Trace [{trace_id}] is dropped with lowest percentage {lowest_percentage}')
|
|
131
131
|
return SamplingResult(self._not_sampled_decision(), trace_state=trace_state)
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
sampler_logger.debug('No noisy operation matched, sampling the trace')
|
|
134
134
|
return SamplingResult(Decision.RECORD_AND_SAMPLE, attributes=attributes, trace_state=_get_parent_trace_state(parent_context))
|
|
135
135
|
|
|
136
136
|
def _match_http_server_sample_rule(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "1.0.90"
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: odigos-opentelemetry-python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.90
|
|
4
4
|
Summary: Odigos Initializer for Python OpenTelemetry Components
|
|
5
5
|
Author-email: odigos-io <support@odigos.io>
|
|
6
6
|
Requires-Python: >=3.9
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Dist: uuid7==0.1.0
|
|
9
|
-
Requires-Dist: urllib3
|
|
10
|
-
Requires-Dist: urllib3===2.2.3
|
|
11
|
-
Requires-Dist: odigos-requests==2.32.3.dev0
|
|
9
|
+
Requires-Dist: urllib3>=2.6.3
|
|
12
10
|
Requires-Dist: zipp==3.20.2
|
|
13
11
|
Requires-Dist: idna==3.10
|
|
14
12
|
Requires-Dist: asgiref==3.8.1
|
|
15
|
-
Requires-Dist: requests==2.32.3
|
|
16
13
|
Requires-Dist: certifi==2025.1.31
|
|
17
14
|
Requires-Dist: charset-normalizer==3.4.1
|
|
18
15
|
Requires-Dist: googleapis-common-protos==1.66.0
|
|
@@ -79,4 +76,5 @@ Requires-Dist: opentelemetry-instrumentation-vertexai==2.1b0
|
|
|
79
76
|
Requires-Dist: opentelemetry-instrumentation-weaviate==0.50.1
|
|
80
77
|
Provides-Extra: test
|
|
81
78
|
Requires-Dist: pytest>=8.0; extra == "test"
|
|
79
|
+
Requires-Dist: pyyaml>=6.0; extra == "test"
|
|
82
80
|
Dynamic: license-file
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
uuid7==0.1.0
|
|
2
|
-
urllib3
|
|
3
|
-
urllib3===2.2.3
|
|
4
|
-
odigos-requests==2.32.3.dev0
|
|
2
|
+
urllib3>=2.6.3
|
|
5
3
|
zipp==3.20.2
|
|
6
4
|
idna==3.10
|
|
7
5
|
asgiref==3.8.1
|
|
8
|
-
requests==2.32.3
|
|
9
6
|
certifi==2025.1.31
|
|
10
7
|
charset-normalizer==3.4.1
|
|
11
8
|
googleapis-common-protos==1.66.0
|
|
@@ -73,3 +70,4 @@ opentelemetry-instrumentation-weaviate==0.50.1
|
|
|
73
70
|
|
|
74
71
|
[test]
|
|
75
72
|
pytest>=8.0
|
|
73
|
+
pyyaml>=6.0
|
{odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/http_client.py
RENAMED
|
@@ -5,7 +5,7 @@ import json
|
|
|
5
5
|
import time
|
|
6
6
|
import base64
|
|
7
7
|
import threading
|
|
8
|
-
import
|
|
8
|
+
import http.client
|
|
9
9
|
import logging
|
|
10
10
|
|
|
11
11
|
from uuid_extensions import uuid7
|
|
@@ -69,7 +69,7 @@ class OpAMPHTTPClient:
|
|
|
69
69
|
python_version = f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}'
|
|
70
70
|
error_message = f"Opentelemetry SDK require Python in version 3.8 or higher [{python_version} is not supported]"
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
opamp_logger.warning(f"{error_message}, sending disconnect message to OpAMP server...")
|
|
73
73
|
self.send_unsupported_version_disconnect_message(error_message=error_message)
|
|
74
74
|
self.opamp_connection_event.event.set()
|
|
75
75
|
return
|
|
@@ -94,7 +94,7 @@ class OpAMPHTTPClient:
|
|
|
94
94
|
self.worker()
|
|
95
95
|
|
|
96
96
|
except Exception as e:
|
|
97
|
-
|
|
97
|
+
opamp_logger.error(f"Error running OpAMP client: {e}")
|
|
98
98
|
failure_message = self.get_agent_failure_disconnect_message(error_message=str(e))
|
|
99
99
|
self.send_agent_to_server_message(failure_message)
|
|
100
100
|
|
|
@@ -234,7 +234,7 @@ class OpAMPHTTPClient:
|
|
|
234
234
|
pass
|
|
235
235
|
|
|
236
236
|
if server_to_agent.flags & opamp_pb2.ServerToAgentFlags_ReportFullState:
|
|
237
|
-
|
|
237
|
+
opamp_logger.info("Received request to report full state")
|
|
238
238
|
|
|
239
239
|
agent_description = self.get_agent_description()
|
|
240
240
|
agent_health = self.get_agent_health(component_health=True, status=AgentHealthStatus.HEALTHY.value)
|
|
@@ -251,8 +251,8 @@ class OpAMPHTTPClient:
|
|
|
251
251
|
# Catch exception and don't update the config
|
|
252
252
|
# The default config is preloaded when the EBPFSpanProcessor is initialized
|
|
253
253
|
pass
|
|
254
|
-
|
|
255
|
-
except
|
|
254
|
+
# OSError contain all socket or network failures, and HTTPException is for HTTP protocol errors
|
|
255
|
+
except (OSError, http.client.HTTPException):
|
|
256
256
|
pass
|
|
257
257
|
self.condition.wait(30)
|
|
258
258
|
|
|
@@ -330,11 +330,11 @@ class OpAMPHTTPClient:
|
|
|
330
330
|
return config
|
|
331
331
|
|
|
332
332
|
def send_heartbeat(self) -> opamp_pb2.ServerToAgent: # type: ignore
|
|
333
|
-
|
|
333
|
+
opamp_logger.debug("Sending heartbeat to OpAMP server...")
|
|
334
334
|
try:
|
|
335
335
|
agent_to_server = opamp_pb2.AgentToServer(remote_config_status=self.remote_config_status)
|
|
336
336
|
return self.send_agent_to_server_message(agent_to_server)
|
|
337
|
-
except
|
|
337
|
+
except (OSError, http.client.HTTPException):
|
|
338
338
|
pass
|
|
339
339
|
|
|
340
340
|
def get_agent_description(self) -> opamp_pb2.AgentDescription: # type: ignore
|
|
@@ -419,7 +419,7 @@ class OpAMPHTTPClient:
|
|
|
419
419
|
|
|
420
420
|
def shutdown(self, custom_failure_message: Optional[str] = None, component_health: bool = False):
|
|
421
421
|
self.running = False
|
|
422
|
-
|
|
422
|
+
opamp_logger.info("Sending agent disconnect message to OpAMP server...")
|
|
423
423
|
if custom_failure_message:
|
|
424
424
|
disconnect_message = self.get_agent_failure_disconnect_message(
|
|
425
425
|
error_message=custom_failure_message,
|
{odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/transport.py
RENAMED
|
@@ -2,19 +2,31 @@ import os
|
|
|
2
2
|
import socket
|
|
3
3
|
import http.client
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
_OPAMP_PATH = "/v1/opamp"
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _post(conn: http.client.HTTPConnection, body: bytes, headers: dict) -> bytes:
|
|
9
|
+
try:
|
|
10
|
+
conn.request("POST", _OPAMP_PATH, body=body, headers=headers)
|
|
11
|
+
response = conn.getresponse()
|
|
12
|
+
status = response.status
|
|
13
|
+
data = response.read()
|
|
14
|
+
if status >= 400:
|
|
15
|
+
raise http.client.HTTPException(f"opamp POST returned status {status}")
|
|
16
|
+
return data
|
|
17
|
+
finally:
|
|
18
|
+
conn.close()
|
|
6
19
|
|
|
7
20
|
|
|
8
21
|
class TCPTransport:
|
|
9
22
|
"""HTTP/1.1 over TCP. Talks to ODIGOS_OPAMP_SERVER_HOST."""
|
|
10
23
|
|
|
11
24
|
def __init__(self, host: str):
|
|
12
|
-
self.
|
|
25
|
+
self._host = host
|
|
13
26
|
|
|
14
27
|
def post(self, body: bytes, headers: dict, timeout: float) -> bytes:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return response.content
|
|
28
|
+
conn = http.client.HTTPConnection(self._host, timeout=timeout)
|
|
29
|
+
return _post(conn, body, headers)
|
|
18
30
|
|
|
19
31
|
|
|
20
32
|
class UnixTransport:
|
|
@@ -25,14 +37,7 @@ class UnixTransport:
|
|
|
25
37
|
|
|
26
38
|
def post(self, body: bytes, headers: dict, timeout: float) -> bytes:
|
|
27
39
|
conn = _UnixHTTPConnection(self._socket_path, timeout=timeout)
|
|
28
|
-
|
|
29
|
-
conn.request("POST", "/v1/opamp", body=body, headers=headers)
|
|
30
|
-
response = conn.getresponse()
|
|
31
|
-
if response.status >= 400:
|
|
32
|
-
raise RuntimeError(f"opamp unix POST returned status {response.status}")
|
|
33
|
-
return response.read()
|
|
34
|
-
finally:
|
|
35
|
-
conn.close()
|
|
40
|
+
return _post(conn, body, headers)
|
|
36
41
|
|
|
37
42
|
|
|
38
43
|
class _UnixHTTPConnection(http.client.HTTPConnection):
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "odigos-opentelemetry-python"
|
|
7
|
-
version = "1.0.
|
|
7
|
+
version = "1.0.90"
|
|
8
8
|
description = "Odigos Initializer for Python OpenTelemetry Components"
|
|
9
9
|
requires-python = ">=3.9"
|
|
10
10
|
authors = [
|
|
@@ -12,13 +12,10 @@ authors = [
|
|
|
12
12
|
]
|
|
13
13
|
dependencies = [
|
|
14
14
|
"uuid7 == 0.1.0",
|
|
15
|
-
"urllib3
|
|
16
|
-
"urllib3 === 2.2.3",
|
|
17
|
-
"odigos-requests == 2.32.3.dev0",
|
|
15
|
+
"urllib3 >= 2.6.3", # security floor: urllib3 redirect/retry CVEs fixed in 2.5.0
|
|
18
16
|
"zipp == 3.20.2",
|
|
19
17
|
"idna == 3.10",
|
|
20
18
|
"asgiref == 3.8.1",
|
|
21
|
-
"requests == 2.32.3",
|
|
22
19
|
"certifi == 2025.1.31",
|
|
23
20
|
"charset-normalizer == 3.4.1",
|
|
24
21
|
"googleapis-common-protos == 1.66.0",
|
|
@@ -90,6 +87,7 @@ dependencies = [
|
|
|
90
87
|
[project.optional-dependencies]
|
|
91
88
|
test = [
|
|
92
89
|
"pytest >= 8.0",
|
|
90
|
+
"pyyaml >= 6.0",
|
|
93
91
|
]
|
|
94
92
|
|
|
95
93
|
[dependency-groups]
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
# This is the main odigos-opentelemetry-python logger setup function.
|
|
5
|
-
# It is used by all modules within this package to ensure that all logs are captured by the same logger.
|
|
6
|
-
def setup_logging():
|
|
7
|
-
odigos_logger = logging.getLogger('odigos')
|
|
8
|
-
odigos_logger.setLevel(logging.DEBUG)
|
|
9
|
-
handler = logging.StreamHandler()
|
|
10
|
-
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
11
|
-
handler.setFormatter(formatter)
|
|
12
|
-
odigos_logger.addHandler(handler)
|
|
13
|
-
|
|
14
|
-
odigos_logger.propagate = False # Prevent logs from reaching the root logger
|
|
15
|
-
odigos_logger.disabled = True # Comment to enable the logger
|
|
16
|
-
|
|
17
|
-
# Suppress third-party loggers used by odigos-opentelemetry-python (before they are used)
|
|
18
|
-
logging.getLogger('urllib3_odigos').setLevel(logging.CRITICAL)
|
|
19
|
-
logging.getLogger('requests_odigos').setLevel(logging.CRITICAL)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
setup_logging()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = "1.0.89"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/envs.py
RENAMED
|
File without changes
|
{odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/initializer/exit_hook.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/anyvalue_pb2.py
RENAMED
|
File without changes
|
|
File without changes
|
{odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/health_status.py
RENAMED
|
File without changes
|
{odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/opamp_pb2.py
RENAMED
|
File without changes
|
{odigos_opentelemetry_python-1.0.89 → odigos_opentelemetry_python-1.0.90}/opamp/opamp_registry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|