rian 0.3.0-next.1 → 0.3.0-next.3

Sign up to get free protection for your applications and to get access to all the features.
package/async.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import type { CallableScope, Scope, Span } from 'rian';
2
+
3
+ export function currentSpan(): Scope | null;
4
+ export function span(name: string): CallableScope;
5
+
6
+ export { tracer, report } from 'rian';
package/async.js ADDED
@@ -0,0 +1 @@
1
+ const { AsyncLocalStorage:e } = require('async_hooks');const { measure:t } = require('rian/utils');const { make:n, parse:r, SAMPLED_FLAG:a } = require('tctx');const { is_sampled:o } = require('tctx');var s=new Set,l=new WeakMap;async function i(e){let t=[],n=new Map;for(let[e,r]of s){let a;n.has(r)?a=n.get(r).spans:n.set(r,{resource:r,spans:a=new Set}),a.add(e),l.has(r)&&(t.push(...l.get(r)),l.delete(r))}return s.clear(),t.length&&await Promise.all(t),e(n.values())}function c(e,t){return o(t)}var p=new e;function u(){return p.getStore()?.[1]||null}function d(e){let r=p.getStore();if(!r)throw Error("TODO");let a=r[0],o=a.resource,i=r[1],c=a.sampler,u=i?.traceparent??a.root_id,m=u?u.child():n(),f="boolean"!=typeof c?c(e,m,o):c;m.flags;let w={id:m,parent:u,start:Date.now(),name:e,events:[],context:{}};f&&s.add([w,o]);let x=e=>p.run([a,x],t,x,e);x.traceparent=m,x.span=d,x.set_context=e=>{"function"!=typeof e?Object.assign(w.context,e):w.context=e(w.context)},x.add_event=(e,t)=>{w.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},x.end=()=>{null==w.end&&(w.end=Date.now())};let g=l.get(o);return x.__add_promise=e=>{g.add(e),e.then((()=>g.delete(e)))},p.run([a,x],(()=>x))}function m(e,t){let n=t?.sampler??c,a=t?.context||{};a["service.name"]=e,a["telemetry.sdk.name"]="rian",a["telemetry.sdk.version"]="0.3.0-next.3";let o={root_id:"string"==typeof t?.traceparent?r(t.traceparent):void 0,resource:a,sampler:n};return l.set(a,new Set),{span:e=>p.run([o,null],d,e)}}exports.currentSpan=u;exports.report=i;exports.span=d;exports.tracer=m;
package/async.mjs ADDED
@@ -0,0 +1 @@
1
+ import{AsyncLocalStorage as e}from"async_hooks";import{measure as t}from"rian/utils";import{make as n,parse as r,SAMPLED_FLAG as a}from"tctx";import{is_sampled as o}from"tctx";var s=new Set,l=new WeakMap;async function i(e){let t=[],n=new Map;for(let[e,r]of s){let a;n.has(r)?a=n.get(r).spans:n.set(r,{resource:r,spans:a=new Set}),a.add(e),l.has(r)&&(t.push(...l.get(r)),l.delete(r))}return s.clear(),t.length&&await Promise.all(t),e(n.values())}function c(e,t){return o(t)}var p=new e;function u(){return p.getStore()?.[1]||null}function d(e){let r=p.getStore();if(!r)throw Error("TODO");let a=r[0],o=a.resource,i=r[1],c=a.sampler,u=i?.traceparent??a.root_id,m=u?u.child():n(),f="boolean"!=typeof c?c(e,m,o):c;m.flags;let w={id:m,parent:u,start:Date.now(),name:e,events:[],context:{}};f&&s.add([w,o]);let x=e=>p.run([a,x],t,x,e);x.traceparent=m,x.span=d,x.set_context=e=>{"function"!=typeof e?Object.assign(w.context,e):w.context=e(w.context)},x.add_event=(e,t)=>{w.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},x.end=()=>{null==w.end&&(w.end=Date.now())};let g=l.get(o);return x.__add_promise=e=>{g.add(e),e.then((()=>g.delete(e)))},p.run([a,x],(()=>x))}function m(e,t){let n=t?.sampler??c,a=t?.context||{};a["service.name"]=e,a["telemetry.sdk.name"]="rian",a["telemetry.sdk.version"]="0.3.0-next.3";let o={root_id:"string"==typeof t?.traceparent?r(t.traceparent):void 0,resource:a,sampler:n};return l.set(a,new Set),{span:e=>p.run([o,null],d,e)}}export{u as currentSpan,i as report,d as span,m as tracer};
@@ -0,0 +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=>{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.3"},spans:n}]})}return e({resourceSpans:a})};exports.exporter=n;
@@ -0,0 +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=>{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.3"},spans:n}]})}return e({resourceSpans:a})};export{n as exporter};
@@ -0,0 +1 @@
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;
@@ -0,0 +1 @@
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/index.d.ts CHANGED
@@ -1,5 +1,60 @@
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
+ * Returning false will not include this span in the {@link Exporter}.
47
+ *
48
+ * Sampling does impact the traceparent, for injection — and is encoded there.
49
+ */
50
+ export type Sampler = (
51
+ readonly name: string,
52
+ readonly id: Traceparent,
53
+ readonly context: Context,
54
+ ) => boolean;
55
+
56
+ // --- spans
57
+
3
58
  /**
4
59
  * Spans are units within a distributed trace. Spans encapsulate mainly 3 pieces of information, a
5
60
  * {@link Span.name|name}, and a {@link Span.start|start} and {@link Span.end|end} time.
@@ -20,7 +75,7 @@ import type { Traceparent } from 'tctx';
20
75
  * Spans are aimed to interoperate with
21
76
  * {@link https://github.com/opentracing/specification/blob/master/specification.md|OpenTracing's Spans}, albeit not entirely api compatible — they do share principles.
22
77
  */
23
- export interface Span {
78
+ export type Span = {
24
79
  /**
25
80
  * A human-readable name for this span. For example the function name, the name of a subtask,
26
81
  * or stage of the larger stack.
@@ -84,9 +139,11 @@ export interface Span {
84
139
  * new span.
85
140
  */
86
141
  events: { name: string; timestamp: number; attributes: Context }[];
87
- }
142
+ };
88
143
 
89
- export interface Scope {
144
+ // --- scopes
145
+
146
+ export type Scope = {
90
147
  /**
91
148
  * A W3C traceparent. One can .toString() this if you want to cross a network.
92
149
  */
@@ -116,70 +173,19 @@ export interface Scope {
116
173
  * timestamp nulled out — when the tracer ends.
117
174
  */
118
175
  end(): void;
119
- }
176
+ };
120
177
 
121
- export interface Tracer extends Pick<Scope, 'span'> {
122
- report(): ReturnType<Exporter>;
123
- }
178
+ export type CallableScope = Scope & {
179
+ (cb: (scope: Omit<Scope, 'end'>) => void): ReturnType<typeof cb>;
180
+ };
124
181
 
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;
182
+ // --- main api
133
183
 
134
- /**
135
- * @borrows {@link Span.context}
136
- */
137
- export interface Context {
138
- [property: string]: any;
139
- }
184
+ export function tracer(name: string, options?: Options): Tracer;
140
185
 
141
186
  /**
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.
187
+ * Awaits all active promises, and then calls the {@link Options.exporter|exporter}. Passing all collected spans.
149
188
  */
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
- }
189
+ export async function report<T extends Exporter>(
190
+ exporter: T,
191
+ ): 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 { make:t, parse:n, SAMPLED_FLAG:a } = require('tctx');const { is_sampled:r } = require('tctx');var o=new Set,s=new WeakMap;async function l(e){let t=[],n=new Map;for(let[e,a]of o){let r;n.has(a)?r=n.get(a).spans:n.set(a,{resource:a,spans:r=new Set}),r.add(e),s.has(a)&&(t.push(...s.get(a)),s.delete(a))}return o.clear(),t.length&&await Promise.all(t),e(n.values())}function i(e,t){return r(t)}function d(a,r){let l=r?.sampler??i,d=r?.context||{};d["service.name"]=a,d["telemetry.sdk.name"]="rian",d["telemetry.sdk.version"]="0.3.0-next.3";let p=new Set;s.set(d,p);let c="string"==typeof r?.traceparent?n(r.traceparent):void 0,m=(n,a)=>{let r=a?a.child():t(),s="boolean"!=typeof l?l(n,r,d):l;r.flags;let i={id:r,parent:a,start:Date.now(),name:n,events:[],context:{}};s&&o.add([i,d]);let c=t=>e(c,t);return c.traceparent=r,c.span=e=>m(e,r),c.set_context=e=>"function"==typeof e?void(i.context=e(i.context)):void Object.assign(i.context,e),c.add_event=(e,t)=>{i.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},c.end=()=>{null==i.end&&(i.end=Date.now())},c.__add_promise=e=>{p.add(e),e.then((()=>p.delete(e)))},c};return{span:e=>m(e,c)}}exports.report=l;exports.tracer=d;
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{make as t,parse as n,SAMPLED_FLAG as a}from"tctx";import{is_sampled as r}from"tctx";var o=new Set,s=new WeakMap;async function l(e){let t=[],n=new Map;for(let[e,a]of o){let r;n.has(a)?r=n.get(a).spans:n.set(a,{resource:a,spans:r=new Set}),r.add(e),s.has(a)&&(t.push(...s.get(a)),s.delete(a))}return o.clear(),t.length&&await Promise.all(t),e(n.values())}function i(e,t){return r(t)}function d(a,r){let l=r?.sampler??i,d=r?.context||{};d["service.name"]=a,d["telemetry.sdk.name"]="rian",d["telemetry.sdk.version"]="0.3.0-next.3";let p=new Set;s.set(d,p);let c="string"==typeof r?.traceparent?n(r.traceparent):void 0,m=(n,a)=>{let r=a?a.child():t(),s="boolean"!=typeof l?l(n,r,d):l;r.flags;let i={id:r,parent:a,start:Date.now(),name:n,events:[],context:{}};s&&o.add([i,d]);let c=t=>e(c,t);return c.traceparent=r,c.span=e=>m(e,r),c.set_context=e=>"function"==typeof e?void(i.context=e(i.context)):void Object.assign(i.context,e),c.add_event=(e,t)=>{i.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},c.end=()=>{null==i.end&&(i.end=Date.now())},c.__add_promise=e=>{p.add(e),e.then((()=>p.delete(e)))},c};return{span:e=>m(e,c)}}export{l as report,d 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.3",
4
4
  "description": "Effective tracing for the edge and origins",
5
5
  "keywords": [
6
6
  "opentelemetry",
@@ -25,20 +25,25 @@
25
25
  "import": "./index.mjs",
26
26
  "require": "./index.js"
27
27
  },
28
+ "./async": {
29
+ "types": "./async.d.ts",
30
+ "import": "./async.mjs",
31
+ "require": "./async.js"
32
+ },
28
33
  "./exporter.otel.http": {
29
- "types": "./exporter.otel.http/index.d.ts",
30
- "import": "./exporter.otel.http/index.mjs",
31
- "require": "./exporter.otel.http/index.js"
34
+ "types": "./exporter.otel.http.d.ts",
35
+ "import": "./exporter.otel.http.mjs",
36
+ "require": "./exporter.otel.http.js"
32
37
  },
33
38
  "./exporter.zipkin": {
34
- "types": "./exporter.zipkin/index.d.ts",
35
- "import": "./exporter.zipkin/index.mjs",
36
- "require": "./exporter.zipkin/index.js"
39
+ "types": "./exporter.zipkin.d.ts",
40
+ "import": "./exporter.zipkin.mjs",
41
+ "require": "./exporter.zipkin.js"
37
42
  },
38
43
  "./utils": {
39
- "types": "./utils/index.d.ts",
40
- "import": "./utils/index.mjs",
41
- "require": "./utils/index.js"
44
+ "types": "./utils.d.ts",
45
+ "import": "./utils.mjs",
46
+ "require": "./utils.js"
42
47
  },
43
48
  "./package.json": "./package.json"
44
49
  },
@@ -49,6 +54,7 @@
49
54
  "*.mjs",
50
55
  "*.js",
51
56
  "*.d.ts",
57
+ "!global.d.ts",
52
58
  "exporter.*/*",
53
59
  "utils/*"
54
60
  ],
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 `.report()` a tracer, done.
31
+ - ✅ **Simple** — `create` a tracer, and `report()`, done.
32
32
 
33
33
  - 🏎 **Performant** — check the [benchmarks](#-benchmark).
34
34
 
@@ -39,7 +39,7 @@
39
39
  > Visit [/examples](/examples) for more info!
40
40
 
41
41
  ```ts
42
- import { create } from 'rian';
42
+ import { create, report } from 'rian';
43
43
  import { measure } from 'rian/utils';
44
44
  import { exporter } from 'rian/exporter.otel.http';
45
45
 
@@ -52,9 +52,7 @@ const otel_endpoint = exporter((payload) =>
52
52
  );
53
53
 
54
54
  // ~> Create a tracer — typically "per request" or "per operation"
55
- const tracer = create('my-service', {
56
- exporter: otel_endpoint,
57
- });
55
+ const tracer = create('my-service');
58
56
 
59
57
  // Let us trace
60
58
 
@@ -80,7 +78,7 @@ span.end();
80
78
  req.end();
81
79
 
82
80
  // ~> And finally let's export — will also end the root span.
83
- await tracer.report();
81
+ await report(otel_endpoint);
84
82
 
85
83
  /*
86
84
  And we end up with something like this in our reporting tool:
@@ -114,7 +112,7 @@ Implements the OpenTelemetry protocol for use with http transports.
114
112
  <details><summary>NewRelic</summary>
115
113
 
116
114
  ```ts
117
- import { create } from 'rian';
115
+ import { create, report } from 'rian';
118
116
  import { exporter } from 'rian/exporter.zipkin';
119
117
 
120
118
  const newrelic = exporter((payload) =>
@@ -130,9 +128,9 @@ const newrelic = exporter((payload) =>
130
128
  }),
131
129
  );
132
130
 
133
- const tracer = create('my-service', {
134
- exporter: newrelic,
135
- });
131
+ const tracer = create('my-service');
132
+
133
+ await report(newrelic);
136
134
  ```
137
135
 
138
136
  [learn more](https://docs.newrelic.com/docs/distributed-tracing/trace-api/introduction-trace-api/)
@@ -142,7 +140,7 @@ const tracer = create('my-service', {
142
140
  <details><summary>LightStep</summary>
143
141
 
144
142
  ```ts
145
- import { create } from 'rian';
143
+ import { create, report } from 'rian';
146
144
  import { exporter } from 'rian/exporter.otel.http';
147
145
 
148
146
  const lightstep = exporter((payload) =>
@@ -156,9 +154,9 @@ const lightstep = exporter((payload) =>
156
154
  }),
157
155
  );
