rian 0.3.0-next.1 → 0.3.0-next.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ 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=>{let a=[];for(let{resource:e,spans:s}of n){let n=[];for(let e of s){let a,{kind:s,error:u,...i}=e.context;u&&(a={code:2},"message"in u&&(a.message=u.message)),n.push({traceId:e.id.trace_id,spanId:e.id.parent_id,parentSpanId:e.parent?.parent_id,name:e.name,kind:r(s||"INTERNAL"),startTimeUnixNano:1e6*e.start,endTimeUnixNano:e.end?1e6*e.end:void 0,droppedAttributesCount:0,droppedEventsCount:0,droppedLinksCount:0,attributes:t(i),status:a||{code:0},events:e.events.map((e=>({name:e.name,attributes:t(e.attributes),droppedAttributesCount:0,timeUnixNano:1e6*e.timestamp})))})}a.push({resource:{attributes:t(e),droppedAttributesCount:0},instrumentationLibrarySpans:[{instrumentationLibrary:{name:"rian",version:"0.3.0-next.2"},spans:n}]})}return e({resourceSpans:a})};exports.exporter=n;
@@ -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};
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=>{let a=[];for(let{resource:e,spans:s}of n){let n=[];for(let e of s){let a,{kind:s,error:u,...i}=e.context;u&&(a={code:2},"message"in u&&(a.message=u.message)),n.push({traceId:e.id.trace_id,spanId:e.id.parent_id,parentSpanId:e.parent?.parent_id,name:e.name,kind:r(s||"INTERNAL"),startTimeUnixNano:1e6*e.start,endTimeUnixNano:e.end?1e6*e.end:void 0,droppedAttributesCount:0,droppedEventsCount:0,droppedLinksCount:0,attributes:t(i),status:a||{code:0},events:e.events.map((e=>({name:e.name,attributes:t(e.attributes),droppedAttributesCount:0,timeUnixNano:1e6*e.timestamp})))})}a.push({resource:{attributes:t(e),droppedAttributesCount:0},instrumentationLibrarySpans:[{instrumentationLibrary:{name:"rian",version:"0.3.0-next.2"},spans:n}]})}return e({resourceSpans:a})};export{n as exporter};
@@ -1 +1 @@
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
+ const { flattie:e } = require('flattie');var t=t=>a=>{let r=[];for(let t of a)for(let a of t.spans){let{kind:n,error:i,...s}=a.context;i&&(s.error=!("message"in i)||{name:i.name,message:i.message,stack:i.stack}),r.push({id:a.id.parent_id,traceId:a.id.trace_id,parentId:a.parent?a.parent.parent_id:void 0,name:a.name,kind:"INTERNAL"===n?void 0:n,timestamp:1e3*a.start,duration:a.end?1e3*(a.end-a.start):void 0,localEndpoint:{serviceName:t.resource["service.name"]},tags:e({...t.resource,...s},".",!0),annotations:a.events.map((e=>({value:`${e.name} :: ${JSON.stringify(e.attributes)}`,timestamp:1e3*e.timestamp})))})}return t(r)};exports.exporter=t;
@@ -1 +1 @@
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};
1
+ import{flattie as e}from"flattie";var t=t=>a=>{let r=[];for(let t of a)for(let a of t.spans){let{kind:n,error:i,...s}=a.context;i&&(s.error=!("message"in i)||{name:i.name,message:i.message,stack:i.stack}),r.push({id:a.id.parent_id,traceId:a.id.trace_id,parentId:a.parent?a.parent.parent_id:void 0,name:a.name,kind:"INTERNAL"===n?void 0:n,timestamp:1e3*a.start,duration:a.end?1e3*(a.end-a.start):void 0,localEndpoint:{serviceName:t.resource["service.name"]},tags:e({...t.resource,...s},".",!0),annotations:a.events.map((e=>({value:`${e.name} :: ${JSON.stringify(e.attributes)}`,timestamp:1e3*e.timestamp})))})}return t(r)};export{t as exporter};
package/global.d.ts ADDED
@@ -0,0 +1 @@
1
+ declare const RIAN_VERSION: string;
package/index.d.ts CHANGED
@@ -1,5 +1,61 @@
1
1
  import type { Traceparent } from 'tctx';
2
2
 
