-
Notifications
You must be signed in to change notification settings - Fork 30k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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: #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>
- Loading branch information
Showing
25 changed files
with
677 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
5c27e44
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jasnell Is there any particular reason emit is not exposed as part of the trace_events API? With emit, the JS developers can generate custom trace data using their own categories. They can currently do it anyway via binding. So I think we might as well make emit available in trace_events module.
5c27e44
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the
emit
function that is there is not intended for public use and is not safe but public use.... specifically, it will abort if the inputs are not correct. It's also extremely slow at this point. I am currently working on an implementation of an V8 builtin function that would offer the same functionality in a manner that is much faster. Even still, however, that will not be exposed to user code immediately, as the priority is getting Node.js' own code instrumented with trace events before we open that mechanism up to user code.5c27e44
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two issues associated with emit can be mitigated. 1. process will abort with incorrect inputs ==> we clearly document the expected inputs and maybe even allow the process to continue rather than abort? 2. performs slowly ==> it is the same performance impact for node own code instrumentation and custom code trace, so again we can document it. Your fix at the V8 level is an excellent performance boost. However, it does not preclude the use of custom tracing, especially when the trace_events API allows custom trace categories in createTracing. I understand node own tracing has priority. I also believe user code tracing is flexible and useful. So I will write a short doc on the side if nothing is going to change in the trace_events module in the near future.