158
156
 
159
- const tracer = create('my-service', {
160
- exporter: lightstep,
161
- });
157
+ const tracer = create('my-service');
158
+
159
+ await report(lightstep);
162
160
  ```
163
161
 
164
162
  [learn more](https://opentelemetry.lightstep.com/tracing/)
@@ -204,22 +202,18 @@ Rian is still in active development, but ready for production!
204
202
  Validation :: single span
205
203
  ✔ rian
206
204
  ✔ opentelemetry
207
- ✔ opentracing
208
205
 
209
206
  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)
207
+ rian x 385,085 ops/sec ±4.26% (85 runs sampled)
208
+ opentelemetry x 205,004 ops/sec ±11.99% (65 runs sampled)
213
209
 
214
210
  Validation :: child span
215
211
  ✔ rian
216
212
  ✔ opentelemetry
217
- ✔ opentracing
218
213
 
219
214
  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)
215
+ rian x 206,736 ops/sec ±6.37% (86 runs sampled)
216
+ opentelemetry x 128,298 ops/sec ±14.82% (68 runs sampled)
223
217
  ```
224
218
 
225
219
  > And please... I know these results are anything but the full story. But it's a number and point on comparison.
@@ -1 +0,0 @@
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 +0,0 @@
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 +0,0 @@
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 +0,0 @@
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};
File without changes
File without changes
File without changes