@siglo/opentelemetry 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +179 -2
- package/dist/attributes.d.ts +14 -0
- package/dist/attributes.d.ts.map +1 -0
- package/dist/attributes.js +16 -0
- package/dist/attributes.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/instrument.d.ts +21 -0
- package/dist/instrument.d.ts.map +1 -0
- package/dist/instrument.js +162 -0
- package/dist/instrument.js.map +1 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/w3c.d.ts +15 -0
- package/dist/w3c.d.ts.map +1 -0
- package/dist/w3c.js +46 -0
- package/dist/w3c.js.map +1 -0
- package/package.json +52 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Jerico de guzman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,180 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @siglo/opentelemetry Adapter Guide
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@siglo/opentelemetry` provides vendor-neutral distributed tracing, semantic spans, context event streaming, and W3C Trace Context propagation for `Siglo` workflows. It is fully compliant with the OpenTelemetry API (`@opentelemetry/api` v1.9.0+) and integrates seamlessly with collectors like Jaeger, Zipkin, Datadog, Prometheus, New Relic, and AWS X-Ray.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Overview & Architecture
|
|
8
|
+
|
|
9
|
+
The OpenTelemetry integration creates an end-to-end distributed span hierarchy covering workflows, steps, retries, and context mutations:
|
|
10
|
+
|
|
11
|
+
```mermaid
|
|
12
|
+
flowchart TD
|
|
13
|
+
Req["Incoming HTTP / Kafka / SQS Request<br/>(with W3C traceparent)"] -->|extractTraceContext()| WFSpan["Span: workflow:CheckoutPipeline<br/>• siglo.workflow.name = 'CheckoutPipeline'<br/>• siglo.workflow.version = '2.1.0'<br/>• siglo.stack.id = 'stack_9812_01'<br/>• siglo.namespace = 'ecommerce-us'<br/>• siglo.timeout = 30000"]
|
|
14
|
+
WFSpan --> Step1["Span: step:validateCart<br/>• siglo.step.name = ...<br/>• siglo.step.attempt = 1<br/>• Status: OK"]
|
|
15
|
+
WFSpan --> Step2["Span: step:chargeCard<br/>• siglo.step.attempt = 1<br/>• (Failure: recordException)"]
|
|
16
|
+
Step2 -->|Retry| Step2Retry["Span: step:chargeCard (retry #2)<br/>• siglo.step.attempt = 2<br/>• Status: OK"]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. Installation & Requirements
|
|
22
|
+
|
|
23
|
+
Install `@siglo/opentelemetry` and the OpenTelemetry API:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @siglo/core @siglo/opentelemetry @opentelemetry/api
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Recommended OpenTelemetry SDK packages for Node.js:
|
|
30
|
+
```bash
|
|
31
|
+
npm install --save-dev @opentelemetry/sdk-node @opentelemetry/sdk-trace-node @opentelemetry/exporter-trace-otlp-grpc
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 3. Semantic Attributes Reference
|
|
37
|
+
|
|
38
|
+
`SemanticAttributes` defines standardized OpenTelemetry attribute keys:
|
|
39
|
+
|
|
40
|
+
| Attribute Constant | String Key | Type | Description |
|
|
41
|
+
| :--- | :--- | :--- | :--- |
|
|
42
|
+
| `WORKFLOW_NAME` | `siglo.workflow.name` | `string` | Canonical name of the executing workflow. |
|
|
43
|
+
| `WORKFLOW_VERSION` | `siglo.workflow.version` | `string` | Semantic version string of the workflow. |
|
|
44
|
+
| `WORKFLOW_ID` | `siglo.workflow.id` | `string` | Unique workflow identifier. |
|
|
45
|
+
| `STACK_ID` | `siglo.stack.id` | `string` | Unique stack execution identifier. |
|
|
46
|
+
| `STEP_NAME` | `siglo.step.name` | `string` | Name or debug label of the active step. |
|
|
47
|
+
| `STEP_ID` | `siglo.step.id` | `string` | Internal node identifier in the workflow graph AST. |
|
|
48
|
+
| `STEP_ATTEMPT` | `siglo.step.attempt` | `number` | 1-based attempt count (incremented on retries). |
|
|
49
|
+
| `NAMESPACE` | `siglo.namespace` | `string` | Tenant namespace partition (requires `allowNamespace: true`). |
|
|
50
|
+
| `CACHE_HIT` | `siglo.cache.hit` | `boolean` | `true` if step result was served from cache. |
|
|
51
|
+
| `TIMEOUT` | `siglo.timeout` | `number` | Configured timeout in milliseconds. |
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 4. API Reference
|
|
56
|
+
|
|
57
|
+
### `instrumentWorkflow(workflow, options)`
|
|
58
|
+
|
|
59
|
+
Instruments a `Flow` instance with a root span, sets execution attributes, and automatically instruments all child steps:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
function instrumentWorkflow<TInput = any, TOutput = any>(
|
|
63
|
+
workflow: Flow<TInput, TOutput>,
|
|
64
|
+
options?: SigloTelemetryOptions
|
|
65
|
+
): Flow<TInput, TOutput>;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Options (`SigloTelemetryOptions`):
|
|
69
|
+
- `tracer` (`Tracer`): Custom OpenTelemetry `Tracer` instance. If omitted, uses `trace.getTracer('@siglo/opentelemetry', '1.0.0')`.
|
|
70
|
+
- `serviceName` (`string`): Tracer service name identifier.
|
|
71
|
+
- `workflowName` (`string`): Override workflow span label.
|
|
72
|
+
- `workflowVersion` (`string`): Workflow version (default: `'1.0.0'`).
|
|
73
|
+
- `allowNamespace` (`boolean`): If `true`, injects `siglo.namespace` into span attributes. Default `false` to prevent accidental namespace leakage.
|
|
74
|
+
- `allowContextFields` (`string[]`): Whitelist of step context mutation keys that are allowed to be recorded as span attributes.
|
|
75
|
+
- `redactHook` (`(key: string, value: unknown) => unknown`): Sanitizer hook to scrub sensitive or PII data before recording attributes.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### `instrumentStep(step, options)`
|
|
80
|
+
|
|
81
|
+
Wraps an individual `Step` with a child span covering step execution, attempt count tracking, status reporting, and exception capturing:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
function instrumentStep<TInput = any, TOutput = any>(
|
|
85
|
+
step: Step<TInput, TOutput>,
|
|
86
|
+
options?: SigloTelemetryOptions
|
|
87
|
+
): Step<TInput, TOutput>;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### `createTelemetryStorageAdapter(options)`
|
|
93
|
+
|
|
94
|
+
Creates a `StorageAdapter` that transforms context changes into OpenTelemetry span attributes:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
function createTelemetryStorageAdapter(options?: SigloTelemetryOptions): StorageAdapter;
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
#### Security & PII Protection:
|
|
101
|
+
By default, **no context fields are streamed to OpenTelemetry spans**. Only fields explicitly declared in `allowContextFields` are emitted as `siglo.context.<field>`, and all values pass through `redactHook` if configured.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### W3C Distributed Context Propagation Helpers
|
|
106
|
+
|
|
107
|
+
- **`injectTraceContext(carrier, ctx?)`**: Injects active OpenTelemetry span context into headers or metadata dictionaries.
|
|
108
|
+
- **`extractTraceContext(carrier, ctx?)`**: Extracts OpenTelemetry `Context` from HTTP headers or Kafka message headers.
|
|
109
|
+
- **`getTraceHeaders(span?)`**: Returns `{ traceparent: string, tracestate?: string }` from the active or supplied span.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 5. Complete Production Instrumentation Example
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
117
|
+
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
|
|
118
|
+
import { trace } from '@opentelemetry/api';
|
|
119
|
+
import { Step, flow } from '@siglo/core';
|
|
120
|
+
import {
|
|
121
|
+
instrumentWorkflow,
|
|
122
|
+
createTelemetryStorageAdapter,
|
|
123
|
+
getTraceHeaders
|
|
124
|
+
} from '@siglo/opentelemetry';
|
|
125
|
+
|
|
126
|
+
// 1. Initialize OpenTelemetry SDK
|
|
127
|
+
const sdk = new NodeSDK({
|
|
128
|
+
traceExporter: new OTLPTraceExporter({ url: 'http://localhost:4317' }),
|
|
129
|
+
serviceName: 'order-service',
|
|
130
|
+
});
|
|
131
|
+
sdk.start();
|
|
132
|
+
|
|
133
|
+
const tracer = trace.getTracer('order-service', '1.0.0');
|
|
134
|
+
|
|
135
|
+
// 2. Configure Storage Adapter with PII Sanitization
|
|
136
|
+
const telemetryStorage = createTelemetryStorageAdapter({
|
|
137
|
+
allowContextFields: ['orderId', 'orderStatus', 'cardLast4', 'totalAmount'],
|
|
138
|
+
redactHook: (key, val) => {
|
|
139
|
+
if (key === 'cardLast4') {
|
|
140
|
+
return `****${String(val).slice(-4)}`;
|
|
141
|
+
}
|
|
142
|
+
return val;
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
Step.useStorage(telemetryStorage);
|
|
146
|
+
|
|
147
|
+
// 3. Define Workflow Steps with Retry
|
|
148
|
+
const validateOrder = Step.create('validateOrder', async (input: any) => {
|
|
149
|
+
return { orderId: input.orderId, validated: true };
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const chargePayment = Step.create('chargePayment', async (param: any) => {
|
|
153
|
+
// Simulate transient failure on first attempt
|
|
154
|
+
if (param.$attempt && param.$attempt() === 0) {
|
|
155
|
+
throw new Error('Temporary payment gateway blip');
|
|
156
|
+
}
|
|
157
|
+
return { paymentStatus: 'CHARGED', cardLast4: '4242' };
|
|
158
|
+
})
|
|
159
|
+
.retry({ maxRetries: 2, delayMs: 100 })
|
|
160
|
+
;
|
|
161
|
+
|
|
162
|
+
const orderWorkflow = flow(validateOrder, chargePayment);
|
|
163
|
+
|
|
164
|
+
// 4. Instrument Workflow
|
|
165
|
+
const monitoredWorkflow = instrumentWorkflow(orderWorkflow, {
|
|
166
|
+
tracer,
|
|
167
|
+
workflowName: 'CustomerOrderProcessing',
|
|
168
|
+
workflowVersion: '2.4.0',
|
|
169
|
+
allowNamespace: true,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// 5. Run Monitored Workflow
|
|
173
|
+
const result = await monitoredWorkflow.run(
|
|
174
|
+
{ orderId: 'ORD-7718', totalAmount: 89.5 },
|
|
175
|
+
{ namespace: 'tenant-emea' }
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
console.log('Workflow finished with Stack ID:', result.$stackId());
|
|
179
|
+
console.log('Outgoing W3C Headers for downstreams:', getTraceHeaders());
|
|
180
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const SemanticAttributes: {
|
|
2
|
+
readonly WORKFLOW_NAME: "siglo.workflow.name";
|
|
3
|
+
readonly WORKFLOW_VERSION: "siglo.workflow.version";
|
|
4
|
+
readonly WORKFLOW_ID: "siglo.workflow.id";
|
|
5
|
+
readonly STACK_ID: "siglo.stack.id";
|
|
6
|
+
readonly STEP_NAME: "siglo.step.name";
|
|
7
|
+
readonly STEP_ID: "siglo.step.id";
|
|
8
|
+
readonly STEP_ATTEMPT: "siglo.step.attempt";
|
|
9
|
+
readonly NAMESPACE: "siglo.namespace";
|
|
10
|
+
readonly CACHE_HIT: "siglo.cache.hit";
|
|
11
|
+
readonly TIMEOUT: "siglo.timeout";
|
|
12
|
+
};
|
|
13
|
+
export type SemanticAttributeKey = (typeof SemanticAttributes)[keyof typeof SemanticAttributes];
|
|
14
|
+
//# sourceMappingURL=attributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.d.ts","sourceRoot":"","sources":["../src/attributes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB;;;;;;;;;;;CAWrB,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SemanticAttributes = void 0;
|
|
4
|
+
exports.SemanticAttributes = {
|
|
5
|
+
WORKFLOW_NAME: 'siglo.workflow.name',
|
|
6
|
+
WORKFLOW_VERSION: 'siglo.workflow.version',
|
|
7
|
+
WORKFLOW_ID: 'siglo.workflow.id',
|
|
8
|
+
STACK_ID: 'siglo.stack.id',
|
|
9
|
+
STEP_NAME: 'siglo.step.name',
|
|
10
|
+
STEP_ID: 'siglo.step.id',
|
|
11
|
+
STEP_ATTEMPT: 'siglo.step.attempt',
|
|
12
|
+
NAMESPACE: 'siglo.namespace',
|
|
13
|
+
CACHE_HIT: 'siglo.cache.hit',
|
|
14
|
+
TIMEOUT: 'siglo.timeout',
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attributes.js","sourceRoot":"","sources":["../src/attributes.ts"],"names":[],"mappings":";;;AAAa,QAAA,kBAAkB,GAAG;IAC9B,aAAa,EAAE,qBAAqB;IACpC,gBAAgB,EAAE,wBAAwB;IAC1C,WAAW,EAAE,mBAAmB;IAChC,QAAQ,EAAE,gBAAgB;IAC1B,SAAS,EAAE,iBAAiB;IAC5B,OAAO,EAAE,eAAe;IACxB,YAAY,EAAE,oBAAoB;IAClC,SAAS,EAAE,iBAAiB;IAC5B,SAAS,EAAE,iBAAiB;IAC5B,OAAO,EAAE,eAAe;CAClB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./attributes"), exports);
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
19
|
+
__exportStar(require("./w3c"), exports);
|
|
20
|
+
__exportStar(require("./instrument"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,0CAAwB;AACxB,wCAAsB;AACtB,+CAA6B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Tracer } from '@opentelemetry/api';
|
|
2
|
+
import { Flow, Step, StorageAdapter } from '@siglo/core';
|
|
3
|
+
import { SigloTelemetryOptions } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Returns an OpenTelemetry tracer based on configuration.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getTracer(options?: SigloTelemetryOptions): Tracer;
|
|
8
|
+
/**
|
|
9
|
+
* Creates a StorageAdapter that streams allowed, sanitized context changes to active telemetry spans.
|
|
10
|
+
*/
|
|
11
|
+
export declare function createTelemetryStorageAdapter(options?: SigloTelemetryOptions): StorageAdapter;
|
|
12
|
+
/**
|
|
13
|
+
* Instruments an individual Step with an OpenTelemetry child span covering action execution,
|
|
14
|
+
* attempt counting, and error recording.
|
|
15
|
+
*/
|
|
16
|
+
export declare function instrumentStep<TInput = any, TOutput = any>(step: Step<TInput, TOutput>, options?: SigloTelemetryOptions): Step<TInput, TOutput>;
|
|
17
|
+
/**
|
|
18
|
+
* Wraps a Flow execution with end-to-end OpenTelemetry spans and instruments child steps.
|
|
19
|
+
*/
|
|
20
|
+
export declare function instrumentWorkflow<TInput = any, TOutput = any>(workflow: Flow<TInput, TOutput>, options?: SigloTelemetryOptions): Flow<TInput, TOutput>;
|
|
21
|
+
//# sourceMappingURL=instrument.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrument.d.ts","sourceRoot":"","sources":["../src/instrument.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,MAAM,EACT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACH,IAAI,EACJ,IAAI,EACJ,cAAc,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAKhD;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAEjE;AAaD;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CAsBjG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,EACtD,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3B,OAAO,GAAE,qBAA0B,GACpC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAqDvB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,EAC1D,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,GAAE,qBAA0B,GACpC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CA0DvB"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTracer = getTracer;
|
|
4
|
+
exports.createTelemetryStorageAdapter = createTelemetryStorageAdapter;
|
|
5
|
+
exports.instrumentStep = instrumentStep;
|
|
6
|
+
exports.instrumentWorkflow = instrumentWorkflow;
|
|
7
|
+
const api_1 = require("@opentelemetry/api");
|
|
8
|
+
const attributes_1 = require("./attributes");
|
|
9
|
+
const DEFAULT_TRACER_NAME = '@siglo/opentelemetry';
|
|
10
|
+
const DEFAULT_TRACER_VERSION = '1.0.0';
|
|
11
|
+
/**
|
|
12
|
+
* Returns an OpenTelemetry tracer based on configuration.
|
|
13
|
+
*/
|
|
14
|
+
function getTracer(options) {
|
|
15
|
+
return options?.tracer || api_1.trace.getTracer(options?.serviceName || DEFAULT_TRACER_NAME, DEFAULT_TRACER_VERSION);
|
|
16
|
+
}
|
|
17
|
+
function resolveValue(valOrFn) {
|
|
18
|
+
if (typeof valOrFn === 'function') {
|
|
19
|
+
try {
|
|
20
|
+
return valOrFn();
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return valOrFn;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Creates a StorageAdapter that streams allowed, sanitized context changes to active telemetry spans.
|
|
30
|
+
*/
|
|
31
|
+
function createTelemetryStorageAdapter(options = {}) {
|
|
32
|
+
return {
|
|
33
|
+
name: 'opentelemetry',
|
|
34
|
+
onContextChange(entry) {
|
|
35
|
+
if (!options.allowContextFields || !options.allowContextFields.includes(entry.field)) {
|
|
36
|
+
return; // Omit by default to protect secrets and full context
|
|
37
|
+
}
|
|
38
|
+
const activeSpan = api_1.trace.getActiveSpan();
|
|
39
|
+
if (activeSpan) {
|
|
40
|
+
let val = entry.value;
|
|
41
|
+
if (options.redactHook) {
|
|
42
|
+
val = options.redactHook(entry.field, val);
|
|
43
|
+
}
|
|
44
|
+
if (val !== undefined) {
|
|
45
|
+
activeSpan.setAttribute(`siglo.context.${entry.field}`, typeof val === 'object' && val !== null ? JSON.stringify(val) : String(val));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Instruments an individual Step with an OpenTelemetry child span covering action execution,
|
|
53
|
+
* attempt counting, and error recording.
|
|
54
|
+
*/
|
|
55
|
+
function instrumentStep(step, options = {}) {
|
|
56
|
+
const tracer = getTracer(options);
|
|
57
|
+
const originalAction = step.action;
|
|
58
|
+
if (!originalAction) {
|
|
59
|
+
return step;
|
|
60
|
+
}
|
|
61
|
+
let invocationCount = 0;
|
|
62
|
+
const isNamespaceAllowed = options.allowNamespace ?? false;
|
|
63
|
+
step.action = (async (param, current, index) => {
|
|
64
|
+
invocationCount++;
|
|
65
|
+
const stackId = resolveValue(param?.$stackId);
|
|
66
|
+
const retryCount = resolveValue(param?.$attempt);
|
|
67
|
+
const attempt = retryCount !== undefined ? retryCount + 1 : invocationCount;
|
|
68
|
+
const namespace = resolveValue(param?.$namespace);
|
|
69
|
+
const stepName = step.name || step.$stepId || 'unnamed-step';
|
|
70
|
+
const spanName = attempt > 1 ? `step:${stepName} (retry #${attempt})` : `step:${stepName}`;
|
|
71
|
+
const stepSpan = tracer.startSpan(spanName, {
|
|
72
|
+
attributes: {
|
|
73
|
+
[attributes_1.SemanticAttributes.STEP_NAME]: stepName,
|
|
74
|
+
...(step.$stepId ? { [attributes_1.SemanticAttributes.STEP_ID]: step.$stepId } : {}),
|
|
75
|
+
[attributes_1.SemanticAttributes.STEP_ATTEMPT]: attempt,
|
|
76
|
+
...(stackId ? { [attributes_1.SemanticAttributes.STACK_ID]: stackId } : {}),
|
|
77
|
+
...(isNamespaceAllowed && namespace
|
|
78
|
+
? { [attributes_1.SemanticAttributes.NAMESPACE]: namespace }
|
|
79
|
+
: {}),
|
|
80
|
+
...(step.timeoutMs ? { [attributes_1.SemanticAttributes.TIMEOUT]: step.timeoutMs } : {}),
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
const ctx = api_1.trace.setSpan(api_1.context.active(), stepSpan);
|
|
84
|
+
return api_1.context.with(ctx, async () => {
|
|
85
|
+
try {
|
|
86
|
+
const result = await originalAction(param, current, index);
|
|
87
|
+
stepSpan.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
stepSpan.recordException(err);
|
|
92
|
+
stepSpan.setStatus({
|
|
93
|
+
code: api_1.SpanStatusCode.ERROR,
|
|
94
|
+
message: err?.message || 'Step execution failed',
|
|
95
|
+
});
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
stepSpan.end();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
return step;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Wraps a Flow execution with end-to-end OpenTelemetry spans and instruments child steps.
|
|
107
|
+
*/
|
|
108
|
+
function instrumentWorkflow(workflow, options = {}) {
|
|
109
|
+
const tracer = getTracer(options);
|
|
110
|
+
// Instrument individual child steps if available
|
|
111
|
+
if (Array.isArray(workflow.steps)) {
|
|
112
|
+
for (const step of workflow.steps) {
|
|
113
|
+
if (step && typeof step === 'object' && 'action' in step) {
|
|
114
|
+
instrumentStep(step, options);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const originalRun = workflow.run.bind(workflow);
|
|
119
|
+
const isNamespaceAllowed = options.allowNamespace ?? false;
|
|
120
|
+
workflow.run = (async (input, execOptions = {}) => {
|
|
121
|
+
const workflowName = options.workflowName || workflow.name || 'workflow';
|
|
122
|
+
const workflowVersion = options.workflowVersion || workflow.workflowVersion || '1.0.0';
|
|
123
|
+
const namespace = execOptions?.namespace;
|
|
124
|
+
const wfSpan = tracer.startSpan(`workflow:${workflowName}`, {
|
|
125
|
+
attributes: {
|
|
126
|
+
[attributes_1.SemanticAttributes.WORKFLOW_NAME]: workflowName,
|
|
127
|
+
[attributes_1.SemanticAttributes.WORKFLOW_VERSION]: String(workflowVersion),
|
|
128
|
+
...(isNamespaceAllowed && namespace
|
|
129
|
+
? { [attributes_1.SemanticAttributes.NAMESPACE]: namespace }
|
|
130
|
+
: {}),
|
|
131
|
+
...(execOptions?.timeout || workflow.timeoutMs
|
|
132
|
+
? { [attributes_1.SemanticAttributes.TIMEOUT]: execOptions?.timeout || workflow.timeoutMs }
|
|
133
|
+
: {}),
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
const ctx = api_1.trace.setSpan(api_1.context.active(), wfSpan);
|
|
137
|
+
return api_1.context.with(ctx, async () => {
|
|
138
|
+
try {
|
|
139
|
+
const result = await originalRun(input, execOptions);
|
|
140
|
+
const stackId = resolveValue(result?.$stackId);
|
|
141
|
+
if (stackId) {
|
|
142
|
+
wfSpan.setAttribute(attributes_1.SemanticAttributes.STACK_ID, stackId);
|
|
143
|
+
}
|
|
144
|
+
wfSpan.setStatus({ code: api_1.SpanStatusCode.OK });
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
wfSpan.recordException(err);
|
|
149
|
+
wfSpan.setStatus({
|
|
150
|
+
code: api_1.SpanStatusCode.ERROR,
|
|
151
|
+
message: err?.message || 'Workflow execution failed',
|
|
152
|
+
});
|
|
153
|
+
throw err;
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
wfSpan.end();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
return workflow;
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=instrument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../src/instrument.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Tracer, Span } from '@opentelemetry/api';
|
|
2
|
+
export interface SigloTelemetryOptions {
|
|
3
|
+
tracer?: Tracer;
|
|
4
|
+
serviceName?: string;
|
|
5
|
+
workflowName?: string;
|
|
6
|
+
workflowVersion?: string;
|
|
7
|
+
allowNamespace?: boolean;
|
|
8
|
+
allowContextFields?: string[];
|
|
9
|
+
redactHook?: (key: string, value: unknown) => unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface W3CTraceHeaders {
|
|
12
|
+
traceparent?: string;
|
|
13
|
+
tracestate?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ActiveExecutionSpan {
|
|
16
|
+
workflowSpan: Span;
|
|
17
|
+
stepSpans: Map<string, Span>;
|
|
18
|
+
}
|
|
19
|
+
export type RivuletTelemetryOptions = SigloTelemetryOptions;
|
|
20
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,WAAW,qBAAqB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;CACzD;AAED,MAAM,WAAW,eAAe;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAChC,YAAY,EAAE,IAAI,CAAC;IACnB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;CAChC;AAGD,MAAM,MAAM,uBAAuB,GAAG,qBAAqB,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/w3c.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Span, Context } from '@opentelemetry/api';
|
|
2
|
+
import { W3CTraceHeaders } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Injects the active or specified OpenTelemetry context into a headers / carrier object.
|
|
5
|
+
*/
|
|
6
|
+
export declare function injectTraceContext(carrier?: Record<string, string>, ctx?: Context): Record<string, string>;
|
|
7
|
+
/**
|
|
8
|
+
* Extracts an OpenTelemetry context from a headers / carrier object (e.g., from HTTP or Kafka headers).
|
|
9
|
+
*/
|
|
10
|
+
export declare function extractTraceContext(carrier: Record<string, string | undefined>, ctx?: Context): Context;
|
|
11
|
+
/**
|
|
12
|
+
* Extracts W3C traceparent and tracestate from an active Span or SpanContext.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getTraceHeaders(span?: Span): W3CTraceHeaders;
|
|
15
|
+
//# sourceMappingURL=w3c.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"w3c.d.ts","sourceRoot":"","sources":["../src/w3c.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,IAAI,EAEJ,OAAO,EAGV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1C;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EACpC,GAAG,GAAE,OAA0B,GAChC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGxB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAC3C,GAAG,GAAE,OAA0B,GAChC,OAAO,CAQT;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,eAAe,CAiB5D"}
|
package/dist/w3c.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.injectTraceContext = injectTraceContext;
|
|
4
|
+
exports.extractTraceContext = extractTraceContext;
|
|
5
|
+
exports.getTraceHeaders = getTraceHeaders;
|
|
6
|
+
const api_1 = require("@opentelemetry/api");
|
|
7
|
+
/**
|
|
8
|
+
* Injects the active or specified OpenTelemetry context into a headers / carrier object.
|
|
9
|
+
*/
|
|
10
|
+
function injectTraceContext(carrier = {}, ctx = api_1.context.active()) {
|
|
11
|
+
api_1.propagation.inject(ctx, carrier, api_1.defaultTextMapSetter);
|
|
12
|
+
return carrier;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Extracts an OpenTelemetry context from a headers / carrier object (e.g., from HTTP or Kafka headers).
|
|
16
|
+
*/
|
|
17
|
+
function extractTraceContext(carrier, ctx = api_1.context.active()) {
|
|
18
|
+
const sanitizedCarrier = {};
|
|
19
|
+
for (const [key, val] of Object.entries(carrier)) {
|
|
20
|
+
if (typeof val === 'string') {
|
|
21
|
+
sanitizedCarrier[key.toLowerCase()] = val;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return api_1.propagation.extract(ctx, sanitizedCarrier, api_1.defaultTextMapGetter);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Extracts W3C traceparent and tracestate from an active Span or SpanContext.
|
|
28
|
+
*/
|
|
29
|
+
function getTraceHeaders(span) {
|
|
30
|
+
const targetSpan = span || api_1.trace.getActiveSpan();
|
|
31
|
+
if (!targetSpan) {
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
const spanCtx = targetSpan.spanContext();
|
|
35
|
+
if (!spanCtx || !spanCtx.traceId) {
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
const flags = (spanCtx.traceFlags || 0).toString(16).padStart(2, '0');
|
|
39
|
+
const traceparent = `00-${spanCtx.traceId}-${spanCtx.spanId}-${flags}`;
|
|
40
|
+
const headers = { traceparent };
|
|
41
|
+
if (spanCtx.traceState) {
|
|
42
|
+
headers.tracestate = spanCtx.traceState.serialize();
|
|
43
|
+
}
|
|
44
|
+
return headers;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=w3c.js.map
|
package/dist/w3c.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"w3c.js","sourceRoot":"","sources":["../src/w3c.ts"],"names":[],"mappings":";;AAcA,gDAMC;AAKD,kDAWC;AAKD,0CAiBC;AA1DD,4CAQ4B;AAG5B;;GAEG;AACH,SAAgB,kBAAkB,CAC9B,UAAkC,EAAE,EACpC,MAAe,aAAO,CAAC,MAAM,EAAE;IAE/B,iBAAW,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,0BAAoB,CAAC,CAAC;IACvD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAC/B,OAA2C,EAC3C,MAAe,aAAO,CAAC,MAAM,EAAE;IAE/B,MAAM,gBAAgB,GAA2B,EAAE,CAAC;IACpD,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/C,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC1B,gBAAgB,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,GAAG,CAAC;QAC9C,CAAC;IACL,CAAC;IACD,OAAO,iBAAW,CAAC,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,0BAAoB,CAAC,CAAC;AAC5E,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,IAAW;IACvC,MAAM,UAAU,GAAG,IAAI,IAAI,WAAK,CAAC,aAAa,EAAE,CAAC;IACjD,IAAI,CAAC,UAAU,EAAE,CAAC;QACd,OAAO,EAAE,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IACzC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAC/B,OAAO,EAAE,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtE,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;IACvE,MAAM,OAAO,GAAoB,EAAE,WAAW,EAAE,CAAC;IACjD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,54 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@siglo/opentelemetry",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenTelemetry observability integration for Siglo workflows",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public",
|
|
23
|
+
"registry": "https://registry.npmjs.org/"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.json",
|
|
27
|
+
"prepublishOnly": "npm run build",
|
|
28
|
+
"test": "npm run build && mocha -r tsx 'src/**/*.test.ts'"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/jsoftgem/siglo.git",
|
|
33
|
+
"directory": "packages/opentelemetry"
|
|
34
|
+
},
|
|
35
|
+
"author": "Jerico de Guzman",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/jsoftgem/siglo/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/jsoftgem/siglo#readme",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@opentelemetry/api": "^1.9.0",
|
|
43
|
+
"@siglo/core": "^1.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/chai": "^5.2.3",
|
|
47
|
+
"@types/mocha": "^10.0.10",
|
|
48
|
+
"@types/node": "^26.6.5",
|
|
49
|
+
"chai": "^3.5.0",
|
|
50
|
+
"mocha": "^12.0.3",
|
|
51
|
+
"tsx": "^4.23.15",
|
|
52
|
+
"typescript": "~5.7.0"
|
|
53
|
+
}
|
|
54
|
+
}
|