@contractspec/lib.observability 0.0.0-canary-20260113162409
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/CHANGELOG.md +351 -0
- package/LICENSE +21 -0
- package/README.md +85 -0
- package/dist/anomaly/alert-manager.d.mts +21 -0
- package/dist/anomaly/alert-manager.mjs +23 -0
- package/dist/anomaly/anomaly-detector.d.mts +26 -0
- package/dist/anomaly/anomaly-detector.mjs +58 -0
- package/dist/anomaly/baseline-calculator.d.mts +26 -0
- package/dist/anomaly/baseline-calculator.mjs +37 -0
- package/dist/anomaly/root-cause-analyzer.d.mts +23 -0
- package/dist/anomaly/root-cause-analyzer.mjs +27 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.mjs +14 -0
- package/dist/intent/aggregator.d.mts +60 -0
- package/dist/intent/aggregator.mjs +98 -0
- package/dist/intent/detector.d.mts +32 -0
- package/dist/intent/detector.mjs +122 -0
- package/dist/logging/index.d.mts +20 -0
- package/dist/logging/index.mjs +40 -0
- package/dist/metrics/index.d.mts +17 -0
- package/dist/metrics/index.mjs +26 -0
- package/dist/pipeline/evolution-pipeline.d.mts +40 -0
- package/dist/pipeline/evolution-pipeline.mjs +66 -0
- package/dist/pipeline/lifecycle-pipeline.d.mts +44 -0
- package/dist/pipeline/lifecycle-pipeline.mjs +73 -0
- package/dist/tracing/index.d.mts +9 -0
- package/dist/tracing/index.mjs +47 -0
- package/dist/tracing/middleware.d.mts +19 -0
- package/dist/tracing/middleware.mjs +80 -0
- package/package.json +81 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# @contractspec/lib.observability
|
|
2
|
+
|
|
3
|
+
## 0.0.0-canary-20260113162409
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- caf8701: feat: add cli vibe command to run workflow
|
|
8
|
+
- c69b849: feat: add api web services (mcp & website)
|
|
9
|
+
- 42b8d78: feat: add cli `contractspec vibe` workflow to simplify usage
|
|
10
|
+
- fd38e85: feat: auto-fix contractspec issues
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- e7ded36: feat: improve stability (adding ts-morph)
|
|
15
|
+
- c231a8b: test: improve workspace stability
|
|
16
|
+
- Updated dependencies [e7ded36]
|
|
17
|
+
- Updated dependencies [caf8701]
|
|
18
|
+
- Updated dependencies [c69b849]
|
|
19
|
+
- Updated dependencies [c231a8b]
|
|
20
|
+
- Updated dependencies [42b8d78]
|
|
21
|
+
- Updated dependencies [fd38e85]
|
|
22
|
+
- @contractspec/lib.lifecycle@0.0.0-canary-20260113162409
|
|
23
|
+
|
|
24
|
+
## 1.46.2
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- 7e21625: feat: library services (landing page & api)
|
|
29
|
+
- Updated dependencies [7e21625]
|
|
30
|
+
- @contractspec/lib.lifecycle@1.46.2
|
|
31
|
+
|
|
32
|
+
## 1.46.1
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- 2d8a72b: fix: mcp for presentation
|
|
37
|
+
- Updated dependencies [2d8a72b]
|
|
38
|
+
- @contractspec/lib.lifecycle@1.46.1
|
|
39
|
+
|
|
40
|
+
## 1.46.0
|
|
41
|
+
|
|
42
|
+
### Minor Changes
|
|
43
|
+
|
|
44
|
+
- 07cb19b: feat: feat: cleaude code & opencode integrations
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- Updated dependencies [07cb19b]
|
|
49
|
+
- @contractspec/lib.lifecycle@1.46.0
|
|
50
|
+
|
|
51
|
+
## 1.45.6
|
|
52
|
+
|
|
53
|
+
### Patch Changes
|
|
54
|
+
|
|
55
|
+
- a913074: feat: improve ai agents rules management"
|
|
56
|
+
- Updated dependencies [a913074]
|
|
57
|
+
- @contractspec/lib.lifecycle@1.45.6
|
|
58
|
+
|
|
59
|
+
## 1.45.5
|
|
60
|
+
|
|
61
|
+
### Patch Changes
|
|
62
|
+
|
|
63
|
+
- 9ddd7fa: feat: improve versioning
|
|
64
|
+
- Updated dependencies [9ddd7fa]
|
|
65
|
+
- @contractspec/lib.lifecycle@1.45.5
|
|
66
|
+
|
|
67
|
+
## 1.45.4
|
|
68
|
+
|
|
69
|
+
### Patch Changes
|
|
70
|
+
|
|
71
|
+
- fix: github action
|
|
72
|
+
- Updated dependencies
|
|
73
|
+
- @contractspec/lib.lifecycle@1.45.4
|
|
74
|
+
|
|
75
|
+
## 1.45.3
|
|
76
|
+
|
|
77
|
+
### Patch Changes
|
|
78
|
+
|
|
79
|
+
- e74ea9e: feat: version management
|
|
80
|
+
- Updated dependencies [e74ea9e]
|
|
81
|
+
- @contractspec/lib.lifecycle@1.45.3
|
|
82
|
+
|
|
83
|
+
## 1.45.2
|
|
84
|
+
|
|
85
|
+
### Patch Changes
|
|
86
|
+
|
|
87
|
+
- 39ca241: code cleaning
|
|
88
|
+
- Updated dependencies [39ca241]
|
|
89
|
+
- @contractspec/lib.lifecycle@1.45.2
|
|
90
|
+
|
|
91
|
+
## 1.45.1
|
|
92
|
+
|
|
93
|
+
### Patch Changes
|
|
94
|
+
|
|
95
|
+
- feat: improve app config and examples contracts
|
|
96
|
+
- Updated dependencies
|
|
97
|
+
- @contractspec/lib.lifecycle@1.45.1
|
|
98
|
+
|
|
99
|
+
## 1.45.0
|
|
100
|
+
|
|
101
|
+
### Minor Changes
|
|
102
|
+
|
|
103
|
+
- e73ca1d: feat: improve app config and examples contracts
|
|
104
|
+
feat: Contract layers support (features, examples, app-configs)
|
|
105
|
+
|
|
106
|
+
### New CLI Commands
|
|
107
|
+
- `contractspec list layers` - List all contract layers with filtering
|
|
108
|
+
|
|
109
|
+
### Enhanced Commands
|
|
110
|
+
- `contractspec ci` - New `layers` check category validates features/examples/config
|
|
111
|
+
- `contractspec doctor` - New `layers` health checks
|
|
112
|
+
- `contractspec integrity` - Now shows layer statistics
|
|
113
|
+
|
|
114
|
+
### New APIs
|
|
115
|
+
- `discoverLayers()` - Scan workspace for all layer files
|
|
116
|
+
- `scanExampleSource()` - Parse ExampleSpec from source code
|
|
117
|
+
- `isExampleFile()` - Check if file is an example spec
|
|
118
|
+
|
|
119
|
+
### Patch Changes
|
|
120
|
+
|
|
121
|
+
- Updated dependencies [e73ca1d]
|
|
122
|
+
- @contractspec/lib.lifecycle@1.45.0
|
|
123
|
+
|
|
124
|
+
## 1.44.1
|
|
125
|
+
|
|
126
|
+
### Patch Changes
|
|
127
|
+
|
|
128
|
+
- 3c594fb: fix
|
|
129
|
+
- Updated dependencies [3c594fb]
|
|
130
|
+
- @contractspec/lib.lifecycle@1.44.1
|
|
131
|
+
|
|
132
|
+
## 1.44.0
|
|
133
|
+
|
|
134
|
+
### Minor Changes
|
|
135
|
+
|
|
136
|
+
- 5f3a868: chore: isolate branding to contractspec.io
|
|
137
|
+
|
|
138
|
+
### Patch Changes
|
|
139
|
+
|
|
140
|
+
- Updated dependencies [5f3a868]
|
|
141
|
+
- @contractspec/lib.lifecycle@1.44.0
|
|
142
|
+
|
|
143
|
+
## 1.43.3
|
|
144
|
+
|
|
145
|
+
### Patch Changes
|
|
146
|
+
|
|
147
|
+
- 9216062: fix: cross-platform compatibility
|
|
148
|
+
- Updated dependencies [9216062]
|
|
149
|
+
- @contractspec/lib.lifecycle@1.43.3
|
|
150
|
+
|
|
151
|
+
## 1.43.2
|
|
152
|
+
|
|
153
|
+
### Patch Changes
|
|
154
|
+
|
|
155
|
+
- 24d9759: improve documentation
|
|
156
|
+
- Updated dependencies [24d9759]
|
|
157
|
+
- @contractspec/lib.lifecycle@1.43.2
|
|
158
|
+
|
|
159
|
+
## 1.43.1
|
|
160
|
+
|
|
161
|
+
### Patch Changes
|
|
162
|
+
|
|
163
|
+
- e147271: fix: improve stability
|
|
164
|
+
- Updated dependencies [e147271]
|
|
165
|
+
- @contractspec/lib.lifecycle@1.43.1
|
|
166
|
+
|
|
167
|
+
## 1.43.0
|
|
168
|
+
|
|
169
|
+
### Minor Changes
|
|
170
|
+
|
|
171
|
+
- 042d072: feat: schema declaration using json schema, including zod
|
|
172
|
+
|
|
173
|
+
### Patch Changes
|
|
174
|
+
|
|
175
|
+
- Updated dependencies [042d072]
|
|
176
|
+
- @contractspec/lib.lifecycle@1.43.0
|
|
177
|
+
|
|
178
|
+
## 1.42.10
|
|
179
|
+
|
|
180
|
+
### Patch Changes
|
|
181
|
+
|
|
182
|
+
- 1e6a0f1: fix: mcp server
|
|
183
|
+
- Updated dependencies [1e6a0f1]
|
|
184
|
+
- @contractspec/lib.lifecycle@1.42.10
|
|
185
|
+
|
|
186
|
+
## 1.42.9
|
|
187
|
+
|
|
188
|
+
### Patch Changes
|
|
189
|
+
|
|
190
|
+
- 9281db7: fix ModelRegistry
|
|
191
|
+
- Updated dependencies [9281db7]
|
|
192
|
+
- @contractspec/lib.lifecycle@1.42.9
|
|
193
|
+
|
|
194
|
+
## 1.42.8
|
|
195
|
+
|
|
196
|
+
### Patch Changes
|
|
197
|
+
|
|
198
|
+
- e07b5ac: fix
|
|
199
|
+
- Updated dependencies [e07b5ac]
|
|
200
|
+
- @contractspec/lib.lifecycle@1.42.8
|
|
201
|
+
|
|
202
|
+
## 1.42.7
|
|
203
|
+
|
|
204
|
+
### Patch Changes
|
|
205
|
+
|
|
206
|
+
- e9b575d: fix release
|
|
207
|
+
- Updated dependencies [e9b575d]
|
|
208
|
+
- @contractspec/lib.lifecycle@1.42.7
|
|
209
|
+
|
|
210
|
+
## 1.42.6
|
|
211
|
+
|
|
212
|
+
### Patch Changes
|
|
213
|
+
|
|
214
|
+
- 1500242: fix tooling
|
|
215
|
+
- Updated dependencies [1500242]
|
|
216
|
+
- @contractspec/lib.lifecycle@1.42.6
|
|
217
|
+
|
|
218
|
+
## 1.42.5
|
|
219
|
+
|
|
220
|
+
### Patch Changes
|
|
221
|
+
|
|
222
|
+
- 1299719: fix vscode
|
|
223
|
+
- Updated dependencies [1299719]
|
|
224
|
+
- @contractspec/lib.lifecycle@1.42.5
|
|
225
|
+
|
|
226
|
+
## 1.42.4
|
|
227
|
+
|
|
228
|
+
### Patch Changes
|
|
229
|
+
|
|
230
|
+
- ac28b99: fix: generate from openapi
|
|
231
|
+
- Updated dependencies [ac28b99]
|
|
232
|
+
- @contractspec/lib.lifecycle@1.42.4
|
|
233
|
+
|
|
234
|
+
## 1.42.3
|
|
235
|
+
|
|
236
|
+
### Patch Changes
|
|
237
|
+
|
|
238
|
+
- 3f5d015: fix(tooling): cicd
|
|
239
|
+
- Updated dependencies [3f5d015]
|
|
240
|
+
- @contractspec/lib.lifecycle@1.42.3
|
|
241
|
+
|
|
242
|
+
## 1.42.2
|
|
243
|
+
|
|
244
|
+
### Patch Changes
|
|
245
|
+
|
|
246
|
+
- 1f9ac4c: fix
|
|
247
|
+
- Updated dependencies [1f9ac4c]
|
|
248
|
+
- @contractspec/lib.lifecycle@1.42.2
|
|
249
|
+
|
|
250
|
+
## 1.42.1
|
|
251
|
+
|
|
252
|
+
### Patch Changes
|
|
253
|
+
|
|
254
|
+
- f043995: Fix release
|
|
255
|
+
- Updated dependencies [f043995]
|
|
256
|
+
- @contractspec/lib.lifecycle@1.42.1
|
|
257
|
+
|
|
258
|
+
## 1.42.0
|
|
259
|
+
|
|
260
|
+
### Minor Changes
|
|
261
|
+
|
|
262
|
+
- 8eefd9c: initial release
|
|
263
|
+
|
|
264
|
+
### Patch Changes
|
|
265
|
+
|
|
266
|
+
- Updated dependencies [8eefd9c]
|
|
267
|
+
- @contractspec/lib.lifecycle@1.42.0
|
|
268
|
+
|
|
269
|
+
## 0.5.0
|
|
270
|
+
|
|
271
|
+
### Minor Changes
|
|
272
|
+
|
|
273
|
+
- Refactor to be compatible with ai-sdk v6
|
|
274
|
+
|
|
275
|
+
### Patch Changes
|
|
276
|
+
|
|
277
|
+
- Updated dependencies
|
|
278
|
+
- @contractspec/lib.lifecycle@0.4.0
|
|
279
|
+
|
|
280
|
+
## 0.4.1
|
|
281
|
+
|
|
282
|
+
### Patch Changes
|
|
283
|
+
|
|
284
|
+
- Fix dependencies
|
|
285
|
+
- Updated dependencies
|
|
286
|
+
- @contractspec/lib.lifecycle@0.3.1
|
|
287
|
+
|
|
288
|
+
## 0.4.0
|
|
289
|
+
|
|
290
|
+
### Minor Changes
|
|
291
|
+
|
|
292
|
+
- b7621d3: Fix version
|
|
293
|
+
|
|
294
|
+
### Patch Changes
|
|
295
|
+
|
|
296
|
+
- Updated dependencies [b7621d3]
|
|
297
|
+
- @contractspec/lib.lifecycle@0.3.0
|
|
298
|
+
|
|
299
|
+
## 0.3.0
|
|
300
|
+
|
|
301
|
+
### Minor Changes
|
|
302
|
+
|
|
303
|
+
- fix
|
|
304
|
+
|
|
305
|
+
### Patch Changes
|
|
306
|
+
|
|
307
|
+
- Updated dependencies
|
|
308
|
+
- @contractspec/lib.lifecycle@0.2.0
|
|
309
|
+
|
|
310
|
+
## 0.2.2
|
|
311
|
+
|
|
312
|
+
### Patch Changes
|
|
313
|
+
|
|
314
|
+
- fix dependencies
|
|
315
|
+
- Updated dependencies
|
|
316
|
+
- @contractspec/lib.lifecycle@0.1.2
|
|
317
|
+
|
|
318
|
+
## 0.2.1
|
|
319
|
+
|
|
320
|
+
### Patch Changes
|
|
321
|
+
|
|
322
|
+
- fix
|
|
323
|
+
- Updated dependencies
|
|
324
|
+
- @contractspec/lib.lifecycle@0.1.1
|
|
325
|
+
|
|
326
|
+
## 0.2.0
|
|
327
|
+
|
|
328
|
+
### Minor Changes
|
|
329
|
+
|
|
330
|
+
- b1d0876: Managed platform
|
|
331
|
+
|
|
332
|
+
### Patch Changes
|
|
333
|
+
|
|
334
|
+
- Updated dependencies [b1d0876]
|
|
335
|
+
- @contractspec/lib.lifecycle@0.1.0
|
|
336
|
+
|
|
337
|
+
## 0.1.0
|
|
338
|
+
|
|
339
|
+
### Minor Changes
|
|
340
|
+
|
|
341
|
+
- f1f4ddd: Foundation Hardening
|
|
342
|
+
|
|
343
|
+
## 0.1.0
|
|
344
|
+
|
|
345
|
+
### Minor Changes
|
|
346
|
+
|
|
347
|
+
- Initial release
|
|
348
|
+
- OpenTelemetry tracing integration
|
|
349
|
+
- Metrics collection (counters, histograms)
|
|
350
|
+
- Structured logging with trace correlation
|
|
351
|
+
- HTTP tracing middleware
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Chaman Ventures, SASU
|
|
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
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @contractspec/lib.observability
|
|
2
|
+
|
|
3
|
+
Website: https://contractspec.io/
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
OpenTelemetry integration for tracing, metrics, and structured logging.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Distributed Tracing**: Automatic span creation and propagation
|
|
11
|
+
- **Metrics**: Counters, histograms, and gauges
|
|
12
|
+
- **Structured Logging**: JSON logs with trace correlation
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @contractspec/lib.observability @opentelemetry/api
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Tracing
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { traceAsync } from '@contractspec/lib.observability/tracing';
|
|
26
|
+
|
|
27
|
+
await traceAsync('process_order', async (span) => {
|
|
28
|
+
span.setAttribute('order_id', order.id);
|
|
29
|
+
await db.save(order);
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Metrics
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { createCounter } from '@contractspec/lib.observability/metrics';
|
|
37
|
+
|
|
38
|
+
const ordersCounter = createCounter('orders_total');
|
|
39
|
+
ordersCounter.add(1, { status: 'success' });
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Middleware
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { createTracingMiddleware } from '@contractspec/lib.observability/tracing/middleware';
|
|
46
|
+
|
|
47
|
+
app.use(createTracingMiddleware());
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Documentation
|
|
51
|
+
|
|
52
|
+
Full docs: https://contractspec.io/docs/libraries/observability
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { AnomalySignal } from "./anomaly-detector.mjs";
|
|
2
|
+
import { RootCauseAnalysis } from "./root-cause-analyzer.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/anomaly/alert-manager.d.ts
|
|
5
|
+
interface AlertManagerOptions {
|
|
6
|
+
cooldownMs?: number;
|
|
7
|
+
transport: (payload: {
|
|
8
|
+
signal: AnomalySignal;
|
|
9
|
+
analysis: RootCauseAnalysis;
|
|
10
|
+
}) => Promise<void> | void;
|
|
11
|
+
}
|
|
12
|
+
declare class AlertManager {
|
|
13
|
+
private readonly options;
|
|
14
|
+
private readonly cooldownMs;
|
|
15
|
+
private readonly lastAlert;
|
|
16
|
+
constructor(options: AlertManagerOptions);
|
|
17
|
+
notify(signal: AnomalySignal, analysis: RootCauseAnalysis): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { AlertManager, AlertManagerOptions };
|
|
21
|
+
//# sourceMappingURL=alert-manager.d.mts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/anomaly/alert-manager.ts
|
|
2
|
+
var AlertManager = class {
|
|
3
|
+
cooldownMs;
|
|
4
|
+
lastAlert = /* @__PURE__ */ new Map();
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.options = options;
|
|
7
|
+
this.cooldownMs = options.cooldownMs ?? 6e4;
|
|
8
|
+
}
|
|
9
|
+
async notify(signal, analysis) {
|
|
10
|
+
const key = `${signal.type}:${analysis.culprit?.id ?? "none"}`;
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
if (now - (this.lastAlert.get(key) ?? 0) < this.cooldownMs) return;
|
|
13
|
+
await this.options.transport({
|
|
14
|
+
signal,
|
|
15
|
+
analysis
|
|
16
|
+
});
|
|
17
|
+
this.lastAlert.set(key, now);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { AlertManager };
|
|
23
|
+
//# sourceMappingURL=alert-manager.mjs.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaselineCalculator, MetricPoint } from "./baseline-calculator.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/anomaly/anomaly-detector.d.ts
|
|
4
|
+
interface AnomalyThresholds {
|
|
5
|
+
errorRateDelta?: number;
|
|
6
|
+
latencyDelta?: number;
|
|
7
|
+
throughputDrop?: number;
|
|
8
|
+
minSamples?: number;
|
|
9
|
+
}
|
|
10
|
+
interface AnomalySignal {
|
|
11
|
+
type: 'error_rate_spike' | 'latency_regression' | 'throughput_drop';
|
|
12
|
+
delta: number;
|
|
13
|
+
point: MetricPoint;
|
|
14
|
+
baseline: ReturnType<BaselineCalculator['getSnapshot']>;
|
|
15
|
+
}
|
|
16
|
+
declare class AnomalyDetector {
|
|
17
|
+
private readonly baseline;
|
|
18
|
+
private readonly thresholds;
|
|
19
|
+
constructor(options?: AnomalyThresholds);
|
|
20
|
+
evaluate(point: MetricPoint): AnomalySignal[];
|
|
21
|
+
private relativeDelta;
|
|
22
|
+
private relativeDrop;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { AnomalyDetector, AnomalySignal, AnomalyThresholds };
|
|
26
|
+
//# sourceMappingURL=anomaly-detector.d.mts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { BaselineCalculator } from "./baseline-calculator.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/anomaly/anomaly-detector.ts
|
|
4
|
+
var AnomalyDetector = class {
|
|
5
|
+
baseline;
|
|
6
|
+
thresholds = {
|
|
7
|
+
errorRateDelta: .5,
|
|
8
|
+
latencyDelta: .35,
|
|
9
|
+
throughputDrop: .4,
|
|
10
|
+
minSamples: 10
|
|
11
|
+
};
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
this.baseline = new BaselineCalculator();
|
|
14
|
+
this.thresholds = {
|
|
15
|
+
...this.thresholds,
|
|
16
|
+
...options
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
evaluate(point) {
|
|
20
|
+
const baselineSnapshot = this.baseline.update(point);
|
|
21
|
+
if (baselineSnapshot.sampleCount < this.thresholds.minSamples) return [];
|
|
22
|
+
const signals = [];
|
|
23
|
+
const errorDelta = this.relativeDelta(point.errorRate, baselineSnapshot.errorRate);
|
|
24
|
+
if (errorDelta > this.thresholds.errorRateDelta) signals.push({
|
|
25
|
+
type: "error_rate_spike",
|
|
26
|
+
delta: errorDelta,
|
|
27
|
+
point,
|
|
28
|
+
baseline: baselineSnapshot
|
|
29
|
+
});
|
|
30
|
+
const latencyDelta = this.relativeDelta(point.latencyP99, baselineSnapshot.latencyP99);
|
|
31
|
+
if (latencyDelta > this.thresholds.latencyDelta) signals.push({
|
|
32
|
+
type: "latency_regression",
|
|
33
|
+
delta: latencyDelta,
|
|
34
|
+
point,
|
|
35
|
+
baseline: baselineSnapshot
|
|
36
|
+
});
|
|
37
|
+
const throughputDelta = this.relativeDrop(point.throughput, baselineSnapshot.throughput);
|
|
38
|
+
if (throughputDelta > this.thresholds.throughputDrop) signals.push({
|
|
39
|
+
type: "throughput_drop",
|
|
40
|
+
delta: throughputDelta,
|
|
41
|
+
point,
|
|
42
|
+
baseline: baselineSnapshot
|
|
43
|
+
});
|
|
44
|
+
return signals;
|
|
45
|
+
}
|
|
46
|
+
relativeDelta(value, baseline) {
|
|
47
|
+
if (baseline === 0) return 0;
|
|
48
|
+
return (value - baseline) / baseline;
|
|
49
|
+
}
|
|
50
|
+
relativeDrop(value, baseline) {
|
|
51
|
+
if (baseline === 0) return 0;
|
|
52
|
+
return (baseline - value) / baseline;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
export { AnomalyDetector };
|
|
58
|
+
//# sourceMappingURL=anomaly-detector.mjs.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/anomaly/baseline-calculator.d.ts
|
|
2
|
+
interface MetricPoint {
|
|
3
|
+
latencyP99: number;
|
|
4
|
+
latencyP95: number;
|
|
5
|
+
errorRate: number;
|
|
6
|
+
throughput: number;
|
|
7
|
+
timestamp: Date;
|
|
8
|
+
}
|
|
9
|
+
interface BaselineSnapshot {
|
|
10
|
+
latencyP99: number;
|
|
11
|
+
latencyP95: number;
|
|
12
|
+
errorRate: number;
|
|
13
|
+
throughput: number;
|
|
14
|
+
sampleCount: number;
|
|
15
|
+
}
|
|
16
|
+
declare class BaselineCalculator {
|
|
17
|
+
private readonly alpha;
|
|
18
|
+
private snapshot;
|
|
19
|
+
constructor(alpha?: number);
|
|
20
|
+
update(point: MetricPoint): BaselineSnapshot;
|
|
21
|
+
getSnapshot(): BaselineSnapshot;
|
|
22
|
+
private mix;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { BaselineCalculator, BaselineSnapshot, MetricPoint };
|
|
26
|
+
//# sourceMappingURL=baseline-calculator.d.mts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/anomaly/baseline-calculator.ts
|
|
2
|
+
var BaselineCalculator = class {
|
|
3
|
+
snapshot = {
|
|
4
|
+
latencyP99: 0,
|
|
5
|
+
latencyP95: 0,
|
|
6
|
+
errorRate: 0,
|
|
7
|
+
throughput: 0,
|
|
8
|
+
sampleCount: 0
|
|
9
|
+
};
|
|
10
|
+
constructor(alpha = .2) {
|
|
11
|
+
this.alpha = alpha;
|
|
12
|
+
}
|
|
13
|
+
update(point) {
|
|
14
|
+
const { sampleCount } = this.snapshot;
|
|
15
|
+
const nextCount = sampleCount + 1;
|
|
16
|
+
const weight = sampleCount === 0 ? 1 : this.alpha;
|
|
17
|
+
this.snapshot = {
|
|
18
|
+
latencyP99: this.mix(this.snapshot.latencyP99, point.latencyP99, weight),
|
|
19
|
+
latencyP95: this.mix(this.snapshot.latencyP95, point.latencyP95, weight),
|
|
20
|
+
errorRate: this.mix(this.snapshot.errorRate, point.errorRate, weight),
|
|
21
|
+
throughput: this.mix(this.snapshot.throughput, point.throughput, weight),
|
|
22
|
+
sampleCount: nextCount
|
|
23
|
+
};
|
|
24
|
+
return this.snapshot;
|
|
25
|
+
}
|
|
26
|
+
getSnapshot() {
|
|
27
|
+
return this.snapshot;
|
|
28
|
+
}
|
|
29
|
+
mix(current, next, weight) {
|
|
30
|
+
if (this.snapshot.sampleCount === 0) return next;
|
|
31
|
+
return current * (1 - weight) + next * weight;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { BaselineCalculator };
|
|
37
|
+
//# sourceMappingURL=baseline-calculator.mjs.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AnomalySignal } from "./anomaly-detector.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/anomaly/root-cause-analyzer.d.ts
|
|
4
|
+
interface DeploymentEvent {
|
|
5
|
+
id: string;
|
|
6
|
+
operation: string;
|
|
7
|
+
deployedAt: Date;
|
|
8
|
+
stage?: string;
|
|
9
|
+
status: 'in_progress' | 'completed' | 'rolled_back';
|
|
10
|
+
}
|
|
11
|
+
interface RootCauseAnalysis {
|
|
12
|
+
signal: AnomalySignal;
|
|
13
|
+
culprit?: DeploymentEvent;
|
|
14
|
+
notes: string[];
|
|
15
|
+
}
|
|
16
|
+
declare class RootCauseAnalyzer {
|
|
17
|
+
private readonly lookbackMs;
|
|
18
|
+
constructor(lookbackMs?: number);
|
|
19
|
+
analyze(signal: AnomalySignal, deployments: DeploymentEvent[]): RootCauseAnalysis;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { DeploymentEvent, RootCauseAnalysis, RootCauseAnalyzer };
|
|
23
|
+
//# sourceMappingURL=root-cause-analyzer.d.mts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/anomaly/root-cause-analyzer.ts
|
|
2
|
+
var RootCauseAnalyzer = class {
|
|
3
|
+
constructor(lookbackMs = 900 * 1e3) {
|
|
4
|
+
this.lookbackMs = lookbackMs;
|
|
5
|
+
}
|
|
6
|
+
analyze(signal, deployments) {
|
|
7
|
+
const windowStart = new Date(signal.point.timestamp.getTime() - this.lookbackMs);
|
|
8
|
+
const candidates = deployments.filter((deployment) => deployment.deployedAt >= windowStart).sort((a, b) => b.deployedAt.getTime() - a.deployedAt.getTime());
|
|
9
|
+
const notes = [];
|
|
10
|
+
let culprit;
|
|
11
|
+
if (candidates.length > 0) {
|
|
12
|
+
culprit = candidates[0];
|
|
13
|
+
if (culprit) notes.push(`Closest deployment ${culprit.id} (${culprit.operation}) at ${culprit.deployedAt.toISOString()}`);
|
|
14
|
+
} else notes.push("No deployments found within lookback window.");
|
|
15
|
+
if (signal.type === "latency_regression") notes.push("Verify recent schema changes and external dependency latency.");
|
|
16
|
+
if (signal.type === "error_rate_spike") notes.push("Check SLO monitor for correlated incidents.");
|
|
17
|
+
return {
|
|
18
|
+
signal,
|
|
19
|
+
culprit,
|
|
20
|
+
notes
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { RootCauseAnalyzer };
|
|
27
|
+
//# sourceMappingURL=root-cause-analyzer.mjs.map
|