summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJames M Snell <jasnell@gmail.com>2018-04-03 18:05:33 -0700
committerJames M Snell <jasnell@gmail.com>2018-04-17 08:30:20 -0700
commit5c27e44488aa1c00248297204ff3484c24ff3ae7 (patch)
tree4c061d36122bcb91028eb9d0457dfa15bc84604a /lib
parent95fafc0254f6636b7c7546ac63599c79a7182fd9 (diff)
downloadandroid-node-v8-5c27e44488aa1c00248297204ff3484c24ff3ae7.tar.gz
android-node-v8-5c27e44488aa1c00248297204ff3484c24ff3ae7.tar.bz2
android-node-v8-5c27e44488aa1c00248297204ff3484c24ff3ae7.zip
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 <matteo.collina@gmail.com> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/internal/errors.js3
-rw-r--r--lib/internal/modules/cjs/helpers.js3
-rw-r--r--lib/trace_events.js89
3 files changed, 94 insertions, 1 deletions
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index a91f5f6dcf..4823f0b65c 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -984,6 +984,9 @@ E('ERR_TLS_REQUIRED_SERVER_NAME',
E('ERR_TLS_SESSION_ATTACK', 'TLS session renegotiation attack detected', Error);
E('ERR_TLS_SNI_FROM_SERVER',
'Cannot issue SNI from a TLS server-side socket', Error);
+E('ERR_TRACE_EVENTS_CATEGORY_REQUIRED',
+ 'At least one category is required', TypeError);
+E('ERR_TRACE_EVENTS_UNAVAILABLE', 'Trace events are unavailable', Error);
E('ERR_TRANSFORM_ALREADY_TRANSFORMING',
'Calling transform done when still transforming', Error);
diff --git a/lib/internal/modules/cjs/helpers.js b/lib/internal/modules/cjs/helpers.js
index fdad580b3b..60346c5841 100644
--- a/lib/internal/modules/cjs/helpers.js
+++ b/lib/internal/modules/cjs/helpers.js
@@ -101,7 +101,8 @@ const builtinLibs = [
'assert', 'async_hooks', 'buffer', 'child_process', 'cluster', 'crypto',
'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'http2', 'https', 'net',
'os', 'path', 'perf_hooks', 'punycode', 'querystring', 'readline', 'repl',
- 'stream', 'string_decoder', 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'zlib'
+ 'stream', 'string_decoder', 'tls', 'trace_events', 'tty', 'url', 'util',
+ 'v8', 'vm', 'zlib'
];
if (typeof process.binding('inspector').open === 'function') {
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
+};