From b7954b65419a77169617be325e0b4a8b51a93af5 Mon Sep 17 00:00:00 2001 From: Daniel Lemm <61800298+ffe4@users.noreply.github.com> Date: Thu, 3 Sep 2020 17:42:13 +0200 Subject: [PATCH] Add support for OTEL_LOG_LEVEL env var --- .../src/opentelemetry/sdk/__init__.py | 22 +++++++ .../tests/test_sdk_configuration.py | 58 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 opentelemetry-sdk/tests/test_sdk_configuration.py diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/__init__.py index ca21f8b8609..29bf3324006 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/__init__.py @@ -16,6 +16,28 @@ The OpenTelemetry SDK package is an implementation of the OpenTelemetry API """ +import logging +import os + from . import metrics, trace, util __all__ = ["metrics", "trace", "util"] + +_LOG_LEVELS = { + "DEBUG": logging.DEBUG, + "INFO": logging.INFO, + "WARNING": logging.WARNING, + "ERROR": logging.ERROR, + "CRITICAL": logging.CRITICAL, +} + +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) +if os.getenv("OTEL_LOG_LEVEL") is not None: + key = os.getenv("OTEL_LOG_LEVEL").upper() + if key in _LOG_LEVELS: + logger.setLevel(_LOG_LEVELS.get(key)) + else: + logger.warning( + "Invalid value for environment variable OTEL_LOG_LEVEL. Defaulting to INFO." + ) diff --git a/opentelemetry-sdk/tests/test_sdk_configuration.py b/opentelemetry-sdk/tests/test_sdk_configuration.py new file mode 100644 index 00000000000..b730a7a2098 --- /dev/null +++ b/opentelemetry-sdk/tests/test_sdk_configuration.py @@ -0,0 +1,58 @@ +import logging +import unittest +from importlib import reload +from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING +from unittest.mock import patch + +from opentelemetry import sdk + +sdk_logger = logging.getLogger("opentelemetry.sdk") + + +def reload_sdk_with_env(env_dict): + with patch.dict("os.environ", env_dict, clear=True): + reload(sdk) + + +class TestLogLevelEnv(unittest.TestCase): + def tearDown(self): + """reload sdk to reset logging level""" + reload(sdk) + + def test_loglevel_is_info_by_default(self): + reload_sdk_with_env({}) + self.assertEqual(sdk_logger.getEffectiveLevel(), INFO) + + def test_setting_log_level_env_to_valid_value(self): + valid_value_log_level_pairs = [ + ("DEBUG", DEBUG), + ("INFO", INFO), + ("WARNING", WARNING), + ("ERROR", ERROR), + ("CRITICAL", CRITICAL), + ] + for value, log_level in valid_value_log_level_pairs: + reload_sdk_with_env({"OTEL_LOG_LEVEL": value}) + self.assertEqual(sdk_logger.getEffectiveLevel(), log_level, value) + + def test_log_level_is_propagated(self): + reload_sdk_with_env({"OTEL_LOG_LEVEL": "CRITICAL"}) + self.assertEqual(sdk_logger.getEffectiveLevel(), CRITICAL) + self.assertEqual( + sdk_logger.getChild("trace").getEffectiveLevel(), CRITICAL + ) + self.assertEqual( + sdk_logger.getChild("metrics").getEffectiveLevel(), CRITICAL + ) + self.assertEqual( + sdk_logger.getChild("resources").getEffectiveLevel(), CRITICAL + ) + + def test_invalid_log_level_value_warns_and_defaults_to_info(self): + with self.assertLogs(level=WARNING): + reload_sdk_with_env({"OTEL_LOG_LEVEL": "NOT_A_VALID_LOG_LEVEL"}) + self.assertEqual(sdk_logger.getEffectiveLevel(), INFO) + + def test_log_level_is_case_insensitive(self): + reload_sdk_with_env({"OTEL_LOG_LEVEL": "cRiTiCaL"}) + self.assertEqual(sdk_logger.getEffectiveLevel(), CRITICAL)