Skip to content

Commit 580c207

Browse files
committed
src: add fast api call to get spanId and traceId
PR-URL: #284 Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent 6ea71c8 commit 580c207

5 files changed

Lines changed: 145 additions & 42 deletions

File tree

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
@@ -41,6 +41,9 @@ using CFunctionCallbackWithStrings =
4141
bool (*)(v8::Local<v8::Value>,
4242
const v8::FastOneByteString& input,
4343
const v8::FastOneByteString& base);
44+
using CFunctionCallbackWithOneUint8Array =
45+
void (*)(v8::Local<v8::Value>,
46+
const v8::FastApiTypedArray<uint8_t>&);
4447
using CFunctionCallbackWithTwoUint8Arrays =
4548
int32_t (*)(v8::Local<v8::Value>,
4649
const v8::FastApiTypedArray<uint8_t>&,
@@ -126,6 +129,7 @@ class ExternalReferenceRegistry {
126129
V(CFunctionCallbackWithBool) \
127130
V(CFunctionCallbackWithString) \
128131
V(CFunctionCallbackWithStrings) \
132+
V(CFunctionCallbackWithOneUint8Array) \
129133
V(CFunctionCallbackWithTwoUint8Arrays) \
130134
V(CFunctionCallbackWithTwoUint8ArraysFallback) \
131135
V(CFunctionCallbackWithUint8ArrayUint32Int64Bool) \

src/nsolid/nsolid_api.cc

Lines changed: 107 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ using v8::String;
7070
using v8::Symbol;
7171
using v8::Uint32;
7272
using v8::Uint32Array;
73+
using v8::Uint8Array;
7374
using v8::Value;
7475
using v8::WeakCallbackInfo;
7576
using v8::WeakCallbackType;
@@ -1824,14 +1825,12 @@ void EnvList::q_cb_timeout_cb_(nsuv::ns_timer* handle, QCbTimeoutStor* ptr) {
18241825
}
18251826

18261827

1827-
void EnvList::popSpanId(std::string& span_id) {
1828+
void EnvList::popSpanId(std::array<uint8_t, 8>& span_id) {
18281829
int er;
18291830
size_t s;
18301831
if (!span_id_q_.dequeue(span_id, s)) {
18311832
// Generate the buffer synchronously
1832-
unsigned char buf[8];
1833-
utils::generate_random_buf(buf, sizeof(buf));
1834-
span_id = utils::buffer_to_hex(buf, sizeof(buf));
1833+
utils::generate_random_buf(span_id.data(), span_id.size());
18351834
// Notify the nsolid thread to fill the q
18361835
er = fill_tracing_ids_msg_.send();
18371836
CHECK_EQ(er, 0);
@@ -1846,14 +1845,12 @@ void EnvList::popSpanId(std::string& span_id) {
18461845
}
18471846

18481847

1849-
void EnvList::popTraceId(std::string& trace_id) {
1848+
void EnvList::popTraceId(std::array<uint8_t, 16>& trace_id) {
18501849
int er;
18511850
size_t s;
18521851
if (!trace_id_q_.dequeue(trace_id, s)) {
18531852
// Generate the buffer synchronously
1854-
unsigned char buf[16];
1855-
utils::generate_random_buf(buf, sizeof(buf));
1856-
trace_id = utils::buffer_to_hex(buf, sizeof(buf));
1853+
utils::generate_random_buf(trace_id.data(), trace_id.size());
18571854
// Notify the nsolid thread to fill the q
18581855
er = fill_tracing_ids_msg_.send();
18591856
CHECK_EQ(er, 0);
@@ -1869,19 +1866,19 @@ void EnvList::popTraceId(std::string& trace_id) {
18691866

18701867

18711868
void EnvList::fill_span_id_q() {
1872-
unsigned char buf[SPAN_ID_Q_REFILL_ITEMS*8];
1873-
utils::generate_random_buf(buf, sizeof(buf));
18741869
for (unsigned int i = 0; i < SPAN_ID_Q_REFILL_ITEMS; ++i) {
1875-
span_id_q_.enqueue(utils::buffer_to_hex(buf + i*8, 8));
1870+
std::array<uint8_t, 8> span_id;
1871+
utils::generate_random_buf(span_id.data(), span_id.size());
1872+
span_id_q_.enqueue(span_id);
18761873
}
18771874
}
18781875

18791876

18801877
void EnvList::fill_trace_id_q() {
1881-
unsigned char buf[TRACE_ID_Q_REFILL_ITEMS*16];
1882-
utils::generate_random_buf(buf, sizeof(buf));
18831878
for (unsigned int i = 0; i < TRACE_ID_Q_REFILL_ITEMS; ++i) {
1884-
trace_id_q_.enqueue(utils::buffer_to_hex(buf + i*16, 16));
1879+
std::array<uint8_t, 16> trace_id;
1880+
utils::generate_random_buf(trace_id.data(), trace_id.size());
1881+
trace_id_q_.enqueue(trace_id);
18851882
}
18861883
}
18871884

@@ -2455,6 +2452,80 @@ void BindingData::PushSpanDataStringImpl3(BindingData* data,
24552452
}
24562453

24572454

2455+
void BindingData::SlowGetSpanId(const FunctionCallbackInfo<Value>& args) {
2456+
CHECK(args[0]->IsUint8Array());
2457+
Local<Uint8Array> output = args[0].As<Uint8Array>();
2458+
2459+
DCHECK_EQ(output->Length(), 8);
2460+
2461+
std::array<uint8_t, 8> span_id;
2462+
EnvList* envlist = EnvList::Inst();
2463+
envlist->popSpanId(span_id);
2464+
2465+
// Copy binary data to the TypedArray
2466+
uint8_t* buffer =
2467+
static_cast<uint8_t*>(output->Buffer()->Data()) + output->ByteOffset();
2468+
for (size_t i = 0; i < span_id.size(); i++) {
2469+
buffer[i] = span_id[i];
2470+
}
2471+
}
2472+
2473+
2474+
void BindingData::FastGetSpanId(v8::Local<v8::Value> receiver,
2475+
const v8::FastApiTypedArray<uint8_t>& output) {
2476+
std::array<uint8_t, 8> span_id;
2477+
EnvList* envlist = EnvList::Inst();
2478+
envlist->popSpanId(span_id);
2479+
2480+
DCHECK_EQ(output.length(), span_id.size());
2481+
2482+
uint8_t* dst_data;
2483+
CHECK(output.getStorageIfAligned(&dst_data));
2484+
2485+
// Copy binary data directly to the output buffer
2486+
for (size_t i = 0; i < span_id.size(); i++) {
2487+
dst_data[i] = span_id[i];
2488+
}
2489+
}
2490+
2491+
2492+
void BindingData::SlowGetTraceId(const FunctionCallbackInfo<Value>& args) {
2493+
CHECK(args[0]->IsUint8Array());
2494+
Local<Uint8Array> output = args[0].As<Uint8Array>();
2495+
2496+
DCHECK_EQ(output->Length(), 16);
2497+
2498+
std::array<uint8_t, 16> trace_id;
2499+
EnvList* envlist = EnvList::Inst();
2500+
envlist->popTraceId(trace_id);
2501+
2502+
// Copy binary data to the TypedArray
2503+
uint8_t* buffer =
2504+
static_cast<uint8_t*>(output->Buffer()->Data()) + output->ByteOffset();
2505+
for (size_t i = 0; i < trace_id.size(); i++) {
2506+
buffer[i] = trace_id[i];
2507+
}
2508+
}
2509+
2510+
2511+
void BindingData::FastGetTraceId(v8::Local<v8::Value> receiver,
2512+
const v8::FastApiTypedArray<uint8_t>& output) {
2513+
std::array<uint8_t, 16> trace_id;
2514+
EnvList* envlist = EnvList::Inst();
2515+
envlist->popTraceId(trace_id);
2516+
2517+
DCHECK_EQ(output.length(), trace_id.size());
2518+
2519+
uint8_t* dst_data;
2520+
CHECK(output.getStorageIfAligned(&dst_data));
2521+
2522+
// Copy binary data directly to the output buffer
2523+
for (size_t i = 0; i < trace_id.size(); i++) {
2524+
dst_data[i] = trace_id[i];
2525+
}
2526+
}
2527+
2528+
24582529
static void GetEnvMetrics(const FunctionCallbackInfo<Value>& args) {
24592530
Isolate* isolate = args.GetIsolate();
24602531
EnvInst* envinst = EnvInst::GetEnvLocalInst(isolate);
@@ -2805,22 +2876,6 @@ static void SetTrackPromisesFn(const FunctionCallbackInfo<Value>& args) {
28052876
}
28062877

28072878

2808-
static void GetSpanId(const FunctionCallbackInfo<Value>& args) {
2809-
std::string span_id;
2810-
EnvList* envlist = EnvList::Inst();
2811-
envlist->popSpanId(span_id);
2812-
args.GetReturnValue().Set(OneByteString(args.GetIsolate(), span_id.c_str()));
2813-
}
2814-
2815-
2816-
static void GetTraceId(const FunctionCallbackInfo<Value>& args) {
2817-
std::string trace_id;
2818-
EnvList* envlist = EnvList::Inst();
2819-
envlist->popTraceId(trace_id);
2820-
args.GetReturnValue().Set(OneByteString(args.GetIsolate(), trace_id.c_str()));
2821-
}
2822-
2823-
28242879
static void heapprofile_js_cb(SharedEnvInst envinst_sp,
28252880
int status,
28262881
std::string profile,
@@ -3105,6 +3160,10 @@ v8::CFunction BindingData::fast_push_span_data_string_(
31053160
v8::CFunction::Make(FastPushSpanDataString));
31063161
v8::CFunction BindingData::fast_push_span_data_string3_(
31073162
v8::CFunction::Make(FastPushSpanDataString3));
3163+
v8::CFunction BindingData::fast_get_span_id_(
3164+
v8::CFunction::Make(FastGetSpanId));
3165+
v8::CFunction BindingData::fast_get_trace_id_(
3166+
v8::CFunction::Make(FastGetTraceId));
31083167

31093168

31103169
void BindingData::Initialize(Local<Object> target,
@@ -3154,6 +3213,16 @@ void BindingData::Initialize(Local<Object> target,
31543213
"pushSpanDataString3",
31553214
SlowPushSpanDataString3,
31563215
&fast_push_span_data_string3_);
3216+
SetFastMethod(context,
3217+
target,
3218+
"getSpanId",
3219+
SlowGetSpanId,
3220+
&fast_get_span_id_);
3221+
SetFastMethod(context,
3222+
target,
3223+
"getTraceId",
3224+
SlowGetTraceId,
3225+
&fast_get_trace_id_);
31573226

31583227
SetMethod(context, target, "agentId", AgentId);
31593228
SetMethod(context, target, "writeLog", WriteLog);
@@ -3184,8 +3253,6 @@ void BindingData::Initialize(Local<Object> target,
31843253
SetMethod(context, target, "setThreadName", setThreadName);
31853254
SetMethod(context, target, "setToggleTracingFn", SetToggleTracingFn);
31863255
SetMethod(context, target, "setTrackPromisesFn", SetTrackPromisesFn);
3187-
SetMethod(context, target, "getSpanId", GetSpanId);
3188-
SetMethod(context, target, "getTraceId", GetTraceId);
31893256
SetMethod(context, target, "heapProfile", HeapProfile);
31903257
SetMethod(context, target, "heapProfileEnd", HeapProfileEnd);
31913258
SetMethod(context, target, "heapSampling", HeapSampling);
@@ -3295,6 +3362,14 @@ void BindingData::RegisterExternalReferences(
32953362
registry->Register(FastPushSpanDataString3);
32963363
registry->Register(fast_push_span_data_string3_.GetTypeInfo());
32973364

3365+
registry->Register(SlowGetSpanId);
3366+
registry->Register(FastGetSpanId);
3367+
registry->Register(fast_get_span_id_.GetTypeInfo());
3368+
3369+
registry->Register(SlowGetTraceId);
3370+
registry->Register(FastGetTraceId);
3371+
registry->Register(fast_get_trace_id_.GetTypeInfo());
3372+
32983373
registry->Register(AgentId);
32993374
registry->Register(WriteLog);
33003375
registry->Register(GetEnvMetrics);
@@ -3321,8 +3396,6 @@ void BindingData::RegisterExternalReferences(
33213396
registry->Register(setThreadName);
33223397
registry->Register(SetToggleTracingFn);
33233398
registry->Register(SetTrackPromisesFn);
3324-
registry->Register(GetSpanId);
3325-
registry->Register(GetTraceId);
33263399
registry->Register(HeapProfile);
33273400
registry->Register(HeapProfileEnd);
33283401
registry->Register(HeapSampling);

src/nsolid/nsolid_api.h

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

570570
void WriteLogLine(SharedEnvInst, LogWriteInfo);
571571

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

576578
void UpdateHasMetricsStreamHooks(bool has_metrics);
577579

@@ -721,8 +723,9 @@ class EnvList {
721723
TSList<MetricsStreamHookStor> metrics_stream_hook_list_;
722724

723725
nsuv::ns_async fill_tracing_ids_msg_;
724-
TSQueue<std::string> span_id_q_;
725-
TSQueue<std::string> trace_id_q_;
726+
// Use arrays of bytes instead of hex strings to avoid conversions
727+
TSQueue<std::array<uint8_t, 8>> span_id_q_;
728+
TSQueue<std::array<uint8_t, 16>> trace_id_q_;
726729
tracing::TracerImpl tracer_;
727730
DispatchQueue<tracing::SpanItem> span_item_q_;
728731

src/nsolid/nsolid_bindings.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ class BindingData : public SnapshotableObject {
8484
const std::string& val2,
8585
const std::string& val3);
8686

87+
// Fast API versions for GetSpanId and GetTraceId
88+
static void SlowGetSpanId(const v8::FunctionCallbackInfo<v8::Value>& args);
89+
static void SlowGetTraceId(const v8::FunctionCallbackInfo<v8::Value>& args);
90+
static void FastGetSpanId(v8::Local<v8::Value> receiver,
91+
const v8::FastApiTypedArray<uint8_t>& output);
92+
static void FastGetTraceId(v8::Local<v8::Value> receiver,
93+
const v8::FastApiTypedArray<uint8_t>& output);
94+
8795
static void Initialize(v8::Local<v8::Object> target,
8896
v8::Local<v8::Value> unused,
8997
v8::Local<v8::Context> context,
@@ -99,6 +107,8 @@ class BindingData : public SnapshotableObject {
99107
static v8::CFunction fast_push_span_data_uint64_;
100108
static v8::CFunction fast_push_span_data_string_;
101109
static v8::CFunction fast_push_span_data_string3_;
110+
static v8::CFunction fast_get_span_id_;
111+
static v8::CFunction fast_get_trace_id_;
102112
};
103113

104114
} // namespace nsolid

0 commit comments

Comments
 (0)