From 5c27e44488aa1c00248297204ff3484c24ff3ae7 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Tue, 3 Apr 2018 18:05:33 -0700 Subject: trace_events: adds a new trace_events api Removes the requirement to use `--trace-events-enabled` to enable trace events. Tracing is enabled automatically if there are any enabled categories. Adds a new `trace_events` module with an API for enabling/disabling trace events at runtime without a command line flag. ```js const trace_events = require('trace_events'); const categories = [ 'node.perf', 'node.async_hooks' ]; const tracing = trace_events.createTracing({ categories }); tracing.enable(); // do stuff tracing.disable(); ``` Multiple `Tracing` objects may exist and be enabled at any point in time. The enabled trace event categories is the union of all enabled `Tracing` objects and the `--trace-event-categories` flag. PR-URL: https://github.com/nodejs/node/pull/19803 Reviewed-By: Matteo Collina Reviewed-By: Ali Ijaz Sheikh Reviewed-By: Franziska Hinkelmann --- lib/trace_events.js | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 lib/trace_events.js (limited to 'lib/trace_events.js') diff --git a/lib/trace_events.js b/lib/trace_events.js new file mode 100644 index 0000000000..45015c8a63 --- /dev/null +++ b/lib/trace_events.js @@ -0,0 +1,89 @@ +'use strict'; + +const { hasTracing } = process.binding('config'); +const kHandle = Symbol('handle'); +const kEnabled = Symbol('enabled'); +const kCategories = Symbol('categories'); + +const kMaxTracingCount = 10; + +const { + ERR_TRACE_EVENTS_CATEGORY_REQUIRED, + ERR_TRACE_EVENTS_UNAVAILABLE, + ERR_INVALID_ARG_TYPE +} = require('internal/errors').codes; + +if (!hasTracing) + throw new ERR_TRACE_EVENTS_UNAVAILABLE(); + +const { CategorySet, getEnabledCategories } = process.binding('trace_events'); +const { customInspectSymbol } = require('internal/util'); +const { format } = require('util'); + +const enabledTracingObjects = new Set(); + +class Tracing { + constructor(categories) { + this[kHandle] = new CategorySet(categories); + this[kCategories] = categories; + this[kEnabled] = false; + } + + enable() { + if (!this[kEnabled]) { + this[kEnabled] = true; + this[kHandle].enable(); + enabledTracingObjects.add(this); + if (enabledTracingObjects.size > kMaxTracingCount) { + process.emitWarning( + 'Possible trace_events memory leak detected. There are more than ' + + `${kMaxTracingCount} enabled Tracing objects.` + ); + } + } + } + + disable() { + if (this[kEnabled]) { + this[kEnabled] = false; + this[kHandle].disable(); + enabledTracingObjects.delete(this); + } + } + + get enabled() { + return this[kEnabled]; + } + + get categories() { + return this[kCategories].join(','); + } + + [customInspectSymbol](depth, opts) { + const obj = { + enabled: this.enabled, + categories: this.categories + }; + return `Tracing ${format(obj)}`; + } +} + +function createTracing(options) { + if (typeof options !== 'object' || options == null) + throw new ERR_INVALID_ARG_TYPE('options', 'object', options); + + if (!Array.isArray(options.categories)) { + throw new ERR_INVALID_ARG_TYPE('options.categories', 'string[]', + options.categories); + } + + if (options.categories.length <= 0) + throw new ERR_TRACE_EVENTS_CATEGORY_REQUIRED(); + + return new Tracing(options.categories); +} + +module.exports = { + createTracing, + getEnabledCategories +}; -- cgit v1.2.3