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
290291DebugOptions 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+
292387static 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);
@@ -1993,7 +2089,6 @@ void SetupProcessObject(Environment* env,
19932089 READONLY_PROPERTY (versions,
19942090 " http_parser" ,
19952091 FIXED_ONE_BYTE_STRING (env->isolate (), http_parser_version));
1996-
19972092 // +1 to get rid of the leading 'v'
19982093 READONLY_PROPERTY (versions,
19992094 " node" ,
@@ -2016,11 +2111,9 @@ void SetupProcessObject(Environment* env,
20162111 versions,
20172112 " modules" ,
20182113 FIXED_ONE_BYTE_STRING (env->isolate (), node_modules_version));
2019-
20202114 READONLY_PROPERTY (versions,
20212115 " nghttp2" ,
20222116 FIXED_ONE_BYTE_STRING (env->isolate (), NGHTTP2_VERSION));
2023-
20242117 const char node_napi_version[] = NODE_STRINGIFY (NAPI_VERSION);
20252118 READONLY_PROPERTY (
20262119 versions,
@@ -3547,17 +3640,6 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
35473640 Environment env (isolate_data, context, v8_platform.GetTracingAgent ());
35483641 env.Start (argc, argv, exec_argc, exec_argv, v8_is_profiling);
35493642
3550- char name_buffer[512 ];
3551- if (uv_get_process_title (name_buffer, sizeof (name_buffer)) == 0 ) {
3552- // Only emit the metadata event if the title can be retrieved successfully.
3553- // Ignore it otherwise.
3554- TRACE_EVENT_METADATA1 (" __metadata" , " process_name" , " name" ,
3555- TRACE_STR_COPY (name_buffer));
3556- }
3557- TRACE_EVENT_METADATA1 (" __metadata" , " version" , " node" , NODE_VERSION_STRING);
3558- TRACE_EVENT_METADATA1 (" __metadata" , " thread_name" , " name" ,
3559- " JavaScriptMainThread" );
3560-
35613643 const char * path = argc > 1 ? argv[1 ] : nullptr ;
35623644 StartInspector (&env, path, debug_options);
35633645
0 commit comments