rian 0.1.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ import type { Exporter } from 'rian';
2
+
3
+ export const exporter: (request: (payload: any) => any) => Exporter;
@@ -0,0 +1 @@
1
+ const { name:e, version:t } = require('rian/package.json');var r=e=>{let t=typeof e,n={};return"string"===t?n.stringValue=e:"number"===t?Number.isInteger(e)?n.intValue=e:n.doubleValue=e:"boolean"===t?n.boolValue=e:Array.isArray(e)?n.arrayValue={values:e.map((e=>r(e)))}:e&&(n.kvlistValue={values:a(e)}),n},a=e=>{let t=[];for(let a of Object.keys(e))t.push({key:a,value:r(e[a])});return t},n=e=>{switch(e){default:case"INTERNAL":return 1;case"SERVER":return 2;case"CLIENT":return 3;case"PRODUCER":return 4;case"CONSUMER":return 5}},s=r=>(s,i)=>{let u=[];for(let e of s){let t,{kind:r,error:s,...i}=e.context;s&&(t={code:2},"message"in s&&(t.message=s.message)),u.push({traceId:e.id.trace_id,spanId:e.id.parent_id,parentSpanId:e.parent?.parent_id,name:e.name,kind:n(r||"INTERNAL"),startTimeUnixNano:1e6*e.start,endTimeUnixNano:e.end?1e6*e.end:void 0,droppedAttributesCount:0,droppedEventsCount:0,droppedLinksCount:0,attributes:a(i),status:t||{code:0},events:e.events.map((e=>({name:e.name,attributes:a(e.attributes),droppedAttributesCount:0,timeUnixNano:1e6*e.timestamp})))})}return r({resourceSpans:[{resource:{attributes:a(i),droppedAttributesCount:0},instrumentationLibrarySpans:[{instrumentationLibrary:{name:e,version:t},spans:u}]}]})};exports.exporter=s;
@@ -0,0 +1 @@
1
+ import{name as e,version as t}from"rian/package.json";var r=e=>{let t=typeof e,n={};return"string"===t?n.stringValue=e:"number"===t?Number.isInteger(e)?n.intValue=e:n.doubleValue=e:"boolean"===t?n.boolValue=e:Array.isArray(e)?n.arrayValue={values:e.map((e=>r(e)))}:e&&(n.kvlistValue={values:a(e)}),n},a=e=>{let t=[];for(let a of Object.keys(e))t.push({key:a,value:r(e[a])});return t},n=e=>{switch(e){default:case"INTERNAL":return 1;case"SERVER":return 2;case"CLIENT":return 3;case"PRODUCER":return 4;case"CONSUMER":return 5}},s=r=>(s,i)=>{let u=[];for(let e of s){let t,{kind:r,error:s,...i}=e.context;s&&(t={code:2},"message"in s&&(t.message=s.message)),u.push({traceId:e.id.trace_id,spanId:e.id.parent_id,parentSpanId:e.parent?.parent_id,name:e.name,kind:n(r||"INTERNAL"),startTimeUnixNano:1e6*e.start,endTimeUnixNano:e.end?1e6*e.end:void 0,droppedAttributesCount:0,droppedEventsCount:0,droppedLinksCount:0,attributes:a(i),status:t||{code:0},events:e.events.map((e=>({name:e.name,attributes:a(e.attributes),droppedAttributesCount:0,timeUnixNano:1e6*e.timestamp})))})}return r({resourceSpans:[{resource:{attributes:a(i),droppedAttributesCount:0},instrumentationLibrarySpans:[{instrumentationLibrary:{name:e,version:t},spans:u}]}]})};export{s as exporter};
@@ -0,0 +1,3 @@
1
+ import type { Exporter } from 'rian';
2
+
3
+ export const exporter: (request: (payload: any) => any) => Exporter;
@@ -0,0 +1 @@
1
+ const { flattie:e } = require('flattie');var t=t=>(a,n)=>{let r=[];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}),r.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:n.localEndpoint||{serviceName:s["service.name"]},tags:e({...n,...s},".",!0),annotations:t.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,n)=>{let r=[];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}),r.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:n.localEndpoint||{serviceName:s["service.name"]},tags:e({...n,...s},".",!0),annotations:t.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,3 @@
1
- import { Traceparent } from 'tctx';
2
-
3
1
  /**
4
2
  * Spans are units within a distributed trace. Spans encapsulate mainly 3 pieces of information, a
5
3
  * {@link Span.name|name}, and a {@link Span.start|start} and {@link Span.end|end} time.
@@ -20,110 +18,124 @@ import { Traceparent } from 'tctx';
20
18
  * Spans are aimed to interoperate with
21
19
  * {@link https://github.com/opentracing/specification/blob/master/specification.md|OpenTracing's Spans}, albeit not entirely api compatible — they do share principles.
22
20
  */
