diff --git a/src/splunk_otel/distro.py b/src/splunk_otel/distro.py index 4ade904..42c8e4e 100644 --- a/src/splunk_otel/distro.py +++ b/src/splunk_otel/distro.py @@ -17,8 +17,9 @@ from opentelemetry.instrumentation.distro import BaseDistro from opentelemetry.instrumentation.propagators import set_global_response_propagator from opentelemetry.instrumentation.system_metrics import SystemMetricsInstrumentor -from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_HEADERS +from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_HEADERS, OTEL_RESOURCE_ATTRIBUTES +from splunk_otel.__about__ import __version__ as version from splunk_otel.env import ( DEFAULTS, OTEL_LOGS_ENABLED, @@ -32,6 +33,8 @@ ) from splunk_otel.propagator import ServerTimingResponsePropagator +DISTRO_NAME = "splunk-opentelemetry" + class SplunkDistro(BaseDistro): """ @@ -46,6 +49,7 @@ def __init__(self): def _configure(self, **kwargs): self.set_env_defaults() self.set_profiling_env() + self.set_resource_attributes() self.configure_headers() self.set_server_timing_propagator() @@ -58,11 +62,19 @@ def set_profiling_env(self): self.env.setdefault(OTEL_LOGS_ENABLED, "true") self.env.setdefault(OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED, "true") + def set_resource_attributes(self): + self.env.list_append(OTEL_RESOURCE_ATTRIBUTES, f"telemetry.distro.name={DISTRO_NAME}") + self.env.list_append(OTEL_RESOURCE_ATTRIBUTES, f"telemetry.distro.version={version}") + def configure_headers(self): tok = self.env.getval(SPLUNK_ACCESS_TOKEN).strip() if tok: self.env.list_append(OTEL_EXPORTER_OTLP_HEADERS, f"{X_SF_TOKEN}={tok}") + def set_server_timing_propagator(self): + if self.env.is_true(SPLUNK_TRACE_RESPONSE_HEADER_ENABLED, "true"): + set_global_response_propagator(ServerTimingResponsePropagator()) + def load_instrumentor(self, entry_point, **kwargs): # This method is called in a loop by opentelemetry-instrumentation if is_system_metrics_instrumentor(entry_point) and not self.env.is_true(OTEL_METRICS_ENABLED): @@ -70,10 +82,6 @@ def load_instrumentor(self, entry_point, **kwargs): else: super().load_instrumentor(entry_point, **kwargs) - def set_server_timing_propagator(self): - if self.env.is_true(SPLUNK_TRACE_RESPONSE_HEADER_ENABLED, "true"): - set_global_response_propagator(ServerTimingResponsePropagator()) - def is_system_metrics_instrumentor(entry_point): if entry_point.name == "system_metrics": diff --git a/tests/ott_spec.py b/tests/ott_spec.py index 124978f..6c91853 100644 --- a/tests/ott_spec.py +++ b/tests/ott_spec.py @@ -1,3 +1,4 @@ +from oteltest.telemetry import extract_leaves, get_attribute from ott_lib import project_path, trace_loop if __name__ == "__main__": @@ -6,12 +7,10 @@ class SpecOtelTest: def requirements(self): - return (project_path(),) + return project_path(), "oteltest" def environment_variables(self): - return { - "OTEL_SERVICE_NAME": "my-svc", - } + return {"OTEL_SERVICE_NAME": "my-svc"} def wrapper_command(self): return "opentelemetry-instrument" @@ -20,13 +19,18 @@ def on_start(self): return None def on_stop(self, telemetry, stdout: str, stderr: str, returncode: int) -> None: - from oteltest.telemetry import extract_leaves, get_attribute - attributes = extract_leaves(telemetry, "trace_requests", "pbreq", "resource_spans", "resource", "attributes") assert get_attribute(attributes, "telemetry.sdk.name") assert get_attribute(attributes, "telemetry.sdk.version") assert get_attribute(attributes, "telemetry.sdk.language") + assert get_attribute_str(attributes, "telemetry.distro.version") + assert get_attribute_str(attributes, "telemetry.distro.name") == "splunk-opentelemetry" + def is_http(self): return False + + +def get_attribute_str(attributes, key): + return get_attribute(attributes, key).value.string_value diff --git a/tests/test_distro.py b/tests/test_distro.py index 6ba1c1d..0a4c8b4 100644 --- a/tests/test_distro.py +++ b/tests/test_distro.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from opentelemetry.instrumentation.propagators import get_global_response_propagator, set_global_response_propagator +from splunk_otel.__about__ import __version__ as version from splunk_otel.distro import SplunkDistro from splunk_otel.env import Env @@ -20,7 +21,7 @@ def test_distro_env(): env_store = {} configure_distro(env_store) assert env_store["OTEL_TRACES_EXPORTER"] == "otlp" - assert len(env_store) == 14 + assert len(env_store) > 10 def test_access_token(): @@ -89,6 +90,15 @@ def test_profiling_notset(): assert "OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED" not in env_store +def test_resource_attributes(): + env_store = {"OTEL_RESOURCE_ATTRIBUTES": "foo=bar"} + configure_distro(env_store) + attrs = env_store["OTEL_RESOURCE_ATTRIBUTES"] + assert "telemetry.distro.name=splunk-opentelemetry" in attrs + assert f"telemetry.distro.version={version}" in attrs + assert "foo=bar" in attrs + + def configure_distro(env_store): sd = SplunkDistro() sd.env = Env(env_store)