All files / lib trace_events.js

100% Statements 102/102
94.11% Branches 16/17
100% Functions 6/6
100% Lines 102/102

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 1033x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 19x 19x 19x 19x 3x 3x 23x 20x 20x 20x 20x 1x 1x 1x 1x 1x 20x 23x 3x 3x 9x 6x 6x 6x 6x 9x 3x 3x 10x 10x 3x 3x 4x 4x 3x 3x 2x 2x 1x 1x 1x 1x 1x 1x 2x 3x 3x 58x 58x 58x 58x 18x 18x 18x 22x 22x 58x 19x 19x 58x 3x 3x 3x 3x 3x  
'use strict';
 
const {
  ArrayIsArray,
  ArrayPrototypeJoin,
  SafeSet,
  Symbol,
} = primordials;
 
const { hasTracing } = internalBinding('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;
 
const { ownsProcessState } = require('internal/worker');
if (!hasTracing || !ownsProcessState)
  throw new ERR_TRACE_EVENTS_UNAVAILABLE();
 
const { CategorySet, getEnabledCategories } = internalBinding('trace_events');
const { customInspectSymbol } = require('internal/util');
const { format } = require('internal/util/inspect');
const {
  validateObject,
} = require('internal/validators');
 
const enabledTracingObjects = new SafeSet();
 
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 ArrayPrototypeJoin(this[kCategories], ',');
  }
 
  [customInspectSymbol](depth, opts) {
    if (typeof depth === 'number' && depth < 0)
      return this;
 
    const obj = {
      enabled: this.enabled,
      categories: this.categories
    };
    return `Tracing ${format(obj)}`;
  }
}
 
function createTracing(options) {
  validateObject(options, 'options');
 
  if (!ArrayIsArray(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
};