Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for splunk access token env var #532

Merged
merged 2 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/splunk_otel/distro.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@

from opentelemetry.instrumentation.distro import BaseDistro
from opentelemetry.instrumentation.system_metrics import SystemMetricsInstrumentor
from opentelemetry.sdk.environment_variables import OTEL_EXPORTER_OTLP_HEADERS

from splunk_otel.env import DEFAULTS, OTEL_METRICS_ENABLED, Env
from splunk_otel.env import DEFAULTS, OTEL_METRICS_ENABLED, SPLUNK_ACCESS_TOKEN, Env

X_SF_TOKEN = "x-sf-token" # noqa S105


class SplunkDistro(BaseDistro):
Expand All @@ -32,11 +35,17 @@ def __init__(self):

def _configure(self, **kwargs): # noqa: ARG002
self.set_env_defaults()
self.configure_headers()

def set_env_defaults(self):
for key, value in DEFAULTS.items():
self.env.setdefault(key, value)

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 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):
Expand Down
15 changes: 15 additions & 0 deletions tests/ott_lib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import time
from pathlib import Path

from opentelemetry import trace


def project_path():
return str(Path(__file__).parent.parent)


def trace_loop(loops):
tracer = trace.get_tracer("my-tracer")
for _ in range(loops):
with tracer.start_as_current_span("my-span"):
time.sleep(0.5)
29 changes: 29 additions & 0 deletions tests/ott_sf_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from oteltest import Telemetry
from ott_lib import project_path, trace_loop

if __name__ == "__main__":
trace_loop(12)


class AccessTokenOtelTest:
def requirements(self):
return project_path(), "oteltest"

def environment_variables(self):
return {
"OTEL_SERVICE_NAME": "my-svc",
"SPLUNK_ACCESS_TOKEN": "s3cr3t",
}

def wrapper_command(self):
return "opentelemetry-instrument"

def on_start(self):
return None

def on_stop(self, telemetry: Telemetry, stdout: str, stderr: str, returncode: int) -> None: # noqa: ARG002
for request in telemetry.get_trace_requests():
assert request.headers.get("x-sf-token") == "s3cr3t"

def is_http(self):
return False
21 changes: 4 additions & 17 deletions tests/ott_trace_loop.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
import time
from pathlib import Path

from opentelemetry import trace
from oteltest.telemetry import num_spans
from ott_lib import project_path, trace_loop

NUM_SPANS = 12


def trace_loop(loops):
tracer = trace.get_tracer("my-tracer")
for _ in range(loops):
with tracer.start_as_current_span("my-span"):
time.sleep(0.5)


if __name__ == "__main__":
trace_loop(NUM_SPANS)


class MyOtelTest:
class NumSpansOtelTest:
def requirements(self):
parent_dir = str(Path(__file__).parent.parent)
return parent_dir, "oteltest"
return project_path(), "oteltest"

def environment_variables(self):
return {
Expand All @@ -35,8 +23,7 @@ def on_start(self):
return None

def on_stop(self, telemetry, stdout: str, stderr: str, returncode: int) -> None: # noqa: ARG002
span_count = num_spans(telemetry)
assert span_count == NUM_SPANS
assert num_spans(telemetry) == NUM_SPANS

def is_http(self):
return False
35 changes: 30 additions & 5 deletions tests/test_distro.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,36 @@

def test_distro_env():
env_store = {}
# SplunkDistro's parent prevents passing in a constructor arg...
configure_distro(env_store)
assert env_store["OTEL_TRACES_EXPORTER"] == "otlp"
assert len(env_store) == 11


def test_access_token():
env_store = {"SPLUNK_ACCESS_TOKEN": "abc123"}
configure_distro(env_store)
assert env_store["OTEL_EXPORTER_OTLP_HEADERS"] == "x-sf-token=abc123"


def test_access_token_none():
env_store = {}
configure_distro(env_store)
assert "OTEL_EXPORTER_OTLP_HEADERS" not in env_store


def test_access_token_empty():
env_store = {"SPLUNK_ACCESS_TOKEN": ""}
configure_distro(env_store)
assert "OTEL_EXPORTER_OTLP_HEADERS" not in env_store


def test_access_token_whitespace():
env_store = {"SPLUNK_ACCESS_TOKEN": " "}
configure_distro(env_store)
assert "OTEL_EXPORTER_OTLP_HEADERS" not in env_store


def configure_distro(env_store):
sd = SplunkDistro()
# ...so instead we overwrite the field right after construction
sd.env = Env(env_store)
sd.configure()
# spot check default env vars
assert env_store["OTEL_TRACES_EXPORTER"] == "otlp"
assert len(env_store) == 11
Loading