rian 0.3.0-next.9 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- package/async.d.ts +56 -3
- package/async.js +1 -93
- package/async.mjs +1 -93
- package/exporter.otel.http.js +1 -77
- package/exporter.otel.http.mjs +1 -77
- package/exporter.zipkin.js +1 -41
- package/exporter.zipkin.mjs +1 -41
- package/index.d.ts +76 -22
- package/index.js +1 -74
- package/index.mjs +1 -74
- package/package.json +2 -2
- package/readme.md +125 -79
- package/utils.d.ts +10 -51
- package/utils.js +1 -26
- package/utils.mjs +1 -26
- package/exporter.otel.http/index.d.ts +0 -3
- package/exporter.otel.http/index.js +0 -1
- package/exporter.otel.http/index.mjs +0 -1
- package/exporter.zipkin/index.d.ts +0 -3
- package/exporter.zipkin/index.js +0 -1
- package/exporter.zipkin/index.mjs +0 -1
- package/utils/index.d.ts +0 -68
- package/utils/index.js +0 -1
- package/utils/index.mjs +0 -1
package/index.d.ts
CHANGED
@@ -3,8 +3,7 @@ import type { Traceparent } from 'tctx';
|
|
3
3
|
// --- tracer
|
4
4
|
|
5
5
|
/**
|
6
|
-
*
|
7
|
-
* during this execution.
|
6
|
+
* The exporter is called when the {@link report} method is called.
|
8
7
|
*/
|
9
8
|
export type Exporter = (trace: {
|
10
9
|
resource: Context;
|
@@ -23,12 +22,14 @@ export type Options = {
|
|
23
22
|
sampler?: Sampler | boolean;
|
24
23
|
|
25
24
|
/**
|
26
|
-
* A root, or extracted w3c traceparent
|
25
|
+
* A root, or extracted w3c traceparent string header.
|
27
26
|
*
|
28
27
|
* If the id is malformed, the {@link create} method will throw an exception. If no root is
|
29
|
-
* provided then one will be created obeying the {@link Options.sampler|sampling} rules.
|
28
|
+
* provided then one will be created obeying the {@link Options.sampler|sampling} rules on each span.
|
30
29
|
*/
|
31
30
|
traceparent?: string | null;
|
31
|
+
|
32
|
+
clock?: ClockLike;
|
32
33
|
};
|
33
34
|
|
34
35
|
export type Tracer = Pick<Scope, 'span'>;
|
@@ -41,17 +42,24 @@ export type Context = {
|
|
41
42
|
};
|
42
43
|
|
43
44
|
/**
|
44
|
-
*
|
45
|
-
* decisions is made preemptively.
|
46
|
-
*
|
47
|
-
* Returning false will not include this span in the {@link Exporter}.
|
45
|
+
* Allows a sampling decision to be made. This method will influence the {@link Span.id|traceparent} sampling flag.
|
48
46
|
*
|
49
|
-
*
|
47
|
+
* Return true if the span should be sampled, and reported to the {@link Exporter}.
|
48
|
+
* Return false if the span should not be sampled, and not reported to the {@link Exporter}.
|
50
49
|
*/
|
51
50
|
export type Sampler = (
|
51
|
+
/**
|
52
|
+
* The name of the span.
|
53
|
+
*/
|
52
54
|
readonly name: string,
|
55
|
+
/**
|
56
|
+
* The traceparent id of the span.
|
57
|
+
*/
|
53
58
|
readonly id: Traceparent,
|
54
|
-
|
59
|
+
/**
|
60
|
+
* The tracer this span belongs to.
|
61
|
+
*/
|
62
|
+
readonly tracer: { readonly name: string },
|
55
63
|
) => boolean;
|
56
64
|
|
57
65
|
// --- spans
|
@@ -61,20 +69,15 @@ export type Sampler = (
|
|
61
69
|
* {@link Span.name|name}, and a {@link Span.start|start} and {@link Span.end|end} time.
|
62
70
|
*
|
63
71
|
* Each span should be named, not too vague, and not too precise. For example, "resolve_user_ids"
|
64
|
-
* and not "resolver_user_ids[1,2,3]" nor "
|
72
|
+
* and not "resolver_user_ids[1,2,3]" nor "resolver".
|
65
73
|
*
|
66
74
|
* A span forms part of a wider trace, and can be visualized like:
|
67
75
|
*
|
68
76
|
* ```plain
|
69
77
|
* [Span A················································(2ms)]
|
70
78
|
* [Span B·········································(1.7ms)]
|
71
|
-
* [Span D···············(0.8ms)]
|
79
|
+
* [Span D···············(0.8ms)] [Span C......(0.6ms)]
|
72
80
|
* ```
|
73
|
-
*
|
74
|
-
* ---
|
75
|
-
*
|
76
|
-
* Spans are aimed to interoperate with
|
77
|
-
* {@link https://github.com/opentracing/specification/blob/master/specification.md|OpenTracing's Spans}, albeit not entirely api compatible — they do share principles.
|
78
81
|
*/
|
79
82
|
export type Span = {
|
80
83
|
/**
|
@@ -82,6 +85,7 @@ export type Span = {
|
|
82
85
|
* or stage of the larger stack.
|
83
86
|
*
|
84
87
|
* @example
|
88
|
+
*
|
85
89
|
* "resolve_user_ids"
|
86
90
|
* "[POST] /api"
|
87
91
|
*/
|
@@ -105,7 +109,7 @@ export type Span = {
|
|
105
109
|
/**
|
106
110
|
* The time represented as a UNIX epoch timestamp in milliseconds when this span was created.
|
107
111
|
* Typically, via
|
108
|
-
* {@link Scope.
|
112
|
+
* {@link Scope.span|scope.span()}.
|
109
113
|
*/
|
110
114
|
start: number;
|
111
115
|
|
@@ -119,7 +123,7 @@ export type Span = {
|
|
119
123
|
* An arbitrary context object useful for storing information during a trace.
|
120
124
|
*
|
121
125
|
* Usually following a convention such as `tag.*`, `http.*` or any of the
|
122
|
-
* {@link https://
|
126
|
+
* {@link https://opentelemetry.io/docs/reference/specification/trace/semantic_conventions/|OpenTelemetry Trace Semantic Conventions}.
|
123
127
|
*
|
124
128
|
* ### Note!
|
125
129
|
*
|
@@ -153,7 +157,12 @@ export type Scope = {
|
|
153
157
|
/**
|
154
158
|
* Forks the span into a new child span.
|
155
159
|
*/
|
156
|
-
span(
|
160
|
+
span(
|
161
|
+
/**
|
162
|
+
* @borrows {@link Span.name}
|
163
|
+
*/
|
164
|
+
name: string,
|
165
|
+
): CallableScope;
|
157
166
|
|
158
167
|
/**
|
159
168
|
* Allows the span's context to be set. Passing an object will be `Object.assign`ed into the
|
@@ -177,13 +186,33 @@ export type Scope = {
|
|
177
186
|
};
|
178
187
|
|
179
188
|
export type CallableScope = Scope & {
|
180
|
-
|
189
|
+
<Fn extends (scope: Omit<Scope, 'end'>) => any>(cb: Fn): ReturnType<Fn>;
|
181
190
|
};
|
182
191
|
|
183
192
|
// --- main api
|
184
193
|
|
194
|
+
/**
|
195
|
+
* A tracer is a logical unit in your application. This alleviates the need to pass around a tracer instance.
|
196
|
+
*
|
197
|
+
* All spans produced by a tracer will all collect into a single span collection that is given to {@link report}.
|
198
|
+
*
|
199
|
+
* @example
|
200
|
+
*
|
201
|
+
* ```ts
|
202
|
+
* // file: server.ts
|
203
|
+
* const trace = tracer('server');
|
204
|
+
*
|
205
|
+
* // file: orm.ts
|
206
|
+
* const trace = tracer('orm');
|
207
|
+
*
|
208
|
+
* // file: api.ts
|
209
|
+
* const trace = tracer('api');
|
210
|
+
* ```
|
211
|
+
*/
|
185
212
|
export function tracer(name: string, options?: Options): Tracer;
|
186
213
|
|
214
|
+
// -- general api
|
215
|
+
|
187
216
|
/**
|
188
217
|
* Awaits all active promises, and then calls the {@link Options.exporter|exporter}. Passing all collected spans.
|
189
218
|
*/
|
@@ -191,5 +220,30 @@ export async function report<T extends Exporter>(
|
|
191
220
|
exporter: T,
|
192
221
|
): Promise<ReturnType<T>>;
|
193
222
|
|
194
|
-
|
223
|
+
/**
|
224
|
+
* Calling this method will set the resource attributes for this runtime. This is useful for things like:
|
225
|
+
* - setting the deployment environment of the application
|
226
|
+
* - setting the k8s namespace
|
227
|
+
* - ...
|
228
|
+
*
|
229
|
+
* The `name` argument will set the `service.name` attribute. And is required.
|
230
|
+
*
|
231
|
+
* The fields can be whatever you want, but it is recommended to follow the {@link https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/|OpenTelemetry Resource Semantic Conventions}.
|
232
|
+
*
|
233
|
+
* @example
|
234
|
+
*
|
235
|
+
* ```ts
|
236
|
+
* configure('my-service', { 'deployment.environment': 'production', 'k8s.namespace.name': 'default' });
|
237
|
+
* ```
|
238
|
+
*/
|
195
239
|
export function configure(name: string, attributes: Context = {}): void;
|
240
|
+
|
241
|
+
/**
|
242
|
+
* Provinding a clock allows you to control the time of the span.
|
243
|
+
*/
|
244
|
+
export type ClockLike = {
|
245
|
+
/**
|
246
|
+
* Must return the number of milliseconds since the epoch.
|
247
|
+
*/
|
248
|
+
now(): number;
|
249
|
+
};
|
package/index.js
CHANGED
@@ -1,74 +1 @@
|
|
1
|
-
|
2
|
-
const { measureFn } = require('rian/utils');
|
3
|
-
const { make, parse, SAMPLED_FLAG } = require('tctx');
|
4
|
-
|
5
|
-
// src/_internal/index.ts
|
6
|
-
const { is_sampled } = require('tctx');
|
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.0-next.9"
|
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 [span, scope] of span_buffer) {
|
20
|
-
let spans;
|
21
|
-
scopes.has(scope) ? spans = scopes.get(scope).spans : scopes.set(scope, {
|
22
|
-
scope,
|
23
|
-
spans: spans = []
|
24
|
-
}), spans.push(span), wait_promises.has(scope) && (ps.push(...wait_promises.get(scope)), wait_promises.delete(scope));
|
25
|
-
}
|
26
|
-
return span_buffer.clear(), ps.length && await Promise.all(ps), exporter({
|
27
|
-
resource,
|
28
|
-
scopeSpans: scopes.values()
|
29
|
-
});
|
30
|
-
}
|
31
|
-
function defaultSampler(_name, id) {
|
32
|
-
return is_sampled(id);
|
33
|
-
}
|
34
|
-
|
35
|
-
// src/index.ts
|
36
|
-
function tracer(name, options) {
|
37
|
-
let sampler = options?.sampler ?? defaultSampler, scope = { name }, ps = /* @__PURE__ */ new Set();
|
38
|
-
wait_promises.set(scope, ps);
|
39
|
-
let root_id = typeof options?.traceparent == "string" ? parse(options.traceparent) : void 0, span = (name2, parent) => {
|
40
|
-
let id = parent ? parent.child() : make(), should_sample = typeof sampler != "boolean" ? sampler(name2, id, scope) : sampler;
|
41
|
-
should_sample ? id.flags | SAMPLED_FLAG : id.flags & ~SAMPLED_FLAG;
|
42
|
-
let span_obj = {
|
43
|
-
id,
|
44
|
-
parent,
|
45
|
-
start: Date.now(),
|
46
|
-
name: name2,
|
47
|
-
events: [],
|
48
|
-
context: {}
|
49
|
-
};
|
50
|
-
should_sample && span_buffer.add([span_obj, scope]);
|
51
|
-
let $ = (cb) => measureFn($, cb);
|
52
|
-
return $.traceparent = id, $.span = (name3) => span(name3, 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) => {
|
53
|
-
span_obj.events.push({
|
54
|
-
name: name3,
|
55
|
-
timestamp: Date.now(),
|
56
|
-
attributes: attributes || {}
|
57
|
-
});
|
58
|
-
}, $.end = () => {
|
59
|
-
span_obj.end == null && (span_obj.end = Date.now());
|
60
|
-
}, $.__add_promise = (p) => {
|
61
|
-
ps.add(p), p.then(() => ps.delete(p));
|
62
|
-
}, $;
|
63
|
-
};
|
64
|
-
return {
|
65
|
-
span(name2) {
|
66
|
-
return span(name2, root_id);
|
67
|
-
}
|
68
|
-
};
|
69
|
-
}
|
70
|
-
|
71
|
-
|
72
|
-
exports.configure = configure;
|
73
|
-
exports.report = report;
|
74
|
-
exports.tracer = tracer;
|
1
|
+
const { measure:e } = require('rian/utils');const { make:t, parse:n, SAMPLED_FLAG:a } = require('tctx');const { is_sampled:r } = require('tctx');var o={};function s(e,t={}){o={...t,"service.name":e,"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.3.1"}}var p=new Set,c=new WeakMap;async function i(e){let t=[],n=new Map;for(let[e,a]of p){let r;n.has(a)?r=n.get(a).spans:n.set(a,{scope:a,spans:r=[]}),r.push(e),c.has(a)&&(t.push(...c.get(a)),c.delete(a))}return p.clear(),t.length&&await Promise.all(t),e({resource:o,scopeSpans:n.values()})}function l(e,t){return r(t)}function d(a,r){let o=r?.sampler??l,s=r?.clock??Date,i={name:a},d=new Set;c.set(i,d);let m="string"==typeof r?.traceparent?n(r.traceparent):void 0,u=(n,a)=>{let r=a?a.child():t(),c="boolean"!=typeof o?o(n,r,i):o;r.flags;let l={id:r,parent:a,start:s.now(),name:n,events:[],context:{}};c&&p.add([l,i]);let m=t=>e(m,t);return m.traceparent=r,m.span=e=>u(e,r),m.set_context=e=>"function"==typeof e?void(l.context=e(l.context)):void Object.assign(l.context,e),m.add_event=(e,t)=>{l.events.push({name:e,timestamp:s.now(),attributes:t||{}})},m.end=()=>{null==l.end&&(l.end=s.now())},m.__add_promise=e=>{d.add(e),e.then((()=>d.delete(e)))},m};return{span:e=>u(e,m)}}exports.configure=s;exports.report=i;exports.tracer=d;
|
package/index.mjs
CHANGED
@@ -1,74 +1 @@
|
|
1
|
-
|
2
|
-
import { measureFn } from "rian/utils";
|
3
|
-
import { make, parse, SAMPLED_FLAG } from "tctx";
|
4
|
-
|
5
|
-
// src/_internal/index.ts
|
6
|
-
import { is_sampled } from "tctx";
|
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.0-next.9"
|
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 [span, scope] of span_buffer) {
|
20
|
-
let spans;
|
21
|
-
scopes.has(scope) ? spans = scopes.get(scope).spans : scopes.set(scope, {
|
22
|
-
scope,
|
23
|
-
spans: spans = []
|
24
|
-
}), spans.push(span), wait_promises.has(scope) && (ps.push(...wait_promises.get(scope)), wait_promises.delete(scope));
|
25
|
-
}
|
26
|
-
return span_buffer.clear(), ps.length && await Promise.all(ps), exporter({
|
27
|
-
resource,
|
28
|
-
scopeSpans: scopes.values()
|
29
|
-
});
|
30
|
-
}
|
31
|
-
function defaultSampler(_name, id) {
|
32
|
-
return is_sampled(id);
|
33
|
-
}
|
34
|
-
|
35
|
-
// src/index.ts
|
36
|
-
function tracer(name, options) {
|
37
|
-
let sampler = options?.sampler ?? defaultSampler, scope = { name }, ps = /* @__PURE__ */ new Set();
|
38
|
-
wait_promises.set(scope, ps);
|
39
|
-
let root_id = typeof options?.traceparent == "string" ? parse(options.traceparent) : void 0, span = (name2, parent) => {
|
40
|
-
let id = parent ? parent.child() : make(), should_sample = typeof sampler != "boolean" ? sampler(name2, id, scope) : sampler;
|
41
|
-
should_sample ? id.flags | SAMPLED_FLAG : id.flags & ~SAMPLED_FLAG;
|
42
|
-
let span_obj = {
|
43
|
-
id,
|
44
|
-
parent,
|
45
|
-
start: Date.now(),
|
46
|
-
name: name2,
|
47
|
-
events: [],
|
48
|
-
context: {}
|
49
|
-
};
|
50
|
-
should_sample && span_buffer.add([span_obj, scope]);
|
51
|
-
let $ = (cb) => measureFn($, cb);
|
52
|
-
return $.traceparent = id, $.span = (name3) => span(name3, 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) => {
|
53
|
-
span_obj.events.push({
|
54
|
-
name: name3,
|
55
|
-
timestamp: Date.now(),
|
56
|
-
attributes: attributes || {}
|
57
|
-
});
|
58
|
-
}, $.end = () => {
|
59
|
-
span_obj.end == null && (span_obj.end = Date.now());
|
60
|
-
}, $.__add_promise = (p) => {
|
61
|
-
ps.add(p), p.then(() => ps.delete(p));
|
62
|
-
}, $;
|
63
|
-
};
|
64
|
-
return {
|
65
|
-
span(name2) {
|
66
|
-
return span(name2, root_id);
|
67
|
-
}
|
68
|
-
};
|
69
|
-
}
|
70
|
-
export {
|
71
|
-
configure,
|
72
|
-
report,
|
73
|
-
tracer
|
74
|
-
};
|
1
|
+
import{measure as e}from"rian/utils";import{make as t,parse as n,SAMPLED_FLAG as a}from"tctx";import{is_sampled as r}from"tctx";var o={};function s(e,t={}){o={...t,"service.name":e,"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.3.1"}}var p=new Set,c=new WeakMap;async function i(e){let t=[],n=new Map;for(let[e,a]of p){let r;n.has(a)?r=n.get(a).spans:n.set(a,{scope:a,spans:r=[]}),r.push(e),c.has(a)&&(t.push(...c.get(a)),c.delete(a))}return p.clear(),t.length&&await Promise.all(t),e({resource:o,scopeSpans:n.values()})}function l(e,t){return r(t)}function d(a,r){let o=r?.sampler??l,s=r?.clock??Date,i={name:a},d=new Set;c.set(i,d);let m="string"==typeof r?.traceparent?n(r.traceparent):void 0,u=(n,a)=>{let r=a?a.child():t(),c="boolean"!=typeof o?o(n,r,i):o;r.flags;let l={id:r,parent:a,start:s.now(),name:n,events:[],context:{}};c&&p.add([l,i]);let m=t=>e(m,t);return m.traceparent=r,m.span=e=>u(e,r),m.set_context=e=>"function"==typeof e?void(l.context=e(l.context)):void Object.assign(l.context,e),m.add_event=(e,t)=>{l.events.push({name:e,timestamp:s.now(),attributes:t||{}})},m.end=()=>{null==l.end&&(l.end=s.now())},m.__add_promise=e=>{d.add(e),e.then((()=>d.delete(e)))},m};return{span:e=>u(e,m)}}export{s as configure,i as report,d as tracer};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "rian",
|
3
|
-
"version": "0.3.
|
3
|
+
"version": "0.3.1",
|
4
4
|
"description": "Effective tracing for the edge and origins",
|
5
5
|
"keywords": [
|
6
6
|
"opentelemetry",
|
@@ -60,7 +60,7 @@
|
|
60
60
|
],
|
61
61
|
"scripts": {
|
62
62
|
"bench": "node -r tsm bench/index.ts",
|
63
|
-
"build": "bundt",
|
63
|
+
"build": "bundt --minify",
|
64
64
|
"format": "prettier --write \"{*,{src,test}/**/*,examples/*/**,bench/*,.github/**/*}.+(ts|js|json|yml|md)\"",
|
65
65
|
"pretest": "pnpm run build",
|
66
66
|
"test": "uvu -r tsm test \".spec.m?ts$\"",
|