@contractspec/lib.observability 1.57.0 → 1.59.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/anomaly/alert-manager.d.ts +17 -0
  3. package/dist/anomaly/alert-manager.js +24 -0
  4. package/dist/anomaly/anomaly-detector.d.ts +22 -0
  5. package/dist/anomaly/anomaly-detector.js +102 -0
  6. package/dist/anomaly/baseline-calculator.d.ts +23 -0
  7. package/dist/anomaly/baseline-calculator.js +40 -0
  8. package/dist/anomaly/root-cause-analyzer.d.ts +19 -0
  9. package/dist/anomaly/root-cause-analyzer.js +32 -0
  10. package/dist/index.d.ts +16 -0
  11. package/dist/index.js +1078 -0
  12. package/dist/intent/aggregator.d.ts +57 -0
  13. package/dist/intent/aggregator.js +110 -0
  14. package/dist/intent/detector.d.ts +28 -0
  15. package/dist/intent/detector.js +133 -0
  16. package/dist/logging/index.d.ts +17 -0
  17. package/dist/logging/index.js +42 -0
  18. package/dist/metrics/index.d.ts +12 -0
  19. package/dist/metrics/index.js +31 -0
  20. package/dist/node/anomaly/alert-manager.js +23 -0
  21. package/dist/node/anomaly/anomaly-detector.js +101 -0
  22. package/dist/node/anomaly/baseline-calculator.js +39 -0
  23. package/dist/node/anomaly/root-cause-analyzer.js +31 -0
  24. package/dist/node/index.js +1077 -0
  25. package/dist/node/intent/aggregator.js +109 -0
  26. package/dist/node/intent/detector.js +132 -0
  27. package/dist/node/logging/index.js +41 -0
  28. package/dist/node/metrics/index.js +30 -0
  29. package/dist/node/pipeline/evolution-pipeline.js +299 -0
  30. package/dist/node/pipeline/lifecycle-pipeline.js +85 -0
  31. package/dist/node/telemetry/posthog-baseline-reader.js +308 -0
  32. package/dist/node/telemetry/posthog-telemetry.js +60 -0
  33. package/dist/node/tracing/index.js +52 -0
  34. package/dist/node/tracing/middleware.js +150 -0
  35. package/dist/pipeline/evolution-pipeline.d.ts +36 -0
  36. package/dist/pipeline/evolution-pipeline.js +300 -0
  37. package/dist/pipeline/lifecycle-pipeline.d.ts +40 -0
  38. package/dist/pipeline/lifecycle-pipeline.js +86 -0
  39. package/dist/telemetry/posthog-baseline-reader.d.ts +27 -0
  40. package/dist/telemetry/posthog-baseline-reader.js +309 -0
  41. package/dist/telemetry/posthog-telemetry.d.ts +15 -0
  42. package/dist/telemetry/posthog-telemetry.js +61 -0
  43. package/dist/tracing/index.d.ts +5 -0
  44. package/dist/tracing/index.js +53 -0
  45. package/dist/tracing/middleware.d.ts +15 -0
  46. package/dist/tracing/middleware.js +151 -0
  47. package/package.json +140 -43
  48. package/dist/anomaly/alert-manager.d.mts +0 -21
  49. package/dist/anomaly/alert-manager.mjs +0 -23
  50. package/dist/anomaly/anomaly-detector.d.mts +0 -26
  51. package/dist/anomaly/anomaly-detector.mjs +0 -58
  52. package/dist/anomaly/baseline-calculator.d.mts +0 -26
  53. package/dist/anomaly/baseline-calculator.mjs +0 -37
  54. package/dist/anomaly/root-cause-analyzer.d.mts +0 -23
  55. package/dist/anomaly/root-cause-analyzer.mjs +0 -27
  56. package/dist/index.d.mts +0 -15
  57. package/dist/index.mjs +0 -16
  58. package/dist/intent/aggregator.d.mts +0 -60
  59. package/dist/intent/aggregator.mjs +0 -98
  60. package/dist/intent/detector.d.mts +0 -32
  61. package/dist/intent/detector.mjs +0 -122
  62. package/dist/logging/index.d.mts +0 -20
  63. package/dist/logging/index.mjs +0 -40
  64. package/dist/metrics/index.d.mts +0 -17
  65. package/dist/metrics/index.mjs +0 -26
  66. package/dist/pipeline/evolution-pipeline.d.mts +0 -40
  67. package/dist/pipeline/evolution-pipeline.mjs +0 -66
  68. package/dist/pipeline/lifecycle-pipeline.d.mts +0 -44
  69. package/dist/pipeline/lifecycle-pipeline.mjs +0 -73
  70. package/dist/telemetry/posthog-baseline-reader.d.mts +0 -31
  71. package/dist/telemetry/posthog-baseline-reader.mjs +0 -266
  72. package/dist/telemetry/posthog-telemetry.d.mts +0 -19
  73. package/dist/telemetry/posthog-telemetry.mjs +0 -61
  74. package/dist/tracing/index.d.mts +0 -9
  75. package/dist/tracing/index.mjs +0 -47
  76. package/dist/tracing/middleware.d.mts +0 -19
  77. package/dist/tracing/middleware.mjs +0 -80
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @contractspec/lib.observability
2
2
 
