Skip to content

Commit 1cfbc8f

Browse files
committed
src: add fast api call to get spanId and traceId
1 parent cef497d commit 1cfbc8f

File tree

5 files changed

+145
-42
lines changed

5 files changed

+145
-42
lines changed

lib/internal/otel/trace.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
const {
44
JSONStringify,
55
SafeMap,
6+
Uint8Array,
67
} = primordials;
8+
const { Buffer } = require('buffer');
79

810
const binding = internalBinding('nsolid_api');
9-
const { getSpanId,
10-
getTraceId,
11-
nsolid_consts } = binding;
11+
const { nsolid_consts } = binding;
1212

1313
const {
1414
getApi,
@@ -21,6 +21,19 @@ const {
2121

2222
const { now, getTimeOriginTimestamp } = require('internal/perf/utils');
2323

24+
// Utility functions for getting span and trace IDs
25+
function getSpanId() {
26+
const buffer = new Uint8Array(8);
27+
binding.getSpanId(buffer);
28+
return Buffer.from(buffer).toString('hex');
29+
}
30+
31+
function getTraceId() {
32+
const buffer = new Uint8Array(16);
33+
binding.getTraceId(buffer);
34+
return Buffer.from(buffer).toString('hex');
35+
}
36+
2437
class SpanContext {
2538
internalId;
2639
spanId;

src/node_external_reference.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ using CFunctionCallbackWithStrings =
3838
bool (*)(v8::Local<v8::Value>,
3939
const v8::FastOneByteString& input,
4040
const v8::FastOneByteString& base);
41+
using CFunctionCallbackWithOneUint8Array =
42+
void (*)(v8::Local<v8::Value>,
43+
const v8::FastApiTypedArray<uint8_t>&);
4144
using CFunctionCallbackWithTwoUint8Arrays =
4245
int32_t (*)(v8::Local<v8::Value>,
4346
const v8::FastApiTypedArray<uint8_t>&,
@@ -111,6 +114,7 @@ class ExternalReferenceRegistry {
111114
V(CFunctionCallbackWithBool) \
112115
V(CFunctionCallbackWithString) \
113116
V(CFunctionCallbackWithStrings) \
117+
V(CFunctionCallbackWithOneUint8Array) \
114118
V(CFunctionCallbackWithTwoUint8Arrays) \
115119
V(CFunctionCallbackWithTwoUint8ArraysFallback) \
116120
V(CFunctionCallbackWithUint8ArrayUint32Int64Bool) \

src/nsolid/nsolid_api.cc

Lines changed: 107 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ using v8::String;
6464
using v8::Symbol;
6565
using v8::Uint32;
6666
using v8::Uint32Array;
67+
using v8::Uint8Array;
6768
using v8::Value;
6869
using v8::WeakCallbackInfo;
6970
using v8::WeakCallbackType;
@@ -1779,14 +1780,12 @@ void EnvList::q_cb_timeout_cb_(nsuv::ns_timer* handle, QCbTimeoutStor* ptr) {
17791780
}
17801781

17811782

1782-
void EnvList::popSpanId(std::string& span_id) {
1783+
void EnvList::popSpanId(std::array<uint8_t, 8>& span_id) {
17831784
int er;
17841785
size_t s;
17851786
if (!span_id_q_.dequeue(span_id, s)) {
17861787
// Generate the buffer synchronously
1787-
unsigned char buf[8];
1788-
utils::generate_random_buf(buf, sizeof(buf));
1789-
span_id = utils::buffer_to_hex(buf, sizeof(buf));
1788+
utils::generate_random_buf(span_id.data(), span_id.size());
17901789
// Notify the nsolid thread to fill the q
17911790
er = fill_tracing_ids_msg_.send();
17921791
CHECK_EQ(er, 0);
@@ -1801,14 +1800,12 @@ void EnvList::popSpanId(std::string& span_id) {
18011800
}
18021801

18031802

1804-
void EnvList::popTraceId(std::string& trace_id) {
1803+
void EnvList::popTraceId(std::array<uint8_t, 16>& trace_id) {
18051804
int er;
18061805
size_t s;
18071806
if (!trace_id_q_.dequeue(trace_id, s)) {
18081807
// Generate the buffer synchronously
1809-
unsigned char buf[16];
1810-
utils::generate_random_buf(buf, sizeof(buf));
1811-
trace_id = utils::buffer_to_hex(buf, sizeof(buf));
1808+
utils::generate_random_buf(trace_id.data(), trace_id.size());
18121809
// Notify the nsolid thread to fill the q
18131810
er = fill_tracing_ids_msg_.send();
18141811
CHECK_EQ(er, 0);
@@ -1824,19 +1821,19 @@ void EnvList::popTraceId(std::string& trace_id) {
18241821

18251822

18261823
void EnvList::fill_span_id_q() {
1827-
unsigned char buf[SPAN_ID_Q_REFILL_ITEMS*8];
1828-
utils::generate_random_buf(buf, sizeof(buf));
18291824
for (unsigned int i = 0; i < SPAN_ID_Q_REFILL_ITEMS; ++i) {
1830-
span_id_q_.enqueue(utils::buffer_to_hex(buf + i*8, 8));
1825+
std::array<uint8_t, 8> span_id;
1826+
utils::generate_random_buf(span_id.data(), span_id.size());
1827+
span_id_q_.enqueue(span_id);
18311828
}
18321829
}
18331830

18341831

18351832
void EnvList::fill_trace_id_q() {
1836-
unsigned char buf[TRACE_ID_Q_REFILL_ITEMS*16];
1837-
utils::generate_random_buf(buf, sizeof(buf));
18381833
for (unsigned int i = 0; i < TRACE_ID_Q_REFILL_ITEMS; ++i) {
1839-
trace_id_q_.enqueue(utils::buffer_to_hex(buf + i*16, 16));
1834+
std::array<uint8_t, 16> trace_id;
1835+
utils::generate_random_buf(trace_id.data(), trace_id.size());
1836+
trace_id_q_.enqueue(trace_id);
18401837
}
18411838
}
18421839

@@ -2366,6 +2363,80 @@ void BindingData::PushSpanDataStringImpl(BindingData* data,
23662363
}
23672364

23682365

2366+
void BindingData::SlowGetSpanId(const FunctionCallbackInfo<Value>& args) {
2367+
CHECK(args[0]->IsUint8Array());
2368+
Local<Uint8Array> output = args[0].As<Uint8Array>();
2369+
2370+
DCHECK_EQ(output->Length(), 8);
2371+
2372+
std::array<uint8_t, 8> span_id;
2373+
EnvList* envlist = EnvList::Inst();
2374+
envlist->popSpanId(span_id);
2375+
2376+
// Copy binary data to the TypedArray
2377+
uint8_t* buffer =
2378+
static_cast<uint8_t*>(output->Buffer()->Data()) + output->ByteOffset();
2379+
for (size_t i = 0; i < span_id.size(); i++) {
2380+
buffer[i] = span_id[i];
2381+
}
2382+
}
2383+
2384+
2385+
void BindingData::FastGetSpanId(v8::Local<v8::Value> receiver,
2386+
const v8::FastApiTypedArray<uint8_t>& output) {
2387+
std::array<uint8_t, 8> span_id;
2388+
EnvList* envlist = EnvList::Inst();
2389+
envlist->popSpanId(span_id);
2390+
2391+
DCHECK_EQ(output.length(), span_id.size());
2392+
2393+
uint8_t* dst_data;
2394+
CHECK(output.getStorageIfAligned(&dst_data));
2395+
2396+
// Copy binary data directly to the output buffer
2397+
for (size_t i = 0; i < span_id.size(); i++) {
2398+
dst_data[i] = span_id[i];
2399+
}
2400+
}
2401+
2402+
2403+
void BindingData::SlowGetTraceId(const FunctionCallbackInfo<Value>& args) {
2404+
CHECK(args[0]->IsUint8Array());
2405+
Local<Uint8Array> output = args[0].As<Uint8Array>();
2406+
2407+
DCHECK_EQ(output->Length(), 16);
2408+
2409+
std::array<uint8_t, 16> trace_id;
2410+
EnvList* envlist = EnvList::Inst();
2411+
envlist->popTraceId(trace_id);
2412+
2413+
// Copy binary data to the TypedArray
2414+
uint8_t* buffer =
2415+
static_cast<uint8_t*>(output->Buffer()->Data()) + output->ByteOffset();
2416+
for (size_t i = 0; i < trace_id.size(); i++) {
2417+
buffer[i] = trace_id[i];
2418+
}
2419+
}
2420+
2421+
2422+
void BindingData::FastGetTraceId(v8::Local<v8::Value> receiver,
2423+
const v8::FastApiTypedArray<uint8_t>& output) {
2424+
std::array<uint8_t, 16> trace_id;
2425+
EnvList* envlist = EnvList::Inst();
2426+
envlist->popTraceId(trace_id);
2427+
2428+
DCHECK_EQ(output.length(), trace_id.size());
2429+
2430+
uint8_t* dst_data;
2431+
CHECK(output.getStorageIfAligned(&dst_data));
2432+
2433+
// Copy binary data directly to the output buffer
2434+
for (size_t i = 0; i < trace_id.size(); i++) {
2435+
dst_data[i] = trace_id[i];
2436+
}
2437+
}
2438+
2439+
23692440
static void GetEnvMetrics(const FunctionCallbackInfo<Value>& args) {
23702441
Isolate* isolate = args.GetIsolate();
23712442
EnvInst* envinst = EnvInst::GetEnvLocalInst(isolate);
@@ -2620,22 +2691,6 @@ static void SetTrackPromisesFn(const FunctionCallbackInfo<Value>& args) {
26202691
}
26212692

26222693

2623-
static void GetSpanId(const FunctionCallbackInfo<Value>& args) {
2624-
std::string span_id;
2625-
EnvList* envlist = EnvList::Inst();
2626-
envlist->popSpanId(span_id);
2627-
args.GetReturnValue().Set(OneByteString(args.GetIsolate(), span_id.c_str()));
2628-
}
2629-
2630-
2631-
static void GetTraceId(const FunctionCallbackInfo<Value>& args) {
2632-
std::string trace_id;
2633-
EnvList* envlist = EnvList::Inst();
2634-
envlist->popTraceId(trace_id);
2635-
args.GetReturnValue().Set(OneByteString(args.GetIsolate(), trace_id.c_str()));
2636-
}
2637-
2638-
26392694
static void heapprofile_js_cb(SharedEnvInst envinst_sp,
26402695
int status,
26412696
std::string profile,
@@ -2918,6 +2973,10 @@ v8::CFunction BindingData::fast_push_span_data_uint64_(
29182973
v8::CFunction::Make(FastPushSpanDataUint64));
29192974
v8::CFunction BindingData::fast_push_span_data_string_(
29202975
v8::CFunction::Make(FastPushSpanDataString));
2976+
v8::CFunction BindingData::fast_get_span_id_(
2977+
v8::CFunction::Make(FastGetSpanId));
2978+
v8::CFunction BindingData::fast_get_trace_id_(
2979+
v8::CFunction::Make(FastGetTraceId));
29212980

29222981

29232982
void BindingData::Initialize(Local<Object> target,
@@ -2962,6 +3021,16 @@ void BindingData::Initialize(Local<Object> target,
29623021
"pushSpanDataString",
29633022
SlowPushSpanDataString,
29643023
&fast_push_span_data_string_);
3024+
SetFastMethod(context,
3025+
target,
3026+
"getSpanId",
3027+
SlowGetSpanId,
3028+
&fast_get_span_id_);
3029+
SetFastMethod(context,
3030+
target,
3031+
"getTraceId",
3032+
SlowGetTraceId,
3033+
&fast_get_trace_id_);
29653034

29663035
SetMethod(context, target, "agentId", AgentId);
29673036
SetMethod(context, target, "writeLog", WriteLog);
@@ -2991,8 +3060,6 @@ void BindingData::Initialize(Local<Object> target,
29913060
SetMethod(context, target, "setThreadName", setThreadName);
29923061
SetMethod(context, target, "setToggleTracingFn", SetToggleTracingFn);
29933062
SetMethod(context, target, "setTrackPromisesFn", SetTrackPromisesFn);
2994-
SetMethod(context, target, "getSpanId", GetSpanId);
2995-
SetMethod(context, target, "getTraceId", GetTraceId);
29963063
SetMethod(context, target, "heapProfile", HeapProfile);
29973064
SetMethod(context, target, "heapProfileEnd", HeapProfileEnd);
29983065
SetMethod(context, target, "heapSampling", HeapSampling);
@@ -3098,6 +3165,14 @@ void BindingData::RegisterExternalReferences(
30983165
registry->Register(FastPushSpanDataString);
30993166
registry->Register(fast_push_span_data_string_.GetTypeInfo());
31003167

3168+
registry->Register(SlowGetSpanId);
3169+
registry->Register(FastGetSpanId);
3170+
registry->Register(fast_get_span_id_.GetTypeInfo());
3171+
3172+
registry->Register(SlowGetTraceId);
3173+
registry->Register(FastGetTraceId);
3174+
registry->Register(fast_get_trace_id_.GetTypeInfo());
3175+
31013176
registry->Register(AgentId);
31023177
registry->Register(WriteLog);
31033178
registry->Register(GetEnvMetrics);
@@ -3123,8 +3198,6 @@ void BindingData::RegisterExternalReferences(
31233198
registry->Register(setThreadName);
31243199
registry->Register(SetToggleTracingFn);
31253200
registry->Register(SetTrackPromisesFn);
3126-
registry->Register(GetSpanId);
3127-
registry->Register(GetTraceId);
31283201
registry->Register(HeapProfile);
31293202
registry->Register(HeapProfileEnd);
31303203
registry->Register(HeapSampling);

src/nsolid/nsolid_api.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -567,9 +567,11 @@ class EnvList {
567567

568568
void WriteLogLine(SharedEnvInst, LogWriteInfo);
569569

570-
void popSpanId(std::string&);
571-
572-
void popTraceId(std::string&);
570+
// Updated to use raw binary data instead of strings
571+
// NOLINTNEXTLINE(runtime/references)
572+
void popSpanId(std::array<uint8_t, 8>& span_id);
573+
// NOLINTNEXTLINE(runtime/references)
574+
void popTraceId(std::array<uint8_t, 16>& trace_id);
573575

574576
void UpdateHasMetricsStreamHooks(bool has_metrics);
575577

@@ -712,8 +714,9 @@ class EnvList {
712714
TSList<MetricsStreamHookStor> metrics_stream_hook_list_;
713715

714716
nsuv::ns_async fill_tracing_ids_msg_;
715-
TSQueue<std::string> span_id_q_;
716-
TSQueue<std::string> trace_id_q_;
717+
// Use arrays of bytes instead of hex strings to avoid conversions
718+
TSQueue<std::array<uint8_t, 8>> span_id_q_;
719+
TSQueue<std::array<uint8_t, 16>> trace_id_q_;
717720
tracing::TracerImpl tracer_;
718721
DispatchQueue<tracing::SpanItem> span_item_q_;
719722

src/nsolid/nsolid_bindings.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ class BindingData : public SnapshotableObject {
7070
uint32_t type,
7171
const std::string& val);
7272

73+
// Fast API versions for GetSpanId and GetTraceId
74+
static void SlowGetSpanId(const v8::FunctionCallbackInfo<v8::Value>& args);
75+
static void SlowGetTraceId(const v8::FunctionCallbackInfo<v8::Value>& args);
76+
static void FastGetSpanId(v8::Local<v8::Value> receiver,
77+
const v8::FastApiTypedArray<uint8_t>& output);
78+
static void FastGetTraceId(v8::Local<v8::Value> receiver,
79+
const v8::FastApiTypedArray<uint8_t>& output);
80+
7381
static void Initialize(v8::Local<v8::Object> target,
7482
v8::Local<v8::Value> unused,
7583
v8::Local<v8::Context> context,
@@ -84,6 +92,8 @@ class BindingData : public SnapshotableObject {
8492
static v8::CFunction fast_push_span_data_double_;
8593
static v8::CFunction fast_push_span_data_uint64_;
8694
static v8::CFunction fast_push_span_data_string_;
95+
static v8::CFunction fast_get_span_id_;
96+
static v8::CFunction fast_get_trace_id_;
8797
};
8898

8999
} // namespace nsolid

0 commit comments

Comments
 (0)