From 0623d8d19364a8762133efaa2a70c504d979445e Mon Sep 17 00:00:00 2001 From: Steven Woods Date: Mon, 22 Jul 2024 12:19:57 +0100 Subject: [PATCH 1/2] Catch system exit in observer.py to close gracefully Signed-off-by: Steven Woods --- python3/packages/observer.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/python3/packages/observer.py b/python3/packages/observer.py index b6a0db7f6d1..13c01179a44 100644 --- a/python3/packages/observer.py +++ b/python3/packages/observer.py @@ -373,7 +373,7 @@ def _patch_module(module_name): # are not overridden and will be the defined no-op functions. span, patch_module = _init_tracing(observer_configs, observer_config_dir) - # If tracing is now operational, explicity set "OTEL_SDK_DISABLED" to "false". + # If tracing is now operational, explicitly set "OTEL_SDK_DISABLED" to "false". # In our case, different from the standard, we want the tracing disabled by # default, so if the env variable is not set the noop implementation is used. os.environ["OTEL_SDK_DISABLED"] = "false" @@ -420,6 +420,13 @@ def run(file): print(e, file=sys.stderr) # Print the exception message print(traceback.format_exc(), file=sys.stderr) # Print the traceback return 139 # This is what the default SIGSEGV handler on Linux returns + except SystemExit as e: # catch SystemExit so we can close gracefully + _exit_code = e.code if e.code is not None else 0 + debug("Script exited with code %i", _exit_code) + # Print the traceback if _exit_code is non-zero + if _exit_code: + print(traceback.format_exc(), file=sys.stderr) + return _exit_code return run(argv0) From 29344a7fb088e2316c2fc1b76d3fdb99e8e6f408 Mon Sep 17 00:00:00 2001 From: Steven Woods Date: Mon, 22 Jul 2024 12:20:24 +0100 Subject: [PATCH 2/2] CP-49876: Create spans for observer.py itself Creates two spans for observer.py, one for the entire script and one for the opentelemtry import statements. This fixes the current discrepancy between the sm script span and the outer xapi span. Signed-off-by: Steven Woods --- python3/packages/observer.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/python3/packages/observer.py b/python3/packages/observer.py index 13c01179a44..4f2966e5a9a 100644 --- a/python3/packages/observer.py +++ b/python3/packages/observer.py @@ -20,6 +20,17 @@ passed script without any instrumentation. """ +import time + +def to_otel_timestamp(ts): + return int(ts * 1000000000) + +observer_ts_start = to_otel_timestamp(time.time()) +observer_mono_start = time.monotonic() + +def current_otel_time(): + return observer_ts_start + to_otel_timestamp(time.monotonic() - observer_mono_start) + import configparser import functools import inspect @@ -117,6 +128,9 @@ def _init_tracing(configs: List[str], config_dir: str): # On 3.10-3.12, the import of wrapt might trigger warnings, filter them: simplefilter(action="ignore", category=DeprecationWarning) + + import_ts_start = current_otel_time() + import wrapt # type: ignore[import-untyped] from opentelemetry import context, trace from opentelemetry.baggage.propagation import W3CBaggagePropagator @@ -127,6 +141,8 @@ def _init_tracing(configs: List[str], config_dir: str): from opentelemetry.trace.propagation.tracecontext import ( TraceContextTextMapPropagator, ) + + import_ts_end = current_otel_time() except ImportError as err: syslog.error("missing opentelemetry dependencies: %s", err) return _span_noop, _patch_module_noop @@ -359,6 +375,12 @@ def _patch_module(module_name): for m in module_names: _patch_module(m) + # Create spans to track observer.py's setup duration + t = tracers[0] + with t.start_as_current_span("observer.py:init_tracing", start_time=observer_ts_start): + import_span = t.start_span("observer.py:imports", start_time=import_ts_start) + import_span.end(end_time=import_ts_end) + return span_of_tracers, _patch_module