rian 0.2.4 → 0.3.0-next.1
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/exporter.otel.http/index.js +1 -1
- package/exporter.otel.http/index.mjs +1 -1
- package/exporter.zipkin/index.js +1 -1
- package/exporter.zipkin/index.mjs +1 -1
- package/index.d.ts +5 -3
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +1 -1
- package/readme.md +18 -61
- package/utils/index.d.ts +9 -11
- package/utils/index.js +1 -1
- package/utils/index.mjs +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var e=r=>{let n=typeof r,a={};return"string"===n?a.stringValue=r:"number"===n?Number.isInteger(r)?a.intValue=r:a.doubleValue=r:"boolean"===n?a.boolValue=r:Array.isArray(r)?a.arrayValue={values:r.map((t=>e(t)))}:r&&(a.kvlistValue={values:t(r)}),a},t=t=>{let r=[];for(let n of Object.keys(t))r.push({key:n,value:e(t[n])});return r},r=e=>{switch(e){default:case"INTERNAL":return 1;case"SERVER":return 2;case"CLIENT":return 3;case"PRODUCER":return 4;case"CONSUMER":return 5}},n=e=>(n,a)=>{let s=[];for(let e of n){let n,{kind:a,error:u,...i}=e.context;u&&(n={code:2},"message"in u&&(n.message=u.message)),s.push({traceId:e.id.trace_id,spanId:e.id.parent_id,parentSpanId:e.parent?.parent_id,name:e.name,kind:r(a||"INTERNAL"),startTimeUnixNano:1e6*e.start,endTimeUnixNano:e.end?1e6*e.end:void 0,droppedAttributesCount:0,droppedEventsCount:0,droppedLinksCount:0,attributes:t(i),status:n||{code:0},events:e.events.map((e=>({name:e.name,attributes:t(e.attributes),droppedAttributesCount:0,timeUnixNano:1e6*e.timestamp})))})}return e({resourceSpans:[{resource:{attributes:t(a),droppedAttributesCount:0},instrumentationLibrarySpans:[{instrumentationLibrary:{name:"rian",version:"0.3.0-next.1"},spans:s}]}]})};exports.exporter=n;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
var e=r=>{let n=typeof r,a={};return"string"===n?a.stringValue=r:"number"===n?Number.isInteger(r)?a.intValue=r:a.doubleValue=r:"boolean"===n?a.boolValue=r:Array.isArray(r)?a.arrayValue={values:r.map((t=>e(t)))}:r&&(a.kvlistValue={values:t(r)}),a},t=t=>{let r=[];for(let n of Object.keys(t))r.push({key:n,value:e(t[n])});return r},r=e=>{switch(e){default:case"INTERNAL":return 1;case"SERVER":return 2;case"CLIENT":return 3;case"PRODUCER":return 4;case"CONSUMER":return 5}},n=e=>(n,a)=>{let s=[];for(let e of n){let n,{kind:a,error:u,...i}=e.context;u&&(n={code:2},"message"in u&&(n.message=u.message)),s.push({traceId:e.id.trace_id,spanId:e.id.parent_id,parentSpanId:e.parent?.parent_id,name:e.name,kind:r(a||"INTERNAL"),startTimeUnixNano:1e6*e.start,endTimeUnixNano:e.end?1e6*e.end:void 0,droppedAttributesCount:0,droppedEventsCount:0,droppedLinksCount:0,attributes:t(i),status:n||{code:0},events:e.events.map((e=>({name:e.name,attributes:t(e.attributes),droppedAttributesCount:0,timeUnixNano:1e6*e.timestamp})))})}return e({resourceSpans:[{resource:{attributes:t(a),droppedAttributesCount:0},instrumentationLibrarySpans:[{instrumentationLibrary:{name:"rian",version:"0.3.0-next.1"},spans:s}]}]})};export{n as exporter};
|
package/exporter.zipkin/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const { flattie:e } = require('flattie');var t=t=>(a,
|
|
1
|
+
const { flattie:e } = require('flattie');var t=t=>(a,r)=>{let n=[];for(let t of a){let{kind:a,error:i,...s}=t.context;i&&(s.error=!("message"in i)||{name:i.name,message:i.message,stack:i.stack}),n.push({id:t.id.parent_id,traceId:t.id.trace_id,parentId:t.parent?t.parent.parent_id:void 0,name:t.name,kind:"INTERNAL"===a?void 0:a,timestamp:1e3*t.start,duration:t.end?1e3*(t.end-t.start):void 0,localEndpoint:{serviceName:r["service.name"]},tags:e({...r,...s},".",!0),annotations:t.events.map((e=>({value:`${e.name} :: ${JSON.stringify(e.attributes)}`,timestamp:1e3*e.timestamp})))})}return t(n)};exports.exporter=t;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{flattie as e}from"flattie";var t=t=>(a,
|
|
1
|
+
import{flattie as e}from"flattie";var t=t=>(a,r)=>{let n=[];for(let t of a){let{kind:a,error:i,...s}=t.context;i&&(s.error=!("message"in i)||{name:i.name,message:i.message,stack:i.stack}),n.push({id:t.id.parent_id,traceId:t.id.trace_id,parentId:t.parent?t.parent.parent_id:void 0,name:t.name,kind:"INTERNAL"===a?void 0:a,timestamp:1e3*t.start,duration:t.end?1e3*(t.end-t.start):void 0,localEndpoint:{serviceName:r["service.name"]},tags:e({...r,...s},".",!0),annotations:t.events.map((e=>({value:`${e.name} :: ${JSON.stringify(e.attributes)}`,timestamp:1e3*e.timestamp})))})}return t(n)};export{t as exporter};
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Traceparent } from 'tctx';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Spans are units within a distributed trace. Spans encapsulate mainly 3 pieces of information, a
|
|
3
5
|
* {@link Span.name|name}, and a {@link Span.start|start} and {@link Span.end|end} time.
|
|
@@ -93,7 +95,7 @@ export interface Scope {
|
|
|
93
95
|
/**
|
|
94
96
|
* Forks the span into a new child span.
|
|
95
97
|
*/
|
|
96
|
-
|
|
98
|
+
span(name: string): CallableScope;
|
|
97
99
|
|
|
98
100
|
/**
|
|
99
101
|
* Allows the span's context to be set. Passing an object will be `Object.assign`ed into the
|
|
@@ -116,8 +118,8 @@ export interface Scope {
|
|
|
116
118
|
end(): void;
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
export interface Tracer extends
|
|
120
|
-
|
|
121
|
+
export interface Tracer extends Pick<Scope, 'span'> {
|
|
122
|
+
report(): ReturnType<Exporter>;
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
/**
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const { measureFn:e } = require('rian/utils');const t = require('tctx');var n=(e,n)=>!n||t.is_sampled(n),a=
|
|
1
|
+
const { measureFn:e } = require('rian/utils');const t = require('tctx');var n=(e,n)=>!n||t.is_sampled(n),a=(a,r)=>{let o=new Set,s=new Set,i=r.sampler||n,d="boolean"!=typeof i,p=r.context||{};p["service.name"]=a,p["telemetry.sdk.name"]="rian",p["telemetry.sdk.version"]="0.3.0-next.1";let m="string"==typeof r.traceparent?t.parse(r.traceparent):void 0,c=(n,a)=>{let p=d?i(n,a,r.context):i,m=a?a.child(p):t.make(p),l={id:m,parent:a,start:Date.now(),name:n,events:[],context:{}};p&&o.add(l);let x=t=>e(x,t);return x.traceparent=m,x.span=e=>c(e,m),x.set_context=e=>"function"==typeof e?void(l.context=e(l.context)):void Object.assign(l.context,e),x.add_event=(e,t)=>{l.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},x.end=()=>{null==l.end&&(l.end=Date.now())},x.__add_promise=s.add.bind(s),x};return{span:e=>c(e,m),report:async()=>(s.size>0&&await Promise.all([...s.values()]),r.exporter(o,p))}};exports.create=a;
|
package/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{measureFn as e}from"rian/utils";import*as t from"tctx";var n=(e,n)=>!n||t.is_sampled(n),a=
|
|
1
|
+
import{measureFn as e}from"rian/utils";import*as t from"tctx";var n=(e,n)=>!n||t.is_sampled(n),a=(a,r)=>{let o=new Set,s=new Set,i=r.sampler||n,d="boolean"!=typeof i,p=r.context||{};p["service.name"]=a,p["telemetry.sdk.name"]="rian",p["telemetry.sdk.version"]="0.3.0-next.1";let m="string"==typeof r.traceparent?t.parse(r.traceparent):void 0,c=(n,a)=>{let p=d?i(n,a,r.context):i,m=a?a.child(p):t.make(p),l={id:m,parent:a,start:Date.now(),name:n,events:[],context:{}};p&&o.add(l);let x=t=>e(x,t);return x.traceparent=m,x.span=e=>c(e,m),x.set_context=e=>"function"==typeof e?void(l.context=e(l.context)):void Object.assign(l.context,e),x.add_event=(e,t)=>{l.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},x.end=()=>{null==l.end&&(l.end=Date.now())},x.__add_promise=s.add.bind(s),x};return{span:e=>c(e,m),report:async()=>(s.size>0&&await Promise.all([...s.values()]),r.exporter(o,p))}};export{a as create};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
- 🤔 **Familiar** — looks very much like OpenTracing.
|
|
30
30
|
|
|
31
|
-
- ✅ **Simple** — `create` a tracer, and `.
|
|
31
|
+
- ✅ **Simple** — `create` a tracer, and `.report()` a tracer, done.
|
|
32
32
|
|
|
33
33
|
- 🏎 **Performant** — check the [benchmarks](#-benchmark).
|
|
34
34
|
|
|
@@ -52,21 +52,23 @@ const otel_endpoint = exporter((payload) =>
|
|
|
52
52
|
);
|
|
53
53
|
|
|
54
54
|
// ~> Create a tracer — typically "per request" or "per operation"
|
|
55
|
-
const tracer = create('
|
|
55
|
+
const tracer = create('my-service', {
|
|
56
56
|
exporter: otel_endpoint,
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
// Let us trace
|
|
60
60
|
|
|
61
|
-
tracer.
|
|
61
|
+
const req = tracer.span('GET ~> /data');
|
|
62
|
+
|
|
63
|
+
req.set_context({
|
|
62
64
|
user: request_context.user_id,
|
|
63
65
|
});
|
|
64
66
|
|
|
65
67
|
// ~> Wrap any method and be timed 🕺🏻
|
|
66
|
-
const data = await measure(
|
|
68
|
+
const data = await measure(req.span('db::read'), get_data);
|
|
67
69
|
|
|
68
70
|
// ~> Maybe have some in-flow spanning
|
|
69
|
-
const span =
|
|
71
|
+
const span = req.span('process records');
|
|
70
72
|
|
|
71
73
|
for (let row of data) {
|
|
72
74
|
span.add_event('doing stuff', { id: row.id });
|
|
@@ -75,8 +77,10 @@ for (let row of data) {
|
|
|
75
77
|
|
|
76
78
|
span.end();
|
|
77
79
|
|
|
80
|
+
req.end();
|
|
81
|
+
|
|
78
82
|
// ~> And finally let's export — will also end the root span.
|
|
79
|
-
await tracer.
|
|
83
|
+
await tracer.report();
|
|
80
84
|
|
|
81
85
|
/*
|
|
82
86
|
And we end up with something like this in our reporting tool:
|
|
@@ -101,50 +105,10 @@ The main and _default_ module responsible for creating and provisioning spans.
|
|
|
101
105
|
|
|
102
106
|
Exports the spans created using the zipkin protocol and leaves the shipping up to you.
|
|
103
107
|
|
|
104
|
-
> 💡 Note ~> with the nature of zipkin, the `localEndpoint` must be set in your span context.
|
|
105
|
-
>
|
|
106
|
-
> <details><summary>Example</summary>
|
|
107
|
-
>
|
|
108
|
-
> ```ts
|
|
109
|
-
> const tracer = create('example', {
|
|
110
|
-
> context: {
|
|
111
|
-
> localEndpoint: {
|
|
112
|
-
> serviceName: 'my-service', // 👈 important part
|
|
113
|
-
> },
|
|
114
|
-
> },
|
|
115
|
-
> });
|
|
116
|
-
> ```
|
|
117
|
-
>
|
|
118
|
-
> Both of these are functionally equivalent. `service.name` will be used if no `localEndpoint.serviceName` is set.
|
|
119
|
-
>
|
|
120
|
-
> ```ts
|
|
121
|
-
> const tracer = create('example', {
|
|
122
|
-
> context: {
|
|
123
|
-
> 'service.name': 'my-service',
|
|
124
|
-
> },
|
|
125
|
-
> });
|
|
126
|
-
> ```
|
|
127
|
-
>
|
|
128
|
-
> </details>
|
|
129
|
-
|
|
130
108
|
#### Module: [`rian/exporter.otel.http`](./packages/rian/src/exporter.otel.http.ts)
|
|
131
109
|
|
|
132
110
|
Implements the OpenTelemetry protocol for use with http transports.
|
|
133
111
|
|
|
134
|
-
> 💡 Note ~> services require a `service.name` context value.
|
|
135
|
-
>
|
|
136
|
-
> <details><summary>Example</summary>
|
|
137
|
-
>
|
|
138
|
-
> ```ts
|
|
139
|
-
> const tracer = create('example', {
|
|
140
|
-
> context: {
|
|
141
|
-
> 'service.name': 'my-service', // 👈 important part
|
|
142
|
-
> },
|
|
143
|
-
> });
|
|
144
|
-
> ```
|
|
145
|
-
>
|
|
146
|
-
> </details>
|
|
147
|
-
|
|
148
112
|
## 🧑🍳 Exporter Recipes
|
|
149
113
|
|
|
150
114
|
<details><summary>NewRelic</summary>
|
|
@@ -166,10 +130,7 @@ const newrelic = exporter((payload) =>
|
|
|
166
130
|
}),
|
|
167
131
|
);
|
|
168
132
|
|
|
169
|
-
const tracer = create('
|
|
170
|
-
context: {
|
|
171
|
-
'service.name': 'my-service', // 👈 important part
|
|
172
|
-
},
|
|
133
|
+
const tracer = create('my-service', {
|
|
173
134
|
exporter: newrelic,
|
|
174
135
|
});
|
|
175
136
|
```
|
|
@@ -195,10 +156,7 @@ const lightstep = exporter((payload) =>
|
|
|
195
156
|
}),
|
|
196
157
|
);
|
|
197
158
|
|
|
198
|
-
const tracer = create('
|
|
199
|
-
context: {
|
|
200
|
-
'service.name': 'my-service', // 👈 important part
|
|
201
|
-
},
|
|
159
|
+
const tracer = create('my-service', {
|
|
202
160
|
exporter: lightstep,
|
|
203
161
|
});
|
|
204
162
|
```
|
|
@@ -249,9 +207,9 @@ Validation :: single span
|
|
|
249
207
|
✔ opentracing
|
|
250
208
|
|
|
251
209
|
Benchmark :: single span
|
|
252
|
-
rian x
|
|
253
|
-
opentelemetry x
|
|
254
|
-
opentracing x
|
|
210
|
+
rian x 392,796 ops/sec ±3.73% (86 runs sampled)
|
|
211
|
+
opentelemetry x 205,544 ops/sec ±11.98% (65 runs sampled)
|
|
212
|
+
opentracing x 60,043 ops/sec ±35.25% (97 runs sampled)
|
|
255
213
|
|
|
256
214
|
Validation :: child span
|
|
257
215
|
✔ rian
|
|
@@ -259,10 +217,9 @@ Validation :: child span
|
|
|
259
217
|
✔ opentracing
|
|
260
218
|
|
|
261
219
|
Benchmark :: child span
|
|
262
|
-
rian x
|
|
263
|
-
opentelemetry x
|
|
264
|
-
opentracing x
|
|
265
|
-
|
|
220
|
+
rian x 208,186 ops/sec ±6.28% (82 runs sampled)
|
|
221
|
+
opentelemetry x 121,740 ops/sec ±16.56% (62 runs sampled)
|
|
222
|
+
opentracing x 37,405 ops/sec ±0.48% (99 runs sampled)
|
|
266
223
|
```
|
|
267
224
|
|
|
268
225
|
> And please... I know these results are anything but the full story. But it's a number and point on comparison.
|
package/utils/index.d.ts
CHANGED
|
@@ -17,20 +17,19 @@ export type MeasureFn =
|
|
|
17
17
|
* @example
|
|
18
18
|
*
|
|
19
19
|
* ```text
|
|
20
|
-
* const data = await measure(scope,
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
20
|
+
* const data = await measure(scope, get_data, 'user_id_123');
|
|
21
|
+
* ^ ^ ^ ^
|
|
22
|
+
* | | | |
|
|
23
|
+
* | | | the first argument to get_data
|
|
24
|
+
* | | |
|
|
25
|
+
* | | function to be called
|
|
26
|
+
* | |
|
|
27
|
+
* | the parent scope
|
|
28
|
+
* return value from get_data
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
31
|
export const measure: <Fn extends MeasureFn>(
|
|
32
32
|
scope: Scope,
|
|
33
|
-
name: string,
|
|
34
33
|
fn: Fn, // TODO: fn doesnt see scope correctly
|
|
35
34
|
...args: RealMeasureFnParams<Parameters<Fn>>
|
|
36
35
|
) => ReturnType<Fn>;
|
|
@@ -51,7 +50,6 @@ export const measure: <Fn extends MeasureFn>(
|
|
|
51
50
|
*/
|
|
52
51
|
export const wrap: <Fn extends MeasureFn>(
|
|
53
52
|
scope: Scope,
|
|
54
|
-
name: string,
|
|
55
53
|
fn: Fn, // TODO: fn doesnt see scope correctly
|
|
56
54
|
) => Fn;
|
|
57
55
|
|
package/utils/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var r=(r,t,...e)=>{try{var n=t(...e,r),o=n instanceof Promise;return o&&r.__add_promise(n.catch((t=>{r.set_context({error:t})})).finally((()=>r.end()))),n}catch(t){throw t instanceof Error&&r.set_context({error:t}),t}finally{!0!==o&&r.end()}},t=(t,e
|
|
1
|
+
var r=(r,t,...e)=>{try{var n=t(...e,r),o=n instanceof Promise;return o&&r.__add_promise(n.catch((t=>{r.set_context({error:t})})).finally((()=>r.end()))),n}catch(t){throw t instanceof Error&&r.set_context({error:t}),t}finally{!0!==o&&r.end()}},t=(t,e,...n)=>r(t,e,...n),e=(t,e)=>function(){return r(t,e,...arguments)};exports.measure=t;exports.measureFn=r;exports.wrap=e;
|
package/utils/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var r=(r,t,...e)=>{try{var n=t(...e,r),o=n instanceof Promise;return o&&r.__add_promise(n.catch((t=>{r.set_context({error:t})})).finally((()=>r.end()))),n}catch(t){throw t instanceof Error&&r.set_context({error:t}),t}finally{!0!==o&&r.end()}},t=(t,e
|
|
1
|
+
var r=(r,t,...e)=>{try{var n=t(...e,r),o=n instanceof Promise;return o&&r.__add_promise(n.catch((t=>{r.set_context({error:t})})).finally((()=>r.end()))),n}catch(t){throw t instanceof Error&&r.set_context({error:t}),t}finally{!0!==o&&r.end()}},t=(t,e,...n)=>r(t,e,...n),e=(t,e)=>function(){return r(t,e,...arguments)};export{t as measure,r as measureFn,e as wrap};
|