Repository navigation
fix: stream downloadable emulator logs to Emulator UI - #11271
christhompsongoogle wants to merge 1 commit into
Conversation
### Description Fixes an issue where output from downloadable emulators (such as Cloud Firestore and Realtime Database) was written to local disk debug logs but never streamed to the Emulator Suite UI (`/logs`): 1. Parse child process output severity (`INFO`, `WARN`, `ERROR`, `DEBUG`) in `downloadableEmulators.ts` instead of hardcoding `DEBUG`. 2. Configure `WebSocketTransport` in `loggingEmulator.ts` with `level: process.env.DEBUG ? "debug" : "info"`. 3. Set `logger.level = "debug"` in `useConsoleLoggers()` when `process.env.DEBUG` is enabled. ### Scenarios Tested - Unit tests in `src/emulator/downloadableEmulators.spec.ts`, `src/emulator/loggingEmulator.spec.ts`, and `src/logger.spec.ts`. ### Sample Commands ```bash firebase emulators:start firebase emulators:start --debug ```
There was a problem hiding this comment.
Code Review
This pull request enables streaming logs from downloadable emulators (such as Cloud Firestore and Realtime Database) to the Emulator Suite UI by parsing log levels from emulator stdout/stderr streams and updating the logging configuration based on the DEBUG environment variable. Feedback on these changes highlights that logging emulator output directly using the parsed severity levels will cause excessive console spam in the user's terminal. It is recommended to log these messages at the "INFO" level with metadata containing the parsed level, allowing them to be filtered out of the console transport unless debugging is explicitly enabled.
| emulator.instance.stdout?.on("data", (data: Buffer) => { | ||
| const text = data.toString(); | ||
| logger.log(parseLogLevel(text), text); | ||
| emulator.stdout.write(data); | ||
| }); | ||
| emulator.instance.stderr?.on("data", (data) => { | ||
| logger.log("DEBUG", data.toString()); | ||
| emulator.instance.stderr?.on("data", (data: Buffer) => { | ||
| const text = data.toString(); | ||
| logger.log(parseLogLevel(text), text); | ||
| emulator.stdout.write(data); |
There was a problem hiding this comment.
Parsing the log level and logging it directly via logger.log(parseLogLevel(text), text) will cause all INFO, WARN, and ERROR logs from the emulator child processes to be printed directly to the user's terminal/console. This will result in massive console spam during normal emulator operation.
To prevent this console spam while still streaming the logs to the Emulator UI, we can log them at the "INFO" level but include a metadata flag (e.g., emulatorLog: true) and the parsed level in metadata.level. We can then filter out these logs in the Console transport unless --debug is enabled.
emulator.instance.stdout?.on("data", (data: Buffer) => {
const text = data.toString();
logger.log("INFO", text, {
metadata: {
emulatorLog: true,
level: parseLogLevel(text),
},
});
emulator.stdout.write(data);
});
emulator.instance.stderr?.on("data", (data: Buffer) => {
const text = data.toString();
logger.log("INFO", text, {
metadata: {
emulatorLog: true,
level: parseLogLevel(text),
},
});
emulator.stdout.write(data);
});
Description
Fixes an issue where output from downloadable emulators (such as Cloud Firestore and Realtime Database) was written to local disk debug logs but never streamed to the Emulator Suite UI (
/logs):INFO,WARN,ERROR,DEBUG) indownloadableEmulators.tsinstead of hardcodingDEBUG.WebSocketTransportinloggingEmulator.tswithlevel: process.env.DEBUG ? "debug" : "info".logger.level = "debug"inuseConsoleLoggers()whenprocess.env.DEBUGis enabled.Scenarios Tested
src/emulator/downloadableEmulators.spec.ts,src/emulator/loggingEmulator.spec.ts, andsrc/logger.spec.ts.Sample Commands
Description
Scenarios Tested
Sample Commands