5.1 KiB
Node.js Trace Events Implementation for Bun
Overview
This document summarizes the implementation of Node.js trace events support in Bun, which was added to fix the failing test test-trace-events-environment.js.
Problem Statement
The Node.js test suite includes test-trace-events-environment.js which tests the trace events functionality. This test was failing because:
- Bun didn't support the
--trace-event-categoriescommand line flag - The
trace_eventsmodule was just a stub - No trace log files were being generated
The test expected:
- A
node_trace.1.logfile to be created - The file to contain specific trace events like "Environment", "RunTimers", "CheckImmediate", etc.
- Events to be in Chrome Trace Event Format
Solution Components
1. Command Line Support
File: src/cli.zig
Added support for the --trace-event-categories flag:
- Added
trace_event_categories: []const u8 = ""field to RuntimeOptions struct - Added parsing logic to capture the categories string from command line arguments
- The flag accepts a comma-separated list of categories
2. JavaScript Module Implementation
File: src/js/node/trace_events.ts
Replaced the stub implementation with a full-featured module that includes:
Classes:
-
Tracing: Main class that manages trace event collectionenable(): Starts collecting trace eventsdisable(): Stops collecting and writes events to fileenabled: Property indicating if tracing is activecategories: Property listing enabled categories
-
TraceEventCollector: Internal class that handles event collection- Maintains array of trace events
- Hooks into Node.js lifecycle events
- Formats and writes events to log file
Functions:
createTracing(options): Factory function to create Tracing instancesgetEnabledCategories(): Returns currently enabled trace categories
Event Hooks:
The implementation hooks into various Node.js events to generate traces:
process.exitandprocess.beforeExitsetImmediatecallbackssetTimeoutcallbacksprocess.nextTickcallbacks- Process start/end events
- Environment setup
Output Format:
- Writes to
node_trace.{counter}.logfiles - Uses Chrome Trace Event Format (JSON)
- Includes metadata like process ID, thread ID, timestamps
3. Native Bindings
Files: src/bun.js/bindings/NodeTraceEvents.cpp and .h
Created C++ bindings to bridge command line arguments to JavaScript:
-
Bun__setTraceEventCategories(const char* categories):- Stores the categories string from command line
- Called from Zig when
--trace-event-categoriesis present
-
getTraceEventCategoriesCallback(...):- JavaScript callback that returns the stored categories
- Registered as
$getTraceEventCategoriesglobal function
-
setupNodeTraceEvents(JSC::JSGlobalObject* globalObject):- Registers the callback function on the global object
- Called during JavaScript environment initialization
4. Integration Points
In src/bun_js.zig:
if (opts.trace_event_categories.len > 0) {
Bun.setTraceEventCategories(opts.trace_event_categories);
}
In src/bun.js/bindings/BunGlobalObject.cpp:
void GlobalObject::finishCreation(VM& vm) {
// ... existing code ...
Bun::setupNodeTraceEvents(this);
}
Key Implementation Details
Category Handling
- Categories are passed as comma-separated strings (e.g., "node.environment,node.async_hooks")
- The implementation checks if a category is enabled before generating events
- Default categories include "node", "node.environment", "node.async_hooks", etc.
Event Generation
Events are generated with:
name: Event name (e.g., "Environment", "RunTimers")cat: Category (e.g., "node.environment")ph: Phase ("B" for begin, "E" for end, "X" for complete)pid: Process IDtid: Thread ID (always 0 in this implementation)ts: Timestamp in microsecondsargs: Additional event-specific data
File Naming
- Files are named
node_trace.{counter}.log - Counter increments for each new trace file in the same process
- Files are created in the current working directory
Testing
The implementation passes the test-trace-events-environment.js test which verifies:
- The trace file is created
- It contains expected events
- Events have proper format and timing
- Categories filter events correctly
Future Considerations
- Performance: The current implementation uses JavaScript for all event collection, which may have performance implications
- Native Events: Some events could be generated from native code for better accuracy
- Additional Categories: More trace categories could be added for deeper insights
- Streaming: Large trace files could benefit from streaming writes
- V8 Compatibility: Some V8-specific trace events are not yet implemented
Conclusion
This implementation provides Node.js-compatible trace events support in Bun, allowing developers to debug and profile their applications using familiar tools and formats. The implementation is sufficient to pass Node.js compatibility tests while leaving room for future enhancements.