rian 0.3.6 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/async.js +94 -1
- package/async.mjs +94 -1
- package/exporter.console.d.ts +3 -0
- package/exporter.console.js +67 -0
- package/exporter.console.mjs +67 -0
- package/exporter.otel.http.js +77 -1
- package/exporter.otel.http.mjs +77 -1
- package/exporter.zipkin.js +41 -1
- package/exporter.zipkin.mjs +41 -1
- package/index.js +71 -1
- package/index.mjs +71 -1
- package/package.json +11 -6
- package/readme.md +69 -27
- package/utils.js +22 -1
- package/utils.mjs +22 -1
package/async.js
CHANGED
@@ -1 +1,94 @@
|
|
1
|
-
|
1
|
+
// src/async.ts
|
2
|
+
const async_hooks = require('node:async_hooks');
|
3
|
+
const { measure } = require('rian/utils');
|
4
|
+
const tctx = require('tctx');
|
5
|
+
|
6
|
+
// src/_internal/index.ts
|
7
|
+
var resource = {};
|
8
|
+
function configure(name, attributes = {}) {
|
9
|
+
resource = {
|
10
|
+
...attributes,
|
11
|
+
["service.name"]: name,
|
12
|
+
["telemetry.sdk.name"]: "rian",
|
13
|
+
["telemetry.sdk.version"]: "0.3.8"
|
14
|
+
};
|
15
|
+
}
|
16
|
+
var span_buffer = /* @__PURE__ */ new Set(), wait_promises = /* @__PURE__ */ new WeakMap();
|
17
|
+
async function report(exporter) {
|
18
|
+
let ps = [], scopes = /* @__PURE__ */ new Map();
|
19
|
+
for (let [span2, scope] of span_buffer) {
|
20
|
+
let spans;
|
21
|
+
if (scopes.has(scope) ? spans = scopes.get(scope).spans : scopes.set(scope, {
|
22
|
+
scope,
|
23
|
+
spans: spans = []
|
24
|
+
}), spans.push(span2), wait_promises.has(scope)) {
|
25
|
+
let pss = wait_promises.get(scope);
|
26
|
+
ps.push(...pss), pss.clear();
|
27
|
+
}
|
28
|
+
}
|
29
|
+
return span_buffer.clear(), ps.length && await Promise.all(ps), exporter({
|
30
|
+
resource,
|
31
|
+
scopeSpans: scopes.values()
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
// src/async.ts
|
36
|
+
var resourceStore = new async_hooks.AsyncLocalStorage();
|
37
|
+
function currentSpan() {
|
38
|
+
let scope = resourceStore.getStore()?.[1];
|
39
|
+
if (scope == null)
|
40
|
+
throw new Error("no current span");
|
41
|
+
return scope;
|
42
|
+
}
|
43
|
+
function span(name, parent_id) {
|
44
|
+
let context = resourceStore.getStore();
|
45
|
+
if (!context)
|
46
|
+
throw Error("no current tracer");
|
47
|
+
let api = context[0], scope = api.scope, current_span = context[1], should_sample = api.sampler, parent = typeof parent_id == "string" ? tctx.parse(parent_id) : parent_id || current_span?.traceparent, id = parent?.child() || tctx.make(), is_sampling = typeof should_sample == "boolean" ? should_sample : should_sample(name, id, scope);
|
48
|
+
is_sampling ? tctx.sample(id) : tctx.unsample(id);
|
49
|
+
let span_obj = {
|
50
|
+
id,
|
51
|
+
parent,
|
52
|
+
name,
|
53
|
+
start: api.clock.now(),
|
54
|
+
events: [],
|
55
|
+
context: {}
|
56
|
+
};
|
57
|
+
is_sampling && span_buffer.add([span_obj, scope]);
|
58
|
+
let $ = (cb) => resourceStore.run([api, $], measure, $, cb);
|
59
|
+
$.traceparent = id, $.span = (name2) => resourceStore.run([api, $], span, name2), $.set_context = (ctx) => {
|
60
|
+
if (typeof ctx == "function")
|
61
|
+
return void (span_obj.context = ctx(span_obj.context));
|
62
|
+
Object.assign(span_obj.context, ctx);
|
63
|
+
}, $.add_event = (name2, attributes) => {
|
64
|
+
span_obj.events.push({
|
65
|
+
name: name2,
|
66
|
+
timestamp: api.clock.now(),
|
67
|
+
attributes: attributes || {}
|
68
|
+
});
|
69
|
+
}, $.end = () => {
|
70
|
+
span_obj.end == null && (span_obj.end = api.clock.now());
|
71
|
+
};
|
72
|
+
let ps = wait_promises.get(scope);
|
73
|
+
return $.__add_promise = (p) => {
|
74
|
+
ps.add(p), p.then(() => ps.delete(p));
|
75
|
+
}, $;
|
76
|
+
}
|
77
|
+
function tracer(name, options) {
|
78
|
+
let sampler = options?.sampler ?? !0, scope = { name }, api = {
|
79
|
+
scope,
|
80
|
+
sampler,
|
81
|
+
clock: options?.clock ?? Date
|
82
|
+
};
|
83
|
+
return wait_promises.set(scope, /* @__PURE__ */ new Set()), function(cb) {
|
84
|
+
let parent = resourceStore.getStore();
|
85
|
+
return resourceStore.run([api, parent?.[1] || null], cb);
|
86
|
+
};
|
87
|
+
}
|
88
|
+
|
89
|
+
|
90
|
+
exports.configure = configure;
|
91
|
+
exports.currentSpan = currentSpan;
|
92
|
+
exports.report = report;
|
93
|
+
exports.span = span;
|
94
|
+
exports.tracer = tracer;
|
package/async.mjs
CHANGED
@@ -1 +1,94 @@
|
|
1
|
-
|
1
|
+
// src/async.ts
|
2
|
+
import * as async_hooks from "node:async_hooks";
|
3
|
+
import { measure } from "rian/utils";
|
4
|
+
import * as tctx from "tctx";
|
5
|
+
|
6
|
+
// src/_internal/index.ts
|
7
|
+
var resource = {};
|
8
|
+
function configure(name, attributes = {}) {
|
9
|
+
resource = {
|
10
|
+
...attributes,
|
11
|
+
["service.name"]: name,
|
12
|
+
["telemetry.sdk.name"]: "rian",
|
13
|
+
["telemetry.sdk.version"]: "0.3.8"
|
14
|
+
};
|
15
|
+
}
|
16
|
+
var span_buffer = /* @__PURE__ */ new Set(), wait_promises = /* @__PURE__ */ new WeakMap();
|
17
|
+
async function report(exporter) {
|
18
|
+
let ps = [], scopes = /* @__PURE__ */ new Map();
|
19
|
+
for (let [span2, scope] of span_buffer) {
|
20
|
+
let spans;
|
21
|
+
if (scopes.has(scope) ? spans = scopes.get(scope).spans : scopes.set(scope, {
|
22
|
+
scope,
|
23
|
+
spans: spans = []
|
24
|
+
}), spans.push(span2), wait_promises.has(scope)) {
|
25
|
+
let pss = wait_promises.get(scope);
|
26
|
+
ps.push(...pss), pss.clear();
|
27
|
+
}
|
28
|
+
}
|
29
|
+
return span_buffer.clear(), ps.length && await Promise.all(ps), exporter({
|
30
|
+
resource,
|
31
|
+
scopeSpans: scopes.values()
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
// src/async.ts
|
36
|
+
var resourceStore = new async_hooks.AsyncLocalStorage();
|
37
|
+
function currentSpan() {
|
38
|
+
let scope = resourceStore.getStore()?.[1];
|
39
|
+
if (scope == null)
|
40
|
+
throw new Error("no current span");
|
41
|
+
return scope;
|
42
|
+
}
|
43
|
+
function span(name, parent_id) {
|
44
|
+
let context = resourceStore.getStore();
|
45
|
+
if (!context)
|
46
|
+
throw Error("no current tracer");
|
47
|
+
let api = context[0], scope = api.scope, current_span = context[1], should_sample = api.sampler, parent = typeof parent_id == "string" ? tctx.parse(parent_id) : parent_id || current_span?.traceparent, id = parent?.child() || tctx.make(), is_sampling = typeof should_sample == "boolean" ? should_sample : should_sample(name, id, scope);
|
48
|
+
is_sampling ? tctx.sample(id) : tctx.unsample(id);
|
49
|
+
let span_obj = {
|
50
|
+
id,
|
51
|
+
parent,
|
52
|
+
name,
|
53
|
+
start: api.clock.now(),
|
54
|
+
events: [],
|
55
|
+
context: {}
|
56
|
+
};
|
57
|
+
is_sampling && span_buffer.add([span_obj, scope]);
|
58
|
+
let $ = (cb) => resourceStore.run([api, $], measure, $, cb);
|
59
|
+
$.traceparent = id, $.span = (name2) => resourceStore.run([api, $], span, name2), $.set_context = (ctx) => {
|
60
|
+
if (typeof ctx == "function")
|
61
|
+
return void (span_obj.context = ctx(span_obj.context));
|
62
|
+
Object.assign(span_obj.context, ctx);
|
63
|
+
}, $.add_event = (name2, attributes) => {
|
64
|
+
span_obj.events.push({
|
65
|
+
name: name2,
|
66
|
+
timestamp: api.clock.now(),
|
67
|
+
attributes: attributes || {}
|
68
|
+
});
|
69
|
+
}, $.end = () => {
|
70
|
+
span_obj.end == null && (span_obj.end = api.clock.now());
|
71
|
+
};
|
72
|
+
let ps = wait_promises.get(scope);
|
73
|
+
return $.__add_promise = (p) => {
|
74
|
+
ps.add(p), p.then(() => ps.delete(p));
|
75
|
+
}, $;
|
76
|
+
}
|
77
|
+
function tracer(name, options) {
|
78
|
+
let sampler = options?.sampler ?? !0, scope = { name }, api = {
|
79
|
+
scope,
|
80
|
+
sampler,
|
81
|
+
clock: options?.clock ?? Date
|
82
|
+
};
|
83
|
+
return wait_promises.set(scope, /* @__PURE__ */ new Set()), function(cb) {
|
84
|
+
let parent = resourceStore.getStore();
|
85
|
+
return resourceStore.run([api, parent?.[1] || null], cb);
|
86
|
+
};
|
87
|
+
}
|
88
|
+
export {
|
89
|
+
configure,
|
90
|
+
currentSpan,
|
91
|
+
report,
|
92
|
+
span,
|
93
|
+
tracer
|
94
|
+
};
|
@@ -0,0 +1,67 @@
|
|
1
|
+
// src/exporter.console.ts
|
2
|
+
var p = 1;
|
3
|
+
function exporter(max_cols = 120) {
|
4
|
+
if (max_cols < 24)
|
5
|
+
throw new Error("max_cols must be at least 24");
|
6
|
+
return function(trace) {
|
7
|
+
console.log(obj_string(trace.resource) + "─".repeat(max_cols)), max_cols = max_cols - 2;
|
8
|
+
for (let scope of trace.scopeSpans) {
|
9
|
+
let spans = scope.spans;
|
10
|
+
if (!spans.length)
|
11
|
+
return;
|
12
|
+
let tmp, i, max_time = 0, min_time = spans[0].start;
|
13
|
+
for (i = 0; tmp = scope.spans[i++]; )
|
14
|
+
max_time = Math.max(max_time, tmp.end ?? tmp.start), min_time = Math.min(min_time, tmp.start);
|
15
|
+
let t_dur = max_time - min_time, t_dur_str = format(t_dur), max_time_length = t_dur_str.length, max_time_col = max_time_length + 2, max_trace_col = Math.ceil(2 / 3 * (max_cols - max_time_col)), trace_cols = max_trace_col - (p * 2 + 2), max_name_col = max_cols - max_time_col - max_trace_col, mid = Math.ceil(trace_cols / 2), mid_str = format(t_dur / 2), mid_str_anchor = Math.ceil(mid_str.length / 2), out = "";
|
16
|
+
for (out += "╭─ ", out += scope.scope.name, out += `
|
17
|
+
`, out += "│ ", out += "╭".padStart(max_time_col), out += "─".repeat(max_trace_col), out += `╮
|
18
|
+
`, i = 0; tmp = scope.spans[i++]; ) {
|
19
|
+
let start_time = tmp.start - min_time, end_time = (tmp.end ?? max_time) - min_time, start_trace = Math.ceil(start_time / t_dur * trace_cols), end_trace = Math.ceil(end_time / t_dur * trace_cols), dur = end_time - start_time, dur_str = format(dur);
|
20
|
+
out += "│ ", out += dur_str.padStart(max_time_length), out += " │", out += " ".repeat(start_trace + p), out += "┣", out += (tmp.end ? "━" : "╍").repeat(end_trace - start_trace), out += "┫", out += " ".repeat(max_trace_col - end_trace - (p + 2)), out += "│◗ ", out += tmp.name.length + 4 > max_name_col ? tmp.name.substring(0, max_name_col - 4) + "…" : tmp.name, out += `
|
21
|
+
`;
|
22
|
+
}
|
23
|
+
out += "│ ", out += "╰".padStart(max_time_col), out += "┼", out += "┴".repeat(mid - 2), out += "┼", out += "┴".repeat(max_trace_col - mid - 1), out += "┼", out += `╯
|
24
|
+
`, out += "│ ", out += "0 ms".padStart(max_time_length + 2 + 4), out += mid_str.padStart(mid + mid_str_anchor - 4), out += t_dur_str.padStart(
|
25
|
+
trace_cols - mid + 2 - (mid_str_anchor + 4) + t_dur_str.length
|
26
|
+
), out += `
|
27
|
+
│
|
28
|
+
`, out += "│ ";
|
29
|
+
let t_dur_str_seg = format(t_dur / trace_cols), t_max_len = Math.max(t_dur_str_seg.length, t_dur_str.length);
|
30
|
+
out += tmp = `one └┘ unit is less than: ${t_dur_str_seg}
|
31
|
+
`, out += "│ ", out += `total time: ${t_dur_str.padStart(t_max_len)}`.padStart(
|
32
|
+
tmp.length - 1
|
33
|
+
), out += `
|
34
|
+
╰─`, console.log(out);
|
35
|
+
}
|
36
|
+
};
|
37
|
+
}
|
38
|
+
function obj_string(obj, line_prefix = "") {
|
39
|
+
let keys = Object.keys(obj), tmp, i, max_key = 0;
|
40
|
+
for (i = 0; tmp = keys[i++]; max_key = Math.max(max_key, tmp.length))
|
41
|
+
;
|
42
|
+
let out = "";
|
43
|
+
for (i = 0; tmp = keys[i++]; out += line_prefix + tmp.padStart(max_key) + ": " + obj[tmp] + `
|
44
|
+
`)
|
45
|
+
;
|
46
|
+
return out;
|
47
|
+
}
|
48
|
+
var MIN = 6e4, HOUR = MIN * 60, SEC = 1e3;
|
49
|
+
function dec_str(num) {
|
50
|
+
return num % 1 === 0 ? String(num) : num.toFixed(3);
|
51
|
+
}
|
52
|
+
function format(num) {
|
53
|
+
if (num < 0)
|
54
|
+
return "0 ms";
|
55
|
+
if (num < SEC)
|
56
|
+
return `${dec_str(num)} ms`;
|
57
|
+
if (num < MIN)
|
58
|
+
return `${dec_str(num / SEC)} s`;
|
59
|
+
if (num < HOUR) {
|
60
|
+
let m = Math.floor(num / MIN), s = Math.floor(num % MIN / SEC), ms = dec_str(num % SEC);
|
61
|
+
return `${m} m ${s} s ${ms} ms`;
|
62
|
+
}
|
63
|
+
return "> 1hr";
|
64
|
+
}
|
65
|
+
|
66
|
+
|
67
|
+
exports.exporter = exporter;
|
@@ -0,0 +1,67 @@
|
|
1
|
+
// src/exporter.console.ts
|
2
|
+
var p = 1;
|
3
|
+
function exporter(max_cols = 120) {
|
4
|
+
if (max_cols < 24)
|
5
|
+
throw new Error("max_cols must be at least 24");
|
6
|
+
return function(trace) {
|
7
|
+
console.log(obj_string(trace.resource) + "─".repeat(max_cols)), max_cols = max_cols - 2;
|
8
|
+
for (let scope of trace.scopeSpans) {
|
9
|
+
let spans = scope.spans;
|
10
|
+
if (!spans.length)
|
11
|
+
return;
|
12
|
+
let tmp, i, max_time = 0, min_time = spans[0].start;
|
13
|
+
for (i = 0; tmp = scope.spans[i++]; )
|
14
|
+
max_time = Math.max(max_time, tmp.end ?? tmp.start), min_time = Math.min(min_time, tmp.start);
|
15
|
+
let t_dur = max_time - min_time, t_dur_str = format(t_dur), max_time_length = t_dur_str.length, max_time_col = max_time_length + 2, max_trace_col = Math.ceil(2 / 3 * (max_cols - max_time_col)), trace_cols = max_trace_col - (p * 2 + 2), max_name_col = max_cols - max_time_col - max_trace_col, mid = Math.ceil(trace_cols / 2), mid_str = format(t_dur / 2), mid_str_anchor = Math.ceil(mid_str.length / 2), out = "";
|
16
|
+
for (out += "╭─ ", out += scope.scope.name, out += `
|
17
|
+
`, out += "│ ", out += "╭".padStart(max_time_col), out += "─".repeat(max_trace_col), out += `╮
|
18
|
+
`, i = 0; tmp = scope.spans[i++]; ) {
|
19
|
+
let start_time = tmp.start - min_time, end_time = (tmp.end ?? max_time) - min_time, start_trace = Math.ceil(start_time / t_dur * trace_cols), end_trace = Math.ceil(end_time / t_dur * trace_cols), dur = end_time - start_time, dur_str = format(dur);
|
20
|
+
out += "│ ", out += dur_str.padStart(max_time_length), out += " │", out += " ".repeat(start_trace + p), out += "┣", out += (tmp.end ? "━" : "╍").repeat(end_trace - start_trace), out += "┫", out += " ".repeat(max_trace_col - end_trace - (p + 2)), out += "│◗ ", out += tmp.name.length + 4 > max_name_col ? tmp.name.substring(0, max_name_col - 4) + "…" : tmp.name, out += `
|
21
|
+
`;
|
22
|
+
}
|
23
|
+
out += "│ ", out += "╰".padStart(max_time_col), out += "┼", out += "┴".repeat(mid - 2), out += "┼", out += "┴".repeat(max_trace_col - mid - 1), out += "┼", out += `╯
|
24
|
+
`, out += "│ ", out += "0 ms".padStart(max_time_length + 2 + 4), out += mid_str.padStart(mid + mid_str_anchor - 4), out += t_dur_str.padStart(
|
25
|
+
trace_cols - mid + 2 - (mid_str_anchor + 4) + t_dur_str.length
|
26
|
+
), out += `
|
27
|
+
│
|
28
|
+
`, out += "│ ";
|
29
|
+
let t_dur_str_seg = format(t_dur / trace_cols), t_max_len = Math.max(t_dur_str_seg.length, t_dur_str.length);
|
30
|
+
out += tmp = `one └┘ unit is less than: ${t_dur_str_seg}
|
31
|
+
`, out += "│ ", out += `total time: ${t_dur_str.padStart(t_max_len)}`.padStart(
|
32
|
+
tmp.length - 1
|
33
|
+
), out += `
|
34
|
+
╰─`, console.log(out);
|
35
|
+
}
|
36
|
+
};
|
37
|
+
}
|
38
|
+
function obj_string(obj, line_prefix = "") {
|
39
|
+
let keys = Object.keys(obj), tmp, i, max_key = 0;
|
40
|
+
for (i = 0; tmp = keys[i++]; max_key = Math.max(max_key, tmp.length))
|
41
|
+
;
|
42
|
+
let out = "";
|
43
|
+
for (i = 0; tmp = keys[i++]; out += line_prefix + tmp.padStart(max_key) + ": " + obj[tmp] + `
|
44
|
+
`)
|
45
|
+
;
|
46
|
+
return out;
|
47
|
+
}
|
48
|
+
var MIN = 6e4, HOUR = MIN * 60, SEC = 1e3;
|
49
|
+
function dec_str(num) {
|
50
|
+
return num % 1 === 0 ? String(num) : num.toFixed(3);
|
51
|
+
}
|
52
|
+
function format(num) {
|
53
|
+
if (num < 0)
|
54
|
+
return "0 ms";
|
55
|
+
if (num < SEC)
|
56
|
+
return `${dec_str(num)} ms`;
|
57
|
+
if (num < MIN)
|
58
|
+
return `${dec_str(num / SEC)} s`;
|
59
|
+
if (num < HOUR) {
|
60
|
+
let m = Math.floor(num / MIN), s = Math.floor(num % MIN / SEC), ms = dec_str(num % SEC);
|
61
|
+
return `${m} m ${s} s ${ms} ms`;
|
62
|
+
}
|
63
|
+
return "> 1hr";
|
64
|
+
}
|
65
|
+
export {
|
66
|
+
exporter
|
67
|
+
};
|
package/exporter.otel.http.js
CHANGED
@@ -1 +1,77 @@
|
|
1
|
-
|
1
|
+
// src/exporter.otel.http.ts
|
2
|
+
var convert_value_to_anyvalue = (value) => {
|
3
|
+
let type = typeof value, any_value = {};
|
4
|
+
return type === "string" ? any_value.stringValue = value : type === "number" ? Number.isInteger(value) ? any_value.intValue = value : any_value.doubleValue = value : type === "boolean" ? any_value.boolValue = value : Array.isArray(value) ? any_value.arrayValue = {
|
5
|
+
values: value.map((i) => convert_value_to_anyvalue(i))
|
6
|
+
} : value && (any_value.kvlistValue = { values: convert_object_to_kv(value) }), any_value;
|
7
|
+
}, convert_object_to_kv = (input) => {
|
8
|
+
let value = [];
|
9
|
+
for (let key of Object.keys(input))
|
10
|
+
value.push({
|
11
|
+
key,
|
12
|
+
value: convert_value_to_anyvalue(input[key])
|
13
|
+
});
|
14
|
+
return value;
|
15
|
+
}, map_kind = (kind) => {
|
16
|
+
switch (kind) {
|
17
|
+
default:
|
18
|
+
case "INTERNAL":
|
19
|
+
return 1;
|
20
|
+
case "SERVER":
|
21
|
+
return 2;
|
22
|
+
case "CLIENT":
|
23
|
+
return 3;
|
24
|
+
case "PRODUCER":
|
25
|
+
return 4;
|
26
|
+
case "CONSUMER":
|
27
|
+
return 5;
|
28
|
+
}
|
29
|
+
}, exporter = (request) => (trace) => {
|
30
|
+
let scopeSpans = [];
|
31
|
+
for (let scope of trace.scopeSpans) {
|
32
|
+
let spans = [];
|
33
|
+
scopeSpans.push({
|
34
|
+
scope: scope.scope,
|
35
|
+
spans
|
36
|
+
});
|
37
|
+
for (let span of scope.spans) {
|
38
|
+
let { kind, error, ...span_ctx } = span.context, status;
|
39
|
+
error && (status = {
|
40
|
+
code: 2
|
41
|
+
}, "message" in error && (status.message = error.message)), spans.push({
|
42
|
+
traceId: span.id.trace_id,
|
43
|
+
spanId: span.id.parent_id,
|
44
|
+
parentSpanId: span.parent?.parent_id,
|
45
|
+
name: span.name,
|
46
|
+
kind: map_kind(kind || "INTERNAL"),
|
47
|
+
startTimeUnixNano: span.start * 1e6,
|
48
|
+
endTimeUnixNano: span.end ? span.end * 1e6 : void 0,
|
49
|
+
droppedAttributesCount: 0,
|
50
|
+
droppedEventsCount: 0,
|
51
|
+
droppedLinksCount: 0,
|
52
|
+
attributes: convert_object_to_kv(span_ctx),
|
53
|
+
status: status || { code: 0 },
|
54
|
+
events: span.events.map((i) => ({
|
55
|
+
name: i.name,
|
56
|
+
attributes: convert_object_to_kv(i.attributes),
|
57
|
+
droppedAttributesCount: 0,
|
58
|
+
timeUnixNano: i.timestamp * 1e6
|
59
|
+
}))
|
60
|
+
});
|
61
|
+
}
|
62
|
+
}
|
63
|
+
return request({
|
64
|
+
resourceSpans: [
|
65
|
+
{
|
66
|
+
resource: {
|
67
|
+
attributes: convert_object_to_kv(trace.resource),
|
68
|
+
droppedAttributesCount: 0
|
69
|
+
},
|
70
|
+
scopeSpans
|
71
|
+
}
|
72
|
+
]
|
73
|
+
});
|
74
|
+
};
|
75
|
+
|
76
|
+
|
77
|
+
exports.exporter = exporter;
|
package/exporter.otel.http.mjs
CHANGED
@@ -1 +1,77 @@
|
|
1
|
-
|
1
|
+
// src/exporter.otel.http.ts
|
2
|
+
var convert_value_to_anyvalue = (value) => {
|
3
|
+
let type = typeof value, any_value = {};
|
4
|
+
return type === "string" ? any_value.stringValue = value : type === "number" ? Number.isInteger(value) ? any_value.intValue = value : any_value.doubleValue = value : type === "boolean" ? any_value.boolValue = value : Array.isArray(value) ? any_value.arrayValue = {
|
5
|
+
values: value.map((i) => convert_value_to_anyvalue(i))
|
6
|
+
} : value && (any_value.kvlistValue = { values: convert_object_to_kv(value) }), any_value;
|
7
|
+
}, convert_object_to_kv = (input) => {
|
8
|
+
let value = [];
|
9
|
+
for (let key of Object.keys(input))
|
10
|
+
value.push({
|
11
|
+
key,
|
12
|
+
value: convert_value_to_anyvalue(input[key])
|
13
|
+
});
|
14
|
+
return value;
|
15
|
+
}, map_kind = (kind) => {
|
16
|
+
switch (kind) {
|
17
|
+
default:
|
18
|
+
case "INTERNAL":
|
19
|
+
return 1;
|
20
|
+
case "SERVER":
|
21
|
+
return 2;
|
22
|
+
case "CLIENT":
|
23
|
+
return 3;
|
24
|
+
case "PRODUCER":
|
25
|
+
return 4;
|
26
|
+
case "CONSUMER":
|
27
|
+
return 5;
|
28
|
+
}
|
29
|
+
}, exporter = (request) => (trace) => {
|
30
|
+
let scopeSpans = [];
|
31
|
+
for (let scope of trace.scopeSpans) {
|
32
|
+
let spans = [];
|
33
|
+
scopeSpans.push({
|
34
|
+
scope: scope.scope,
|
35
|
+
spans
|
36
|
+
});
|
37
|
+
for (let span of scope.spans) {
|
38
|
+
let { kind, error, ...span_ctx } = span.context, status;
|
39
|
+
error && (status = {
|
40
|
+
code: 2
|
41
|
+
}, "message" in error && (status.message = error.message)), spans.push({
|
42
|
+
traceId: span.id.trace_id,
|
43
|
+
spanId: span.id.parent_id,
|
44
|
+
parentSpanId: span.parent?.parent_id,
|
45
|
+
name: span.name,
|
46
|
+
kind: map_kind(kind || "INTERNAL"),
|
47
|
+
startTimeUnixNano: span.start * 1e6,
|
48
|
+
endTimeUnixNano: span.end ? span.end * 1e6 : void 0,
|
49
|
+
droppedAttributesCount: 0,
|
50
|
+
droppedEventsCount: 0,
|
51
|
+
droppedLinksCount: 0,
|
52
|
+
attributes: convert_object_to_kv(span_ctx),
|
53
|
+
status: status || { code: 0 },
|
54
|
+
events: span.events.map((i) => ({
|
55
|
+
name: i.name,
|
56
|
+
attributes: convert_object_to_kv(i.attributes),
|
57
|
+
droppedAttributesCount: 0,
|
58
|
+
timeUnixNano: i.timestamp * 1e6
|
59
|
+
}))
|
60
|
+
});
|
61
|
+
}
|
62
|
+
}
|
63
|
+
return request({
|
64
|
+
resourceSpans: [
|
65
|
+
{
|
66
|
+
resource: {
|
67
|
+
attributes: convert_object_to_kv(trace.resource),
|
68
|
+
droppedAttributesCount: 0
|
69
|
+
},
|
70
|
+
scopeSpans
|
71
|
+
}
|
72
|
+
]
|
73
|
+
});
|
74
|
+
};
|
75
|
+
export {
|
76
|
+
exporter
|
77
|
+
};
|
package/exporter.zipkin.js
CHANGED
@@ -1 +1,41 @@
|
|
1
|
-
|
1
|
+
// src/exporter.zipkin.ts
|
2
|
+
const { flattie } = require('flattie');
|
3
|
+
var exporter = (request) => (trace) => {
|
4
|
+
let zipkin = [];
|
5
|
+
for (let scope of trace.scopeSpans)
|
6
|
+
for (let span of scope.spans) {
|
7
|
+
let { kind, error, ...span_ctx } = span.context;
|
8
|
+
error && ("message" in error ? span_ctx.error = {
|
9
|
+
name: error.name,
|
10
|
+
message: error.message,
|
11
|
+
stack: error.stack
|
12
|
+
} : span_ctx.error = !0), zipkin.push({
|
13
|
+
id: span.id.parent_id,
|
14
|
+
traceId: span.id.trace_id,
|
15
|
+
parentId: span.parent ? span.parent.parent_id : void 0,
|
16
|
+
name: span.name,
|
17
|
+
kind: kind === "INTERNAL" ? void 0 : kind,
|
18
|
+
timestamp: span.start * 1e3,
|
19
|
+
duration: span.end ? (span.end - span.start) * 1e3 : void 0,
|
20
|
+
localEndpoint: {
|
21
|
+
serviceName: `${trace.resource["service.name"]}@${scope.scope.name}`
|
22
|
+
},
|
23
|
+
tags: flattie(
|
24
|
+
{
|
25
|
+
...trace.resource,
|
26
|
+
...span_ctx
|
27
|
+
},
|
28
|
+
".",
|
29
|
+
!0
|
30
|
+
),
|
31
|
+
annotations: span.events.map((i) => ({
|
32
|
+
value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
|
33
|
+
timestamp: i.timestamp * 1e3
|
34
|
+
}))
|
35
|
+
});
|
36
|
+
}
|
37
|
+
return request(zipkin);
|
38
|
+
};
|
39
|
+
|
40
|
+
|
41
|
+
exports.exporter = exporter;
|
package/exporter.zipkin.mjs
CHANGED
@@ -1 +1,41 @@
|
|
1
|
-
|
1
|
+
// src/exporter.zipkin.ts
|
2
|
+
import { flattie } from "flattie";
|
3
|
+
var exporter = (request) => (trace) => {
|
4
|
+
let zipkin = [];
|
5
|
+
for (let scope of trace.scopeSpans)
|
6
|
+
for (let span of scope.spans) {
|
7
|
+
let { kind, error, ...span_ctx } = span.context;
|
8
|
+
error && ("message" in error ? span_ctx.error = {
|
9
|
+
name: error.name,
|
10
|
+
message: error.message,
|
11
|
+
stack: error.stack
|
12
|
+
} : span_ctx.error = !0), zipkin.push({
|
13
|
+
id: span.id.parent_id,
|
14
|
+
traceId: span.id.trace_id,
|
15
|
+
parentId: span.parent ? span.parent.parent_id : void 0,
|
16
|
+
name: span.name,
|
17
|
+
kind: kind === "INTERNAL" ? void 0 : kind,
|
18
|
+
timestamp: span.start * 1e3,
|
19
|
+
duration: span.end ? (span.end - span.start) * 1e3 : void 0,
|
20
|
+
localEndpoint: {
|
21
|
+
serviceName: `${trace.resource["service.name"]}@${scope.scope.name}`
|
22
|
+
},
|
23
|
+
tags: flattie(
|
24
|
+
{
|
25
|
+
...trace.resource,
|
26
|
+
...span_ctx
|
27
|
+
},
|
28
|
+
".",
|
29
|
+
!0
|
30
|
+
),
|
31
|
+
annotations: span.events.map((i) => ({
|
32
|
+
value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
|
33
|
+
timestamp: i.timestamp * 1e3
|
34
|
+
}))
|
35
|
+
});
|
36
|
+
}
|
37
|
+
return request(zipkin);
|
38
|
+
};
|
39
|
+
export {
|
40
|
+
exporter
|
41
|
+
};
|
package/index.js
CHANGED
@@ -1 +1,71 @@
|
|
1
|
-
|
1
|
+
// src/index.ts
|
2
|
+
const { measure } = require('rian/utils');
|
3
|
+
|
4
|
+
// src/_internal/index.ts
|
5
|
+
var resource = {};
|
6
|
+
function configure(name, attributes = {}) {
|
7
|
+
resource = {
|
8
|
+
...attributes,
|
9
|
+
["service.name"]: name,
|
10
|
+
["telemetry.sdk.name"]: "rian",
|
11
|
+
["telemetry.sdk.version"]: "0.3.8"
|
12
|
+
};
|
13
|
+
}
|
14
|
+
var span_buffer = /* @__PURE__ */ new Set(), wait_promises = /* @__PURE__ */ new WeakMap();
|
15
|
+
async function report(exporter) {
|
16
|
+
let ps = [], scopes = /* @__PURE__ */ new Map();
|
17
|
+
for (let [span, scope] of span_buffer) {
|
18
|
+
let spans;
|
19
|
+
if (scopes.has(scope) ? spans = scopes.get(scope).spans : scopes.set(scope, {
|
20
|
+
scope,
|
21
|
+
spans: spans = []
|
22
|
+
}), spans.push(span), wait_promises.has(scope)) {
|
23
|
+
let pss = wait_promises.get(scope);
|
24
|
+
ps.push(...pss), pss.clear();
|
25
|
+
}
|
26
|
+
}
|
27
|
+
return span_buffer.clear(), ps.length && await Promise.all(ps), exporter({
|
28
|
+
resource,
|
29
|
+
scopeSpans: scopes.values()
|
30
|
+
});
|
31
|
+
}
|
32
|
+
|
33
|
+
// src/index.ts
|
34
|
+
const tctx = require('tctx');
|
35
|
+
function tracer(name, options) {
|
36
|
+
let should_sample = options?.sampler ?? !0, clock = options?.clock ?? Date, scope = { name }, ps = /* @__PURE__ */ new Set();
|
37
|
+
wait_promises.set(scope, ps);
|
38
|
+
let span = (name2, parent_id) => {
|
39
|
+
let parent = typeof parent_id == "string" ? tctx.parse(parent_id) : parent_id, id = parent?.child() || tctx.make(), is_sampling = typeof should_sample == "boolean" ? should_sample : should_sample(name2, id, scope);
|
40
|
+
is_sampling ? tctx.sample(id) : tctx.unsample(id);
|
41
|
+
let span_obj = {
|
42
|
+
id,
|
43
|
+
parent,
|
44
|
+
name: name2,
|
45
|
+
start: clock.now(),
|
46
|
+
events: [],
|
47
|
+
context: {}
|
48
|
+
};
|
49
|
+
is_sampling && span_buffer.add([span_obj, scope]);
|
50
|
+
let $ = (cb) => measure($, cb);
|
51
|
+
return $.traceparent = id, $.span = (name3, p_id) => span(name3, p_id || id), $.set_context = (ctx) => typeof ctx == "function" ? void (span_obj.context = ctx(span_obj.context)) : void Object.assign(span_obj.context, ctx), $.add_event = (name3, attributes) => {
|
52
|
+
span_obj.events.push({
|
53
|
+
name: name3,
|
54
|
+
timestamp: clock.now(),
|
55
|
+
attributes: attributes || {}
|
56
|
+
});
|
57
|
+
}, $.end = () => {
|
58
|
+
span_obj.end == null && (span_obj.end = clock.now());
|
59
|
+
}, $.__add_promise = (p) => {
|
60
|
+
ps.add(p), p.then(() => ps.delete(p));
|
61
|
+
}, $;
|
62
|
+
};
|
63
|
+
return {
|
64
|
+
span
|
65
|
+
};
|
66
|
+
}
|
67
|
+
|
68
|
+
|
69
|
+
exports.configure = configure;
|
70
|
+
exports.report = report;
|
71
|
+
exports.tracer = tracer;
|
package/index.mjs
CHANGED
@@ -1 +1,71 @@
|
|
1
|
-
|
1
|
+
// src/index.ts
|
2
|
+
import { measure } from "rian/utils";
|
3
|
+
|
4
|
+
// src/_internal/index.ts
|
5
|
+
var resource = {};
|
6
|
+
function configure(name, attributes = {}) {
|
7
|
+
resource = {
|
8
|
+
...attributes,
|
9
|
+
["service.name"]: name,
|
10
|
+
["telemetry.sdk.name"]: "rian",
|
11
|
+
["telemetry.sdk.version"]: "0.3.8"
|
12
|
+
};
|
13
|
+
}
|
14
|
+
var span_buffer = /* @__PURE__ */ new Set(), wait_promises = /* @__PURE__ */ new WeakMap();
|
15
|
+
async function report(exporter) {
|
16
|
+
let ps = [], scopes = /* @__PURE__ */ new Map();
|
17
|
+
for (let [span, scope] of span_buffer) {
|
18
|
+
let spans;
|
19
|
+
if (scopes.has(scope) ? spans = scopes.get(scope).spans : scopes.set(scope, {
|
20
|
+
scope,
|
21
|
+
spans: spans = []
|
22
|
+
}), spans.push(span), wait_promises.has(scope)) {
|
23
|
+
let pss = wait_promises.get(scope);
|
24
|
+
ps.push(...pss), pss.clear();
|
25
|
+
}
|
26
|
+
}
|
27
|
+
return span_buffer.clear(), ps.length && await Promise.all(ps), exporter({
|
28
|
+
resource,
|
29
|
+
scopeSpans: scopes.values()
|
30
|
+
});
|
31
|
+
}
|
32
|
+
|
33
|
+
// src/index.ts
|
34
|
+
import * as tctx from "tctx";
|
35
|
+
function tracer(name, options) {
|
36
|
+
let should_sample = options?.sampler ?? !0, clock = options?.clock ?? Date, scope = { name }, ps = /* @__PURE__ */ new Set();
|
37
|
+
wait_promises.set(scope, ps);
|
38
|
+
let span = (name2, parent_id) => {
|
39
|
+
let parent = typeof parent_id == "string" ? tctx.parse(parent_id) : parent_id, id = parent?.child() || tctx.make(), is_sampling = typeof should_sample == "boolean" ? should_sample : should_sample(name2, id, scope);
|
40
|
+
is_sampling ? tctx.sample(id) : tctx.unsample(id);
|
41
|
+
let span_obj = {
|
42
|
+
id,
|
43
|
+
parent,
|
44
|
+
name: name2,
|
45
|
+
start: clock.now(),
|
46
|
+
events: [],
|
47
|
+
context: {}
|
48
|
+
};
|
49
|
+
is_sampling && span_buffer.add([span_obj, scope]);
|
50
|
+
let $ = (cb) => measure($, cb);
|
51
|
+
return $.traceparent = id, $.span = (name3, p_id) => span(name3, p_id || id), $.set_context = (ctx) => typeof ctx == "function" ? void (span_obj.context = ctx(span_obj.context)) : void Object.assign(span_obj.context, ctx), $.add_event = (name3, attributes) => {
|
52
|
+
span_obj.events.push({
|
53
|
+
name: name3,
|
54
|
+
timestamp: clock.now(),
|
55
|
+
attributes: attributes || {}
|
56
|
+
});
|
57
|
+
}, $.end = () => {
|
58
|
+
span_obj.end == null && (span_obj.end = clock.now());
|
59
|
+
}, $.__add_promise = (p) => {
|
60
|
+
ps.add(p), p.then(() => ps.delete(p));
|
61
|
+
}, $;
|
62
|
+
};
|
63
|
+
return {
|
64
|
+
span
|
65
|
+
};
|
66
|
+
}
|
67
|
+
export {
|
68
|
+
configure,
|
69
|
+
report,
|
70
|
+
tracer
|
71
|
+
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "rian",
|
3
|
-
"version": "0.3.
|
3
|
+
"version": "0.3.8",
|
4
4
|
"description": "Effective tracing for the edge and origins",
|
5
5
|
"keywords": [
|
6
6
|
"opentelemetry",
|
@@ -40,6 +40,11 @@
|
|
40
40
|
"import": "./exporter.zipkin.mjs",
|
41
41
|
"require": "./exporter.zipkin.js"
|
42
42
|
},
|
43
|
+
"./exporter.console": {
|
44
|
+
"types": "./exporter.console.d.ts",
|
45
|
+
"import": "./exporter.console.mjs",
|
46
|
+
"require": "./exporter.console.js"
|
47
|
+
},
|
43
48
|
"./utils": {
|
44
49
|
"types": "./utils.d.ts",
|
45
50
|
"import": "./utils.mjs",
|
@@ -60,25 +65,25 @@
|
|
60
65
|
],
|
61
66
|
"scripts": {
|
62
67
|
"bench": "node -r tsm bench/index.ts",
|
63
|
-
"build": "bundt
|
68
|
+
"build": "bundt",
|
64
69
|
"format": "prettier --write \"{*,{src,test}/**/*,examples/*/**,bench/*,.github/**/*}.+(ts|js|json|yml|md)\"",
|
65
|
-
"pretest": "pnpm run build",
|
66
70
|
"test": "uvu src \".test.ts$\" -r tsm",
|
67
71
|
"typecheck": "tsc --noEmit"
|
68
72
|
},
|
69
73
|
"prettier": "@marais/prettier",
|
70
74
|
"dependencies": {
|
71
75
|
"flattie": "^1.1.0",
|
72
|
-
"tctx": "^0.0
|
76
|
+
"tctx": "^0.1.0"
|
73
77
|
},
|
74
78
|
"devDependencies": {
|
75
79
|
"@marais/prettier": "0.0.4",
|
76
80
|
"@marais/tsconfig": "0.0.4",
|
81
|
+
"@types/node": "20.4.5",
|
77
82
|
"bundt": "2.0.0-next.5",
|
78
83
|
"nanospy": "1.0.0",
|
79
|
-
"prettier": "
|
84
|
+
"prettier": "3.0.0",
|
80
85
|
"tsm": "2.3.0",
|
81
|
-
"typescript": "5.1.
|
86
|
+
"typescript": "5.1.6",
|
82
87
|
"uvu": "0.5.4"
|
83
88
|
},
|
84
89
|
"volta": {
|
package/readme.md
CHANGED
@@ -1,24 +1,39 @@
|
|
1
|
-
<div align="
|
1
|
+
<div align="left">
|
2
|
+
|
3
|
+
<samp>
|
4
|
+
|
2
5
|
<img src="files/logo-light.svg#gh-light-mode-only" alt="rian light mode logo" width="200px">
|
3
6
|
<img src="files/logo-dark.svg#gh-dark-mode-only" alt="rian dark mode logo" width="200px">
|
4
|
-
<br />
|
5
|
-
<br />
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
</samp>
|
9
|
+
|
10
|
+
**A utility to simplify your tracing**
|
11
|
+
|
9
12
|
<a href="https://npm-stat.com/charts.html?package=rian">
|
10
|
-
|
13
|
+
<img src="https://badgen.net/npm/dm/rian?color=black&label=npm%20downloads" alt="js downloads">
|
14
|
+
</a>
|
15
|
+
<a href="https://licenses.dev/npm/rian">
|
16
|
+
<img src="https://licenses.dev/b/npm/rian?style=dark" alt="licenses" />
|
11
17
|
</a>
|
12
|
-
<a href="https://
|
13
|
-
|
18
|
+
<a href="https://unpkg.com/rian/index.mjs">
|
19
|
+
<img src="https://img.badgesize.io/https://unpkg.com/rian/index.mjs?compression=gzip&label=gzip&color=black" alt="gzip size" />
|
14
20
|
</a>
|
15
|
-
<a href="https://
|
16
|
-
|
21
|
+
<a href="https://unpkg.com/rian/index.mjs">
|
22
|
+
<img src="https://img.badgesize.io/https://unpkg.com/rian/index.mjs?compression=brotli&label=brotli&color=black" alt="brotli size" />
|
17
23
|
</a>
|
18
|
-
</span>
|
19
24
|
|
20
|
-
<br
|
21
|
-
<br
|
25
|
+
<br>
|
26
|
+
<br>
|
27
|
+
|
28
|
+
<sup>
|
29
|
+
|
30
|
+
This is free to use software, but if you do like it, consisder supporting me ❤️
|
31
|
+
|
32
|
+
[](https://github.com/sponsors/maraisr)
|
33
|
+
[](https://www.buymeacoffee.com/marais)
|
34
|
+
|
35
|
+
</sup>
|
36
|
+
|
22
37
|
</div>
|
23
38
|
|
24
39
|
## ⚡ Features
|
@@ -40,8 +55,8 @@ import { configure, tracer, report } from 'rian';
|
|
40
55
|
import { exporter } from 'rian/exporter.otel.http';
|
41
56
|
|
42
57
|
// ~> configure the environment, all tracers will inherit this
|
43
|
-
configure('my-service' {
|
44
|
-
'service.version': 'DEV'
|
58
|
+
configure('my-service', {
|
59
|
+
'service.version': 'DEV',
|
45
60
|
});
|
46
61
|
|
47
62
|
// ~> create a tracer — typically "per request" or "per operation".
|
@@ -83,20 +98,47 @@ http.listen((req, executionCtx) => {
|
|
83
98
|
executionCtx.defer(() => report(otel_exporter));
|
84
99
|
return handler(req);
|
85
100
|
});
|
101
|
+
```
|
102
|
+
|
103
|
+
You only need to `report` in your application once somewhere. All spans are collected into the same "bucket".
|
86
104
|
|
87
|
-
|
88
|
-
And we end up with something like this in our reporting tool:
|
105
|
+
<details><summary>Example output</summary>
|
89
106
|
|
90
|
-
[
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
107
|
+
Using: [examples/basic.ts](examples/basic.ts)
|
108
|
+
|
109
|
+
```
|
110
|
+
╭─ basic
|
111
|
+
│ ╭─────────────────────────────────────────────────────────────────╮
|
112
|
+
│ 95 ms │ ┣━━━━━━━━━━┫ │◗ setup
|
113
|
+
│ 41 ms │ ┣━━━━┫ │◗ bootstrap
|
114
|
+
│ 32 ms │ ┣━━━┫ │◗ building
|
115
|
+
│ 59 ms │ ┣━━━━━┫ │◗ precompile
|
116
|
+
│ 80 ms │ ┣━━━━━━━━┫ │◗ verify
|
117
|
+
│ 75 ms │ ┣━━━━━━━┫ │◗ spawn thread
|
118
|
+
│ 371 ms │ ┣╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┫ │◗ doesnt finish
|
119
|
+
│ 347 ms │ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ │◗ running
|
120
|
+
│ 341 ms │ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ │◗ e2e
|
121
|
+
│ 38 ms │ ┣━━━┫ │◗ snapshot
|
122
|
+
│ 13 ms │ ┣━┫ │◗ url for page /my-product/sle…
|
123
|
+
│ ╰┼┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┼┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┼╯
|
124
|
+
│ 0 ms 318.500 ms 637 ms
|
125
|
+
│
|
126
|
+
│ one └┘ unit is less than: 10.443 ms
|
127
|
+
│ total time: 637 ms
|
128
|
+
╰─
|
129
|
+
╭─ thread #1
|
130
|
+
│ ╭──────────────────────────────────────────────────────────────────╮
|
131
|
+
│ 20 ms │ ┣━━━━━━━━━━━━━━━━━━━━┫ │◗ setup
|
132
|
+
│ 63 ms │ ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫ │◗ bootstrap
|
133
|
+
│ ╰┼┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┼┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┼╯
|
134
|
+
│ 0 ms 31.500 ms 63 ms
|
135
|
+
│
|
136
|
+
│ one └┘ unit is less than: 1.016 ms
|
137
|
+
│ total time: 63 ms
|
138
|
+
╰─
|
97
139
|
```
|
98
140
|
|
99
|
-
|
141
|
+
</details>
|
100
142
|
|
101
143
|
## 🔎 API
|
102
144
|
|
@@ -276,6 +318,6 @@ MIT © [Marais Rossouw](https://marais.io)
|
|
276
318
|
|
277
319
|
##### Disclaimer
|
278
320
|
|
279
|
-
<sup>- NewRelic is a registered trademark of https://newrelic.com/ and not affiliated with this project.</sup><br
|
280
|
-
<sup>- Datadog is a registered trademark of https://www.datadoghq.com/ and not affiliated with this project.</sup><br
|
321
|
+
<sup>- NewRelic is a registered trademark of https://newrelic.com/ and not affiliated with this project.</sup><br>
|
322
|
+
<sup>- Datadog is a registered trademark of https://www.datadoghq.com/ and not affiliated with this project.</sup><br>
|
281
323
|
<sup>- Lightstep is a registered trademark of https://lightstep.com/ and not affiliated with this project.</sup>
|
package/utils.js
CHANGED
@@ -1 +1,22 @@
|
|
1
|
-
|
1
|
+
// src/utils.ts
|
2
|
+
function measure(scope, fn) {
|
3
|
+
try {
|
4
|
+
var r = fn(scope), is_promise = r instanceof Promise;
|
5
|
+
return is_promise && scope.__add_promise(
|
6
|
+
r.catch(
|
7
|
+
(e) => void scope.set_context({
|
8
|
+
error: e
|
9
|
+
})
|
10
|
+
).finally(() => scope.end())
|
11
|
+
), r;
|
12
|
+
} catch (e) {
|
13
|
+
throw e instanceof Error && scope.set_context({
|
14
|
+
error: e
|
15
|
+
}), e;
|
16
|
+
} finally {
|
17
|
+
is_promise !== !0 && scope.end();
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
exports.measure = measure;
|
package/utils.mjs
CHANGED
@@ -1 +1,22 @@
|
|
1
|
-
|
1
|
+
// src/utils.ts
|
2
|
+
function measure(scope, fn) {
|
3
|
+
try {
|
4
|
+
var r = fn(scope), is_promise = r instanceof Promise;
|
5
|
+
return is_promise && scope.__add_promise(
|
6
|
+
r.catch(
|
7
|
+
(e) => void scope.set_context({
|
8
|
+
error: e
|
9
|
+
})
|
10
|
+
).finally(() => scope.end())
|
11
|
+
), r;
|
12
|
+
} catch (e) {
|
13
|
+
throw e instanceof Error && scope.set_context({
|
14
|
+
error: e
|
15
|
+
}), e;
|
16
|
+
} finally {
|
17
|
+
is_promise !== !0 && scope.end();
|
18
|
+
}
|
19
|
+
}
|
20
|
+
export {
|
21
|
+
measure
|
22
|
+
};
|