diff --git a/sentry_sdk/integrations/loguru.py b/sentry_sdk/integrations/loguru.py index 2c0279d0ce..aedd393b6f 100644 --- a/sentry_sdk/integrations/loguru.py +++ b/sentry_sdk/integrations/loguru.py @@ -8,7 +8,7 @@ _BaseHandler, ) from sentry_sdk.logger import _log_level_to_otel -from sentry_sdk.utils import has_logs_enabled +from sentry_sdk.utils import has_logs_enabled, safe_repr from typing import TYPE_CHECKING @@ -193,6 +193,14 @@ def loguru_sentry_logs_handler(message): if record.get("name"): attrs["logger.name"] = record["name"] + extra = record.get("extra") + if isinstance(extra, dict): + for key, value in extra.items(): + if isinstance(value, (str, int, float, bool)): + attrs[f"sentry.message.parameter.{key}"] = value + else: + attrs[f"sentry.message.parameter.{key}"] = safe_repr(value) + client._capture_log( { "severity_text": otel_severity_text, diff --git a/tests/integrations/loguru/test_loguru.py b/tests/integrations/loguru/test_loguru.py index 2a307a50cb..2414f57958 100644 --- a/tests/integrations/loguru/test_loguru.py +++ b/tests/integrations/loguru/test_loguru.py @@ -473,6 +473,103 @@ def test_logger_with_all_attributes( } +def test_logger_capture_parameters_from_args( + sentry_init, capture_envelopes, uninstall_integration, request +): + # This is currently not supported as regular args don't get added to extra + # (which we use for populating parameters). Adding this test to make that + # explicit and so that it's easy to change later. + uninstall_integration("loguru") + request.addfinalizer(logger.remove) + + sentry_init(enable_logs=True) + envelopes = capture_envelopes() + + logger.warning("Task ID: {}", 123) + + sentry_sdk.get_client().flush() + + logs = envelopes_to_logs(envelopes) + + attributes = logs[0]["attributes"] + assert "sentry.message.parameter.0" not in attributes + + +def test_logger_capture_parameters_from_kwargs( + sentry_init, capture_envelopes, uninstall_integration, request +): + uninstall_integration("loguru") + request.addfinalizer(logger.remove) + + sentry_init(enable_logs=True) + envelopes = capture_envelopes() + + logger.warning("Task ID: {task_id}", task_id=123) + + sentry_sdk.get_client().flush() + + logs = envelopes_to_logs(envelopes) + + attributes = logs[0]["attributes"] + assert attributes["sentry.message.parameter.task_id"] == 123 + + +def test_logger_capture_parameters_from_contextualize( + sentry_init, capture_envelopes, uninstall_integration, request +): + uninstall_integration("loguru") + request.addfinalizer(logger.remove) + + sentry_init(enable_logs=True) + envelopes = capture_envelopes() + + with logger.contextualize(task_id=123): + logger.warning("Log") + + sentry_sdk.get_client().flush() + + logs = envelopes_to_logs(envelopes) + + attributes = logs[0]["attributes"] + assert attributes["sentry.message.parameter.task_id"] == 123 + + +def test_logger_capture_parameters_from_bind( + sentry_init, capture_envelopes, uninstall_integration, request +): + uninstall_integration("loguru") + request.addfinalizer(logger.remove) + + sentry_init(enable_logs=True) + envelopes = capture_envelopes() + + logger.bind(task_id=123).warning("Log") + sentry_sdk.get_client().flush() + + logs = envelopes_to_logs(envelopes) + + attributes = logs[0]["attributes"] + assert attributes["sentry.message.parameter.task_id"] == 123 + + +def test_logger_capture_parameters_from_patch( + sentry_init, capture_envelopes, uninstall_integration, request +): + uninstall_integration("loguru") + request.addfinalizer(logger.remove) + + sentry_init(enable_logs=True) + envelopes = capture_envelopes() + + logger.patch(lambda record: record["extra"].update(task_id=123)).warning("Log") + sentry_sdk.get_client().flush() + + logs = envelopes_to_logs(envelopes) + + attributes = logs[0]["attributes"] + assert attributes["sentry.message.parameter.task_id"] == 123 + + def test_no_parameters_no_template( sentry_init, capture_envelopes, uninstall_integration, request ):