rian 0.1.1 → 0.2.1

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,110 @@
1
+ // src/exporter.otel.http.ts
2
+ const { name:rian_name, version:rian_version } = require('rian/package.json');
3
+ var SpanStatusCode_UNSET = 0;
4
+ var SpanStatusCode_ERROR = 2;
5
+ var 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
+ var 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
+ var map_kind = (kind) => {
35
+ switch (kind) {
36
+ default:
37
+ case "INTERNAL": {
38
+ return 1;
39
+ }
40
+ case "SERVER": {
41
+ return 2;
42
+ }
43
+ case "CLIENT": {
44
+ return 3;
45
+ }
46
+ case "PRODUCER": {
47
+ return 4;
48
+ }
49
+ case "CONSUMER": {
50
+ return 5;
51
+ }
52
+ }
53
+ };
54
+ var exporter = (request) => (spans, context) => {
55
+ const otel_spans = [];
56
+ for (let span of spans) {
57
+ const { kind, error, ...span_ctx } = span.context;
58
+ let status;
59
+ if (error) {
60
+ status = {
61
+ code: SpanStatusCode_ERROR
62
+ };
63
+ if ("message" in error) {
64
+ status.message = error.message;
65
+ }
66
+ }
67
+ otel_spans.push({
68
+ traceId: span.id.trace_id,
69
+ spanId: span.id.parent_id,
70
+ parentSpanId: span.parent?.parent_id,
71
+ name: span.name,
72
+ kind: map_kind(kind || "INTERNAL"),
73
+ startTimeUnixNano: span.start * 1e6,
74
+ endTimeUnixNano: span.end ? span.end * 1e6 : void 0,
75
+ droppedAttributesCount: 0,
76
+ droppedEventsCount: 0,
77
+ droppedLinksCount: 0,
78
+ attributes: convert_object_to_kv(span_ctx),
79
+ status: status || { code: SpanStatusCode_UNSET },
80
+ events: span.events.map((i) => ({
81
+ name: i.name,
82
+ attributes: convert_object_to_kv(i.attributes),
83
+ droppedAttributesCount: 0,
84
+ timeUnixNano: i.timestamp * 1e6
85
+ }))
86
+ });
87
+ }
88
+ return request({
89
+ resourceSpans: [
90
+ {
91
+ resource: {
92
+ attributes: convert_object_to_kv(context),
93
+ droppedAttributesCount: 0
94
+ },
95
+ instrumentationLibrarySpans: [
96
+ {
97
+ instrumentationLibrary: {
98
+ name: rian_name,
99
+ version: rian_version
100
+ },
101
+ spans: otel_spans
102
+ }
103
+ ]
104
+ }
105
+ ]
106
+ });
107
+ };
108
+
109
+
110
+ exports.exporter = exporter;
@@ -0,0 +1,110 @@
1
+ // src/exporter.otel.http.ts
2
+ import { name as rian_name, version as rian_version } from "rian/package.json";
3
+ var SpanStatusCode_UNSET = 0;
4
+ var SpanStatusCode_ERROR = 2;
5
+ var 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
+ var 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
+ var map_kind = (kind) => {
35
+ switch (kind) {
36
+ default:
37
+ case "INTERNAL": {
38
+ return 1;
39
+ }
40
+ case "SERVER": {
41
+ return 2;
42
+ }
43
+ case "CLIENT": {
44
+ return 3;
45
+ }
46
+ case "PRODUCER": {
47
+ return 4;
48
+ }
49
+ case "CONSUMER": {
50
+ return 5;
51
+ }
52
+ }
53
+ };
54
+ var exporter = (request) => (spans, context) => {
55
+ const otel_spans = [];
56
+ for (let span of spans) {
57
+ const { kind, error, ...span_ctx } = span.context;
58
+ let status;
59
+ if (error) {
60
+ status = {
61
+ code: SpanStatusCode_ERROR
62
+ };
63
+ if ("message" in error) {
64
+ status.message = error.message;
65
+ }
66
+ }
67
+ otel_spans.push({
68
+ traceId: span.id.trace_id,
69
+ spanId: span.id.parent_id,
70
+ parentSpanId: span.parent?.parent_id,
71
+ name: span.name,
72
+ kind: map_kind(kind || "INTERNAL"),
73
+ startTimeUnixNano: span.start * 1e6,
74
+ endTimeUnixNano: span.end ? span.end * 1e6 : void 0,
75
+ droppedAttributesCount: 0,
76
+ droppedEventsCount: 0,
77
+ droppedLinksCount: 0,
78
+ attributes: convert_object_to_kv(span_ctx),
79
+ status: status || { code: SpanStatusCode_UNSET },
80
+ events: span.events.map((i) => ({
81
+ name: i.name,
82
+ attributes: convert_object_to_kv(i.attributes),
83
+ droppedAttributesCount: 0,
84
+ timeUnixNano: i.timestamp * 1e6
85
+ }))
86
+ });
87
+ }
88
+ return request({
89
+ resourceSpans: [
90
+ {
91
+ resource: {
92
+ attributes: convert_object_to_kv(context),
93
+ droppedAttributesCount: 0
94
+ },
95
+ instrumentationLibrarySpans: [
96
+ {
97
+ instrumentationLibrary: {
98
+ name: rian_name,
99
+ version: rian_version
100
+ },
101
+ spans: otel_spans
102
+ }
103
+ ]
104
+ }
105
+ ]
106
+ });
107
+ };
108
+ export {
109
+ exporter
110
+ };
@@ -0,0 +1,3 @@
1
+ import type { Exporter } from 'rian';
2
+
3
+ export const exporter: (request: (payload: any) => any) => Exporter;
@@ -0,0 +1,43 @@
1
+ // src/exporter.zipkin.ts
2
+ const { flattie } = require('flattie');
3
+ var 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
+ } else {
15
+ span_ctx.error = true;
16
+ }
17
+ }
18
+ zipkin.push({
19
+ id: span.id.parent_id,
20
+ traceId: span.id.trace_id,
21
+ parentId: span.parent ? span.parent.parent_id : void 0,
22
+ name: span.name,
23
+ kind: kind === "INTERNAL" ? void 0 : kind,
24
+ timestamp: span.start * 1e3,
25
+ duration: span.end ? (span.end - span.start) * 1e3 : void 0,
26
+ localEndpoint: context.localEndpoint || {
27
+ serviceName: span_ctx["service.name"]
28
+ },
29
+ tags: flattie({
30
+ ...context,
31
+ ...span_ctx
32
+ }, ".", true),
33
+ annotations: span.events.map((i) => ({
34
+ value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
35
+ timestamp: i.timestamp * 1e3
36
+ }))
37
+ });
38
+ }
39
+ return request(zipkin);
40
+ };
41
+
42
+
43
+ exports.exporter = exporter;
@@ -0,0 +1,43 @@
1
+ // src/exporter.zipkin.ts
2
+ import { flattie } from "flattie";
3
+ var 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
+ } else {
15
+ span_ctx.error = true;
16
+ }
17
+ }
18
+ zipkin.push({
19
+ id: span.id.parent_id,
20
+ traceId: span.id.trace_id,
21
+ parentId: span.parent ? span.parent.parent_id : void 0,
22
+ name: span.name,
23
+ kind: kind === "INTERNAL" ? void 0 : kind,
24
+ timestamp: span.start * 1e3,
25
+ duration: span.end ? (span.end - span.start) * 1e3 : void 0,
26
+ localEndpoint: context.localEndpoint || {
27
+ serviceName: span_ctx["service.name"]
28
+ },
29
+ tags: flattie({
30
+ ...context,
31
+ ...span_ctx
32
+ }, ".", true),
33
+ annotations: span.events.map((i) => ({
34
+ value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
35
+ timestamp: i.timestamp * 1e3
36
+ }))
37
+ });
38
+ }
39
+ return request(zipkin);
40
+ };
41
+ export {
42
+ exporter
43
+ };
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;