diff options
author | James M Snell <jasnell@gmail.com> | 2018-04-03 18:05:33 -0700 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2018-04-17 08:30:20 -0700 |
commit | 5c27e44488aa1c00248297204ff3484c24ff3ae7 (patch) | |
tree | 4c061d36122bcb91028eb9d0457dfa15bc84604a /lib/trace_events.js | |
parent | 95fafc0254f6636b7c7546ac63599c79a7182fd9 (diff) | |
download | android-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/trace_events.js')
-rw-r--r-- | lib/trace_events.js | 89 |
1 files changed, 89 insertions, 0 deletions
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 +}; |