Skip to content

Commit 49f12cf

Browse files
committed
src: abstract tracing agent for both legacy and perfetto
Signed-off-by: Chengzhong Wu <cwu631@bloomberg.net>
1 parent a1074b8 commit 49f12cf

18 files changed

Lines changed: 601 additions & 526 deletions

node.gyp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@
200200
'src/timers.cc',
201201
'src/timer_wrap.cc',
202202
'src/tracing/agent.cc',
203+
'src/tracing/agent_legacy.cc',
203204
'src/tracing/node_trace_buffer.cc',
204205
'src/tracing/node_trace_writer.cc',
205206
'src/tracing/trace_event.cc',
@@ -338,6 +339,7 @@
338339
'src/tcp_wrap.h',
339340
'src/timers.h',
340341
'src/tracing/agent.h',
342+
'src/tracing/agent_legacy.h',
341343
'src/tracing/node_trace_buffer.h',
342344
'src/tracing/node_trace_writer.h',
343345
'src/tracing/trace_event.h',

src/env.cc

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ using v8::SnapshotCreator;
7171
using v8::StackTrace;
7272
using v8::String;
7373
using v8::Symbol;
74-
using v8::TracingController;
7574
using v8::TryCatch;
7675
using v8::Uint32;
7776
using v8::Undefined;
@@ -894,10 +893,9 @@ Environment::Environment(IsolateData* isolate_data,
894893
inspector_agent_ = std::make_unique<inspector::Agent>(this);
895894
#endif
896895

897-
if (tracing::AgentWriterHandle* writer = GetTracingAgentWriter()) {
896+
if (tracing::Agent* agent = tracing::Agent::GetInstance()) {
898897
trace_state_observer_ = std::make_unique<TrackingTraceStateObserver>(this);
899-
if (TracingController* tracing_controller = writer->GetTracingController())
900-
tracing_controller->AddTraceStateObserver(trace_state_observer_.get());
898+
agent->AddTraceStateObserver(trace_state_observer_.get());
901899
}
902900

903901
destroy_async_id_list_.reserve(512);
@@ -1064,10 +1062,8 @@ Environment::~Environment() {
10641062
principal_realm_.reset();
10651063

10661064
if (trace_state_observer_) {
1067-
tracing::AgentWriterHandle* writer = GetTracingAgentWriter();
1068-
CHECK_NOT_NULL(writer);
1069-
if (TracingController* tracing_controller = writer->GetTracingController())
1070-
tracing_controller->RemoveTraceStateObserver(trace_state_observer_.get());
1065+
if (tracing::Agent* agent = tracing::Agent::GetInstance())
1066+
agent->RemoveTraceStateObserver(trace_state_observer_.get());
10711067
}
10721068

10731069
TRACE_EVENT_NESTABLE_ASYNC_END0(

src/inspector/tracing_agent.cc

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "main_thread_interface.h"
44
#include "node_internals.h"
55
#include "node_v8_platform-inl.h"
6+
#include "tracing/agent_legacy.h"
67
#include "v8.h"
78

89
#include <set>
@@ -162,13 +163,14 @@ DispatchResponse TracingAgent::start(
162163
return DispatchResponse::InvalidRequest(
163164
"At least one category should be enabled");
164165

165-
tracing::AgentWriterHandle* writer = GetTracingAgentWriter();
166-
if (writer != nullptr) {
166+
auto* agent =
167+
static_cast<tracing::LegacyTracingAgent*>(tracing::Agent::GetInstance());
168+
if (agent != nullptr) {
167169
trace_writer_ =
168-
writer->agent()->AddClient(categories_set,
169-
std::make_unique<InspectorTraceWriter>(
170-
frontend_object_id_, main_thread_),
171-
tracing::Agent::kIgnoreDefaultCategories);
170+
agent->AddClient(categories_set,
171+
std::make_unique<InspectorTraceWriter>(
172+
frontend_object_id_, main_thread_),
173+
tracing::LegacyTracingAgent::kIgnoreDefaultCategories);
172174
}
173175
return DispatchResponse::Success();
174176
}

src/node_trace_events.cc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void NodeCategorySet::New(const FunctionCallbackInfo<Value>& args) {
7373
if (!*val) return;
7474
categories.emplace(*val);
7575
}
76-
CHECK_NOT_NULL(GetTracingAgentWriter());
76+
CHECK_NOT_NULL(tracing::Agent::GetInstance());
7777
new NodeCategorySet(env, args.This(), std::move(categories));
7878
}
7979

@@ -85,8 +85,10 @@ void NodeCategorySet::Enable(const FunctionCallbackInfo<Value>& args) {
8585
if (!category_set->enabled_ && !categories.empty()) {
8686
// Starts the Tracing Agent if it wasn't started already (e.g. through
8787
// a command line flag.)
88-
StartTracingAgent();
89-
GetTracingAgentWriter()->Enable(categories);
88+
auto* agent = tracing::Agent::GetInstance();
89+
agent->StartTracing(per_process::cli_options->trace_event_categories);
90+
tracing::AgentWriterHandle* writer = agent->GetDefaultWriterHandle();
91+
writer->Enable(categories);
9092
category_set->enabled_ = true;
9193
}
9294
}
@@ -97,15 +99,17 @@ void NodeCategorySet::Disable(const FunctionCallbackInfo<Value>& args) {
9799
CHECK_NOT_NULL(category_set);
98100
const auto& categories = category_set->GetCategories();
99101
if (category_set->enabled_ && !categories.empty()) {
100-
GetTracingAgentWriter()->Disable(categories);
102+
auto* agent = tracing::Agent::GetInstance();
103+
tracing::AgentWriterHandle* writer = agent->GetDefaultWriterHandle();
104+
writer->Disable(categories);
101105
category_set->enabled_ = false;
102106
}
103107
}
104108

105109
void GetEnabledCategories(const FunctionCallbackInfo<Value>& args) {
106110
Environment* env = Environment::GetCurrent(args);
107111
std::string categories =
108-
GetTracingAgentWriter()->agent()->GetEnabledCategories();
112+
tracing::Agent::GetInstance()->GetEnabledCategories();
109113
Local<Value> ret;
110114
if (!categories.empty() &&
111115
ToV8Value(env->context(), categories, env->isolate()).ToLocal(&ret)) {

src/node_v8_platform-inl.h

Lines changed: 12 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -4,84 +4,30 @@
44
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55

66
#include <memory>
7-
#include <string_view>
87

98
#include "env-inl.h"
109
#include "node.h"
11-
#include "node_metadata.h"
12-
#include "node_platform.h"
1310
#include "node_options.h"
14-
#include "tracing/node_trace_writer.h"
15-
#include "tracing/trace_event.h"
16-
#include "tracing/traced_value.h"
17-
#include "util.h"
11+
#include "node_platform.h"
12+
#include "tracing/agent.h"
1813

1914
namespace node {
2015

21-
// Ensures that __metadata trace events are only emitted
22-
// when tracing is enabled.
23-
class NodeTraceStateObserver
24-
: public v8::TracingController::TraceStateObserver {
25-
public:
26-
inline void OnTraceEnabled() override {
27-
std::string title = GetProcessTitle("");
28-
if (!title.empty()) {
29-
// Only emit the metadata event if the title can be retrieved
30-
// successfully. Ignore it otherwise.
31-
TRACE_EVENT_METADATA1(
32-
"__metadata", "process_name", "name", TRACE_STR_COPY(title.c_str()));
33-
}
34-
TRACE_EVENT_METADATA1("__metadata",
35-
"version",
36-
"node",
37-
per_process::metadata.versions.node.c_str());
38-
TRACE_EVENT_METADATA1(
39-
"__metadata", "thread_name", "name", "JavaScriptMainThread");
40-
41-
tracing::ProcessMeta trace_process;
42-
TRACE_EVENT_METADATA1("__metadata",
43-
"node",
44-
"process",
45-
tracing::CastTracedValue(trace_process));
46-
// This only runs the first time tracing is enabled
47-
controller_->RemoveTraceStateObserver(this);
48-
}
49-
50-
inline void OnTraceDisabled() override {
51-
// Do nothing here. This should never be called because the
52-
// observer removes itself when OnTraceEnabled() is called.
53-
UNREACHABLE();
54-
}
55-
56-
explicit NodeTraceStateObserver(v8::TracingController* controller)
57-
: controller_(controller) {}
58-
~NodeTraceStateObserver() override = default;
59-
60-
private:
61-
v8::TracingController* controller_;
62-
};
63-
6416
struct V8Platform {
6517
bool initialized_ = false;
6618

6719
#if NODE_USE_V8_PLATFORM
6820
inline void Initialize(int thread_pool_size) {
6921
CHECK(!initialized_);
7022
initialized_ = true;
71-
tracing_agent_ = std::make_unique<tracing::Agent>();
72-
node::tracing::TraceEventHelper::SetAgent(tracing_agent_.get());
73-
node::tracing::TracingController* controller =
74-
tracing_agent_->GetTracingController();
75-
trace_state_observer_ =
76-
std::make_unique<NodeTraceStateObserver>(controller);
77-
controller->AddTraceStateObserver(trace_state_observer_.get());
78-
tracing_file_writer_ = tracing_agent_->DefaultHandle();
23+
tracing_agent_ = tracing::Agent::CreateDefault();
7924
// Only start the tracing agent if we enabled any tracing categories.
8025
if (!per_process::cli_options->trace_event_categories.empty()) {
8126
StartTracingAgent();
8227
}
8328
// Tracing must be initialized before platform threads are created.
84-
platform_ = new NodePlatform(thread_pool_size, controller);
29+
platform_ = new NodePlatform(thread_pool_size,
30+
tracing_agent_->GetTracingController());
8531
v8::V8::InitializePlatform(platform_);
8632
}
8733
// Make sure V8Platform don not call into Libuv threadpool,
@@ -90,58 +36,33 @@ struct V8Platform {
9036
if (!initialized_)
9137
return;
9238
initialized_ = false;
93-
node::tracing::TraceEventHelper::SetAgent(nullptr);
9439
StopTracingAgent();
9540
platform_->Shutdown();
9641
delete platform_;
9742
platform_ = nullptr;
9843
// Destroy tracing after the platform (and platform threads) have been
9944
// stopped.
10045
tracing_agent_.reset(nullptr);
101-
// The observer remove itself in OnTraceEnabled
102-
trace_state_observer_.reset(nullptr);
10346
}
10447

10548
inline void DrainVMTasks(v8::Isolate* isolate) {
10649
platform_->DrainTasks(isolate);
10750
}
10851

10952
inline void StartTracingAgent() {
110-
constexpr auto convert_to_set =
111-
[](auto& categories) -> std::set<std::string> {
112-
std::set<std::string> out;
113-
for (const auto& s : categories) {
114-
out.emplace(std::string(s.data(), s.size()));
115-
}
116-
return out;
117-
};
118-
// Attach a new NodeTraceWriter only if this function hasn't been called
119-
// before.
120-
if (tracing_file_writer_.IsDefaultHandle()) {
121-
using std::operator""sv;
122-
auto categories = std::views::split(
123-
per_process::cli_options->trace_event_categories, ","sv);
124-
125-
tracing_file_writer_ = tracing_agent_->AddClient(
126-
convert_to_set(categories),
127-
std::unique_ptr<tracing::AsyncTraceWriter>(
128-
new tracing::NodeTraceWriter(
129-
per_process::cli_options->trace_event_file_pattern)),
130-
tracing::Agent::kUseDefaultCategories);
131-
}
53+
if (!initialized_) return;
54+
tracing_agent_->StartTracing(
55+
per_process::cli_options->trace_event_categories);
13256
}
13357

134-
inline void StopTracingAgent() { tracing_file_writer_.reset(); }
135-
136-
inline tracing::AgentWriterHandle* GetTracingAgentWriter() {
137-
return &tracing_file_writer_;
58+
inline void StopTracingAgent() {
59+
if (!initialized_) return;
60+
tracing_agent_->StopTracing();
13861
}
13962

14063
inline NodePlatform* Platform() { return platform_; }
14164

142-
std::unique_ptr<NodeTraceStateObserver> trace_state_observer_;
143-
std::unique_ptr<tracing::Agent> tracing_agent_;
144-
tracing::AgentWriterHandle tracing_file_writer_;
65+
std::unique_ptr<tracing::Agent, tracing::Agent::Deleter> tracing_agent_;
14566
NodePlatform* platform_;
14667
#else // !NODE_USE_V8_PLATFORM
14768
inline void Initialize(int thread_pool_size) {}
@@ -156,8 +77,6 @@ struct V8Platform {
15677
}
15778
inline void StopTracingAgent() {}
15879

159-
inline tracing::AgentWriterHandle* GetTracingAgentWriter() { return nullptr; }
160-
16180
inline NodePlatform* Platform() { return nullptr; }
16281
#endif // !NODE_USE_V8_PLATFORM
16382
};
@@ -166,14 +85,6 @@ namespace per_process {
16685
extern struct V8Platform v8_platform;
16786
}
16887

169-
inline void StartTracingAgent() {
170-
return per_process::v8_platform.StartTracingAgent();
171-
}
172-
173-
inline tracing::AgentWriterHandle* GetTracingAgentWriter() {
174-
return per_process::v8_platform.GetTracingAgentWriter();
175-
}
176-
17788
inline void DisposePlatform() {
17889
per_process::v8_platform.Dispose();
17990
}

0 commit comments

Comments
 (0)