opentelemetry-python-contrib/instrumentation/opentelemetry-instrumentati.../tests/test_logging.py

134 lines
5.1 KiB
Python

# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
from unittest import mock
import pytest
from opentelemetry.instrumentation.logging import ( # pylint: disable=no-name-in-module
DEFAULT_LOGGING_FORMAT,
LoggingInstrumentor,
)
from opentelemetry.test.test_base import TestBase
from opentelemetry.trace import get_tracer
class TestLoggingInstrumentor(TestBase):
@pytest.fixture(autouse=True)
def inject_fixtures(self, caplog):
self.caplog = caplog # pylint: disable=attribute-defined-outside-init
def setUp(self):
super().setUp()
LoggingInstrumentor().instrument()
self.tracer = get_tracer(__name__)
def tearDown(self):
super().tearDown()
LoggingInstrumentor().uninstrument()
def assert_trace_context_injected(self, span_id, trace_id):
with self.caplog.at_level(level=logging.INFO):
logger = logging.getLogger("test logger")
logger.info("hello")
self.assertEqual(len(self.caplog.records), 1)
record = self.caplog.records[0]
self.assertEqual(record.otelSpanID, span_id)
self.assertEqual(record.otelTraceID, trace_id)
self.assertEqual(record.otelServiceName, "unknown_service")
def test_trace_context_injection(self):
with self.tracer.start_as_current_span("s1") as span:
span_id = format(span.get_span_context().span_id, "016x")
trace_id = format(span.get_span_context().trace_id, "032x")
self.assert_trace_context_injected(span_id, trace_id)
def test_trace_context_injection_without_span(self):
self.assert_trace_context_injected("0", "0")
@mock.patch("logging.basicConfig")
def test_basic_config_called(self, basic_config_mock):
LoggingInstrumentor().uninstrument()
LoggingInstrumentor().instrument()
self.assertFalse(basic_config_mock.called)
LoggingInstrumentor().uninstrument()
env_patch = mock.patch.dict(
"os.environ", {"OTEL_PYTHON_LOG_CORRELATION": "true"}
)
env_patch.start()
LoggingInstrumentor().instrument()
basic_config_mock.assert_called_with(
format=DEFAULT_LOGGING_FORMAT, level=logging.INFO
)
env_patch.stop()
@mock.patch("logging.basicConfig")
def test_custom_format_and_level_env(self, basic_config_mock):
LoggingInstrumentor().uninstrument()
LoggingInstrumentor().instrument()
self.assertFalse(basic_config_mock.called)
LoggingInstrumentor().uninstrument()
env_patch = mock.patch.dict(
"os.environ",
{
"OTEL_PYTHON_LOG_CORRELATION": "true",
"OTEL_PYTHON_LOG_FORMAT": "%(message)s %(otelSpanID)s",
"OTEL_PYTHON_LOG_LEVEL": "error",
},
)
env_patch.start()
LoggingInstrumentor().instrument()
basic_config_mock.assert_called_with(
format="%(message)s %(otelSpanID)s", level=logging.ERROR
)
env_patch.stop()
@mock.patch("logging.basicConfig")
def test_custom_format_and_level_api(
self, basic_config_mock
): # pylint: disable=no-self-use
LoggingInstrumentor().uninstrument()
LoggingInstrumentor().instrument(
set_logging_format=True,
logging_format="%(message)s span_id=%(otelSpanID)s",
log_level=logging.WARNING,
)
basic_config_mock.assert_called_with(
format="%(message)s span_id=%(otelSpanID)s", level=logging.WARNING
)
def test_uninstrumented(self):
with self.tracer.start_as_current_span("s1") as span:
span_id = format(span.get_span_context().span_id, "016x")
trace_id = format(span.get_span_context().trace_id, "032x")
self.assert_trace_context_injected(span_id, trace_id)
LoggingInstrumentor().uninstrument()
self.caplog.clear()
with self.tracer.start_as_current_span("s1") as span:
span_id = format(span.get_span_context().span_id, "016x")
trace_id = format(span.get_span_context().trace_id, "032x")
with self.caplog.at_level(level=logging.INFO):
logger = logging.getLogger("test logger")
logger.info("hello")
self.assertEqual(len(self.caplog.records), 1)
record = self.caplog.records[0]
self.assertFalse(hasattr(record, "otelSpanID"))
self.assertFalse(hasattr(record, "otelTraceID"))
self.assertFalse(hasattr(record, "otelServiceName"))