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