3
+ // --- tracer
4
+
5
+ /**
6
+ * An exporter is a method called when the parent scope ends, gets given a Set of all spans traced
7
+ * during this execution.
8
+ */
9
+ export type Exporter = (resources: IterableIterator<Resource>) => any;
10
+
11
+ export type Resource = {
12
+ resource: Context;
13
+ spans: ReadonlySet<Readonly<Span>>;
14
+ };
15
+
16
+ export type Options = {
17
+ /**
18
+ * @borrows {@link Sampler}
19
+ */
20
+ sampler?: Sampler | boolean;
21
+
22
+ context?: Context;
23
+
24
+ /**
25
+ * A root, or extracted w3c traceparent stringed header.
26
+ *
27
+ * If the id is malformed, the {@link create} method will throw an exception. If no root is
28
+ * provided then one will be created obeying the {@link Options.sampler|sampling} rules.
29
+ */
30
+ traceparent?: string | null;
31
+ };
32
+
33
+ export type Tracer = Pick<Scope, 'span'>;
34
+
35
+ /**
36
+ * @borrows {@link Span.context}
37
+ */
38
+ export type Context = {
39
+ [property: string]: any;
40
+ };
41
+
42
+ /**
43
+ * Should return true when you want to sample the span, this is ran before the span is traced — so
44
+ * decisions is made preemptively.
45
+ *
46
+ * The Span itself will still be included in the {@link Options.exporter|exporter}, and can be
47
+ * filtered out there.
48
+ *
49
+ * Sampling does impact the traceparent, for injection — and is encoded there.
50
+ */
51
+ export type Sampler = (
52
+ name: string,
53
+ parentId?: Traceparent,
54
+ context?: Context,
55
+ ) => boolean;
56
+
57
+ // --- spans
58
+
3
59
  /**
4
60
  * Spans are units within a distributed trace. Spans encapsulate mainly 3 pieces of information, a
5
61
  * {@link Span.name|name}, and a {@link Span.start|start} and {@link Span.end|end} time.
@@ -20,7 +76,7 @@ import type { Traceparent } from 'tctx';
20
76
  * Spans are aimed to interoperate with
21
77
  * {@link https://github.com/opentracing/specification/blob/master/specification.md|OpenTracing's Spans}, albeit not entirely api compatible — they do share principles.
22
78
  */
23
- export interface Span {
79
+ export type Span = {
24
80
  /**
25
81
  * A human-readable name for this span. For example the function name, the name of a subtask,
26
82
  * or stage of the larger stack.
@@ -84,9 +140,11 @@ export interface Span {
84
140
  * new span.
85
141
  */
86
142
  events: { name: string; timestamp: number; attributes: Context }[];
87
- }
143
+ };
88
144
 
