Skip to content

Commit 10dd462

Browse files
fengmk2claude
andauthored
feat: build from Node.js v24 (#253)
close #251 macOS uses C++20 (required for Node.js v24+) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: Claude <[email protected]>
1 parent 1706ac4 commit 10dd462

File tree

5 files changed

+218
-6
lines changed

5 files changed

+218
-6
lines changed

.github/workflows/nodejs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
{os: "macos-latest", arch: "x64"},
1717
{os: "ubuntu-latest", arch: "x64"},
1818
]
19-
node-version: [ 18, 20, 22 ]
19+
node-version: [ 18, 20, 22, 24 ]
2020
steps:
2121
- name: Set up Python
2222
uses: actions/setup-python@v4

.github/workflows/release.yml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
name: Release
2-
32
on:
43
push:
54
branches: [ master ]
65

6+
permissions:
7+
contents: write
8+
deployments: write
9+
issues: write
10+
pull-requests: write
11+
id-token: write
12+
713
jobs:
814
release:
9-
name: Node.js
10-
uses: X-Profiler/github-actions/.github/workflows/node-release.yml@master
15+
name: NPM
16+
uses: X-Profiler/github-actions/.github/workflows/npm-release.yml@master
1117
secrets:
12-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
1318
GIT_TOKEN: ${{ secrets.GIT_TOKEN }}

