• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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