rian 0.3.7 → 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 -1
- package/exporter.console.mjs +67 -1
- 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 +3 -3
- package/readme.md +3 -0
- 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
|
+
};
|
package/exporter.console.js
CHANGED
|
@@ -1 +1,67 @@
|
|
|
1
|
-
|
|
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;
|
package/exporter.console.mjs
CHANGED
|
@@ -1 +1,67 @@
|
|
|
1
|
-
|
|
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",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
],
|
|
66
66
|
"scripts": {
|
|
67
67
|
"bench": "node -r tsm bench/index.ts",
|
|
68
|
-
"build": "bundt
|
|
68
|
+
"build": "bundt",
|
|
69
69
|
"format": "prettier --write \"{*,{src,test}/**/*,examples/*/**,bench/*,.github/**/*}.+(ts|js|json|yml|md)\"",
|
|
70
70
|
"test": "uvu src \".test.ts$\" -r tsm",
|
|
71
71
|
"typecheck": "tsc --noEmit"
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"prettier": "@marais/prettier",
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"flattie": "^1.1.0",
|
|
76
|
-
"tctx": "^0.0
|
|
76
|
+
"tctx": "^0.1.0"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"@marais/prettier": "0.0.4",
|
package/readme.md
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
<a href="https://npm-stat.com/charts.html?package=rian">
|
|
13
13
|
<img src="https://badgen.net/npm/dm/rian?color=black&label=npm%20downloads" alt="js downloads">
|
|
14
14
|
</a>
|
|
15
|
+
<a href="https://licenses.dev/npm/rian">
|
|
16
|
+
<img src="https://licenses.dev/b/npm/rian?style=dark" alt="licenses" />
|
|
17
|
+
</a>
|
|
15
18
|
<a href="https://unpkg.com/rian/index.mjs">
|
|
16
19
|
<img src="https://img.badgesize.io/https://unpkg.com/rian/index.mjs?compression=gzip&label=gzip&color=black" alt="gzip size" />
|
|
17
20
|
</a>
|
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
|
+
};
|