CLAUDE.md

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
X-Profiler is a Node.js native addon for runtime profiling and performance monitoring. It outputs performance logs at regular intervals and enables real-time runtime state sampling via external commands (xprofctl CLI).
8+
9+
**Supported Platforms:** Windows, Linux (x64/arm64), macOS (x64/arm64)
10+
**Node.js Versions:** v18.x, v20.x, v22.x, v24.x (LTS only)
11+
12+
## Build Commands
13+
14+
```bash
15+
# Build the native addon (requires C++ toolchain)
16+
npm run build
17+
18+
# Build with pre-built binary download (fallback to build from source)
19+
npm install
20+
21+
# Run all tests
22+
npm run test
23+
24+
# Run a single test file
25+
npm run test-single test/config.test.js
26+
27+
# Generate coverage report
28+
npm run cov
29+
30+
# Run coverage for a single test
31+
npm run cov-single test/config.test.js
32+
33+
# Full CI suite (lint + build + coverage)
34+
npm run ci
35+
36+
# Format C++ code (requires clang-format)
37+
npm run format
38+
39+
# Lint JavaScript code
40+
npm run lint
41+
```
42+
43+
## Build System & C++ Compilation
44+
45+
**C++ Standard Requirements:**
46+
- Linux: Uses C++17 (`-std=c++17` in `cflags`)
47+
- macOS: Uses C++20 (`-std=c++20` in `xcode_settings.OTHER_CFLAGS`) - required for Node.js v24+
48+
- Windows: Uses MSVC default settings
49+
50+
The project uses:
51+
- **node-gyp** for native compilation
52+
- **@mapbox/node-pre-gyp** for binary distribution via GitHub Releases
53+
- **NAN (Native Abstractions for Node.js)** for V8 API compatibility
54+
55+
Build output: `build/binding/Release/node-v{abi}-{platform}-{arch}/xprofiler.node`
56+
57+
## Architecture
58+
59+
### Multi-Threading Model
60+
61+
The addon runs **three concurrent threads**:
62+
63+
1. **Main Thread** - JavaScript execution, configuration, API calls
64+
2. **LogBypass Thread** - Periodic statistics collection (separate libuv loop)
65+
3. **CommandsListener Thread** - IPC socket server accepting xprofctl commands
66+
67+
### Code Organization
68+
69+
**JavaScript Layer** (`/lib/`, `/patch/`, root):
70+
- `xprofiler.js` - Main entry point and public API
71+
- `lib/configure.js` - Configuration merging (env vars → defaults → user config)
72+
- `patch/http.js` - HTTP module patching via diagnostics_channel (Node.js v18+)
73+
74+
**Native C++ Layer** (`/src/`):
75+
76+
**Core:**
77+
- `xprofiler.cc` - Module initialization, NAN bindings export
78+
- `environment_data.h/cc` - Per-isolate profiling state
79+
- `environment_registry.h/cc` - Multi-isolate management
80+
81+
**JavaScript Bindings** (`/src/jsapi/`):
82+
- Bridge between JS and C++ (export_configure, export_logger, export_http, etc.)
83+
84+
**Statistics Collection** (`/src/logbypass/`):
85+
- Runs in separate thread, samples at `log_interval` (default 60s)
86+
- Collects: CPU, heap, GC, libuv handles, HTTP metrics
87+
88+
**Remote Commands** (`/src/commands/`):
89+
- IPC listener accepts commands from `xprofctl` CLI
90+
- Profiling: CPU profiling, heap profiling, heap snapshots, GC profiling
91+
- Diagnostics: Reports (JS/native stacks, heap stats, UV stats, system info)
92+
- Simple: version, config get/set
93+
94+
**Platform-Specific** (`/src/platform/`):
95+
- `unix/` - Linux/macOS (Unix sockets, /proc/stat, getrusage)
96+
- `win/` - Windows (named pipes, Performance Counters, DbgHelp)
97+
98+
**V8 Hooks** (`/src/hooks/`):
99+
- `fatal_error.cc` - FatalError handler (can trigger diagnostics/coredump)
100+
- `heap_limit.cc` - Auto-increment heap limit on OOM
101+
102+
## Configuration System
103+
104+
**3-Level Priority:**
105+
```
106+
User Config (xprofiler.start({...})) [highest]
107+
108+
Environment Variables (XPROFILER_*)
109+
110+
Default Config (configuration.js) [lowest]
111+
```
112+
113+
**Key Configurations:**
114+
- `log_dir` - Output directory (default: `os.tmpdir()`)
115+
- `log_interval` - Sampling interval in seconds (default: 60)
116+
- `log_format_alinode` - Alinode format compatibility (default: false)
117+
- `patch_http` - Enable HTTP patching (default: true)
118+
- `enable_fatal_error_hook` - FatalError handling (default: true)
119+
- `enable_auto_incr_heap_limit` - Auto-grow heap on OOM (default: false)
120+
121+
See `configuration.js` for full list and README.md for environment variable names.
122+
123+
## Testing
124+
125+
**Framework:** Mocha + expect.js
126+
**Coverage:** nyc (Istanbul)
127+
128+
**Test Structure:**
129+
- `/test/*.test.js` - Unit tests for core features
130+
- `/test/patch/*.test.js` - Module patching tests
131+
- `/test/fixtures/` - Test helpers and utilities
132+
133+
**Important:** Tests use `mm` library for mocking. Always call `mm.restore()` in afterEach hooks.
134+
135+
## Common Development Tasks
136+
137+
### Adding a New Configuration Option
138+
139+
1. Add default value to `configuration.js`
140+
2. Add environment variable parsing to `lib/configure.js`
141+
3. Update native config struct in `src/configure.h`
142+
4. Add JS binding in `src/jsapi/export_configure.cc`
143+
5. Add test to `test/config.test.js`
144+
145+
### Adding a New xprofctl Command
146+
147+
1. Define command in `src/commands/parser.cc`
148+
2. Implement handler in appropriate `src/commands/*/` subdirectory
149+
3. Add command output logic in `src/commands/dump.cc`
150+
4. Update `bin/xprofctl` CLI with new command/args
151+
5. Add test to `test/commands.test.js`
152+
153+
### Modifying Statistics Collection
154+
155+
1. Update data structures in `src/library/common.h`
156+
2. Modify collection logic in `src/logbypass/*.cc`
157+
3. Update output formatting in logger
158+
4. Add test to `test/logbypass.test.js`
159+
160+
## Platform-Specific Considerations
161+
162+
**Linux:**
163+
- CPU stats via `/proc/stat` parsing
164+
- Coredump support via `src/platform/unix/core/linux/`
165+
- glibc mallopt configuration
166+
167+
**macOS:**
168+
- CPU stats via `getrusage()`
169+
- Stack traces via macOS-specific APIs
170+
- No coredump support
171+
172+
**Windows:**
173+
- Named pipes for IPC (not Unix sockets)
174+
- Windows Performance Counters for CPU
175+
- DbgHelp.dll for stack traces
176+
- Different path handling (`\\.\pipe\xprofiler-ctl`)
177+
178+
## IPC Protocol
179+
180+
**Socket Path:**
181+
- Unix: `<log_dir>/xprofiler-ctl-uds-path.sock`
182+
- Windows: `\\.\pipe\xprofiler-ctl`
183+
184+
**Command Format:** JSON messages between xprofctl and CommandsListener thread
185+
186+
**Output Location:** Profiling artifacts saved to `log_dir` with timestamps
187+
188+
## CI/CD
189+
190+
**GitHub Actions:** `.github/workflows/nodejs.yml`
191+
- Matrix: 3 OS × 4 Node.js versions
192+
- Steps: Build → Test → Coverage → Upload to codecov
193+
- Runs on every commit
194+
195+
**Binary Distribution:**
196+
- Pre-built binaries released to GitHub Releases
197+
- node-pre-gyp downloads matching binary during npm install
198+
- Fallback to source compilation if binary unavailable
199+
200+
## Important Notes
201+
202+
- **Thread Safety:** Use `xpf_mutex.h` for synchronization between threads
203+
- **V8 Isolation:** Use `RequestInterrupt()` for safe cross-thread V8 access
204+
- **NAN Deprecations:** Some NAN APIs are deprecated in Node.js v24 (warnings are non-critical)
205+
- **Log Format:** Two formats supported (xprofiler native vs Alinode compatibility)
206+
- **Process Tracking:** Uses `~/.xprofiler` file to track running processes with xprofiler enabled

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ xprofiler 插件支持三大主流操作系统:
2323
- v18.x
2424
- v20.x
2525
- v22.x
26+
- v24.x
2627

2728
更低的版本已经不在 Node.js 官方 LTS 计划中,故正常情况下不再支持。
2829

binding.gyp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"GCC_ENABLE_CPP_EXCEPTIONS": "YES",
8989
"GCC_OPTIMIZATION_LEVEL": "3",
9090
"OTHER_CFLAGS": [
91-
"-std=c++17",
91+
"-std=c++20",
9292
"-Wconversion",
9393
"-Wno-sign-conversion",
9494
]

0 commit comments

Comments
 (0)