Skip to content

Commit 834ed04

Browse files
feat: use instrument hooks for measurements
1 parent 95ca8c4 commit 834ed04

File tree

11 files changed

+206
-23
lines changed

11 files changed

+206
-23
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
steps:
1313
- uses: "actions/checkout@v4"
1414
with:
15-
fetch-depth: 0
15+
submodules: true
1616
- name: Install valgrind
1717
run: |
1818
sudo apt-get update
@@ -32,6 +32,8 @@ jobs:
3232
examples: ${{ steps.list-examples.outputs.examples }}
3333
steps:
3434
- uses: "actions/checkout@v4"
35+
with:
36+
submodules: true
3537
# list the directories in ./examples and output them to a github action workflow variables as a JSON array
3638
- run: |
3739
examples=$(find ./examples -maxdepth 1 -mindepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n") | map(select(length > 0))')
@@ -50,7 +52,7 @@ jobs:
5052
steps:
5153
- uses: "actions/checkout@v4"
5254
with:
53-
fetch-depth: 0
55+
submodules: true
5456
- name: Install valgrind
5557
run: |
5658
sudo apt-get update

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules
22
.rollup.cache
33
dist
44
generated
5+
packages/core/src/native_core/instruments/hooks

packages/core/binding.gyp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,30 @@
88
"cflags_cc!": [
99
"-fno-exceptions"
1010
],
11+
"cflags": [
12+
"-Wno-maybe-uninitialized",
13+
"-Wno-unused-variable",
14+
"-Wno-unused-parameter",
15+
"-Wno-unused-but-set-variable",
16+
"-Wno-type-limits"
17+
],
18+
"cflags_cc": [
19+
"-Wno-maybe-uninitialized",
20+
"-Wno-unused-variable",
21+
"-Wno-unused-parameter",
22+
"-Wno-unused-but-set-variable",
23+
"-Wno-type-limits"
24+
],
1125
"sources": [
12-
"src/native_core/measurement/measurement.cc",
1326
"src/native_core/linux_perf/linux_perf.cc",
1427
"src/native_core/linux_perf/linux_perf_listener.cc",
28+
"src/native_core/instruments/hooks_wrapper.cc",
29+
"src/native_core/instruments/hooks/dist/core.c",
1530
"src/native_core/native_core.cc"
1631
],
1732
"include_dirs": [
18-
"<!@(node -p \"require('node-addon-api').include\")"
33+
"<!@(node -p \"require('node-addon-api').include\")",
34+
"src/native_core/instruments/hooks/includes"
1935
],
2036
"defines": [
2137
"NAPI_DISABLE_CPP_EXCEPTIONS"

packages/core/src/index.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ export const isBound = native_core.isBound;
1111
export const mongoMeasurement = new MongoMeasurement();
1212

1313
export const setupCore = () => {
14-
native_core.Measurement.stopInstrumentation(
15-
`Metadata: codspeed-node ${__VERSION__}`
16-
);
14+
native_core.InstrumentHooks.setIntegration("codspeed-node", __VERSION__);
1715
linuxPerf.start();
1816
checkV8Flags();
1917
};
@@ -29,4 +27,4 @@ export type {
2927
export { getV8Flags, tryIntrospect } from "./introspection";
3028
export { optimizeFunction, optimizeFunctionSync } from "./optimization";
3129
export * from "./utils";
32-
export const Measurement = native_core.Measurement;
30+
export const InstrumentHooks = native_core.InstrumentHooks;

packages/core/src/native_core/index.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import path from "path";
2+
import { InstrumentHooks } from "./instruments/hooks";
23
import { LinuxPerf } from "./linux_perf/linux_perf";
3-
import { Measurement } from "./measurement/measurement";
4+
45
interface NativeCore {
5-
Measurement: Measurement;
6+
InstrumentHooks: InstrumentHooks;
67
LinuxPerf: typeof LinuxPerf;
78
}
89

@@ -22,12 +23,12 @@ try {
2223
};
2324
} catch (e) {
2425
native_core = {
25-
Measurement: {
26+
InstrumentHooks: {
2627
isInstrumented: () => false,
27-
// eslint-disable-next-line @typescript-eslint/no-empty-function
28-
startInstrumentation: () => {},
29-
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
30-
stopInstrumentation: (at) => {},
28+
startBenchmark: () => 1,
29+
stopBenchmark: () => 1,
30+
setExecutedBenchmark: () => 1,
31+
setIntegration: () => 1,
3132
},
3233
LinuxPerf: class LinuxPerf {
3334
start() {
Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface InstrumentHooks {
2+
isInstrumented: () => boolean;
3+
startBenchmark: () => number;
4+
stopBenchmark: () => number;
5+
setExecutedBenchmark: (pid: number, uri: string) => number;
6+
setIntegration: (name: string, version: string) => number;
7+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#include "hooks_wrapper.h"
2+
#include "hooks/includes/core.h"
3+
#include <memory>
4+
5+
namespace codspeed_native {
6+
namespace instruments {
7+
namespace hooks_wrapper {
8+
9+
// Global instance to maintain state across calls
10+
static std::unique_ptr<InstrumentHooks, decltype(&instrument_hooks_deinit)>
11+
g_hooks{nullptr, &instrument_hooks_deinit};
12+
13+
// Initialize instrument hooks if not already done
14+
static InstrumentHooks *ensureInitialized() {
15+
if (!g_hooks) {
16+
InstrumentHooks *hooks = instrument_hooks_init();
17+
if (hooks) {
18+
g_hooks.reset(hooks);
19+
}
20+
}
21+
return g_hooks.get();
22+
}
23+
24+
Napi::Boolean IsInstrumented(const Napi::CallbackInfo &info) {
25+
Napi::Env env = info.Env();
26+
InstrumentHooks *hooks = ensureInitialized();
27+
28+
if (!hooks) {
29+
return Napi::Boolean::New(env, false);
30+
}
31+
32+
bool instrumented = instrument_hooks_is_instrumented(hooks);
33+
return Napi::Boolean::New(env, instrumented);
34+
}
35+
36+
Napi::Number StartBenchmark(const Napi::CallbackInfo &info) {
37+
Napi::Env env = info.Env();
38+
InstrumentHooks *hooks = ensureInitialized();
39+
40+
if (!hooks) {
41+
return Napi::Number::New(env, 1); // Return error code
42+
}
43+
44+
uint8_t result = instrument_hooks_start_benchmark(hooks);
45+
return Napi::Number::New(env, result);
46+
}
47+
48+
Napi::Number StopBenchmark(const Napi::CallbackInfo &info) {
49+
Napi::Env env = info.Env();
50+
InstrumentHooks *hooks = ensureInitialized();
51+
52+
if (!hooks) {
53+
return Napi::Number::New(env, 1); // Return error code
54+
}
55+
56+
uint8_t result = instrument_hooks_stop_benchmark(hooks);
57+
return Napi::Number::New(env, result);
58+
}
59+
60+
Napi::Number SetExecutedBenchmark(const Napi::CallbackInfo &info) {
61+
Napi::Env env = info.Env();
62+
63+
if (info.Length() != 2) {
64+
Napi::TypeError::New(env, "Expected 2 arguments: pid and uri")
65+
.ThrowAsJavaScriptException();
66+
return Napi::Number::New(env, 1);
67+
}
68+
69+
if (!info[0].IsNumber() || !info[1].IsString()) {
70+
Napi::TypeError::New(env, "Expected number (pid) and string (uri)")
71+
.ThrowAsJavaScriptException();
72+
return Napi::Number::New(env, 1);
73+
}
74+
75+
InstrumentHooks *hooks = ensureInitialized();
76+
if (!hooks) {
77+
return Napi::Number::New(env, 1);
78+
}
79+
80+
uint32_t pid = info[0].As<Napi::Number>().Uint32Value();
81+
std::string uri = info[1].As<Napi::String>().Utf8Value();
82+
83+
uint8_t result =
84+
instrument_hooks_set_executed_benchmark(hooks, pid, uri.c_str());
85+
return Napi::Number::New(env, result);
86+
}
87+
88+
Napi::Number SetIntegration(const Napi::CallbackInfo &info) {
89+
Napi::Env env = info.Env();
90+
91+
if (info.Length() != 2) {
92+
Napi::TypeError::New(env, "Expected 2 arguments: name and version")
93+
.ThrowAsJavaScriptException();
94+
return Napi::Number::New(env, 1);
95+
}
96+
97+
if (!info[0].IsString() || !info[1].IsString()) {
98+
Napi::TypeError::New(env, "Expected string (name) and string (version)")
99+
.ThrowAsJavaScriptException();
100+
return Napi::Number::New(env, 1);
101+
}
102+
103+
InstrumentHooks *hooks = ensureInitialized();
104+
if (!hooks) {
105+
return Napi::Number::New(env, 1);
106+
}
107+
108+
std::string name = info[0].As<Napi::String>().Utf8Value();
109+
std::string version = info[1].As<Napi::String>().Utf8Value();
110+
111+
uint8_t result =
112+
instrument_hooks_set_integration(hooks, name.c_str(), version.c_str());
113+
return Napi::Number::New(env, result);
114+
}
115+
116+
Napi::Object Initialize(Napi::Env env, Napi::Object exports) {
117+
Napi::Object instrumentHooksObj = Napi::Object::New(env);
118+
119+
instrumentHooksObj.Set(Napi::String::New(env, "isInstrumented"),
120+
Napi::Function::New(env, IsInstrumented));
121+
instrumentHooksObj.Set(Napi::String::New(env, "startBenchmark"),
122+
Napi::Function::New(env, StartBenchmark));
123+
instrumentHooksObj.Set(Napi::String::New(env, "stopBenchmark"),
124+
Napi::Function::New(env, StopBenchmark));
125+
instrumentHooksObj.Set(Napi::String::New(env, "setExecutedBenchmark"),
126+
Napi::Function::New(env, SetExecutedBenchmark));
127+
instrumentHooksObj.Set(Napi::String::New(env, "setIntegration"),
128+
Napi::Function::New(env, SetIntegration));
129+
130+
exports.Set(Napi::String::New(env, "InstrumentHooks"), instrumentHooksObj);
131+
132+
return exports;
133+
}
134+
135+
} // namespace hooks_wrapper
136+
} // namespace instruments
137+
} // namespace codspeed_native
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef INSTRUMENTS_HOOKS_WRAPPER_H
2+
#define INSTRUMENTS_HOOKS_WRAPPER_H
3+
4+
#include <napi.h>
5+
6+
namespace codspeed_native {
7+
namespace instruments {
8+
namespace hooks_wrapper {
9+
10+
Napi::Boolean IsInstrumented(const Napi::CallbackInfo &info);
11+
Napi::Number StartBenchmark(const Napi::CallbackInfo &info);
12+
Napi::Number StopBenchmark(const Napi::CallbackInfo &info);
13+
Napi::Number SetExecutedBenchmark(const Napi::CallbackInfo &info);
14+
Napi::Number SetIntegration(const Napi::CallbackInfo &info);
15+
Napi::Object Initialize(Napi::Env env, Napi::Object exports);
16+
17+
} // namespace hooks_wrapper
18+
} // namespace instruments
19+
} // namespace codspeed_native
20+
21+
#endif // INSTRUMENTS_HOOKS_WRAPPER_H

packages/core/src/native_core/native_core.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#include "linux_perf/linux_perf.h"
2-
#include "measurement/measurement.h"
2+
#include "instruments/hooks_wrapper.h"
33
#include <napi.h>
44

55
namespace codspeed_native {
66

77
Napi::Object Initialize(Napi::Env env, Napi::Object exports) {
88
codspeed_native::LinuxPerf::Initialize(env, exports);
9-
codspeed_native::Measurement::Initialize(env, exports);
9+
codspeed_native::instruments::hooks_wrapper::Initialize(env, exports);
1010

1111
return exports;
1212
}

0 commit comments

Comments
 (0)