89
- export interface Scope {
145
+ // --- scopes
146
+
147
+ export type Scope = {
90
148
  /**
91
149
  * A W3C traceparent. One can .toString() this if you want to cross a network.
92
150
  */
@@ -116,70 +174,19 @@ export interface Scope {
116
174
  * timestamp nulled out — when the tracer ends.
117
175
  */
118
176
  end(): void;
119
- }
177
+ };
120
178
 
121
- export interface Tracer extends Pick<Scope, 'span'> {
122
- report(): ReturnType<Exporter>;
123
- }
179
+ export type CallableScope = Scope & {
180
+ (cb: (scope: Omit<Scope, 'end'>) => void): ReturnType<typeof cb>;
181
+ };
124
182
 
125
- /**
126
- * An exporter is a method called when the parent scope ends, gets given a Set of all spans traced
127
- * during this execution.
128
- */
129
- export type Exporter = (
130
- spans: ReadonlySet<Readonly<Span>>,
131
- context: Context,
132
- ) => any;
183
+ // --- main api
133
184
 
134
- /**
135
- * @borrows {@link Span.context}
136
- */
137
- export interface Context {
138
- [property: string]: any;
139
- }
185
+ export function tracer(name: string, options?: Options): Tracer;
140
186
 
141
187
  /**
142
- * Should return true when you want to sample the span, this is ran before the span is traced — so
143
- * decisions is made preemptively.
144
- *
145
- * The Span itself will still be included in the {@link Options.exporter|exporter}, and can be
146
- * filtered out there.
147
- *
148
- * Sampling does impact the traceparent, for injection — and is encoded there.
188
+ * Awaits all active promises, and then calls the {@link Options.exporter|exporter}. Passing all collected spans.
149
189
  */
150
- export type Sampler = (
151
- name: string,
152
- parentId?: Traceparent,
153
- context?: Context,
154
- ) => boolean;
155
-
156
- export interface Options {
157
- /**
158
- * @borrows {@link Exporter}
159
- */
160
- exporter: Exporter;
161
-
162
- /**
163
- * @borrows {@link Sampler}
164
- */
165
- sampler?: Sampler | boolean;
166
-
167
- context?: Context;
168
-
169
- /**
170
- * A root, or extracted w3c traceparent stringed header.
171
- *
172
- * If the id is malformed, the {@link create} method will throw an exception. If no root is
173
- * provided then one will be created obeying the {@link Options.sampler|sampling} rules.
174
- */
175
- traceparent?: string | null;
176
- }
177
-
178
- export const create: (name: string, options: Options) => Tracer;
179
-
180
- // ==> internals
181
-
182
- /** @internal */
183
- export interface CallableScope extends Scope {
184
- (cb: (scope: Omit<Scope, 'end'>) => void): ReturnType<typeof cb>;
185
- }
190
+ export async function report<T extends Exporter>(
191
+ exporter: T,
192
+ ): Promise<ReturnType<T>>;
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=(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;
1
+ const { measureFn:e } = require('rian/utils');const t = require('tctx');var n=(e,n)=>!n||t.is_sampled(n),a=new Set,r=new WeakMap;function s(s,o){let l=o?.sampler||n,d="boolean"!=typeof l,i=o?.context||{};i["service.name"]=s,i["telemetry.sdk.name"]="rian",i["telemetry.sdk.version"]="0.3.0-next.2";let p=new Set;r.set(i,p);let c="string"==typeof o?.traceparent?t.parse(o.traceparent):void 0,m=(n,r)=>{let s=d?l(n,r,i):l,o=r?r.child(s):t.make(s),c={id:o,parent:r,start:Date.now(),name:n,events:[],context:{}};s&&a.add([c,i]);let u=t=>e(u,t);return u.traceparent=o,u.span=e=>m(e,o),u.set_context=e=>"function"==typeof e?void(c.context=e(c.context)):void Object.assign(c.context,e),u.add_event=(e,t)=>{c.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},u.end=()=>{null==c.end&&(c.end=Date.now())},u.__add_promise=e=>{p.add(e),e.then((()=>p.delete(e)))},u};return{span:e=>m(e,c)}}async function o(e){let t=[],n=new Map;for(let[e,s]of a){let a;n.has(s)?a=n.get(s).spans:n.set(s,{resource:s,spans:a=new Set}),a.add(e),r.has(s)&&(t.push(...r.get(s)),r.delete(s))}return a.clear(),t.length&&await Promise.all(t),e(n.values())}exports.report=o;exports.tracer=s;
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=(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};
1
+ import{measureFn as e}from"rian/utils";import*as t from"tctx";var n=(e,n)=>!n||t.is_sampled(n),a=new Set,r=new WeakMap;function s(s,o){let l=o?.sampler||n,d="boolean"!=typeof l,i=o?.context||{};i["service.name"]=s,i["telemetry.sdk.name"]="rian",i["telemetry.sdk.version"]="0.3.0-next.2";let p=new Set;r.set(i,p);let c="string"==typeof o?.traceparent?t.parse(o.traceparent):void 0,m=(n,r)=>{let s=d?l(n,r,i):l,o=r?r.child(s):t.make(s),c={id:o,parent:r,start:Date.now(),name:n,events:[],context:{}};s&&a.add([c,i]);let u=t=>e(u,t);return u.traceparent=o,u.span=e=>m(e,o),u.set_context=e=>"function"==typeof e?void(c.context=e(c.context)):void Object.assign(c.context,e),u.add_event=(e,t)=>{c.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},u.end=()=>{null==c.end&&(c.end=Date.now())},u.__add_promise=e=>{p.add(e),e.then((()=>p.delete(e)))},u};return{span:e=>m(e,c)}}async function o(e){let t=[],n=new Map;for(let[e,s]of a){let a;n.has(s)?a=n.get(s).spans:n.set(s,{resource:s,spans:a=new Set}),a.add(e),r.has(s)&&(t.push(...r.get(s)),r.delete(s))}return a.clear(),t.length&&await Promise.all(t),e(n.values())}export{o as report,s as tracer};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rian",
3
- "version": "0.3.0-next.1",
3
+ "version": "0.3.0-next.2",
4
4
  "description": "Effective tracing for the edge and origins",
5
5
  "keywords": [
6
6
  "opentelemetry",
package/readme.md CHANGED
@@ -204,22 +204,18 @@ Rian is still in active development, but ready for production!
204
204
  Validation :: single span
205
205
  ✔ rian
206
206
  ✔ opentelemetry
207
- ✔ opentracing
208
207
 
209
208
  Benchmark :: single span
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)
209
+ rian x 385,085 ops/sec ±4.26% (85 runs sampled)
210
+ opentelemetry x 205,004 ops/sec ±11.99% (65 runs sampled)
213
211
 
214
212
  Validation :: child span
215
213
  ✔ rian
216
214
  ✔ opentelemetry
217
- ✔ opentracing
218
215
 
219
216
  Benchmark :: child span
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)
217
+ rian x 206,736 ops/sec ±6.37% (86 runs sampled)
218
+ opentelemetry x 128,298 ops/sec ±14.82% (68 runs sampled)
223
219
  ```
224
220
 
225
221
  > And please... I know these results are anything but the full story. But it's a number and point on comparison.