Skip to content

feat(logs): add log4net integration - #5172

Merged
jamescrosswell merged 18 commits into
mainfrom
feat/logs-log4net
Jul 16, 2026
Merged

feat(logs): add log4net integration#5172
jamescrosswell merged 18 commits into
mainfrom
feat/logs-log4net

Refactor Appender to avoid a huge Append method

13260a4
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden completed Jul 16, 2026 in 0s

4 issues

High

Structured logs not captured for events below MinimumEventLevel due to early return - `src/Sentry.Log4Net/SentryAppender.cs:97-98`

The CaptureStructuredLog call is placed after the early return at line 97-98, so structured logs are never captured for events below MinimumEventLevel. The test DoAppend_StructuredLoggingWithoutException_LeavesBreadcrumb expects structured logs to be captured even for breadcrumb-only events, but this code path returns before reaching CaptureStructuredLog.

Structured logs not captured when log level is below MinimumEventLevel - `src/Sentry.Log4Net/SentryAppender.cs:98`

When EnableLogs is true and the log level is below MinimumEventLevel, structured logs are not captured due to the early return on line 98. The test DoAppend_StructuredLoggingWithoutException_LeavesBreadcrumb expects structured logs to be captured in this scenario, and Serilog's implementation captures structured logs independently of event/breadcrumb thresholds. Add CaptureStructuredLog call before the early return, or refactor to call it at the end regardless of the event/breadcrumb path.

Also found at:

  • test/Sentry.Log4Net.Tests/SentryAppenderTests.Structured.cs:216

Low

NullReferenceException when loggingEvent.Level is null in ToSentryLogLevel - `src/Sentry.Log4Net/LevelMapping.cs:38-44`

ToSentryLogLevel uses >= comparisons against log4net Level values. log4net's operator >= dereferences the left operand's numeric field without a null check, so a null loggingEvent.Level throws NullReferenceException (the initial level == Level.Off guard is null-safe and falls through). The sibling ToSentryLevel/ToBreadcrumbLevel methods use only ==, which is null-safe and returns null, so those paths handle null gracefully while the structured-log path does not. The thrown NRE is caught by the try/catch around CaptureStructuredLog in Append, so it does not crash the process — but the structured log is silently dropped and an error diagnostic is logged, giving inconsistent behavior versus the event/breadcrumb paths. Add null => null, as the first switch arm to match the other mappers.

Whitespace-only property keys handled inconsistently between structured logs and events - `src/Sentry.Log4Net/SentryAppender.Structured.cs:35-37`

Use !string.IsNullOrWhiteSpace(key) instead of key.Length != 0 to match the filtering in GetLoggingEventProperties, which filters whitespace-only keys. Currently, a property key like " " would be included in structured logs but filtered from SentryEvent extras.

4 skills analyzed
Skill Findings Duration Cost
security-review 0 1m 7s $0.31
code-review 1 3m 58s $2.38
find-bugs 3 9m 39s $5.11
gha-security-review 0 6m 41s $0.50

⏱ 21m 26s · 2.8M in / 141.5k out · $8.30