1'use strict'; 2 3const { 4 ArrayIsArray, 5 ArrayPrototypeJoin, 6 SafeSet, 7 Symbol, 8} = primordials; 9 10const { hasTracing } = internalBinding('config'); 11const kHandle = Symbol('handle'); 12const kEnabled = Symbol('enabled'); 13const kCategories = Symbol('categories'); 14 15const kMaxTracingCount = 10; 16 17const { 18 ERR_TRACE_EVENTS_CATEGORY_REQUIRED, 19 ERR_TRACE_EVENTS_UNAVAILABLE, 20 ERR_INVALID_ARG_TYPE 21} = require('internal/errors').codes; 22 23const { ownsProcessState } = require('internal/worker'); 24if (!hasTracing || !ownsProcessState) 25 throw new ERR_TRACE_EVENTS_UNAVAILABLE(); 26 27const { CategorySet, getEnabledCategories } = internalBinding('trace_events'); 28const { customInspectSymbol } = require('internal/util'); 29const { format } = require('internal/util/inspect'); 30 31const enabledTracingObjects = new SafeSet(); 32 33class Tracing { 34 constructor(categories) { 35 this[kHandle] = new CategorySet(categories); 36 this[kCategories] = categories; 37 this[kEnabled] = false; 38 } 39 40 enable() { 41 if (!this[kEnabled]) { 42 this[kEnabled] = true; 43 this[kHandle].enable(); 44 enabledTracingObjects.add(this); 45 if (enabledTracingObjects.size > kMaxTracingCount) { 46 process.emitWarning( 47 'Possible trace_events memory leak detected. There are more than ' + 48 `${kMaxTracingCount} enabled Tracing objects.` 49 ); 50 } 51 } 52 } 53 54 disable() { 55 if (this[kEnabled]) { 56 this[kEnabled] = false; 57 this[kHandle].disable(); 58 enabledTracingObjects.delete(this); 59 } 60 } 61 62 get enabled() { 63 return this[kEnabled]; 64 } 65 66 get categories() { 67 return ArrayPrototypeJoin(this[kCategories], ','); 68 } 69 70 [customInspectSymbol](depth, opts) { 71 if (typeof depth === 'number' && depth < 0) 72 return this; 73 74 const obj = { 75 enabled: this.enabled, 76 categories: this.categories 77 }; 78 return `Tracing ${format(obj)}`; 79 } 80} 81 82function createTracing(options) { 83 if (typeof options !== 'object' || options === null) 84 throw new ERR_INVALID_ARG_TYPE('options', 'object', options); 85 86 if (!ArrayIsArray(options.categories)) { 87 throw new ERR_INVALID_ARG_TYPE('options.categories', 'string[]', 88 options.categories); 89 } 90 91 if (options.categories.length <= 0) 92 throw new ERR_TRACE_EVENTS_CATEGORY_REQUIRED(); 93 94 return new Tracing(options.categories); 95} 96 97module.exports = { 98 createTracing, 99 getEnabledCategories 100}; 101