Skip to content

Commit fe7ef63

Browse files
authored
feat(cli): Add initial event logging system (#43013)
# Why Based on / Supersedes #42249 We should be able to log JSONL events and capture them for debugging. In theory, most places that receive/send events, or that have `debug` calls that are ultimately useful to be surfaced in non-terminal environments or when more output is needed should have event calls. In the future, we may be able to add the `profiler` system to this as well, and be able to fork performance-relevant data (e.g. performance marks and profiler outputs) out of the event system. As a proof of concept, this ports the `MetroTerminalReporter` events to the new system (with new requirements applied) # How **Base Requirements:** - should be able to write to file descriptors (compatible with both unix sockets and files/streams), and to file paths - shouldn't slow down the runtime of the CLI by much more than the cost to stringify JSONL events - should be able to define types ahead of time and collect them in one place Most events we want to capture can be captured rapidly (we shouldn't care too much about how many events we log), and we should keep pre-processing to a minimum to allow the event system to always be active without much overhead. The stream that we're writing with is similar to `FastUtf8Stream` / `SonicBoom` and is non-blocking. Flushing is avoided to keep performance high. - Implement non-blocking `LogStream` - Add `installEventLogger` to entrypoint - protects stdout/stderr when logger is active on one of them) - Add `events('category')` helper to create structured log events - Add logger to `MetroTerminalReporter` to demonstrate usage - Clean up calls in `MetroTerminalReporter` and pass sanitized data to event logger - Add `shouldReduceLogs` helper and disable bundling progress when headless is active and event logger is used - **Drive-by fix:** Rename `projectRoot` variable in `MetroTerminalReporter` to `serverRoot` to reflect its actual path # Test Plan Verify that metro events are logged: - Run `LOG_EVENTS=events.log expo start` and check `events.log` - Run `LOG_EVENTS=1 expo start` and check standard output # Checklist <!-- Please check the appropriate items below if they apply to your diff. --> - [x] I added a `changelog.md` entry and rebuilt the package sources according to [this short guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting) - [ ] This diff will work correctly for `npx expo prebuild` & EAS Build (eg: updated a module plugin). - [ ] Conforms with the [Documentation Writing Style Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
1 parent d02129a commit fe7ef63

10 files changed

Lines changed: 1335 additions & 102 deletions

File tree

packages/@expo/cli/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ _This version does not introduce any user-facing changes._
3434
- Retrieve default route's IP address concurrently ([#42923](https://github.com/expo/expo/pull/42923) by [@kitten](https://github.com/kitten))
3535
- Replace `require-from-string` with `@expo/require-utils` ([#42884](https://github.com/expo/expo/pull/42884) by [@kitten](https://github.com/kitten))
3636
- Refactor env loading and reloading to unified logic and don't overwrite original system values ([#43038](https://github.com/expo/expo/pull/43038) by [@kitten](https://github.com/kitten))
37+
- Add initial event logging system ([#43013](https://github.com/expo/expo/pull/43013) by [@kitten](https://github.com/kitten))
3738

3839
## 55.0.7 — 2026-02-08
3940

packages/@expo/cli/CLAUDE.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CLI tool for all Expo projects. The public interface should be lean, all command
88
├── bin/cli.ts # CLI entry point - registers all commands
99
├── src/
1010
│ ├── api/ # expo.dev API client
11+
│ ├── events/ # JSONL event-based debugger
1112
│ ├── config/ # `expo config` command
1213
│ ├── customize/ # `expo customize` command
1314
│ ├── export/ # `expo export` command (production bundling)
@@ -138,7 +139,42 @@ See `src/utils/open.ts` for an example of handling the `SYSTEMROOT`/`SystemRoot`
138139

139140
## Debug logs
140141

141-
Debug logs support `DEBUG=expo:*`, for legacy reasons we support `EXPO_DEBUG=1` which sets `DEBUG=expo:*` in the bin.ts file.
142+
**Old debugging system:**
143+
Debug logs used to be created with the `debug` package with individual modules creating a `debug` function to use for logging.
144+
This can then be activated with `DEBUG=expo:*`, and for legacy reasons `EXPO_DEBUG=1` currently sets `DEBUG=expo:*` in the bin.ts file.
145+
146+
```ts
147+
const debug = require('debug')('expo:utils:example');
148+
debug('hello');
149+
```
150+
151+
**New debugging system:**
152+
Newer modules use the `events` helper from `src/events/index.ts` to define structured events in JSON format.
153+
154+
```ts
155+
export const event = events('metro', (t) => [
156+
t.event<'example:start', {
157+
value: string;
158+
}>(),
159+
]);
160+
161+
event('metro:example:start', { value: 'hello' });
162+
```
163+
164+
The `events` function accepts a category name and a function that is used to define the event types, but never called.
165+
When setting `LOG_EVENTS=1` JSONL events will be logged to the standard output, or with `LOG_EVENTS=events.log` events will log to an events.log file.
166+
This is a faster events system than `debug`, captures structured JSON events, and is scalable, and can be used in any module to add richer debug output.
167+
168+
When creatin a nwe events category, add the `event` function it returns to the `Events` type in `src/events/types.ts` to collect all the events' types in one place:
169+
170+
```
171+
// Add a new import:
172+
import type { event as myNewEvent } from '...';
173+
174+
export type Events = collectEventLoggers<[
175+
typeof myNewEvent, // Add the imported new event function here
176+
]>;
177+
```
142178

143179
## Production
144180

packages/@expo/cli/bin/cli.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import chalk from 'chalk';
44
import Debug from 'debug';
55
import { boolish } from 'getenv';
66

7+
import { installEventLogger } from '../src/events';
8+
9+
// Setup event logger output
10+
// NOTE: Done before any console output
11+
installEventLogger();
12+
713
// Check Node.js version and issue a loud warning if it's too outdated
814
// This is sent to stderr (console.error) so it doesn't interfere with programmatic commands
915
const NODE_MIN = [20, 19, 4];

0 commit comments

Comments
 (0)