Skip to content

Commit d7edee4

Browse files
jasnelltargos
authored andcommitted
trace_events: add more process metadata
Now that TracedValue has landed, add more detailed process `__metadata` including versions, arch, platform, release detail, and argv/execArgv to the trace event log. PR-URL: #21785 Reviewed-By: Anna Henningsen <[email protected]>
1 parent 6af4f1f commit d7edee4

File tree

2 files changed

+132
-22
lines changed

2 files changed

+132
-22
lines changed

src/node.cc

+96-14
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "node_debug_options.h"
3131
#include "node_perf.h"
3232
#include "node_context_data.h"
33+
#include "tracing/traced_value.h"
3334

3435
#if defined HAVE_PERFCTR
3536
#include "node_counters.h"
@@ -289,11 +290,106 @@ static v8::Isolate* node_isolate;
289290

290291
DebugOptions debug_options;
291292

293+
// Ensures that __metadata trace events are only emitted
294+
// when tracing is enabled.
295+
class NodeTraceStateObserver :
296+
public v8::TracingController::TraceStateObserver {
297+
public:
298+
void OnTraceEnabled() override {
299+
char name_buffer[512];
300+
if (uv_get_process_title(name_buffer, sizeof(name_buffer)) == 0) {
301+
// Only emit the metadata event if the title can be retrieved
302+
// successfully. Ignore it otherwise.
303+
TRACE_EVENT_METADATA1("__metadata", "process_name",
304+
"name", TRACE_STR_COPY(name_buffer));
305+
}
306+
TRACE_EVENT_METADATA1("__metadata", "version",
307+
"node", NODE_VERSION_STRING);
308+
TRACE_EVENT_METADATA1("__metadata", "thread_name",
309+
"name", "JavaScriptMainThread");
310+
311+
auto trace_process = tracing::TracedValue::Create();
312+
trace_process->BeginDictionary("versions");
313+
314+
const char http_parser_version[] =
315+
NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
316+
"."
317+
NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
318+
"."
319+
NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);
320+
321+
const char node_napi_version[] = NODE_STRINGIFY(NAPI_VERSION);
322+
const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
323+
324+
trace_process->SetString("http_parser", http_parser_version);
325+
trace_process->SetString("node", NODE_VERSION_STRING);
326+
trace_process->SetString("v8", V8::GetVersion());
327+
trace_process->SetString("uv", uv_version_string());
328+
trace_process->SetString("zlib", ZLIB_VERSION);
329+
trace_process->SetString("ares", ARES_VERSION_STR);
330+
trace_process->SetString("modules", node_modules_version);
331+
trace_process->SetString("nghttp2", NGHTTP2_VERSION);
332+
trace_process->SetString("napi", node_napi_version);
333+
334+
#if HAVE_OPENSSL
335+
// Stupid code to slice out the version string.
336+
{ // NOLINT(whitespace/braces)
337+
size_t i, j, k;
338+
int c;
339+
for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
340+
c = OPENSSL_VERSION_TEXT[i];
341+
if ('0' <= c && c <= '9') {
342+
for (j = i + 1; j < k; ++j) {
343+
c = OPENSSL_VERSION_TEXT[j];
344+
if (c == ' ')
345+
break;
346+
}
347+
break;
348+
}
349+
}
350+
trace_process->SetString("openssl",
351+
std::string(&OPENSSL_VERSION_TEXT[i], j - i));
352+
}
353+
#endif
354+
trace_process->EndDictionary();
355+
356+
trace_process->SetString("arch", NODE_ARCH);
357+
trace_process->SetString("platform", NODE_PLATFORM);
358+
359+
trace_process->BeginDictionary("release");
360+
trace_process->SetString("name", NODE_RELEASE);
361+
#if NODE_VERSION_IS_LTS
362+
trace_process->SetString("lts", NODE_VERSION_LTS_CODENAME);
363+
#endif
364+
trace_process->EndDictionary();
365+
TRACE_EVENT_METADATA1("__metadata", "node",
366+
"process", std::move(trace_process));
367+
368+
// This only runs the first time tracing is enabled
369+
controller_->RemoveTraceStateObserver(this);
370+
delete this;
371+
}
372+
373+
void OnTraceDisabled() override {
374+
// Do nothing here. This should never be called because the
375+
// observer removes itself when OnTraceEnabled() is called.
376+
UNREACHABLE();
377+
}
378+
379+
explicit NodeTraceStateObserver(v8::TracingController* controller) :
380+
controller_(controller) {}
381+
~NodeTraceStateObserver() override {}
382+
383+
private:
384+
v8::TracingController* controller_;
385+
};
386+
292387
static struct {
293388
#if NODE_USE_V8_PLATFORM
294389
void Initialize(int thread_pool_size) {
295390
tracing_agent_.reset(new tracing::Agent(trace_file_pattern));
296391
auto controller = tracing_agent_->GetTracingController();
392+
controller->AddTraceStateObserver(new NodeTraceStateObserver(controller));
297393
tracing::TraceEventHelper::SetTracingController(controller);
298394
StartTracingAgent();
299395
platform_ = new NodePlatform(thread_pool_size, controller);
@@ -1992,7 +2088,6 @@ void SetupProcessObject(Environment* env,
19922088
READONLY_PROPERTY(versions,
19932089
"http_parser",
19942090
FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
1995-
19962091
// +1 to get rid of the leading 'v'
19972092
READONLY_PROPERTY(versions,
19982093
"node",
@@ -2015,11 +2110,9 @@ void SetupProcessObject(Environment* env,
20152110
versions,
20162111
"modules",
20172112
FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
2018-
20192113
READONLY_PROPERTY(versions,
20202114
"nghttp2",
20212115
FIXED_ONE_BYTE_STRING(env->isolate(), NGHTTP2_VERSION));
2022-
20232116
const char node_napi_version[] = NODE_STRINGIFY(NAPI_VERSION);
20242117
READONLY_PROPERTY(
20252118
versions,
@@ -3550,17 +3643,6 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
35503643
Environment env(isolate_data, context, v8_platform.GetTracingAgent());
35513644
env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
35523645

3553-
char name_buffer[512];
3554-
if (uv_get_process_title(name_buffer, sizeof(name_buffer)) == 0) {
3555-
// Only emit the metadata event if the title can be retrieved successfully.
3556-
// Ignore it otherwise.
3557-
TRACE_EVENT_METADATA1("__metadata", "process_name", "name",
3558-
TRACE_STR_COPY(name_buffer));
3559-
}
3560-
TRACE_EVENT_METADATA1("__metadata", "version", "node", NODE_VERSION_STRING);
3561-
TRACE_EVENT_METADATA1("__metadata", "thread_name", "name",
3562-
"JavaScriptMainThread");
3563-
35643646
const char* path = argc > 1 ? argv[1] : nullptr;
35653647
StartInspector(&env, path, debug_options);
35663648

test/parallel/test-trace-events-metadata.js

+36-8
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,53 @@ const proc = cp.spawn(process.execPath,
2323
proc.once('exit', common.mustCall(() => {
2424
assert(common.fileExists(FILE_NAME));
2525
fs.readFile(FILE_NAME, common.mustCall((err, data) => {
26-
const traces = JSON.parse(data.toString()).traceEvents;
26+
const traces = JSON.parse(data.toString()).traceEvents
27+
.filter((trace) => trace.cat === '__metadata');
2728
assert(traces.length > 0);
2829
assert(traces.some((trace) =>
29-
trace.cat === '__metadata' && trace.name === 'thread_name' &&
30+
trace.name === 'thread_name' &&
3031
trace.args.name === 'JavaScriptMainThread'));
3132
assert(traces.some((trace) =>
32-
trace.cat === '__metadata' && trace.name === 'thread_name' &&
33+
trace.name === 'thread_name' &&
3334
trace.args.name === 'BackgroundTaskRunner'));
3435
assert(traces.some((trace) =>
35-
trace.cat === '__metadata' && trace.name === 'version' &&
36+
trace.name === 'version' &&
3637
trace.args.node === process.versions.node));
38+
39+
assert(traces.some((trace) =>
40+
trace.name === 'node' &&
41+
trace.args.process.versions.http_parser ===
42+
process.versions.http_parser &&
43+
trace.args.process.versions.node ===
44+
process.versions.node &&
45+
trace.args.process.versions.v8 ===
46+
process.versions.v8 &&
47+
trace.args.process.versions.uv ===
48+
process.versions.uv &&
49+
trace.args.process.versions.zlib ===
50+
process.versions.zlib &&
51+
trace.args.process.versions.ares ===
52+
process.versions.ares &&
53+
trace.args.process.versions.modules ===
54+
process.versions.modules &&
55+
trace.args.process.versions.nghttp2 ===
56+
process.versions.nghttp2 &&
57+
trace.args.process.versions.napi ===
58+
process.versions.napi &&
59+
trace.args.process.versions.openssl ===
60+
process.versions.openssl &&
61+
trace.args.process.arch === process.arch &&
62+
trace.args.process.platform === process.platform &&
63+
trace.args.process.release.name === process.release.name &&
64+
(!process.release.lts ||
65+
trace.args.process.release.lts === process.release.lts)));
66+
3767
if (!common.isSunOS) {
3868
// Changing process.title is currently unsupported on SunOS/SmartOS
3969
assert(traces.some((trace) =>
40-
trace.cat === '__metadata' && trace.name === 'process_name' &&
41-
trace.args.name === 'foo'));
70+
trace.name === 'process_name' && trace.args.name === 'foo'));
4271
assert(traces.some((trace) =>
43-
trace.cat === '__metadata' && trace.name === 'process_name' &&
44-
trace.args.name === 'bar'));
72+
trace.name === 'process_name' && trace.args.name === 'bar'));
4573
}
4674
}));
4775
}));

0 commit comments

Comments
 (0)