From 1dc79b13285386a2f5f6608aa0296d2ec17f9d1c Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Wed, 12 Nov 2025 15:26:55 +0100 Subject: [PATCH 1/5] feat(loguru): Capture extra --- sentry_sdk/integrations/loguru.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/loguru.py b/sentry_sdk/integrations/loguru.py index 2c0279d0ce..6127a9604e 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 extra: + 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, From b7b7282e8c88f68ed4fb2e88239a654f2e7f87ca Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 13 Nov 2025 11:27:03 +0100 Subject: [PATCH 2/5] add comprehensive tests --- tests/integrations/loguru/test_loguru.py | 97 ++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/tests/integrations/loguru/test_loguru.py b/tests/integrations/loguru/test_loguru.py index 2a307a50cb..b6c94e7c79 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 the 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 ): From ef46011561db9274c09eb274ca766fa34672cf4f Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 13 Nov 2025 11:28:20 +0100 Subject: [PATCH 3/5] defensive --- sentry_sdk/integrations/loguru.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/loguru.py b/sentry_sdk/integrations/loguru.py index 6127a9604e..130f87e082 100644 --- a/sentry_sdk/integrations/loguru.py +++ b/sentry_sdk/integrations/loguru.py @@ -194,7 +194,7 @@ def loguru_sentry_logs_handler(message): attrs["logger.name"] = record["name"] extra = record.get("extra") - if extra: + if isinstance(extra, dict) and extra: for key, value in extra.items(): if isinstance(value, (str, int, float, bool)): attrs[f"sentry.message.parameter.{key}"] = value From 92361d426ba443bca561e71a88e185deaff59c60 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 13 Nov 2025 11:28:52 +0100 Subject: [PATCH 4/5] simplify --- sentry_sdk/integrations/loguru.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/loguru.py b/sentry_sdk/integrations/loguru.py index 130f87e082..aedd393b6f 100644 --- a/sentry_sdk/integrations/loguru.py +++ b/sentry_sdk/integrations/loguru.py @@ -194,7 +194,7 @@ def loguru_sentry_logs_handler(message): attrs["logger.name"] = record["name"] extra = record.get("extra") - if isinstance(extra, dict) and 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 From 5d7e6fad1c53cb439410b190fa28767d7f952416 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 13 Nov 2025 11:29:37 +0100 Subject: [PATCH 5/5] . --- tests/integrations/loguru/test_loguru.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integrations/loguru/test_loguru.py b/tests/integrations/loguru/test_loguru.py index b6c94e7c79..2414f57958 100644 --- a/tests/integrations/loguru/test_loguru.py +++ b/tests/integrations/loguru/test_loguru.py @@ -477,7 +477,7 @@ 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 the parameters). Adding this test to make that + # (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)