Skip to content

Commit 46124a6

Browse files
feat: dump node process information when running
1 parent 4f97cbe commit 46124a6

File tree

6 files changed

+91
-15
lines changed

6 files changed

+91
-15
lines changed

packages/core/src/index.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,15 @@ export function getCodspeedRunnerMode(): CodSpeedRunnerMode {
2222

2323
// If CODSPEED_ENV is set, check CODSPEED_RUNNER_MODE
2424
const codspeedRunnerMode = process.env.CODSPEED_RUNNER_MODE;
25-
if (
26-
codspeedRunnerMode === "instrumentation" ||
27-
codspeedRunnerMode === "simulation"
28-
) {
25+
if (codspeedRunnerMode === "instrumentation" || codspeedRunnerMode === "simulation") {
2926
return "simulation";
3027
} else if (codspeedRunnerMode === "memory") {
3128
return "memory";
3229
} else if (codspeedRunnerMode === "walltime") {
3330
return "walltime";
3431
}
3532

36-
console.warn(
37-
`Unknown codspeed runner mode: ${codspeedRunnerMode}, defaulting to disabled`
38-
);
33+
console.warn(`Unknown codspeed runner mode: ${codspeedRunnerMode}, defaulting to disabled`);
3934
return "disabled";
4035
}
4136

@@ -50,24 +45,27 @@ export function getInstrumentMode(): InstrumentMode {
5045

5146
export const setupCore = () => {
5247
if (!native_core.isBound) {
53-
throw new Error(
54-
"Native core module is not bound, CodSpeed integration will not work properly"
55-
);
48+
throw new Error("Native core module is not bound, CodSpeed integration will not work properly");
5649
}
5750

5851
native_core.InstrumentHooks.setIntegration("codspeed-node", __VERSION__);
5952
linuxPerf.start();
6053
checkV8Flags();
54+
55+
// Collect Node.js runtime environment to detect changes that could
56+
// cause performance differences across runs
57+
const hooks = native_core.InstrumentHooks;
58+
hooks.setEnvironment("nodejs", "version", process.versions.node);
59+
hooks.setEnvironment("nodejs", "v8", process.versions.v8);
60+
hooks.setEnvironment("nodejs", "arch", process.arch);
61+
hooks.writeEnvironment(process.pid);
6162
};
6263

6364
export const teardownCore = () => {
6465
linuxPerf.stop();
6566
};
6667

67-
export type {
68-
SetupInstrumentsRequestBody,
69-
SetupInstrumentsResponse,
70-
} from "./generated/openapi";
68+
export type { SetupInstrumentsRequestBody, SetupInstrumentsResponse } from "./generated/openapi";
7169
export { getV8Flags, tryIntrospect } from "./introspection";
7270
export { optimizeFunction, optimizeFunctionSync } from "./optimization";
7371
export * from "./utils";

packages/core/src/native_core/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,14 @@ try {
5151
setIntegration: (_name: string, _version: string) => {
5252
return 0;
5353
},
54+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
55+
setEnvironment: (_sectionName: string, _key: string, _value: string) => {
56+
return 0;
57+
},
58+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
59+
writeEnvironment: (_pid: number) => {
60+
return 0;
61+
},
5462
__codspeed_root_frame__: <T>(callback: () => T): T => {
5563
return callback();
5664
},

packages/core/src/native_core/instruments/hooks.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,22 @@ export interface InstrumentHooks {
3232
*/
3333
setIntegration(name: string, version: string): number;
3434

35+
/**
36+
* Register a key-value pair under a named environment section.
37+
* @param sectionName Section name (e.g. "Node.js")
38+
* @param key Key name (e.g. "version")
39+
* @param value Value (e.g. "22.0.0")
40+
* @returns 0 on success, non-zero on error
41+
*/
42+
setEnvironment(sectionName: string, key: string, value: string): number;
43+
44+
/**
45+
* Flush all registered environment sections to disk.
46+
* @param pid Process ID
47+
* @returns 0 on success, non-zero on error
48+
*/
49+
writeEnvironment(pid: number): number;
50+
3551
/**
3652
* Execute a callback function with __codspeed_root_frame__ in its stack trace
3753
* @param callback Function to execute

packages/core/src/native_core/instruments/hooks_wrapper.cc

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,54 @@ Napi::Number SetIntegration(const Napi::CallbackInfo &info) {
8181
return Napi::Number::New(env, result);
8282
}
8383

84+
Napi::Number SetEnvironment(const Napi::CallbackInfo &info) {
85+
Napi::Env env = info.Env();
86+
87+
if (info.Length() != 3) {
88+
Napi::TypeError::New(
89+
env, "Expected 3 arguments: sectionName, key, and value")
90+
.ThrowAsJavaScriptException();
91+
return Napi::Number::New(env, 1);
92+
}
93+
94+
if (!info[0].IsString() || !info[1].IsString() || !info[2].IsString()) {
95+
Napi::TypeError::New(
96+
env,
97+
"Expected string (sectionName), string (key), and string (value)")
98+
.ThrowAsJavaScriptException();
99+
return Napi::Number::New(env, 1);
100+
}
101+
102+
std::string section_name = info[0].As<Napi::String>().Utf8Value();
103+
std::string key = info[1].As<Napi::String>().Utf8Value();
104+
std::string value = info[2].As<Napi::String>().Utf8Value();
105+
106+
uint8_t result = instrument_hooks_set_environment(
107+
hooks, section_name.c_str(), key.c_str(), value.c_str());
108+
return Napi::Number::New(env, result);
109+
}
110+
111+
Napi::Number WriteEnvironment(const Napi::CallbackInfo &info) {
112+
Napi::Env env = info.Env();
113+
114+
if (info.Length() != 1) {
115+
Napi::TypeError::New(env, "Expected 1 argument: pid")
116+
.ThrowAsJavaScriptException();
117+
return Napi::Number::New(env, 1);
118+
}
119+
120+
if (!info[0].IsNumber()) {
121+
Napi::TypeError::New(env, "Expected number (pid)")
122+
.ThrowAsJavaScriptException();
123+
return Napi::Number::New(env, 1);
124+
}
125+
126+
uint32_t pid = info[0].As<Napi::Number>().Uint32Value();
127+
128+
uint8_t result = instrument_hooks_write_environment(hooks, pid);
129+
return Napi::Number::New(env, result);
130+
}
131+
84132
Napi::Value __attribute__ ((noinline)) __codspeed_root_frame__(const Napi::CallbackInfo &info) {
85133
Napi::Env env = info.Env();
86134

@@ -117,6 +165,10 @@ Napi::Object Initialize(Napi::Env env, Napi::Object exports) {
117165
Napi::Function::New(env, SetExecutedBenchmark));
118166
instrumentHooksObj.Set(Napi::String::New(env, "setIntegration"),
119167
Napi::Function::New(env, SetIntegration));
168+
instrumentHooksObj.Set(Napi::String::New(env, "setEnvironment"),
169+
Napi::Function::New(env, SetEnvironment));
170+
instrumentHooksObj.Set(Napi::String::New(env, "writeEnvironment"),
171+
Napi::Function::New(env, WriteEnvironment));
120172
instrumentHooksObj.Set(Napi::String::New(env, "__codspeed_root_frame__"),
121173
Napi::Function::New(env, __codspeed_root_frame__));
122174

packages/core/src/native_core/instruments/hooks_wrapper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Napi::Number StartBenchmark(const Napi::CallbackInfo &info);
1717
Napi::Number StopBenchmark(const Napi::CallbackInfo &info);
1818
Napi::Number SetExecutedBenchmark(const Napi::CallbackInfo &info);
1919
Napi::Number SetIntegration(const Napi::CallbackInfo &info);
20+
Napi::Number SetEnvironment(const Napi::CallbackInfo &info);
21+
Napi::Number WriteEnvironment(const Napi::CallbackInfo &info);
2022
Napi::Object Initialize(Napi::Env env, Napi::Object exports);
2123

2224
} // namespace hooks_wrapper

0 commit comments

Comments
 (0)