Skip to content

feat: vault-core based logger#395

Open
hakaari wants to merge 1 commit intotetherto:mainfrom
hakaari:feat/unified-logger
Open

feat: vault-core based logger#395
hakaari wants to merge 1 commit intotetherto:mainfrom
hakaari:feat/unified-logger

Conversation

@hakaari
Copy link
Copy Markdown
Contributor

@hakaari hakaari commented May 7, 2026

Requirements

Allows extracting logs from main process + worklet for external support.

Changes

  • Added a unified logger behind Diagnostics → Enable logs toggle.
  • Share logs zips them with metadata into the system share sheet.
  • Ability to persist log level (off / debug) in AsyncStorage; Nightly builds default to debug on first launch, every other distribution stays off.
  • Added Sentry behind isNightly() only.
  • Updated README with new Logging and Error reporting sections.

Testing Notes

Tested on iOS Simulator and Pixel 9

Things reviewers should pay attention to

  • Copy

Screenshots/Recordings

Simulator Screenshot - iPhone 17 - 2026-05-07 at 17 28 56

dependencies

tetherto/pearpass-lib-vault-core#55

@hakaari
Copy link
Copy Markdown
Contributor Author

hakaari commented May 7, 2026

@nickgr2 please review. Ignore any inconsistency in package.json, it's not final, pending vault-core PR merge

Copy link
Copy Markdown

@nickgr2 nickgr2 left a comment

Choose a reason for hiding this comment

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

Reviewed at 47a36d3. The Diagnostics screen uses the kit cleanly (PageHeader, ToggleSwitch, Button, Text, useTheme, rawTokens), strings go through Lingui, interactive elements have testIDs, and the README addition is a clear public-facing statement of the Sentry boundary. A few things to address before merge.

Blocker

@sentry/react-native is referenced but missing from package.json / package-lock.json.

  • src/utils/sentry.js: import * as Sentry from '@sentry/react-native'
  • app.config.ts: plugins.push('@sentry/react-native/expo')

Neither declares @sentry/react-native as a dependency, and the package isn't in the lockfile. Nightly builds (PEARPASS_DISTRIBUTION=nightly) will fail at prebuild when Expo tries to load the plugin, and initSentry() will throw at runtime. Please add @sentry/react-native (and update the lockfile) — preferably the version you tested with on the simulator/Pixel 9.

Other findings

loadLogConfiguration() doesn't notify subscribers when storage resolves. registerRootComponent(Main) is intentionally ordered before bootstrap() (per the Android-race comment in index.js), so it's possible for things to read getLogLevelSync() / mount useLogLevel before AsyncStorage returns. The first read sees the default ('off' outside nightly, 'debug' on nightly); the listener registered in useLogLevel's useEffect only fires on setLogLevel, never on the storage-load completion, so the stored level isn't observed until the user toggles. Same applies to the subscribeLogLevel callback wired in src/worklet/index.js after setLogOptions(buildLogOptions(getLogLevelSync())) — if vault-core is created before bootstrap finishes, it gets the default instead of the stored level until the user toggles. Suggest firing all listeners at the end of loadLogConfiguration once cached is updated, so existing consumers reconcile.

getDistributionChannel default changed 'standard''production' in src/constants/distribution.js, but app.config.ts still falls back to 'standard'. The two paths now disagree on the fallback string. Functionally harmless because isFdroid()/isNightly() are the only consumers, but worth aligning to avoid a footgun if anything ever reads the channel string directly.

Minor

  • src/worklet/index.js: the subscribeLogLevel callback is never unsubscribed. One client per app lifetime so currently safe, but worth revisiting if the client can ever be torn down and recreated.
  • createFileLogger allocates a fresh TextEncoder per log line — could be hoisted module-level. Style nit.
  • app.config.ts adds the Sentry plugin whenever isNightly, even if PEARPASS_SENTRY_DSN is unset. The runtime initSentry does check if (!dsn) return, so capturing is safe; just a heads-up that the Expo plugin will still be loaded into the build in that case.

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.

2 participants