-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsimple_tracer.js
55 lines (43 loc) · 1.5 KB
/
simple_tracer.js
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
import { AsyncLocalStorage } from "node:async_hooks";
import crypto from "node:crypto";
class Tracing {
static asyncLocalStorage = new AsyncLocalStorage();
static exporter = (span) => console.log(span);
static getCurrentSpan = () => Tracing.asyncLocalStorage.getStore().span;
static getContext = () => Tracing.asyncLocalStorage.getStore();
static async setContext(ctx, cb, ...args) {
await Tracing.asyncLocalStorage.run(ctx, cb, ...args);
}
static async startSpan(name, lambda) {
let ctx = Tracing.asyncLocalStorage.getStore();
let span = new Span(name, ctx, new Map());
await Tracing.setContext(span.getContext(), lambda, span);
span.end();
Tracing.exporter(span);
}
}
const EMPTY_CONTEXT = {};
Tracing.asyncLocalStorage.enterWith(EMPTY_CONTEXT);
class Span {
constructor(name, context = {}, attributes = new Map()) {
this.startTime = new Date().getTime();
this.startTimestampMs = performance.now();
this.traceID = context.traceID ?? crypto.randomBytes(16).toString("hex");
this.parentSpanID = context.spanID ?? undefined;
this.name = name;
this.attributes = attributes;
this.spanID = crypto.randomBytes(8).toString("hex");
}
getContext() {
return { traceID: this.traceID, spanID: this.spanID, span: this };
}
setAttributes(keyValues) {
for (let [key, value] of Object.entries(keyValues)) {
this.attributes.set(key, value);
}
}
end() {
this.elapsedMs = performance.now() - this.startTimestampMs;
}
}
export { Tracing };