trace.js 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.flushAllTraces = exports.trace = exports.SpanStatus = void 0;
  6. var _report = require("./report");
  7. const NUM_OF_MICROSEC_IN_NANOSEC = BigInt("1000");
  8. let count = 0;
  9. const getId = ()=>{
  10. count++;
  11. return count;
  12. };
  13. var SpanStatus;
  14. exports.SpanStatus = SpanStatus;
  15. (function(SpanStatus) {
  16. SpanStatus[SpanStatus["Started"] = 0] = "Started";
  17. SpanStatus[SpanStatus["Stopped"] = 1] = "Stopped";
  18. })(SpanStatus || (exports.SpanStatus = SpanStatus = {}));
  19. class Span {
  20. constructor({ name , parentId , attrs , startTime }){
  21. this.name = name;
  22. this.parentId = parentId;
  23. this.duration = null;
  24. this.attrs = attrs ? {
  25. ...attrs
  26. } : {};
  27. this.status = 0;
  28. this.id = getId();
  29. this._start = startTime || process.hrtime.bigint();
  30. // hrtime cannot be used to reconstruct tracing span's actual start time
  31. // since it does not have relation to clock time:
  32. // `These times are relative to an arbitrary time in the past, and not related to the time of day and therefore not subject to clock drift`
  33. // https://nodejs.org/api/process.html#processhrtimetime
  34. // Capturing current datetime as additional metadata for external reconstruction.
  35. this.now = Date.now();
  36. }
  37. // Durations are reported as microseconds. This gives 1000x the precision
  38. // of something like Date.now(), which reports in milliseconds.
  39. // Additionally, ~285 years can be safely represented as microseconds as
  40. // a float64 in both JSON and JavaScript.
  41. stop(stopTime) {
  42. const end = stopTime || process.hrtime.bigint();
  43. const duration = (end - this._start) / NUM_OF_MICROSEC_IN_NANOSEC;
  44. this.status = 1;
  45. if (duration > Number.MAX_SAFE_INTEGER) {
  46. throw new Error(`Duration is too long to express as float64: ${duration}`);
  47. }
  48. const timestamp = this._start / NUM_OF_MICROSEC_IN_NANOSEC;
  49. _report.reporter.report(this.name, Number(duration), Number(timestamp), this.id, this.parentId, this.attrs, this.now);
  50. }
  51. traceChild(name, attrs) {
  52. return new Span({
  53. name,
  54. parentId: this.id,
  55. attrs
  56. });
  57. }
  58. manualTraceChild(name, startTime, stopTime, attrs) {
  59. const span = new Span({
  60. name,
  61. parentId: this.id,
  62. attrs,
  63. startTime
  64. });
  65. span.stop(stopTime);
  66. }
  67. setAttribute(key, value) {
  68. this.attrs[key] = String(value);
  69. }
  70. traceFn(fn) {
  71. try {
  72. return fn();
  73. } finally{
  74. this.stop();
  75. }
  76. }
  77. async traceAsyncFn(fn) {
  78. try {
  79. return await fn();
  80. } finally{
  81. this.stop();
  82. }
  83. }
  84. }
  85. exports.Span = Span;
  86. const trace = (name, parentId, attrs)=>{
  87. return new Span({
  88. name,
  89. parentId,
  90. attrs
  91. });
  92. };
  93. exports.trace = trace;
  94. const flushAllTraces = ()=>_report.reporter.flushAll();
  95. exports.flushAllTraces = flushAllTraces;
  96. //# sourceMappingURL=trace.js.map