Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: expose node.http trace flag by array #48142

Closed
wants to merge 2 commits into from
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
11 changes: 7 additions & 4 deletions lib/internal/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ const {
} = primordials;

const { setUnrefTimeout } = require('internal/timers');
const { trace, isTraceCategoryEnabled } = internalBinding('trace_events');
// The trace variable must not be destructured
// because it might break node snapshot serialization
// ref: https://github.com/nodejs/node/pull/48142#discussion_r1204128367
const trace_events = internalBinding('trace_events');
const {
CHAR_LOWERCASE_B,
CHAR_LOWERCASE_E,
Expand Down Expand Up @@ -38,17 +41,17 @@ function getNextTraceEventId() {
}

function isTraceHTTPEnabled() {
return isTraceCategoryEnabled('node.http');
return trace_events.tracingCategories[0] > 0;
}

const traceEventCategory = 'node,node.http';

function traceBegin(...args) {
trace(CHAR_LOWERCASE_B, traceEventCategory, ...args);
trace_events.trace(CHAR_LOWERCASE_B, traceEventCategory, ...args);
}

function traceEnd(...args) {
trace(CHAR_LOWERCASE_E, traceEventCategory, ...args);
trace_events.trace(CHAR_LOWERCASE_E, traceEventCategory, ...args);
}

module.exports = {
Expand Down
3 changes: 2 additions & 1 deletion src/base_object_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ namespace node {
V(blob_binding_data, BlobBindingData) \
V(process_binding_data, process::BindingData) \
V(timers_binding_data, timers::BindingData) \
V(url_binding_data, url::BindingData)
V(url_binding_data, url::BindingData) \
V(trace_events_binding_data, trace_events::BindingData)

#define UNSERIALIZABLE_BINDING_TYPES(V) \
V(http2_binding_data, http2::BindingData) \
Expand Down
1 change: 1 addition & 0 deletions src/node_snapshotable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "node_metadata.h"
#include "node_process.h"
#include "node_snapshot_builder.h"
#include "node_trace_events.h"
#include "node_url.h"
#include "node_util.h"
#include "node_v8.h"
Expand Down
75 changes: 73 additions & 2 deletions src/node_trace_events.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "node_trace_events.h"
#include "base_object-inl.h"
#include "env-inl.h"
#include "memory_tracker-inl.h"
Expand All @@ -20,11 +21,13 @@ using v8::Context;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::NewStringType;
using v8::Object;
using v8::String;
using v8::Uint8Array;
using v8::Value;

class NodeCategorySet : public BaseObject {
Expand Down Expand Up @@ -165,9 +168,77 @@ void NodeCategorySet::RegisterExternalReferences(
registry->Register(NodeCategorySet::Disable);
}

namespace trace_events {

BindingData::BindingData(Realm* realm, v8::Local<v8::Object> object)
: SnapshotableObject(realm, object, type_int) {
// Get the pointer of the memory for the flag that
// store if trace is enabled for http the pointer will
// always be the same and if the category does not exist
// it creates:
// https://github.com/nodejs/node/blob/6bbf2a57fcf33266c5859497f8cc32e1389a358a/deps/v8/src/libplatform/tracing/tracing-controller.cc#L322-L342
auto p = const_cast<uint8_t*>(
TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("node.http"));

// NO_OP deleter
// the idea of this chunk of code is to construct
auto nop = [](void*, size_t, void*) {};
auto bs = v8::ArrayBuffer::NewBackingStore(p, 1, nop, nullptr);
auto ab = v8::ArrayBuffer::New(realm->isolate(), std::move(bs));
v8::Local<Uint8Array> u8 = v8::Uint8Array::New(ab, 0, 1);

object
->Set(realm->context(),
FIXED_ONE_BYTE_STRING(realm->isolate(), "tracingCategories"),
u8)
.Check();
}

bool BindingData::PrepareForSerialization(v8::Local<v8::Context> context,
v8::SnapshotCreator* creator) {
return true;
}

InternalFieldInfoBase* BindingData::Serialize(int index) {
DCHECK_EQ(index, BaseObject::kEmbedderType);
InternalFieldInfo* info =
InternalFieldInfoBase::New<InternalFieldInfo>(type());
return info;
}

void BindingData::Deserialize(v8::Local<v8::Context> context,
v8::Local<v8::Object> holder,
int index,
InternalFieldInfoBase* info) {
DCHECK_EQ(index, BaseObject::kEmbedderType);
v8::HandleScope scope(context->GetIsolate());
Realm* realm = Realm::GetCurrent(context);
BindingData* binding = realm->AddBindingData<BindingData>(context, holder);
CHECK_NOT_NULL(binding);
}

void BindingData::CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Realm* realm = Realm::GetCurrent(context);
realm->AddBindingData<BindingData>(context, target);
}

static void CreatePerContextProperties(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
BindingData::CreatePerContextProperties(target, unused, context, priv);

NodeCategorySet::Initialize(target, unused, context, priv);
}

} // namespace trace_events

} // namespace node

NODE_BINDING_CONTEXT_AWARE_INTERNAL(trace_events,
node::NodeCategorySet::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(
trace_events, node::trace_events::CreatePerContextProperties)
NODE_BINDING_EXTERNAL_REFERENCE(
trace_events, node::NodeCategorySet::RegisterExternalReferences)
41 changes: 41 additions & 0 deletions src/node_trace_events.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef SRC_NODE_TRACE_EVENTS_H_
#define SRC_NODE_TRACE_EVENTS_H_

#include <cinttypes>
#include "aliased_buffer.h"
#include "node.h"
#include "node_snapshotable.h"
#include "util.h"
#include "v8-fast-api-calls.h"
#include "v8.h"

#include <string>

namespace node {
class ExternalReferenceRegistry;

namespace trace_events {

class BindingData : public SnapshotableObject {
public:
BindingData(Realm* realm, v8::Local<v8::Object> obj);

using InternalFieldInfo = InternalFieldInfoBase;

SERIALIZABLE_OBJECT_METHODS()
SET_BINDING_ID(trace_events_binding_data)
SET_NO_MEMORY_INFO()
SET_SELF_SIZE(BindingData)
SET_MEMORY_INFO_NAME(BindingData)

static void CreatePerContextProperties(v8::Local<v8::Object> target,
v8::Local<v8::Value> unused,
v8::Local<v8::Context> context,
void* priv);
};

} // namespace trace_events

} // namespace node

#endif // SRC_NODE_TRACE_EVENTS_H_