23
- interface Span {
24
- /**
25
- * A human-readable name for this span. For example the function name, the name of a subtask,
26
- * or stage of the larger stack.
27
- *
28
- * @example
29
- * "resolve_user_ids"
30
- * "[POST] /api"
31
- */
32
- name: string;
33
- /**
34
- * A w3c trace context compatible id for this span. Will .toString() into an injectable header.
35
- *
36
- * @see https://www.w3.org/TR/trace-context/#traceparent-header
37
- * @see https://github.com/maraisr/tctx
38
- */
39
- id: Traceparent;
40
- /**
41
- * Is the id of rhe parent if this is not the parent {@link Span}.
42
- *
43
- * @see {@link Span.id}
44
- */
45
- parent?: Traceparent;
46
- /**
47
- * The time represented as a UNIX epoch timestamp in milliseconds when this span was created.
48
- * Typically, via
49
- * {@link Scope.fork|tracer.fork()}.
50
- */
51
- start: number;
52
- /**
53
- * The UNIX epoch timestamp in milliseconds when the span ended, or undefined if ending was not
54
- * captured during the current trace. Time should then be assumed as current time.
55
- */
56
- end?: number;
57
- /**
58
- * An arbitrary context object useful for storing information during a trace.
59
- *
60
- * Usually following a convention such as `tag.*`, `http.*` or any of the
61
- * {@link https://github.com/opentracing/specification/blob/master/semantic_conventions.md|Semantic Conventions outlined by OpenTracing}.
62
- *
63
- * ### Note!
64
- *
65
- * There are a few keys with "powers"
66
- *
67
- * - `kind` when set will coerce into the exports scheme, aka INTERNAL in zipkin will be
68
- * `"INTERNAL"`, or `1` in otel
69
- * - `error` when set, will be assumed to be an `Error` instance, and thus its `.message` wil
70
- * exist as `error.message` in zipkin, and `status: 2` in otel.
71
- */
72
- context: Context;
73
- /**
74
- * Events are user-defined timestamped annotations of "events" that happened during the
75
- * lifetime of a span. Consisting of a textual message, and optional attributes.
76
- *
77
- * As a rule-of-thumb use events to attach verbose information about a span, than an entirely
78
- * new span.
79
- */
80
- events: {
81
- name: string;
82
- timestamp: number;
83
- attributes: Context;
84
- }[];
21
+ export interface Span {
22
+ /**
23
+ * A human-readable name for this span. For example the function name, the name of a subtask,
24
+ * or stage of the larger stack.
25
+ *
26
+ * @example
27
+ * "resolve_user_ids"
28
+ * "[POST] /api"
29
+ */
30
+ name: string;
31
+
32
+ /**
33
+ * A w3c trace context compatible id for this span. Will .toString() into an injectable header.
34
+ *
35
+ * @see https://www.w3.org/TR/trace-context/#traceparent-header
36
+ * @see https://github.com/maraisr/tctx
37
+ */
38
+ id: Traceparent;
39
+
40
+ /**
41
+ * Is the id of rhe parent if this is not the parent {@link Span}.
42
+ *
43
+ * @see {@link Span.id}
44
+ */
45
+ parent: Traceparent | undefined;
46
+
47
+ /**
48
+ * The time represented as a UNIX epoch timestamp in milliseconds when this span was created.
49
+ * Typically, via
50
+ * {@link Scope.fork|tracer.fork()}.
51
+ */
52
+ start: number;
53
+
54
+ /**
55
+ * The UNIX epoch timestamp in milliseconds when the span ended, or undefined if ending was not
56
+ * captured during the current trace. Time should then be assumed as current time.
57
+ */
58
+ end?: number;
59
+
60
+ /**
61
+ * An arbitrary context object useful for storing information during a trace.
62
+ *
63
+ * Usually following a convention such as `tag.*`, `http.*` or any of the
64
+ * {@link https://github.com/opentracing/specification/blob/master/semantic_conventions.md|Semantic Conventions outlined by OpenTracing}.
65
+ *
66
+ * ### Note!
67
+ *
68
+ * There are a few keys with "powers"
69
+ *
70
+ * - `kind` when set will coerce into the exports scheme, aka INTERNAL in zipkin will be
71
+ * `"INTERNAL"`, or `1` in otel
72
+ * - `error` when set, will be assumed to be an `Error` instance, and thus its `.message` wil
73
+ * exist as `error.message` in zipkin, and `status: 2` in otel.
74
+ */
75
+ context: Context;
76
+
77
+ /**
78
+ * Events are user-defined timestamped annotations of "events" that happened during the
79
+ * lifetime of a span. Consisting of a textual message, and optional attributes.
80
+ *
81
+ * As a rule-of-thumb use events to attach verbose information about a span, than an entirely
82
+ * new span.
83
+ */
84
+ events: { name: string; timestamp: number; attributes: Context }[];
85
85
  }
86
- interface Scope {
87
- /**
88
- * A W3C traceparent. One can .toString() this if you want to cross a network.
89
- */
90
- traceparent: Traceparent;
91
- /**
92
- * Forks the span into a new child span.
93
- */
94
- fork(name: string): CallableScope;
95
- /**
96
- * Allows the span's context to be set. Passing an object will be `Object.assign`ed into the
97
- * current context.
98
- *
99
- * Passing a function will be available to return a new context.
100
- */
101
- set_context(contextFn: Context | ((context: Context) => Context)): void;
102
- /**
103
- * Adds a new event to the span. As a rule-of-thumb use events to attach verbose information
104
- * about a span, than an entirely new span.
105
- */
106
- add_event(name: string, attributes?: Record<string, any>): void;
107
- /**
108
- * Ends the current span setting its `end` timestamp. Not calling this, will have its `end`
109
- * timestamp nulled out — when the tracer ends.
110
- */
111
- end(): void;
86
+
87
+ export interface Scope {
88
+ /**
89
+ * A W3C traceparent. One can .toString() this if you want to cross a network.
90
+ */
91
+ traceparent: Traceparent;
92
+
93
+ /**
94
+ * Forks the span into a new child span.
95
+ */
96
+ fork(name: string): CallableScope;
97
+
98
+ /**
99
+ * Allows the span's context to be set. Passing an object will be `Object.assign`ed into the
100
+ * current context.
101
+ *
102
+ * Passing a function will be available to return a new context.
103
+ */
104
+ set_context(contextFn: Context | ((context: Context) => Context)): void;
105
+
106
+ /**
107
+ * Adds a new event to the span. As a rule-of-thumb use events to attach verbose information
108
+ * about a span, than an entirely new span.
109
+ */
110
+ add_event(name: string, attributes?: Record<string, any>): void;
111
+
112
+ /**
113
+ * Ends the current span — setting its `end` timestamp. Not calling this, will have its `end`
114
+ * timestamp nulled out — when the tracer ends.
115
+ */
116
+ end(): void;
112
117
  }
113
- interface Tracer extends Omit<Scope, 'end'> {
114
- end(): ReturnType<Exporter>;
118
+
119
+ export interface Tracer extends Omit<Scope, 'end'> {
120
+ end(): ReturnType<Exporter>;
115
121
  }
122
+
116
123
  /**
117
124
  * An exporter is a method called when the parent scope ends, gets given a Set of all spans traced
118
125
  * during this execution.
119
126
  */
120
- declare type Exporter = (spans: ReadonlySet<Readonly<Span>>, context: Context) => any;
127
+ export type Exporter = (
128
+ spans: ReadonlySet<Readonly<Span>>,
129
+ context: Context,
130
+ ) => any;
131
+
121
132
  /**
122
133
  * @borrows {@link Span.context}
123
134
  */
124
- interface Context {
125
- [property: string]: any;
135
+ export interface Context {
136
+ [property: string]: any;
126
137
  }
138
+
127
139
  /**
128
140
  * Should return true when you want to sample the span, this is ran before the span is traced — so
129
141
  * decisions is made preemptively.
@@ -133,28 +145,45 @@ interface Context {
133
145
  *
134
146
  * Sampling does impact the traceparent, for injection — and is encoded there.
135
147
  */
136
- declare type Sampler = (name: string, parentId?: Traceparent, context?: Context) => boolean;
137
- interface Options {
138
- /**
139
- * @borrows {@link Exporter}
140
- */
141
- exporter: Exporter;
142
- /**
143
- * @borrows {@link Sampler}
144
- */
145
- sampler?: Sampler | boolean;
146
- context?: Context;
147
- /**
148
- * A root, or extracted w3c traceparent stringed header.
149
- *
150
- * If the id is malformed, the {@link create} method will throw an exception. If no root is
151
- * provided then one will be created obeying the {@link Options.sampler|sampling} rules.
152
- */
153
- traceparent?: string;
148
+ export type Sampler = (
149
+ name: string,
150
+ parentId?: Traceparent,
151
+ context?: Context,
152
+ ) => boolean;
153
+
154
+ export interface Options {
155
+ /**
156
+ * @borrows {@link Exporter}
157
+ */
158
+ exporter: Exporter;
159
+
160
+ /**
161
+ * @borrows {@link Sampler}
162
+ */
163
+ sampler?: Sampler | boolean;
164
+
165
+ context?: Context;
166
+
167
+ /**
168
+ * A root, or extracted w3c traceparent stringed header.
169
+ *
170
+ * If the id is malformed, the {@link create} method will throw an exception. If no root is
171
+ * provided then one will be created obeying the {@link Options.sampler|sampling} rules.
172
+ */
173
+ traceparent?: string;
154
174
  }
155
- interface CallableScope extends Scope {
156
- (cb: (scope: Omit<Scope, 'end'>) => void): ReturnType<typeof cb>;
175
+
176
+ export const create: (name: string, options: Options) => Tracer;
177
+
178
+ // ==> internals
179
+
180
+ /** @internal */
181
+ export interface CallableScope extends Scope {
182
+ (cb: (scope: Omit<Scope, 'end'>) => void): ReturnType<typeof cb>;
157
183
  }
158
- declare const create: (name: string, options: Options) => Tracer;
159
184
 
160
- export { Context, Exporter, Options, Sampler, Scope, Span, Tracer, create };
185
+ /** @internal */
186
+ export const PROMISES: WeakMap<Scope, Promise<any>[]>;
187
+
188
+ /** @internal */
189
+ export const ADD_PROMISE: (scope: Scope, promise: Promise<any>) => void;
package/index.js CHANGED
@@ -1,121 +1 @@
1
- 'use strict';
2
-
3
- const package_json = require('rian/package.json');
4
- const tctx = require('tctx');
5
- const utils = require('rian/utils');
6
-
7
- function _interopNamespace(e) {
8
- if (e && e.__esModule) return e;
9
- const n = Object.create(null);
10
- if (e) {
11
- for (const k in e) {
12
- if (k !== 'default') {
13
- const d = Object.getOwnPropertyDescriptor(e, k);
14
- Object.defineProperty(n, k, d.get ? d : {
15
- enumerable: true,
16
- get: function () { return e[k]; }
17
- });
18
- }
19
- }
20
- }
21
- n["default"] = e;
22
- return n;
23
- }
24
-
25
- const tctx__namespace = /*#__PURE__*/_interopNamespace(tctx);
26
-
27
- // ==> impl
28
- /**
29
- * @internal
30
- */
31
- const PROMISES = new WeakMap();
32
- /**
33
- * @internal
34
- */
35
- const ADD_PROMISE = (scope, promise) => {
36
- if (PROMISES.has(scope))
37
- PROMISES.get(scope).push(promise);
38
- else
39
- PROMISES.set(scope, [promise]);
40
- };
41
- /**
42
- * The default sampler;
43
- *
44
- * If no parent
45
- * ~> sample
46
- * if parent was off
47
- * ~> never sample
48
- * if parent was on
49
- * ~> always sample
50
- */
51
- const defaultSampler = (_name, parentId) => {
52
- if (!parentId)
53
- return true;
54
- return tctx__namespace.is_sampled(parentId);
55
- };
56
- const sdk_object = {
57
- 'telemetry.sdk.name': package_json.name,
58
- 'telemetry.sdk.version': package_json.version,
59
- };
60
- const create = (name, options) => {
61
- const spans = new Set();
62
- const sampler = options.sampler || defaultSampler;
63
- const sampler_callable = typeof sampler !== 'boolean';
64
- const span = (name, parent) => {
65
- const should_sample = sampler_callable
66
- ? sampler(name, parent, options.context)
67
- : sampler;
68
- const id = parent
69
- ? parent.child(should_sample)
70
- : tctx__namespace.make(should_sample);
71
- const span_obj = {
72
- id,
73
- parent,
74
- start: Date.now(),
75
- name,
76
- events: [],
77
- context: {},
78
- };
79
- if (should_sample)
80
- spans.add(span_obj);
81
- const $ = (cb) => utils.measureFn($, cb);
82
- $.traceparent = id;
83
- $.fork = (name) => span(name, id);
84
- // @ts-expect-error TS7030 its always undefined ts :eye-roll:
85
- $.set_context = (ctx) => {
86
- if (typeof ctx === 'function')
87
- return void (span_obj.context = ctx(span_obj.context));
88
- Object.assign(span_obj.context, ctx);
89
- };
90
- $.add_event = (name, attributes) => {
91
- span_obj.events.push({
92
- name,
93
- timestamp: Date.now(),
94
- attributes: attributes || {},
95
- });
96
- };
97
- $.end = () => {
98
- if (span_obj.end == null)
99
- span_obj.end = Date.now();
100
- };
101
- return $;
102
- };
103
- const root = span(name, typeof options.traceparent === 'string'
104
- ? tctx__namespace.parse(options.traceparent)
105
- : undefined);
106
- const endRoot = root.end.bind(root);
107
- root.end = async () => {
108
- endRoot();
109
- if (PROMISES.has(root))
110
- await Promise.all(PROMISES.get(root));
111
- return options.exporter(spans, {
112
- ...(options.context || {}),
113
- ...sdk_object,
114
- });
115
- };
116
- return root;
117
- };
118
-
119
- exports.ADD_PROMISE = ADD_PROMISE;
120
- exports.PROMISES = PROMISES;
121
- exports.create = create;
1
+ const e = require('tctx');const { measureFn:t } = require('rian/utils');var n=new WeakMap,a=(e,t)=>{n.has(e)?n.get(e).push(t):n.set(e,[t])},r=(t,n)=>!n||e.is_sampled(n),o={"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.2.2"},s=(a,s)=>{let i=new Set,p=s.sampler||r,d="boolean"!=typeof p,c=(n,a)=>{let r=d?p(n,a,s.context):p,o=a?a.child(r):e.make(r),m={id:o,parent:a,start:Date.now(),name:n,events:[],context:{}};r&&i.add(m);let l=e=>t(l,e);return l.traceparent=o,l.fork=e=>c(e,o),l.set_context=e=>{"function"!=typeof e?Object.assign(m.context,e):m.context=e(m.context)},l.add_event=(e,t)=>{m.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},l.end=()=>{null==m.end&&(m.end=Date.now())},l},m=c(a,"string"==typeof s.traceparent?e.parse(s.traceparent):void 0),l=m.end.bind(m);return m.end=async()=>(l(),n.has(m)&&await Promise.all(n.get(m)),s.exporter(i,{...s.context||{},...o})),m};exports.ADD_PROMISE=a;exports.PROMISES=n;exports.create=s;
package/index.mjs CHANGED
@@ -1,97 +1 @@
1
- import { name, version } from 'rian/package.json';
2
- import * as tctx from 'tctx';
3
- import { measureFn } from 'rian/utils';
4
-
5
- // ==> impl
6
- /**
7
- * @internal
8
- */
9
- const PROMISES = new WeakMap();
10
- /**
11
- * @internal
12
- */
13
- const ADD_PROMISE = (scope, promise) => {
14
- if (PROMISES.has(scope))
15
- PROMISES.get(scope).push(promise);
16
- else
17
- PROMISES.set(scope, [promise]);
18
- };
19
- /**
20
- * The default sampler;
21
- *
22
- * If no parent
23
- * ~> sample
24
- * if parent was off
25
- * ~> never sample
26
- * if parent was on
27
- * ~> always sample
28
- */
29
- const defaultSampler = (_name, parentId) => {
30
- if (!parentId)
31
- return true;
32
- return tctx.is_sampled(parentId);
33
- };
34
- const sdk_object = {
35
- 'telemetry.sdk.name': name,
36
- 'telemetry.sdk.version': version,
37
- };
38
- const create = (name, options) => {
39
- const spans = new Set();
40
- const sampler = options.sampler || defaultSampler;
41
- const sampler_callable = typeof sampler !== 'boolean';
42
- const span = (name, parent) => {
43
- const should_sample = sampler_callable
44
- ? sampler(name, parent, options.context)
45
- : sampler;
46
- const id = parent
47
- ? parent.child(should_sample)
48
- : tctx.make(should_sample);
49
- const span_obj = {
50
- id,
51
- parent,
52
- start: Date.now(),
53
- name,
54
- events: [],
55
- context: {},
56
- };
57
- if (should_sample)
58
- spans.add(span_obj);
59
- const $ = (cb) => measureFn($, cb);
60
- $.traceparent = id;
61
- $.fork = (name) => span(name, id);
62
- // @ts-expect-error TS7030 its always undefined ts :eye-roll:
63
- $.set_context = (ctx) => {
64
- if (typeof ctx === 'function')
65
- return void (span_obj.context = ctx(span_obj.context));
66
- Object.assign(span_obj.context, ctx);
67
- };
68
- $.add_event = (name, attributes) => {
69
- span_obj.events.push({
70
- name,
71
- timestamp: Date.now(),
72
- attributes: attributes || {},
73
- });
74
- };
75
- $.end = () => {
76
- if (span_obj.end == null)
77
- span_obj.end = Date.now();
78
- };
79
- return $;
80
- };
81
- const root = span(name, typeof options.traceparent === 'string'
82
- ? tctx.parse(options.traceparent)
83
- : undefined);
84
- const endRoot = root.end.bind(root);
85
- root.end = async () => {
86
- endRoot();
87
- if (PROMISES.has(root))
88
- await Promise.all(PROMISES.get(root));
89
- return options.exporter(spans, {
90
- ...(options.context || {}),
91
- ...sdk_object,
92
- });
93
- };
94
- return root;
95
- };
96
-
97
- export { ADD_PROMISE, PROMISES, create };
1
+ import*as e from"tctx";import{measureFn as t}from"rian/utils";var n=new WeakMap,a=(e,t)=>{n.has(e)?n.get(e).push(t):n.set(e,[t])},r=(t,n)=>!n||e.is_sampled(n),o={"telemetry.sdk.name":"rian","telemetry.sdk.version":"0.2.2"},s=(a,s)=>{let i=new Set,p=s.sampler||r,d="boolean"!=typeof p,c=(n,a)=>{let r=d?p(n,a,s.context):p,o=a?a.child(r):e.make(r),m={id:o,parent:a,start:Date.now(),name:n,events:[],context:{}};r&&i.add(m);let l=e=>t(l,e);return l.traceparent=o,l.fork=e=>c(e,o),l.set_context=e=>{"function"!=typeof e?Object.assign(m.context,e):m.context=e(m.context)},l.add_event=(e,t)=>{m.events.push({name:e,timestamp:Date.now(),attributes:t||{}})},l.end=()=>{null==m.end&&(m.end=Date.now())},l},m=c(a,"string"==typeof s.traceparent?e.parse(s.traceparent):void 0),l=m.end.bind(m);return m.end=async()=>(l(),n.has(m)&&await Promise.all(n.get(m)),s.exporter(i,{...s.context||{},...o})),m};export{a as ADD_PROMISE,n as PROMISES,s as create};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rian",
3
- "version": "0.1.1",
3
+ "version": "0.2.2",
4
4
  "description": "Effective tracing for the edge and origins",
5
5
  "keywords": [
6
6
  "opentelemetry",
@@ -26,20 +26,24 @@
26
26
  "type": "module",
27
27
  "exports": {
28
28
  ".": {
29
+ "types": "./index.d.ts",
29
30
  "import": "./index.mjs",
30
31
  "require": "./index.js"
31
32
  },
32
33
  "./exporter.otel.http": {
33
- "import": "./exporter.otel.http.mjs",
34
- "require": "./exporter.otel.http.js"
34
+ "types": "./exporter.otel.http/index.d.ts",
35
+ "import": "./exporter.otel.http/index.mjs",
36
+ "require": "./exporter.otel.http/index.js"
35
37
  },
36
38
  "./exporter.zipkin": {
37
- "import": "./exporter.zipkin.mjs",
38
- "require": "./exporter.zipkin.js"
39
+ "types": "./exporter.zipkin/index.d.ts",
40
+ "import": "./exporter.zipkin/index.mjs",
41
+ "require": "./exporter.zipkin/index.js"
39
42
  },
40
43
  "./utils": {
41
- "import": "./utils.mjs",
42
- "require": "./utils.js"
44
+ "types": "./utils/index.d.ts",
45
+ "import": "./utils/index.mjs",
46
+ "require": "./utils/index.js"
43
47
  },
44
48
  "./package.json": "./package.json"
45
49
  },
@@ -49,10 +53,18 @@
49
53
  "files": [
50
54
  "*.mjs",
51
55
  "*.js",
52
- "*.d.ts"
56
+ "*.d.ts",
57
+ "exporter.*/*",
58
+ "utils/*"
53
59
  ],
60
+ "scripts": {
61
+ "build": "bundt --minify"
62
+ },
54
63
  "dependencies": {
55
64
  "flattie": "^1.1.0",
56
65
  "tctx": "^0.0.10"
66
+ },
67
+ "devDependencies": {
68
+ "bundt": "2.0.0-next.5"
57
69
  }
58
70
  }
@@ -1,7 +1,9 @@
1
- import { Scope } from 'rian';
1
+ import type { Scope } from 'rian';
2
+
3
+ export type MeasureFn =
4
+ | ((...args: [...args: any[]]) => any)
5
+ | ((...args: [...args: any[], scope: Scope]) => any);
2
6
 
3
- declare type MeasureFn = ((...args: [...args: any[]]) => any) | ((...args: [...args: any[], scope: Scope]) => any);
4
- declare type RealMeasureFnParams<T extends unknown[]> = T extends [] ? [] : T extends [...rest: infer U, scope: Scope] ? U : T;
5
7
  /**
6
8
  * With a passed function — will start a span, and run the function, when the function finishes
7
9
  * the span finishes.
@@ -26,7 +28,13 @@ declare type RealMeasureFnParams<T extends unknown[]> = T extends [] ? [] : T ex
26
28
  * return value from get_data
27
29
  * ```
28
30
  */
29
- declare const measure: <Fn extends MeasureFn>(scope: Scope, name: string, fn: Fn, ...args: RealMeasureFnParams<Parameters<Fn>>) => ReturnType<Fn>;
31
+ export const measure: <Fn extends MeasureFn>(
32
+ scope: Scope,
33
+ name: string,
34
+ fn: Fn, // TODO: fn doesnt see scope correctly
35
+ ...args: RealMeasureFnParams<Parameters<Fn>>
36
+ ) => ReturnType<Fn>;
37
+
30
38
  /**
31
39
  * Wraps any function with a measured scoped function. Useful for when defer function execution
32
40
  * till a later time.
@@ -41,6 +49,20 @@ declare const measure: <Fn extends MeasureFn>(scope: Scope, name: string, fn: Fn
41
49
  * wrapped();
42
50
  * ```
43
51
  */
44
- declare const wrap: <Fn extends MeasureFn>(scope: Scope, name: string, fn: Fn) => Fn;
52
+ export const wrap: <Fn extends MeasureFn>(
53
+ scope: Scope,
54
+ name: string,
55
+ fn: Fn, // TODO: fn doesnt see scope correctly
56
+ ) => Fn;
57
+
58
+ // ==> internals
59
+
60
+ /** @internal */
61
+ export type RealMeasureFnParams<T extends unknown[]> = T extends []
62
+ ? []
63
+ : T extends [...rest: infer U, scope: Scope]
64
+ ? U
65
+ : T;
45
66
 
46
- export { MeasureFn, measure, wrap };
67
+ /** @internal */
68
+ export const measureFn: (scope: Scope, fn: any, ...args: any[]) => any;
package/utils/index.js ADDED
@@ -0,0 +1 @@
1
+ const { ADD_PROMISE:r, PROMISES:t } = require('rian');var n=(n,o,...e)=>{try{var a=o(...e,n),c=a instanceof Promise;return c&&!t.has(n)&&r(n,a.catch((r=>{n.set_context({error:r})})).finally((()=>n.end()))),a}catch(r){throw r instanceof Error&&n.set_context({error:r}),r}finally{!0!==c&&n.end()}},o=(r,t,o,...e)=>n(r.fork(t),o,...e),e=(r,t,o)=>function(){return n(r.fork(t),o,...arguments)};exports.measure=o;exports.measureFn=n;exports.wrap=e;
@@ -0,0 +1 @@
1
+ import{ADD_PROMISE as r,PROMISES as t}from"rian";var n=(n,o,...e)=>{try{var a=o(...e,n),c=a instanceof Promise;return c&&!t.has(n)&&r(n,a.catch((r=>{n.set_context({error:r})})).finally((()=>n.end()))),a}catch(r){throw r instanceof Error&&n.set_context({error:r}),r}finally{!0!==c&&n.end()}},o=(r,t,o,...e)=>n(r.fork(t),o,...e),e=(r,t,o)=>function(){return n(r.fork(t),o,...arguments)};export{o as measure,n as measureFn,e as wrap};
@@ -1,5 +0,0 @@
1
- import * as rian from 'rian';
2
-
3
- declare const exporter: (request: (payload: any) => any) => rian.Exporter;
4
-
5
- export { exporter };
@@ -1,113 +0,0 @@
1
- 'use strict';
2
-
3
- const package_json = require('rian/package.json');
4
-
5
- const SpanStatusCode_UNSET = 0;
6
- const SpanStatusCode_ERROR = 2;
7
- const convert_value_to_anyvalue = (value) => {
8
- let type = typeof value, any_value = {};
9
- if (type === 'string')
10
- any_value.stringValue = value;
11
- else if (type === 'number')
12
- if (Number.isInteger(value))
13
- any_value.intValue = value;
14
- else
15
- any_value.doubleValue = value;
16
- else if (type === 'boolean')
17
- any_value.boolValue = value;
18
- else if (Array.isArray(value))
19
- any_value.arrayValue = {
20
- values: value.map((i) => convert_value_to_anyvalue(i)),
21
- };
22
- else if (value)
23
- any_value.kvlistValue = { values: convert_object_to_kv(value) };
24
- return any_value;
25
- };
26
- const convert_object_to_kv = (input) => {
27
- const value = [];
28
- for (let key of Object.keys(input)) {
29
- value.push({
30
- key,
31
- value: convert_value_to_anyvalue(input[key]),
32
- });
33
- }
34
- return value;
35
- };
36
- // https://github.com/open-telemetry/opentelemetry-proto/blob/b43e9b18b76abf3ee040164b55b9c355217151f3/opentelemetry/proto/trace/v1/trace.proto#L127-L155
37
- const map_kind = (kind) => {
38
- switch (kind) {
39
- default:
40
- case 'INTERNAL': {
41
- return 1;
42
- }
43
- case 'SERVER': {
44
- return 2;
45
- }
46
- case 'CLIENT': {
47
- return 3;
48
- }
49
- case 'PRODUCER': {
50
- return 4;
51
- }
52
- case 'CONSUMER': {
53
- return 5;
54
- }
55
- }
56
- };
57
- const exporter = (request) => (spans, context) => {
58
- const otel_spans = [];
59
- for (let span of spans) {
60
- const { kind, error, ...span_ctx } = span.context;
61
- let status;
62
- if (error) {
63
- status = {
64
- code: SpanStatusCode_ERROR,
65
- };
66
- if ('message' in error) {
67
- status.message = error.message;
68
- }
69
- }
70
- otel_spans.push({
71
- traceId: span.id.trace_id,
72
- spanId: span.id.parent_id,
73
- parentSpanId: span.parent?.parent_id,
74
- name: span.name,
75
- kind: map_kind(kind || 'INTERNAL'),
76
- startTimeUnixNano: span.start * 1000000,
77
- endTimeUnixNano: span.end ? span.end * 1000000 : undefined,
78
- droppedAttributesCount: 0,
79
- droppedEventsCount: 0,
80
- droppedLinksCount: 0,
81
- attributes: convert_object_to_kv(span_ctx),
82
- // @ts-expect-error TS2454
83
- status: status || { code: SpanStatusCode_UNSET },
84
- events: span.events.map((i) => ({
85
- name: i.name,
86
- attributes: convert_object_to_kv(i.attributes),
87
- droppedAttributesCount: 0,
88
- timeUnixNano: i.timestamp * 1000000,
89
- })),
90
- });
91
- }
92
- return request({
93
- resourceSpans: [
94
- {
95
- resource: {
96
- attributes: convert_object_to_kv(context),
97
- droppedAttributesCount: 0,
98
- },
99
- instrumentationLibrarySpans: [
100
- {
101
- instrumentationLibrary: {
102
- name: package_json.name,
103
- version: package_json.version,
104
- },
105
- spans: otel_spans,
106
- },
107
- ],
108
- },
109
- ],
110
- });
111
- };
112
-
113
- exports.exporter = exporter;
@@ -1,111 +0,0 @@
1
- import { name, version } from 'rian/package.json';
2
-
3
- const SpanStatusCode_UNSET = 0;
4
- const SpanStatusCode_ERROR = 2;
5
- const convert_value_to_anyvalue = (value) => {
6
- let type = typeof value, any_value = {};
7
- if (type === 'string')
8
- any_value.stringValue = value;
9
- else if (type === 'number')
10
- if (Number.isInteger(value))
11
- any_value.intValue = value;
12
- else
13
- any_value.doubleValue = value;
14
- else if (type === 'boolean')
15
- any_value.boolValue = value;
16
- else if (Array.isArray(value))
17
- any_value.arrayValue = {
18
- values: value.map((i) => convert_value_to_anyvalue(i)),
19
- };
20
- else if (value)
21
- any_value.kvlistValue = { values: convert_object_to_kv(value) };
22
- return any_value;
23
- };
24
- const convert_object_to_kv = (input) => {
25
- const value = [];
26
- for (let key of Object.keys(input)) {
27
- value.push({
28
- key,
29
- value: convert_value_to_anyvalue(input[key]),
30
- });
31
- }
32
- return value;
33
- };
34
- // https://github.com/open-telemetry/opentelemetry-proto/blob/b43e9b18b76abf3ee040164b55b9c355217151f3/opentelemetry/proto/trace/v1/trace.proto#L127-L155
35
- const map_kind = (kind) => {
36
- switch (kind) {
37
- default:
38
- case 'INTERNAL': {
39
- return 1;
40
- }
41
- case 'SERVER': {
42
- return 2;
43
- }
44
- case 'CLIENT': {
45
- return 3;
46
- }
47
- case 'PRODUCER': {
48
- return 4;
49
- }
50
- case 'CONSUMER': {
51
- return 5;
52
- }
53
- }
54
- };
55
- const exporter = (request) => (spans, context) => {
56
- const otel_spans = [];
57
- for (let span of spans) {
58
- const { kind, error, ...span_ctx } = span.context;
59
- let status;
60
- if (error) {
61
- status = {
62
- code: SpanStatusCode_ERROR,
63
- };
64
- if ('message' in error) {
65
- status.message = error.message;
66
- }
67
- }
68
- otel_spans.push({
69
- traceId: span.id.trace_id,
70
- spanId: span.id.parent_id,
71
- parentSpanId: span.parent?.parent_id,
72
- name: span.name,
73
- kind: map_kind(kind || 'INTERNAL'),
74
- startTimeUnixNano: span.start * 1000000,
75
- endTimeUnixNano: span.end ? span.end * 1000000 : undefined,
76
- droppedAttributesCount: 0,
77
- droppedEventsCount: 0,
78
- droppedLinksCount: 0,
79
- attributes: convert_object_to_kv(span_ctx),
80
- // @ts-expect-error TS2454
81
- status: status || { code: SpanStatusCode_UNSET },
82
- events: span.events.map((i) => ({
83
- name: i.name,
84
- attributes: convert_object_to_kv(i.attributes),
85
- droppedAttributesCount: 0,
86
- timeUnixNano: i.timestamp * 1000000,
87
- })),
88
- });
89
- }
90
- return request({
91
- resourceSpans: [
92
- {
93
- resource: {
94
- attributes: convert_object_to_kv(context),
95
- droppedAttributesCount: 0,
96
- },
97
- instrumentationLibrarySpans: [
98
- {
99
- instrumentationLibrary: {
100
- name: name,
101
- version: version,
102
- },
103
- spans: otel_spans,
104
- },
105
- ],
106
- },
107
- ],
108
- });
109
- };
110
-
111
- export { exporter };
@@ -1,5 +0,0 @@
1
- import * as rian from 'rian';
2
-
3
- declare const exporter: (request: (payload: any) => any) => rian.Exporter;
4
-
5
- export { exporter };
@@ -1,45 +0,0 @@
1
- 'use strict';
2
-
3
- const flattie = require('flattie');
4
-
5
- const exporter = (request) => (spans, context) => {
6
- const zipkin = [];
7
- for (let span of spans) {
8
- const { kind, error, ...span_ctx } = span.context;
9
- if (error) {
10
- if ('message' in error) {
11
- span_ctx.error = {
12
- name: error.name,
13
- message: error.message,
14
- stack: error.stack,
15
- };
16
- }
17
- else {
18
- span_ctx.error = true;
19
- }
20
- }
21
- zipkin.push({
22
- id: span.id.parent_id,
23
- traceId: span.id.trace_id,
24
- parentId: span.parent ? span.parent.parent_id : undefined,
25
- name: span.name,
26
- kind: kind === 'INTERNAL' ? undefined : kind,
27
- timestamp: span.start * 1000,
28
- duration: span.end ? (span.end - span.start) * 1000 : undefined,
29
- localEndpoint: context.localEndpoint || {
30
- serviceName: span_ctx['service.name'],
31
- },
32
- tags: flattie.flattie({
33
- ...context,
34
- ...span_ctx,
35
- }, '.', true),
36
- annotations: span.events.map((i) => ({
37
- value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
38
- timestamp: i.timestamp * 1000,
39
- })),
40
- });
41
- }
42
- return request(zipkin);
43
- };
44
-
45
- exports.exporter = exporter;
@@ -1,43 +0,0 @@
1
- import { flattie } from 'flattie';
2
-
3
- const exporter = (request) => (spans, context) => {
4
- const zipkin = [];
5
- for (let span of spans) {
6
- const { kind, error, ...span_ctx } = span.context;
7
- if (error) {
8
- if ('message' in error) {
9
- span_ctx.error = {
10
- name: error.name,
11
- message: error.message,
12
- stack: error.stack,
13
- };
14
- }
15
- else {
16
- span_ctx.error = true;
17
- }
18
- }
19
- zipkin.push({
20
- id: span.id.parent_id,
21
- traceId: span.id.trace_id,
22
- parentId: span.parent ? span.parent.parent_id : undefined,
23
- name: span.name,
24
- kind: kind === 'INTERNAL' ? undefined : kind,
25
- timestamp: span.start * 1000,
26
- duration: span.end ? (span.end - span.start) * 1000 : undefined,
27
- localEndpoint: context.localEndpoint || {
28
- serviceName: span_ctx['service.name'],
29
- },
30
- tags: flattie({
31
- ...context,
32
- ...span_ctx,
33
- }, '.', true),
34
- annotations: span.events.map((i) => ({
35
- value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
36
- timestamp: i.timestamp * 1000,
37
- })),
38
- });
39
- }
40
- return request(zipkin);
41
- };
42
-
43
- export { exporter };
package/utils.js DELETED
@@ -1,79 +0,0 @@
1
- 'use strict';
2
-
3
- const rian = require('rian');
4
-
5
- const set_error = (scope, error) => {
6
- scope.set_context({
7
- error,
8
- });
9
- };
10
- /**
11
- * @internal
12
- */
13
- const measureFn = (scope, fn, ...args) => {
14
- try {
15
- var r = fn(...args, scope), is_promise = r instanceof Promise;
16
- if (is_promise && rian.PROMISES.has(scope))
17
- rian.ADD_PROMISE(scope, r
18
- .catch((e) => void set_error(scope, e))
19
- .finally(() => scope.end()));
20
- return r;
21
- }
22
- catch (e) {
23
- if (e instanceof Error)
24
- set_error(scope, e);
25
- throw e;
26
- }
27
- finally {
28
- // @ts-expect-error TS2454
29
- if (is_promise !== true)
30
- scope.end();
31
- }
32
- };
33
- /**
34
- * With a passed function — will start a span, and run the function, when the function finishes
35
- * the span finishes.
36
- *
37
- * The measure method will return whatever the function is, so if it's a promise, it returns a
38
- * promise and so on. Any error is caught and re thrown, and automatically tracked in the
39
- * context under the `error` property.
40
- *
41
- * All promises are tracked, and awaited on a `tracer.end`.
42
- *
43
- * @example
44
- *
45
- * ```text
46
- * const data = await measure(scope, 'name', get_data, 'user_id_123');
47
- * ^ ^ ^ ^ ^
48
- * | | | | |
49
- * | | | | the first argument to get_data
50
- * | | | function to be called
51
- * | | the name of the sub scope
52
- * | |
53
- * | the parent scope
54
- * return value from get_data
55
- * ```
56
- */
57
- const measure = (scope, name, fn, // TODO: fn doesnt see scope correctly
58
- ...args) => measureFn(scope.fork(name), fn, ...args);
59
- /**
60
- * Wraps any function with a measured scoped function. Useful for when defer function execution
61
- * till a later time.
62
- *
63
- * @example
64
- *
65
- * ```js
66
- * const wrapped = wrap(scope, "run something", my_function);
67
- *
68
- * // ... lots of things, where the access to `scope` is lost.
69
- *
70
- * wrapped();
71
- * ```
72
- */
73
- const wrap = (scope, name, fn) => function () {
74
- return measureFn(scope.fork(name), fn, ...arguments);
75
- };
76
-
77
- exports.measure = measure;
78
- exports.measureFn = measureFn;
79
- exports.wrap = wrap;
package/utils.mjs DELETED
@@ -1,75 +0,0 @@
1
- import { PROMISES, ADD_PROMISE } from 'rian';
2
-
3
- const set_error = (scope, error) => {
4
- scope.set_context({
5
- error,
6
- });
7
- };
8
- /**
9
- * @internal
10
- */
11
- const measureFn = (scope, fn, ...args) => {
12
- try {
13
- var r = fn(...args, scope), is_promise = r instanceof Promise;
14
- if (is_promise && PROMISES.has(scope))
15
- ADD_PROMISE(scope, r
16
- .catch((e) => void set_error(scope, e))
17
- .finally(() => scope.end()));
18
- return r;
19
- }
20
- catch (e) {
21
- if (e instanceof Error)
22
- set_error(scope, e);
23
- throw e;
24
- }
25
- finally {
26
- // @ts-expect-error TS2454
27
- if (is_promise !== true)
28
- scope.end();
29
- }
30
- };
31
- /**
32
- * With a passed function — will start a span, and run the function, when the function finishes
33
- * the span finishes.
34
- *
35
- * The measure method will return whatever the function is, so if it's a promise, it returns a
36
- * promise and so on. Any error is caught and re thrown, and automatically tracked in the
37
- * context under the `error` property.
38
- *
39
- * All promises are tracked, and awaited on a `tracer.end`.
40
- *
41
- * @example
42
- *
43
- * ```text
44
- * const data = await measure(scope, 'name', get_data, 'user_id_123');
45
- * ^ ^ ^ ^ ^
46
- * | | | | |
47
- * | | | | the first argument to get_data
48
- * | | | function to be called
49
- * | | the name of the sub scope
50
- * | |
51
- * | the parent scope
52
- * return value from get_data
53
- * ```
54
- */
55
- const measure = (scope, name, fn, // TODO: fn doesnt see scope correctly
56
- ...args) => measureFn(scope.fork(name), fn, ...args);
57
- /**
58
- * Wraps any function with a measured scoped function. Useful for when defer function execution
59
- * till a later time.
60
- *
61
- * @example
62
- *
63
- * ```js
64
- * const wrapped = wrap(scope, "run something", my_function);
65
- *
66
- * // ... lots of things, where the access to `scope` is lost.
67
- *
68
- * wrapped();
69
- * ```
70
- */
71
- const wrap = (scope, name, fn) => function () {
72
- return measureFn(scope.fork(name), fn, ...arguments);
73
- };
74
-
75
- export { measure, measureFn, wrap };