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: https://github.com/nodejs/node/pull/21785 Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
81bc23fe61
commit
ededb4b510
110
src/node.cc
110
src/node.cc
@ -30,6 +30,7 @@
|
||||
#include "node_debug_options.h"
|
||||
#include "node_perf.h"
|
||||
#include "node_context_data.h"
|
||||
#include "tracing/traced_value.h"
|
||||
|
||||
#if defined HAVE_PERFCTR
|
||||
#include "node_counters.h"
|
||||
@ -289,11 +290,106 @@ static v8::Isolate* node_isolate;
|
||||
|
||||
DebugOptions debug_options;
|
||||
|
||||
// Ensures that __metadata trace events are only emitted
|
||||
// when tracing is enabled.
|
||||
class NodeTraceStateObserver :
|
||||
public v8::TracingController::TraceStateObserver {
|
||||
public:
|
||||
void OnTraceEnabled() override {
|
||||
char name_buffer[512];
|
||||
if (uv_get_process_title(name_buffer, sizeof(name_buffer)) == 0) {
|
||||
// Only emit the metadata event if the title can be retrieved
|
||||
// successfully. Ignore it otherwise.
|
||||
TRACE_EVENT_METADATA1("__metadata", "process_name",
|
||||
"name", TRACE_STR_COPY(name_buffer));
|
||||
}
|
||||
TRACE_EVENT_METADATA1("__metadata", "version",
|
||||
"node", NODE_VERSION_STRING);
|
||||
TRACE_EVENT_METADATA1("__metadata", "thread_name",
|
||||
"name", "JavaScriptMainThread");
|
||||
|
||||
auto trace_process = tracing::TracedValue::Create();
|
||||
trace_process->BeginDictionary("versions");
|
||||
|
||||
const char http_parser_version[] =
|
||||
NODE_STRINGIFY(HTTP_PARSER_VERSION_MAJOR)
|
||||
"."
|
||||
NODE_STRINGIFY(HTTP_PARSER_VERSION_MINOR)
|
||||
"."
|
||||
NODE_STRINGIFY(HTTP_PARSER_VERSION_PATCH);
|
||||
|
||||
const char node_napi_version[] = NODE_STRINGIFY(NAPI_VERSION);
|
||||
const char node_modules_version[] = NODE_STRINGIFY(NODE_MODULE_VERSION);
|
||||
|
||||
trace_process->SetString("http_parser", http_parser_version);
|
||||
trace_process->SetString("node", NODE_VERSION_STRING);
|
||||
trace_process->SetString("v8", V8::GetVersion());
|
||||
trace_process->SetString("uv", uv_version_string());
|
||||
trace_process->SetString("zlib", ZLIB_VERSION);
|
||||
trace_process->SetString("ares", ARES_VERSION_STR);
|
||||
trace_process->SetString("modules", node_modules_version);
|
||||
trace_process->SetString("nghttp2", NGHTTP2_VERSION);
|
||||
trace_process->SetString("napi", node_napi_version);
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
// Stupid code to slice out the version string.
|
||||
{ // NOLINT(whitespace/braces)
|
||||
size_t i, j, k;
|
||||
int c;
|
||||
for (i = j = 0, k = sizeof(OPENSSL_VERSION_TEXT) - 1; i < k; ++i) {
|
||||
c = OPENSSL_VERSION_TEXT[i];
|
||||
if ('0' <= c && c <= '9') {
|
||||
for (j = i + 1; j < k; ++j) {
|
||||
c = OPENSSL_VERSION_TEXT[j];
|
||||
if (c == ' ')
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
trace_process->SetString("openssl",
|
||||
std::string(&OPENSSL_VERSION_TEXT[i], j - i));
|
||||
}
|
||||
#endif
|
||||
trace_process->EndDictionary();
|
||||
|
||||
trace_process->SetString("arch", NODE_ARCH);
|
||||
trace_process->SetString("platform", NODE_PLATFORM);
|
||||
|
||||
trace_process->BeginDictionary("release");
|
||||
trace_process->SetString("name", NODE_RELEASE);
|
||||
#if NODE_VERSION_IS_LTS
|
||||
trace_process->SetString("lts", NODE_VERSION_LTS_CODENAME);
|
||||
#endif
|
||||
trace_process->EndDictionary();
|
||||
TRACE_EVENT_METADATA1("__metadata", "node",
|
||||
"process", std::move(trace_process));
|
||||
|
||||
// This only runs the first time tracing is enabled
|
||||
controller_->RemoveTraceStateObserver(this);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void OnTraceDisabled() override {
|
||||
// Do nothing here. This should never be called because the
|
||||
// observer removes itself when OnTraceEnabled() is called.
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
explicit NodeTraceStateObserver(v8::TracingController* controller) :
|
||||
controller_(controller) {}
|
||||
~NodeTraceStateObserver() override {}
|
||||
|
||||
private:
|
||||
v8::TracingController* controller_;
|
||||
};
|
||||
|
||||
static struct {
|
||||
#if NODE_USE_V8_PLATFORM
|
||||
void Initialize(int thread_pool_size) {
|
||||
tracing_agent_.reset(new tracing::Agent(trace_file_pattern));
|
||||
auto controller = tracing_agent_->GetTracingController();
|
||||
controller->AddTraceStateObserver(new NodeTraceStateObserver(controller));
|
||||
tracing::TraceEventHelper::SetTracingController(controller);
|
||||
StartTracingAgent();
|
||||
platform_ = new NodePlatform(thread_pool_size, controller);
|
||||
@ -1993,7 +2089,6 @@ void SetupProcessObject(Environment* env,
|
||||
READONLY_PROPERTY(versions,
|
||||
"http_parser",
|
||||
FIXED_ONE_BYTE_STRING(env->isolate(), http_parser_version));
|
||||
|
||||
// +1 to get rid of the leading 'v'
|
||||
READONLY_PROPERTY(versions,
|
||||
"node",
|
||||
@ -2016,11 +2111,9 @@ void SetupProcessObject(Environment* env,
|
||||
versions,
|
||||
"modules",
|
||||
FIXED_ONE_BYTE_STRING(env->isolate(), node_modules_version));
|
||||
|
||||
READONLY_PROPERTY(versions,
|
||||
"nghttp2",
|
||||
FIXED_ONE_BYTE_STRING(env->isolate(), NGHTTP2_VERSION));
|
||||
|
||||
const char node_napi_version[] = NODE_STRINGIFY(NAPI_VERSION);
|
||||
READONLY_PROPERTY(
|
||||
versions,
|
||||
@ -3547,17 +3640,6 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
|
||||
Environment env(isolate_data, context, v8_platform.GetTracingAgent());
|
||||
env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling);
|
||||
|
||||
char name_buffer[512];
|
||||
if (uv_get_process_title(name_buffer, sizeof(name_buffer)) == 0) {
|
||||
// Only emit the metadata event if the title can be retrieved successfully.
|
||||
// Ignore it otherwise.
|
||||
TRACE_EVENT_METADATA1("__metadata", "process_name", "name",
|
||||
TRACE_STR_COPY(name_buffer));
|
||||
}
|
||||
TRACE_EVENT_METADATA1("__metadata", "version", "node", NODE_VERSION_STRING);
|
||||
TRACE_EVENT_METADATA1("__metadata", "thread_name", "name",
|
||||
"JavaScriptMainThread");
|
||||
|
||||
const char* path = argc > 1 ? argv[1] : nullptr;
|
||||
StartInspector(&env, path, debug_options);
|
||||
|
||||
|
@ -23,25 +23,53 @@ const proc = cp.spawn(process.execPath,
|
||||
proc.once('exit', common.mustCall(() => {
|
||||
assert(common.fileExists(FILE_NAME));
|
||||
fs.readFile(FILE_NAME, common.mustCall((err, data) => {
|
||||
const traces = JSON.parse(data.toString()).traceEvents;
|
||||
const traces = JSON.parse(data.toString()).traceEvents
|
||||
.filter((trace) => trace.cat === '__metadata');
|
||||
assert(traces.length > 0);
|
||||
assert(traces.some((trace) =>
|
||||
trace.cat === '__metadata' && trace.name === 'thread_name' &&
|
||||
trace.name === 'thread_name' &&
|
||||
trace.args.name === 'JavaScriptMainThread'));
|
||||
assert(traces.some((trace) =>
|
||||
trace.cat === '__metadata' && trace.name === 'thread_name' &&
|
||||
trace.name === 'thread_name' &&
|
||||
trace.args.name === 'BackgroundTaskRunner'));
|
||||
assert(traces.some((trace) =>
|
||||
trace.cat === '__metadata' && trace.name === 'version' &&
|
||||
trace.name === 'version' &&
|
||||
trace.args.node === process.versions.node));
|
||||
|
||||
assert(traces.some((trace) =>
|
||||
trace.name === 'node' &&
|
||||
trace.args.process.versions.http_parser ===
|
||||
process.versions.http_parser &&
|
||||
trace.args.process.versions.node ===
|
||||
process.versions.node &&
|
||||
trace.args.process.versions.v8 ===
|
||||
process.versions.v8 &&
|
||||
trace.args.process.versions.uv ===
|
||||
process.versions.uv &&
|
||||
trace.args.process.versions.zlib ===
|
||||
process.versions.zlib &&
|
||||
trace.args.process.versions.ares ===
|
||||
process.versions.ares &&
|
||||
trace.args.process.versions.modules ===
|
||||
process.versions.modules &&
|
||||
trace.args.process.versions.nghttp2 ===
|
||||
process.versions.nghttp2 &&
|
||||
trace.args.process.versions.napi ===
|
||||
process.versions.napi &&
|
||||
trace.args.process.versions.openssl ===
|
||||
process.versions.openssl &&
|
||||
trace.args.process.arch === process.arch &&
|
||||
trace.args.process.platform === process.platform &&
|
||||
trace.args.process.release.name === process.release.name &&
|
||||
(!process.release.lts ||
|
||||
trace.args.process.release.lts === process.release.lts)));
|
||||
|
||||
if (!common.isSunOS) {
|
||||
// Changing process.title is currently unsupported on SunOS/SmartOS
|
||||
assert(traces.some((trace) =>
|
||||
trace.cat === '__metadata' && trace.name === 'process_name' &&
|
||||
trace.args.name === 'foo'));
|
||||
trace.name === 'process_name' && trace.args.name === 'foo'));
|
||||
assert(traces.some((trace) =>
|
||||
trace.cat === '__metadata' && trace.name === 'process_name' &&
|
||||
trace.args.name === 'bar'));
|
||||
trace.name === 'process_name' && trace.args.name === 'bar'));
|
||||
}
|
||||
}));
|
||||
}));
|
||||
|
Loading…
x
Reference in New Issue
Block a user