Skip to content

Commit d4b2149

Browse files
pvitalGSVarsha
authored andcommitted
feat: Add support to disable log collection.
Disabling log spans collection at the tracer level to prevent duplication in the backend when both the application tracer and an OpenTelemetry collector are running on the same system. Signed-off-by: Paulo Vital <[email protected]>
1 parent 1992162 commit d4b2149

File tree

2 files changed

+86
-4
lines changed

2 files changed

+86
-4
lines changed

src/instana/instrumentation/logging.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import wrapt
1111

1212
from instana.log import logger
13+
from instana.singletons import agent
1314
from instana.util.runtime import get_runtime_env_info
1415
from instana.util.traceutils import get_tracer_tuple, tracing_is_off
1516

@@ -27,12 +28,18 @@ def log_with_instana(
2728

2829
# We take into consideration if `stacklevel` is already present in `kwargs`.
2930
# This prevents the error `_log() got multiple values for keyword argument 'stacklevel'`
30-
stacklevel_in = kwargs.pop("stacklevel", 1 if get_runtime_env_info()[0] not in ["ppc64le", "s390x"] else 2)
31+
stacklevel_in = kwargs.pop(
32+
"stacklevel", 1 if get_runtime_env_info()[0] not in ["ppc64le", "s390x"] else 2
33+
)
3134
stacklevel = stacklevel_in + 1 + (sys.version_info >= (3, 14))
3235

3336
try:
34-
# Only needed if we're tracing and serious log
35-
if tracing_is_off() or argv[0] < logging.WARN:
37+
# Only needed if we're tracing and serious log and logging spans are not disabled
38+
if (
39+
tracing_is_off()
40+
or argv[0] < logging.WARN
41+
or agent.options.is_span_disabled(category="logging")
42+
):
3643
return wrapped(*argv, **kwargs, stacklevel=stacklevel)
3744

3845
tracer, parent_span, _ = get_tracer_tuple()

tests/clients/test_logging.py

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def test_parameters(self) -> None:
7070
try:
7171
a = 42
7272
b = 0
73-
c = a / b
73+
c = a / b # noqa: F841
7474
except Exception as e:
7575
self.logger.exception("Exception: %s", str(e))
7676

@@ -168,3 +168,78 @@ def main():
168168
assert spans[0].k is SpanKind.CLIENT
169169

170170
assert spans[0].data["log"].get("message") == "foo bar"
171+
172+
173+
class TestLoggingDisabling:
174+
@pytest.fixture(autouse=True)
175+
def _resource(self) -> Generator[None, None, None]:
176+
# Setup
177+
self.recorder = tracer.span_processor
178+
self.recorder.clear_spans()
179+
self.logger = logging.getLogger("unit test")
180+
181+
# Save original options
182+
self.original_options = agent.options
183+
184+
yield
185+
186+
# Teardown
187+
agent.options = self.original_options
188+
agent.options.allow_exit_as_root = False
189+
190+
def test_logging_enabled(self) -> None:
191+
with tracer.start_as_current_span("test"):
192+
self.logger.warning("test message")
193+
194+
spans = self.recorder.queued_spans()
195+
assert len(spans) == 2
196+
assert spans[0].k is SpanKind.CLIENT
197+
assert spans[0].data["log"].get("message") == "test message"
198+
199+
def test_logging_disabled(self) -> None:
200+
# Disable logging spans
201+
agent.options.disabled_spans = ["logging"]
202+
203+
with tracer.start_as_current_span("test"):
204+
self.logger.warning("test message")
205+
206+
spans = self.recorder.queued_spans()
207+
assert len(spans) == 1 # Only the parent span, no logging span
208+
209+
def test_logging_disabled_via_env_var(self, monkeypatch):
210+
# Disable logging spans via environment variable
211+
monkeypatch.setenv("INSTANA_TRACING_DISABLE", "logging")
212+
213+
# Create new options to read from environment
214+
original_options = agent.options
215+
agent.options = type(original_options)()
216+
217+
with tracer.start_as_current_span("test"):
218+
self.logger.warning("test message")
219+
220+
spans = self.recorder.queued_spans()
221+
assert len(spans) == 1 # Only the parent span, no logging span
222+
223+
# Restore original options
224+
agent.options = original_options
225+
226+
def test_logging_disabled_via_yaml(self) -> None:
227+
# Disable logging spans via YAML configuration
228+
original_options = agent.options
229+
agent.options = type(original_options)()
230+
231+
# Simulate YAML configuration
232+
tracing_config = {"disable": [{"logging": True}]}
233+
agent.options.set_tracing(tracing_config)
234+
235+
with tracer.start_as_current_span("test"):
236+
self.logger.warning("test message")
237+
238+
spans = self.recorder.queued_spans()
239+
assert len(spans) == 1 # Only the parent span, no logging span
240+
241+
# Restore original options
242+
agent.options = original_options
243+
244+
245+
# Made with Bob

0 commit comments

Comments
 (0)