Spaces:
Running
Running
File size: 5,214 Bytes
1df763a |
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 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
"use strict";
/**
* trace-event - A library to create a trace of your node app per
* Google's Trace Event format:
* // JSSTYLED
* https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Tracer = void 0;
const stream_1 = require("stream");
function evCommon() {
var hrtime = process.hrtime(); // [seconds, nanoseconds]
var ts = hrtime[0] * 1000000 + Math.round(hrtime[1] / 1000); // microseconds
return {
ts,
pid: process.pid,
tid: process.pid // no meaningful tid for node.js
};
}
class Tracer extends stream_1.Readable {
constructor(opts = {}) {
super();
this.noStream = false;
this.events = [];
if (typeof opts !== "object") {
throw new Error("Invalid options passed (must be an object)");
}
if (opts.parent != null && typeof opts.parent !== "object") {
throw new Error("Invalid option (parent) passed (must be an object)");
}
if (opts.fields != null && typeof opts.fields !== "object") {
throw new Error("Invalid option (fields) passed (must be an object)");
}
if (opts.objectMode != null &&
(opts.objectMode !== true && opts.objectMode !== false)) {
throw new Error("Invalid option (objectsMode) passed (must be a boolean)");
}
this.noStream = opts.noStream || false;
this.parent = opts.parent;
if (this.parent) {
this.fields = Object.assign({}, opts.parent && opts.parent.fields);
}
else {
this.fields = {};
}
if (opts.fields) {
Object.assign(this.fields, opts.fields);
}
if (!this.fields.cat) {
// trace-viewer *requires* `cat`, so let's have a fallback.
this.fields.cat = "default";
}
else if (Array.isArray(this.fields.cat)) {
this.fields.cat = this.fields.cat.join(",");
}
if (!this.fields.args) {
// trace-viewer *requires* `args`, so let's have a fallback.
this.fields.args = {};
}
if (this.parent) {
// TODO: Not calling Readable ctor here. Does that cause probs?
// Probably if trying to pipe from the child.
// Might want a serpate TracerChild class for these guys.
this._push = this.parent._push.bind(this.parent);
}
else {
this._objectMode = Boolean(opts.objectMode);
var streamOpts = { objectMode: this._objectMode };
if (this._objectMode) {
this._push = this.push;
}
else {
this._push = this._pushString;
streamOpts.encoding = "utf8";
}
stream_1.Readable.call(this, streamOpts);
}
}
/**
* If in no streamMode in order to flush out the trace
* you need to call flush.
*/
flush() {
if (this.noStream === true) {
for (const evt of this.events) {
this._push(evt);
}
this._flush();
}
}
_read(_) { }
_pushString(ev) {
var separator = "";
if (!this.firstPush) {
this.push("[");
this.firstPush = true;
}
else {
separator = ",\n";
}
this.push(separator + JSON.stringify(ev), "utf8");
}
_flush() {
if (!this._objectMode) {
this.push("]");
}
}
child(fields) {
return new Tracer({
parent: this,
fields: fields
});
}
begin(fields) {
return this.mkEventFunc("b")(fields);
}
end(fields) {
return this.mkEventFunc("e")(fields);
}
completeEvent(fields) {
return this.mkEventFunc("X")(fields);
}
instantEvent(fields) {
return this.mkEventFunc("I")(fields);
}
mkEventFunc(ph) {
return (fields) => {
var ev = evCommon();
// Assign the event phase.
ev.ph = ph;
if (fields) {
if (typeof fields === "string") {
ev.name = fields;
}
else {
for (const k of Object.keys(fields)) {
if (k === "cat") {
ev.cat = fields.cat.join(",");
}
else {
ev[k] = fields[k];
}
}
}
}
if (!this.noStream) {
this._push(ev);
}
else {
this.events.push(ev);
}
};
}
}
exports.Tracer = Tracer;
/*
* These correspond to the "Async events" in the Trace Events doc.
*
* Required fields:
* - name
* - id
*
* Optional fields:
* - cat (array)
* - args (object)
* - TODO: stack fields, other optional fields?
*
* Dev Note: We don't explicitly assert that correct fields are
* used for speed (premature optimization alert!).
*/
|