3
+ ## 1.59.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 1a0cf44: fix: publishConfig not supported by bun
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [1a0cf44]
12
+ - @contractspec/lib.contracts@1.59.0
13
+ - @contractspec/lib.lifecycle@1.59.0
14
+
15
+ ## 1.58.0
16
+
17
+ ### Minor Changes
18
+
19
+ - d1f0fd0: chore: Migrate non-app package builds from tsdown to shared Bun tooling, add `@contractspec/tool.bun`, and standardize `prebuild`/`build`/`typecheck` with platform-aware exports and `tsc` declaration emission into `dist`.
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies [d1f0fd0]
24
+ - Updated dependencies [4355a9e]
25
+ - @contractspec/lib.contracts@1.58.0
26
+ - @contractspec/lib.lifecycle@1.58.0
27
+
3
28
  ## 1.57.0
4
29
 
5
30
  ### Minor Changes
@@ -0,0 +1,17 @@
1
+ import type { AnomalySignal } from './anomaly-detector';
2
+ import type { RootCauseAnalysis } from './root-cause-analyzer';
3
+ export interface AlertManagerOptions {
4
+ cooldownMs?: number;
5
+ transport: (payload: {
6
+ signal: AnomalySignal;
7
+ analysis: RootCauseAnalysis;
8
+ }) => Promise<void> | void;
9
+ }
10
+ export declare class AlertManager {
11
+ private readonly options;
12
+ private readonly cooldownMs;
13
+ private readonly lastAlert;
14
+ constructor(options: AlertManagerOptions);
15
+ notify(signal: AnomalySignal, analysis: RootCauseAnalysis): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=alert-manager.d.ts.map
@@ -0,0 +1,24 @@
1
+ // @bun
2
+ // src/anomaly/alert-manager.ts
3
+ class AlertManager {
4
+ options;
5
+ cooldownMs;
6
+ lastAlert = new Map;
7
+ constructor(options) {
8
+ this.options = options;
9
+ this.cooldownMs = options.cooldownMs ?? 60000;
10
+ }
11
+ async notify(signal, analysis) {
12
+ const key = `${signal.type}:${analysis.culprit?.id ?? "none"}`;
13
+ const now = Date.now();
14
+ const last = this.lastAlert.get(key) ?? 0;
15
+ if (now - last < this.cooldownMs) {
16
+ return;
17
+ }
18
+ await this.options.transport({ signal, analysis });
19
+ this.lastAlert.set(key, now);
20
+ }
21
+ }
22
+ export {
23
+ AlertManager
24
+ };
@@ -0,0 +1,22 @@
1
+ import { BaselineCalculator, type MetricPoint } from './baseline-calculator';
2
+ export interface AnomalyThresholds {
3
+ errorRateDelta?: number;
4
+ latencyDelta?: number;
5
+ throughputDrop?: number;
6
+ minSamples?: number;
7
+ }
8
+ export interface AnomalySignal {
9
+ type: 'error_rate_spike' | 'latency_regression' | 'throughput_drop';
10
+ delta: number;
11
+ point: MetricPoint;
12
+ baseline: ReturnType<BaselineCalculator['getSnapshot']>;
13
+ }
14
+ export declare class AnomalyDetector {
15
+ private readonly baseline;
16
+ private readonly thresholds;
17
+ constructor(options?: AnomalyThresholds);
18
+ evaluate(point: MetricPoint): AnomalySignal[];
19
+ private relativeDelta;
20
+ private relativeDrop;
21
+ }
22
+ //# sourceMappingURL=anomaly-detector.d.ts.map
@@ -0,0 +1,102 @@
1
+ // @bun
2
+ // src/anomaly/baseline-calculator.ts
3
+ class BaselineCalculator {
4
+ alpha;
5
+ snapshot = {
6
+ latencyP99: 0,
7
+ latencyP95: 0,
8
+ errorRate: 0,
9
+ throughput: 0,
10
+ sampleCount: 0
11
+ };
12
+ constructor(alpha = 0.2) {
13
+ this.alpha = alpha;
14
+ }
15
+ update(point) {
16
+ const { sampleCount } = this.snapshot;
17
+ const nextCount = sampleCount + 1;
18
+ const weight = sampleCount === 0 ? 1 : this.alpha;
19
+ this.snapshot = {
20
+ latencyP99: this.mix(this.snapshot.latencyP99, point.latencyP99, weight),
21
+ latencyP95: this.mix(this.snapshot.latencyP95, point.latencyP95, weight),
22
+ errorRate: this.mix(this.snapshot.errorRate, point.errorRate, weight),
23
+ throughput: this.mix(this.snapshot.throughput, point.throughput, weight),
24
+ sampleCount: nextCount
25
+ };
26
+ return this.snapshot;
27
+ }
28
+ getSnapshot() {
29
+ return this.snapshot;
30
+ }
31
+ mix(current, next, weight) {
32
+ if (this.snapshot.sampleCount === 0) {
33
+ return next;
34
+ }
35
+ return current * (1 - weight) + next * weight;
36
+ }
37
+ }
38
+
39
+ // src/anomaly/anomaly-detector.ts
40
+ class AnomalyDetector {
41
+ baseline;
42
+ thresholds = {
43
+ errorRateDelta: 0.5,
44
+ latencyDelta: 0.35,
45
+ throughputDrop: 0.4,
46
+ minSamples: 10
47
+ };
48
+ constructor(options = {}) {
49
+ this.baseline = new BaselineCalculator;
50
+ this.thresholds = { ...this.thresholds, ...options };
51
+ }
52
+ evaluate(point) {
53
+ const baselineSnapshot = this.baseline.update(point);
54
+ if (baselineSnapshot.sampleCount < this.thresholds.minSamples) {
55
+ return [];
56
+ }
57
+ const signals = [];
58
+ const errorDelta = this.relativeDelta(point.errorRate, baselineSnapshot.errorRate);
59
+ if (errorDelta > this.thresholds.errorRateDelta) {
60
+ signals.push({
61
+ type: "error_rate_spike",
62
+ delta: errorDelta,
63
+ point,
64
+ baseline: baselineSnapshot
65
+ });
66
+ }
67
+ const latencyDelta = this.relativeDelta(point.latencyP99, baselineSnapshot.latencyP99);
68
+ if (latencyDelta > this.thresholds.latencyDelta) {
69
+ signals.push({
70
+ type: "latency_regression",
71
+ delta: latencyDelta,
72
+ point,
73
+ baseline: baselineSnapshot
74
+ });
75
+ }
76
+ const throughputDelta = this.relativeDrop(point.throughput, baselineSnapshot.throughput);
77
+ if (throughputDelta > this.thresholds.throughputDrop) {
78
+ signals.push({
79
+ type: "throughput_drop",
80
+ delta: throughputDelta,
81
+ point,
82
+ baseline: baselineSnapshot
83
+ });
84
+ }
85
+ return signals;
86
+ }
87
+ relativeDelta(value, baseline) {
88
+ if (baseline === 0) {
89
+ return 0;
90
+ }
91
+ return (value - baseline) / baseline;
92
+ }
93
+ relativeDrop(value, baseline) {
94
+ if (baseline === 0) {
95
+ return 0;
96
+ }
97
+ return (baseline - value) / baseline;
98
+ }
99
+ }
100
+ export {
101
+ AnomalyDetector
102
+ };
@@ -0,0 +1,23 @@
1
+ export interface MetricPoint {
2
+ latencyP99: number;
3
+ latencyP95: number;
4
+ errorRate: number;
5
+ throughput: number;
6
+ timestamp: Date;
7
+ }
8
+ export interface BaselineSnapshot {
9
+ latencyP99: number;
10
+ latencyP95: number;
11
+ errorRate: number;
12
+ throughput: number;
13
+ sampleCount: number;
14
+ }
15
+ export declare class BaselineCalculator {
16
+ private readonly alpha;
17
+ private snapshot;
18
+ constructor(alpha?: number);
19
+ update(point: MetricPoint): BaselineSnapshot;
20
+ getSnapshot(): BaselineSnapshot;
21
+ private mix;
22
+ }
23
+ //# sourceMappingURL=baseline-calculator.d.ts.map
@@ -0,0 +1,40 @@
1
+ // @bun
2
+ // src/anomaly/baseline-calculator.ts
3
+ class BaselineCalculator {
4
+ alpha;
5
+ snapshot = {
6
+ latencyP99: 0,
7
+ latencyP95: 0,
8
+ errorRate: 0,
9
+ throughput: 0,
10
+ sampleCount: 0
11
+ };
12
+ constructor(alpha = 0.2) {
13
+ this.alpha = alpha;
14
+ }
15
+ update(point) {
16
+ const { sampleCount } = this.snapshot;
17
+ const nextCount = sampleCount + 1;
18
+ const weight = sampleCount === 0 ? 1 : this.alpha;
19
+ this.snapshot = {
20
+ latencyP99: this.mix(this.snapshot.latencyP99, point.latencyP99, weight),
21
+ latencyP95: this.mix(this.snapshot.latencyP95, point.latencyP95, weight),
22
+ errorRate: this.mix(this.snapshot.errorRate, point.errorRate, weight),
23
+ throughput: this.mix(this.snapshot.throughput, point.throughput, weight),
24
+ sampleCount: nextCount
25
+ };
26
+ return this.snapshot;
27
+ }
28
+ getSnapshot() {
29
+ return this.snapshot;
30
+ }
31
+ mix(current, next, weight) {
32
+ if (this.snapshot.sampleCount === 0) {
33
+ return next;
34
+ }
35
+ return current * (1 - weight) + next * weight;
36
+ }
37
+ }
38
+ export {
39
+ BaselineCalculator
40
+ };
@@ -0,0 +1,19 @@
1
+ import type { AnomalySignal } from './anomaly-detector';
2
+ export interface DeploymentEvent {
3
+ id: string;
4
+ operation: string;
5
+ deployedAt: Date;
6
+ stage?: string;
7
+ status: 'in_progress' | 'completed' | 'rolled_back';
8
+ }
9
+ export interface RootCauseAnalysis {
10
+ signal: AnomalySignal;
11
+ culprit?: DeploymentEvent;
12
+ notes: string[];
13
+ }
14
+ export declare class RootCauseAnalyzer {
15
+ private readonly lookbackMs;
16
+ constructor(lookbackMs?: number);
17
+ analyze(signal: AnomalySignal, deployments: DeploymentEvent[]): RootCauseAnalysis;
18
+ }
19
+ //# sourceMappingURL=root-cause-analyzer.d.ts.map
@@ -0,0 +1,32 @@
1
+ // @bun
2
+ // src/anomaly/root-cause-analyzer.ts
3
+ class RootCauseAnalyzer {
4
+ lookbackMs;
5
+ constructor(lookbackMs = 15 * 60 * 1000) {
6
+ this.lookbackMs = lookbackMs;
7
+ }
8
+ analyze(signal, deployments) {
9
+ const windowStart = new Date(signal.point.timestamp.getTime() - this.lookbackMs);
10
+ const candidates = deployments.filter((deployment) => deployment.deployedAt >= windowStart).sort((a, b) => b.deployedAt.getTime() - a.deployedAt.getTime());
11
+ const notes = [];
12
+ let culprit;
13
+ if (candidates.length > 0) {
14
+ culprit = candidates[0];
15
+ if (culprit) {
16
+ notes.push(`Closest deployment ${culprit.id} (${culprit.operation}) at ${culprit.deployedAt.toISOString()}`);
17
+ }
18
+ } else {
19
+ notes.push("No deployments found within lookback window.");
20
+ }
21
+ if (signal.type === "latency_regression") {
22
+ notes.push("Verify recent schema changes and external dependency latency.");
23
+ }
24
+ if (signal.type === "error_rate_spike") {
25
+ notes.push("Check SLO monitor for correlated incidents.");
26
+ }
27
+ return { signal, culprit, notes };
28
+ }
29
+ }
30
+ export {
31
+ RootCauseAnalyzer
32
+ };
@@ -0,0 +1,16 @@
1
+ export { getTracer, traceAsync, traceSync } from './tracing';
2
+ export { getMeter, createCounter, createUpDownCounter, createHistogram, standardMetrics, } from './metrics';
3
+ export { Logger, logger } from './logging';
4
+ export { createTracingMiddleware, type TracingMiddlewareOptions, } from './tracing/middleware';
5
+ export { IntentAggregator, type IntentAggregatorSnapshot, type TelemetrySample, } from './intent/aggregator';
6
+ export { IntentDetector, type IntentSignal, type IntentSignalType, } from './intent/detector';
7
+ export { EvolutionPipeline, type EvolutionPipelineEvent, type EvolutionPipelineOptions, } from './pipeline/evolution-pipeline';
8
+ export { LifecycleKpiPipeline, type LifecycleKpiPipelineOptions, type LifecyclePipelineEvent, } from './pipeline/lifecycle-pipeline';
9
+ export { PosthogTelemetryProvider, type PosthogTelemetryProviderOptions, } from './telemetry/posthog-telemetry';
10
+ export { PosthogBaselineReader } from './telemetry/posthog-baseline-reader';
11
+ export type { LogLevel, LogEntry } from './logging';
12
+ export { BaselineCalculator } from './anomaly/baseline-calculator';
13
+ export { AnomalyDetector, type AnomalySignal, type AnomalyThresholds, } from './anomaly/anomaly-detector';
14
+ export { RootCauseAnalyzer, type RootCauseAnalysis, } from './anomaly/root-cause-analyzer';
15
+ export { AlertManager } from './anomaly/alert-manager';
16
+ //# sourceMappingURL=index.d.ts.map