Skip to content

Prevent function crash when setting unknown log level. #418

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

Merged
merged 1 commit into from
Feb 14, 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
6 changes: 2 additions & 4 deletions datadog_lambda/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import logging
from datadog_lambda.cold_start import initialize_cold_start_tracing
from datadog_lambda.logger import initialize_logging

initialize_cold_start_tracing()

Expand All @@ -13,5 +12,4 @@

__version__ = importlib_metadata.version(__name__)

logger = logging.getLogger(__name__)
logger.setLevel(logging.getLevelName(os.environ.get("DD_LOG_LEVEL", "INFO").upper()))
initialize_logging(__name__)
27 changes: 27 additions & 0 deletions datadog_lambda/logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import logging
import os

try:
_level_mappping = logging.getLevelNamesMapping()
except AttributeError:
# python 3.8
_level_mappping = {name: num for num, name in logging._levelToName.items()}
# https://docs.datadoghq.com/agent/troubleshooting/debug_mode/?tab=agentv6v7#agent-log-level
_level_mappping.update(
{
"TRACE": 5,
"WARN": logging.WARNING,
"OFF": 100,
}
)


def initialize_logging(name):
logger = logging.getLogger(name)
str_level = (os.environ.get("DD_LOG_LEVEL") or "INFO").upper()
level = _level_mappping.get(str_level)
if level is None:
logger.setLevel(logging.INFO)
logger.warning("Invalid log level: %s Defaulting to INFO", str_level)
else:
logger.setLevel(level)
43 changes: 43 additions & 0 deletions tests/test_logger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import io
import logging
import pytest

from datadog_lambda.logger import initialize_logging

_test_initialize_logging = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great parameterizing!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in python, it's spelled parametrizing, whoever wrote it forgot the second e 😆

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder which one is the english version and which is the american one lol

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to wikipedia I guess both spells are correct? And that they're all british? https://en.wiktionary.org/wiki/parametrize

("TRACE", (10, 20, 30, 40, 50)),
("DEBUG", (10, 20, 30, 40, 50)),
("debug", (10, 20, 30, 40, 50)),
("INFO", (20, 30, 40, 50)),
("WARNING", (30, 40, 50)),
("WARN", (30, 40, 50)),
("ERROR", (40, 50)),
("CRITICAL", (50,)),
("OFF", ()),
("", (20, 30, 40, 50)),
(None, (20, 30, 40, 50)),
("PURPLE", (30, 20, 30, 40, 50)), # log warning then default to INFO
)


@pytest.mark.parametrize("level,logged_levels", _test_initialize_logging)
def test_initialize_logging(level, logged_levels, monkeypatch):
if level is not None:
monkeypatch.setenv("DD_LOG_LEVEL", level)

stream = io.StringIO()
handler = logging.StreamHandler(stream)
handler.setFormatter(logging.Formatter("%(levelno)s"))
logger = logging.getLogger(__name__)
logger.addHandler(handler)

initialize_logging(__name__)

logger.debug("debug")
logger.info("info")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

logged = tuple(map(int, stream.getvalue().strip().split()))
assert logged == logged_levels