Skip to content

Commit 2f54dbd

Browse files
authored
feat(ourlogs): canonicalize paths from the logger integration (#4336)
We'd like to allow linking to the 'source code' line in the logs page - this canonicalizes the path relative to the project root (if one is defined) ![Screenshot 2025-04-28 at 12 03 45 PM](https://github.com/user-attachments/assets/89dde691-d9c3-45b2-b289-c42996496bf3) Solves LOGS-58
1 parent 7f01372 commit 2f54dbd

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

sentry_sdk/integrations/logging.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ def _capture_log_from_record(client, record):
355355
# type: (BaseClient, LogRecord) -> None
356356
scope = sentry_sdk.get_current_scope()
357357
otel_severity_number, otel_severity_text = _python_level_to_otel(record.levelno)
358+
project_root = client.options["project_root"]
358359
attrs = {
359360
"sentry.origin": "auto.logger.log",
360361
} # type: dict[str, str | bool | float | int]
@@ -374,7 +375,10 @@ def _capture_log_from_record(client, record):
374375
if record.lineno:
375376
attrs["code.line.number"] = record.lineno
376377
if record.pathname:
377-
attrs["code.file.path"] = record.pathname
378+
if project_root is not None and record.pathname.startswith(project_root):
379+
attrs["code.file.path"] = record.pathname[len(project_root) + 1 :]
380+
else:
381+
attrs["code.file.path"] = record.pathname
378382
if record.funcName:
379383
attrs["code.function.name"] = record.funcName
380384

tests/test_logs.py

+30-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,6 @@ def test_logging_errors(sentry_init, capture_envelopes):
346346
error_event_2 = envelopes[1].items[0].payload.json
347347
assert error_event_2["level"] == "error"
348348

349-
print(envelopes)
350349
logs = envelopes_to_logs(envelopes)
351350
assert logs[0]["severity_text"] == "error"
352351
assert "sentry.message.template" not in logs[0]["attributes"]
@@ -364,6 +363,36 @@ def test_logging_errors(sentry_init, capture_envelopes):
364363
assert len(logs) == 2
365364

366365

366+
def test_log_strips_project_root(sentry_init, capture_envelopes):
367+
"""
368+
The python logger should strip project roots from the log record path
369+
"""
370+
sentry_init(
371+
_experiments={"enable_logs": True},
372+
project_root="/custom/test",
373+
)
374+
envelopes = capture_envelopes()
375+
376+
python_logger = logging.Logger("test-logger")
377+
python_logger.handle(
378+
logging.LogRecord(
379+
name="test-logger",
380+
level=logging.WARN,
381+
pathname="/custom/test/blah/path.py",
382+
lineno=123,
383+
msg="This is a test log with a custom pathname",
384+
args=(),
385+
exc_info=None,
386+
)
387+
)
388+
get_client().flush()
389+
390+
logs = envelopes_to_logs(envelopes)
391+
assert len(logs) == 1
392+
attrs = logs[0]["attributes"]
393+
assert attrs["code.file.path"] == "blah/path.py"
394+
395+
367396
def test_auto_flush_logs_after_100(sentry_init, capture_envelopes):
368397
"""
369398
If you log >100 logs, it should automatically trigger a flush.

0 commit comments

Comments
 (0)