Observability Skill
Applicability
- Platforms: iOS and Android
- React Native: 0.76+ (New Architecture interop assumed unless a checklist item says otherwise)
When to Use
- Adding crash reporting, analytics, performance traces, or a logging strategy
- Reviewing what a change records about the user or the session
- Debugging a production failure that cannot be reproduced on a device
Severity
- Merge-blocking: a new event or log in this diff includes a name, email, token, or payment data.
- Should-fix: missing traces and breadcrumb wording.
Guidance
Names, emails, and payment data in logs are also merge-blocking under critical-rules. File that finding once, from critical-rules, when the line is in the diff.
Crashes and errors
- Uncaught JavaScript errors, unhandled promise rejections, and native crashes are reported, and release builds can be symbolicated
- An error boundary reports the screen it failed on and still shows a recovery UI
- Caught errors that the user can retry are not also reported as crashes
- Dev and debug builds do not send events to the production project
Context
- Breadcrumbs record the action (screen opened, request failed) without the payload
- A correlation id is attached to the client event and the matching server request
- User id, when set, is an internal id, not an email, name, or phone number
- Events are separated by environment (dev, staging, production)
Incorrect:
logger.error('checkout failed', { email, cardLast4, token });Correct:
logger.error('checkout failed', {
correlationId,
screen: 'Checkout',
status: error.status,
});Performance
- Screen-load and API-latency traces exist for the flows that matter, with a start and an end
- A trace is cancelled or dropped when the screen unmounts before it finishes
- JS-thread stalls are sampled; they are not logged on every frame
Analytics and privacy
- Event names are stable and documented; properties follow one schema
- No names, emails, payment data, tokens, or free-text user content are in events or logs
- Collection starts only after the required consent (see
security) - Offline events are queued with a cap and are not sent with a payload captured before consent
Anti-Patterns
| Anti-Pattern | Risk | Fix |
|---|---|---|
| Logging the request body | PII and tokens land in a vendor log | Log status, route template, and correlation id |
| A catch that reports and also swallows | The user sees a success while the crash tool fills with noise | Show the error, and report only unexpected failures |
| One analytics name reused for different actions | Funnels lie | One name per action, with a written schema |
| Sending debug logs to the production project | Dev traffic hides real crashes | Split the project or the environment tag and drop dev |
Pitfalls
- Release crashes without source maps or native symbols point at minified frames. Confirm symbol upload for the build that shipped.
- A high sample rate on a chatty trace (scroll, animation) can drain battery and blow the quota. Sample those; keep crashes unsampled.
- Offline queues replay old events after the user logs out. Drop or re-key the queue on sign-out.
- Breadcrumbs that include search text or form values become a second store of personal data. Keep them to navigation and outcomes.