Skip to content

fix(dart): Route SDK diagnostic logs to browser console on web#3698

Open
theprantadutta wants to merge 1 commit into
getsentry:mainfrom
theprantadutta:fix/web-debug-logs-via-console
Open

fix(dart): Route SDK diagnostic logs to browser console on web#3698
theprantadutta wants to merge 1 commit into
getsentry:mainfrom
theprantadutta:fix/web-debug-logs-via-console

Conversation

@theprantadutta
Copy link
Copy Markdown

📜 Description

Splits the default output for SentryInternalLogger into platform-specific implementations selected via the existing _io_* / _web_* companion-file pattern (already used by _io_platform.dart / _web_platform.dart, origin_io.dart / origin_web.dart, dart_exception_type_identifier_io.dart / _web.dart, etc.):

  • _io_default_log_output.dart keeps the existing dart:developer.log behaviour on the VM, so DevTools and IDE log views are unchanged.

  • _web_default_log_output.dart forwards to window.console.* via package:web, mapping SentryLevel to the matching console method:

    SentryLevel console.*
    fatal / error console.error
    warning console.warn
    info console.info
    debug console.debug

💡 Motivation and Context

dart:developer.log does not surface in the browser dev console on Flutter Web, so SDK diagnostic messages (the ones gated by options.debug = true) were silently dropped during web development.

I deliberately used package:web console.* instead of print, to address @buenaflor's concern from the issue thread:

"Something we need to be careful of is that we have an integration that reports prints as breadcrumbs, I want to make sure we don't spill out internal prints as breadcrumbs."

Sentry's print-breadcrumb integration installs a ZoneSpecification(print:) hook inside runZonedGuarded and records every print call as a Breadcrumb. If the SDK's own internal diagnostic logger went through print, every internal line would feed back as a user-visible breadcrumb on captured events. Calling console.* directly bypasses that hook entirely.

Additionally, RuntimeChecker.kDebugMode already short-circuits the logger at the top of _log(), so the whole code path is tree-shaken from release builds regardless of platform — providing a second layer of safety against the breadcrumb-feedback scenario even if a future integration changes how print is intercepted.

Closes #3043

💚 How did you test it?

  • Added packages/dart/test/utils/default_log_output_test.dart with two tests for the IO path: (a) it never produces output via print (so the same property holds for the web path, which uses console.*); (b) it accepts all SentryLevels without throwing.
  • Added a routing test to internal_logger_test.dart that verifies the conditional import resolves to the IO file on the VM (no print output when logging through the public SentryInternalLogger).
  • Verified the web target compiles cleanly: dart compile js -o build/main.dart.js web/main.dart in packages/dart/example_web/ succeeds with the new conditional import in place.
  • The existing 25 internal_logger_test.dart tests still pass.
  • dart analyze --fatal-warnings on packages/dart/ — clean.

The web console.* behaviour itself is not unit-tested on the VM (the web file can't be exercised there); the example_web compile path provides the static-typecheck guarantee, and a Flutter Web app with options.debug = true would surface the diagnostic logs at the appropriate severity in the dev console.

📝 Checklist

  • I reviewed submitted code
  • I added tests to verify changes
  • No new PII added or SDK only sends newly added PII if sendDefaultPii is enabled
  • I updated the docs if needed (no doc changes — internal logger format)
  • All tests passing (existing + new)
  • No breaking changes (purely an additive platform split; VM behaviour unchanged)

`SentryInternalLogger`'s default output uses `dart:developer.log`,
which does not surface in the browser dev console on Flutter Web —
SDK diagnostic messages (gated by `options.debug = true`) were
silently dropped during web development.

Split the default log output into platform-specific implementations
selected via the existing `_io_*` / `_web_*` companion-file pattern
already used in `packages/dart/lib/src/`:

- `_io_default_log_output.dart` keeps the existing
  `dart:developer.log` behaviour for the VM, so DevTools and IDE log
  views are unchanged.
- `_web_default_log_output.dart` forwards to `window.console.*` via
  `package:web` (`console.error` for fatal/error, `console.warn` for
  warning, `console.info` for info, `console.debug` for debug).

`console.*` is preferred over `print` for two reasons:

1. `print` on Flutter Web routes through `dart:html`'s
   `consoleLog` indirectly; the SDK already installs a
   `ZoneSpecification(print:)` hook that records every `print` call
   as a `Breadcrumb`. Routing our own internal diagnostic output
   through `print` would feed those internal lines back as
   user-visible breadcrumbs. Calling `console.*` directly bypasses
   that hook entirely.
2. Mapping `SentryLevel` to the matching `console` method gives the
   browser dev console an opportunity to highlight warnings/errors
   visually rather than rendering everything as plain log lines.

The SDK's internal logger is also short-circuited by
`RuntimeChecker.kDebugMode` in release builds, so the new code is
tree-shaken from production regardless of platform.

Closes getsentry#3043
@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.96%. Comparing base (87fcdd8) to head (8263aa5).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3698   +/-   ##
=======================================
  Coverage   86.96%   86.96%           
=======================================
  Files         335      336    +1     
  Lines       11976    11978    +2     
=======================================
+ Hits        10415    10417    +2     
  Misses       1561     1561           
Flag Coverage Δ
sentry 86.77% <100.00%> (+<0.01%) ⬆️
sentry_dio 97.73% <ø> (ø)
sentry_drift 93.57% <ø> (ø)
sentry_file 65.29% <ø> (ø)
sentry_firebase_remote_config 100.00% <ø> (ø)
sentry_flutter 91.52% <ø> (ø)
sentry_hive 77.48% <ø> (ø)
sentry_isar 74.37% <ø> (ø)
sentry_link 21.50% <ø> (ø)
sentry_logging 97.01% <ø> (ø)
sentry_sqflite 88.81% <ø> (ø)
sentry_supabase 97.27% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Copy Markdown
Contributor

@buenaflor buenaflor left a comment

Choose a reason for hiding this comment

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

lgtm 👍

@buenaflor
Copy link
Copy Markdown
Contributor

buenaflor commented May 13, 2026

I'll rerun some of the tests later, seems like CI is acting up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Flutter Web] Debug logs do not show up in the browser dev console

2 participants