Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions lib/_http_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,9 @@ function ClientRequest(input, options, cb) {
api.context.with(api.trace.setSpan(api.context.active(), span), () => {
fn.call(this);
// At this point we know the request is actually being initiated
const u = `${protocol}//${this.getHeader('host')}${this.path}`;
span._pushSpanDataString(kSpanHttpMethod, method);
span._pushSpanDataString(kSpanHttpProtocolVersion, '1.1');
span._pushSpanDataString(kSpanHttpReqUrl, u);
span._pushSpanDataString3(kSpanHttpReqUrl, protocol, this.getHeader('host') || 'localhost', this.path);
this.prependOnceListener('error', requestOnError);
this.once('close', requestOnClose);
}, this);
Expand Down
5 changes: 2 additions & 3 deletions lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -1111,8 +1111,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
let api;
let span;
if (generateSpan(kSpanHttpServer)) {
const protocol = req.connection.encrypted ? 'https' : 'http';
const u = `${protocol}://${req.headers.host || 'localhost'}${req.originalUrl || req.url}`;
const protocol = req.connection.encrypted ? 'https:' : 'http:';
api = getApi();
const tracer = api.trace.getTracer('http');
const ctxt = extractSpanContextFromHttpHeaders(api.ROOT_CONTEXT,
Expand All @@ -1126,7 +1125,7 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
req[nsolid_span_id_s] = span;
span._pushSpanDataString(kSpanHttpMethod, req.method);
span._pushSpanDataString(kSpanHttpProtocolVersion, req.httpVersion);
span._pushSpanDataString(kSpanHttpReqUrl, u);
span._pushSpanDataString3(kSpanHttpReqUrl, protocol, req.headers.host || 'localhost', req.originalUrl || req.url);
}

if (req.upgrade) {
Expand Down
24 changes: 16 additions & 8 deletions lib/internal/otel/trace.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const {
const binding = internalBinding('nsolid_api');
const { getSpanId,
getTraceId,
pushSpanDataString,
nsolid_consts } = binding;

const {
Expand Down Expand Up @@ -38,7 +37,7 @@ class SpanContext {
}
}

function Span(internalId, ids_str, spanContext, startTime, type, kind, links) {
function Span(internalId, parentSpanId, spanContext, startTime, type, kind, links) {
this._spanContext = spanContext;
this.ended = false;
this.internalId = internalId;
Expand All @@ -56,7 +55,11 @@ function Span(internalId, ids_str, spanContext, startTime, type, kind, links) {
this._pushSpanDataUint64(nsolid_consts.kSpanKind, this.kind);
}

this._pushSpanDataString(nsolid_consts.kSpanOtelIds, ids_str);
this._pushSpanDataString(nsolid_consts.kSpanTraceId, spanContext.traceId);
this._pushSpanDataString(nsolid_consts.kSpanSpanId, spanContext.spanId);
if (parentSpanId) {
this._pushSpanDataString(nsolid_consts.kSpanParentSpanId, parentSpanId);
}
}
}

Expand Down Expand Up @@ -210,7 +213,15 @@ Span.prototype._pushSpanDataDouble = function(type, name) {

Span.prototype._pushSpanDataString = function(type, name) {
if (this._isSampled()) {
pushSpanDataString(this.internalId, type, name);
binding.pushSpanDataString(this.internalId, type, name);
}

return this;
};

Span.prototype._pushSpanDataString3 = function(type, val1, val2, val3) {
if (this._isSampled()) {
binding.pushSpanDataString3(this.internalId, type, val1, val2, val3);
}

return this;
Expand Down Expand Up @@ -240,20 +251,17 @@ class Tracer {
}
}

let ids_str;
let traceState;
let traceId;

const spanId = getSpanId();
if (!parentContext) {
// New root span.
traceId = getTraceId();
ids_str = `${traceId}:${spanId}`;
} else {
// New child span.
traceId = parentContext.traceId;
traceState = parentContext.traceState;
ids_str = `${traceId}:${spanId}:${parentContext.spanId}`;
}

const internalId = newInternalSpanId();
Expand All @@ -269,7 +277,7 @@ class Tracer {

const startTime = options.startTime || now();
const span = new Span(internalId,
ids_str,
parentContext?.spanId,
spanContext,
startTime,
options.type || nsolid_consts.kSpanCustom,
Expand Down
15 changes: 15 additions & 0 deletions src/node_external_reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ using CFunctionBufferCopy =
uint32_t source_start,
uint32_t to_copy);

using CFunctionPushSpanDataString =
void (*)(v8::Local<v8::Object> receiver,
uint32_t trace_id,
uint32_t type,
const v8::FastOneByteString& val);
using CFunctionPushSpanDataString3 =
void (*)(v8::Local<v8::Object> receiver,
uint32_t trace_id,
uint32_t type,
const v8::FastOneByteString& val1,
const v8::FastOneByteString& val2,
const v8::FastOneByteString& val3);

// This class manages the external references from the V8 heap
// to the C++ addresses in Node.js.
class ExternalReferenceRegistry {
Expand Down Expand Up @@ -117,6 +130,8 @@ class ExternalReferenceRegistry {
V(CFunctionWithBool) \
V(CFunctionBufferCopy) \
V(CFunctionWriteString) \
V(CFunctionPushSpanDataString) \
V(CFunctionPushSpanDataString3) \
V(const v8::CFunctionInfo*) \
V(v8::FunctionCallback) \
V(v8::AccessorNameGetterCallback) \
Expand Down
126 changes: 103 additions & 23 deletions src/nsolid/nsolid_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ using nsuv::ns_timer;

using tracing::Span;
using tracing::SpanItem;
using tracing::SpanPropBase;

using v8::ArrayBuffer;
using v8::BackingStore;
using v8::Context;
using v8::FastOneByteString;
using v8::Float64Array;
using v8::Function;
using v8::FunctionCallbackInfo;
Expand Down Expand Up @@ -2319,34 +2319,94 @@ void BindingData::PushSpanDataUint64Impl(BindingData* data,
SpanItem{ trace_id, envinst->thread_id(), std::move(prop) });
}


static void PushSpanDataString(const FunctionCallbackInfo<Value>& args) {
void BindingData::SlowPushSpanDataString(
const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
EnvInst* envinst = EnvInst::GetEnvLocalInst(isolate);
DCHECK_NE(envinst, nullptr);
DCHECK_EQ(args.Length(), 3);
DCHECK(args[0]->IsUint32());
DCHECK(args[1]->IsUint32());
DCHECK(args[2]->IsString());
uint32_t trace_id = args[0].As<Uint32>()->Value();
Span::PropType prop_type =
static_cast<Span::PropType>(args[1].As<Uint32>()->Value());
std::unique_ptr<SpanPropBase> prop;
uint32_t type = args[1].As<Uint32>()->Value();
Local<String> value_s = args[2].As<String>();
if (prop_type == Span::kSpanOtelIds && value_s->IsOneByte()) {
char ids[67];
int len = value_s->WriteOneByte(isolate, reinterpret_cast<uint8_t*>(ids));
ids[len] = '\0';
prop = Span::createSpanProp<std::string>(prop_type, ids);
} else {
String::Utf8Value value_str(isolate, value_s);
prop = Span::createSpanProp<std::string>(prop_type, *value_str);
}
BindingData* data = FromJSObject<BindingData>(args.This());
const std::string val = *String::Utf8Value(isolate, value_s);
PushSpanDataStringImpl(data, trace_id, type, val);
}


SpanItem item = { trace_id,
envinst->thread_id(),
std::move(prop) };
EnvList::Inst()->GetTracer()->pushSpanData(std::move(item));
void BindingData::FastPushSpanDataString(v8::Local<v8::Object> receiver,
uint32_t trace_id,
uint32_t type,
const FastOneByteString& val) {
PushSpanDataStringImpl(FromJSObject<BindingData>(receiver),
trace_id,
type,
std::string(val.data, val.length));
}


void BindingData::PushSpanDataStringImpl(BindingData* data,
uint32_t trace_id,
uint32_t type,
const std::string& val) {
Span::PropType prop_type = static_cast<Span::PropType>(type);
auto prop = Span::createSpanProp<std::string>(prop_type, val);
EnvInst* envinst = data->env()->envinst_.get();
EnvList::Inst()->GetTracer()->pushSpanData(
SpanItem{ trace_id, envinst->thread_id(), std::move(prop) });
}


void BindingData::SlowPushSpanDataString3(
const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
DCHECK_EQ(args.Length(), 5);
DCHECK(args[0]->IsUint32());
DCHECK(args[1]->IsUint32());
DCHECK(args[2]->IsString());
DCHECK(args[3]->IsString());
DCHECK(args[4]->IsString());
uint32_t trace_id = args[0].As<Uint32>()->Value();
uint32_t type = args[1].As<Uint32>()->Value();
Local<String> value_s1 = args[2].As<String>();
Local<String> value_s2 = args[3].As<String>();
Local<String> value_s3 = args[4].As<String>();
BindingData* data = FromJSObject<BindingData>(args.This());
const std::string val1 = *String::Utf8Value(isolate, value_s1);
const std::string val2 = *String::Utf8Value(isolate, value_s2);
const std::string val3 = *String::Utf8Value(isolate, value_s3);
PushSpanDataStringImpl3(data, trace_id, type, val1, val2, val3);
}


void BindingData::FastPushSpanDataString3(v8::Local<v8::Object> receiver,
uint32_t trace_id,
uint32_t type,
const FastOneByteString& val1,
const FastOneByteString& val2,
const FastOneByteString& val3) {
PushSpanDataStringImpl3(FromJSObject<BindingData>(receiver),
trace_id,
type,
std::string(val1.data, val1.length),
std::string(val2.data, val2.length),
std::string(val3.data, val3.length));
}

void BindingData::PushSpanDataStringImpl3(BindingData* data,
uint32_t trace_id,
uint32_t type,
const std::string& val1,
const std::string& val2,
const std::string& val3) {
Span::PropType prop_type = static_cast<Span::PropType>(type);
ASSERT_EQ(prop_type, Span::kSpanHttpReqUrl);
auto prop =
Span::createSpanProp<std::string>(prop_type, val1 + "//" + val2 + val3);
EnvInst* envinst = data->env()->envinst_.get();
EnvList::Inst()->GetTracer()->pushSpanData(
SpanItem{ trace_id, envinst->thread_id(), std::move(prop) });
}


Expand Down Expand Up @@ -2900,6 +2960,10 @@ v8::CFunction BindingData::fast_push_span_data_double_(
v8::CFunction::Make(FastPushSpanDataDouble));
v8::CFunction BindingData::fast_push_span_data_uint64_(
v8::CFunction::Make(FastPushSpanDataUint64));
v8::CFunction BindingData::fast_push_span_data_string_(
v8::CFunction::Make(FastPushSpanDataString));
v8::CFunction BindingData::fast_push_span_data_string3_(
v8::CFunction::Make(FastPushSpanDataString3));


void BindingData::Initialize(Local<Object> target,
Expand Down Expand Up @@ -2939,10 +3003,19 @@ void BindingData::Initialize(Local<Object> target,
"pushSpanDataUint64",
SlowPushSpanDataUint64,
&fast_push_span_data_uint64_);
SetFastMethod(context,
target,
"pushSpanDataString",
SlowPushSpanDataString,
&fast_push_span_data_string_);
SetFastMethod(context,
target,
"pushSpanDataString3",
SlowPushSpanDataString3,
&fast_push_span_data_string3_);

SetMethod(context, target, "agentId", AgentId);
SetMethod(context, target, "writeLog", WriteLog);
SetMethod(context, target, "pushSpanDataString", PushSpanDataString);
SetMethod(context, target, "getEnvMetrics", GetEnvMetrics);
SetMethod(context, target, "getProcessMetrics", GetProcessMetrics);
SetMethod(context, target, "getProcessInfo", GetProcessInfo);
Expand Down Expand Up @@ -3072,9 +3145,16 @@ void BindingData::RegisterExternalReferences(
registry->Register(FastPushSpanDataUint64);
registry->Register(fast_push_span_data_uint64_.GetTypeInfo());

registry->Register(SlowPushSpanDataString);
registry->Register(FastPushSpanDataString);
registry->Register(fast_push_span_data_string_.GetTypeInfo());

registry->Register(SlowPushSpanDataString3);
registry->Register(FastPushSpanDataString3);
registry->Register(fast_push_span_data_string3_.GetTypeInfo());

registry->Register(AgentId);
registry->Register(WriteLog);
registry->Register(PushSpanDataString);
registry->Register(GetEnvMetrics);
registry->Register(GetProcessMetrics);
registry->Register(GetProcessInfo);
Expand Down
28 changes: 28 additions & 0 deletions src/nsolid/nsolid_bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include "node_snapshotable.h"
#include "v8-fast-api-calls.h"

namespace node {
namespace nsolid {
Expand Down Expand Up @@ -58,6 +59,31 @@ class BindingData : public SnapshotableObject {
uint32_t type,
uint64_t val);

static void SlowPushSpanDataString(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void FastPushSpanDataString(v8::Local<v8::Object> receiver,
uint32_t trace_id,
uint32_t type,
const v8::FastOneByteString& val);
static void PushSpanDataStringImpl(BindingData* data,
uint32_t trace_id,
uint32_t type,
const std::string& val);
static void SlowPushSpanDataString3(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void FastPushSpanDataString3(v8::Local<v8::Object> receiver,
uint32_t trace_id,
uint32_t type,
const v8::FastOneByteString& val1,
const v8::FastOneByteString& val2,
const v8::FastOneByteString& val3);
static void PushSpanDataStringImpl3(BindingData* data,
uint32_t trace_id,
uint32_t type,
const std::string& val1,
const std::string& val2,
const std::string& val3);

static void Initialize(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
Expand All @@ -71,6 +97,8 @@ class BindingData : public SnapshotableObject {
static v8::CFunction fast_push_server_bucket_;
static v8::CFunction fast_push_span_data_double_;
static v8::CFunction fast_push_span_data_uint64_;
static v8::CFunction fast_push_span_data_string_;
static v8::CFunction fast_push_span_data_string3_;
};

} // namespace nsolid
Expand Down
21 changes: 12 additions & 9 deletions src/nsolid/nsolid_trace.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,19 @@ void Span::add_prop(const SpanPropBase& prop) {
stor_.start = performance_process_start_timestamp + prop.val<double>();
}
break;
case Span::kSpanOtelIds:
case Span::kSpanTraceId:
{
auto res = utils::split(prop.val<std::string>(), ':', 3);
size_t size = res.size();
DCHECK(size == 2 || size == 3);
stor_.trace_id = res[0];
stor_.span_id = res[1];
if (size == 3) {
stor_.parent_id = res[2];
}
stor_.trace_id = prop.val<std::string>();
}
break;
case Span::kSpanSpanId:
{
stor_.span_id = prop.val<std::string>();
}
break;
case Span::kSpanParentSpanId:
{
stor_.parent_id = prop.val<std::string>();
}
break;
case Span::kSpanEnd:
Expand Down
Loading
Loading