@gravito/core 1.6.0 → 1.6.1
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/dist/Metrics-VOWWRNNR.js +219 -0
- package/dist/chunk-R5U7XKVJ.js +16 -0
- package/dist/{compat-C4Src6NN.d.cts → compat-CI8hiulX.d.cts} +19 -0
- package/dist/{compat-C4Src6NN.d.ts → compat-CI8hiulX.d.ts} +19 -0
- package/dist/compat.d.cts +1 -1
- package/dist/compat.d.ts +1 -1
- package/dist/engine/index.cjs +326 -29
- package/dist/engine/index.d.cts +222 -2
- package/dist/engine/index.d.ts +222 -2
- package/dist/engine/index.js +326 -29
- package/dist/index.cjs +9039 -4976
- package/dist/index.d.cts +2693 -419
- package/dist/index.d.ts +2693 -419
- package/dist/index.js +8779 -5118
- package/package.json +4 -3
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import "./chunk-R5U7XKVJ.js";
|
|
2
|
+
|
|
3
|
+
// src/observability/Metrics.ts
|
|
4
|
+
var DEFAULTS = {
|
|
5
|
+
port: 9090,
|
|
6
|
+
prefix: "gravito_event_",
|
|
7
|
+
interval: 6e4,
|
|
8
|
+
// 60 秒
|
|
9
|
+
defaultMetrics: true
|
|
10
|
+
};
|
|
11
|
+
async function setupPrometheusMetrics(config = {}) {
|
|
12
|
+
const finalConfig = {
|
|
13
|
+
port: config.port ?? parseInt(process.env.PROMETHEUS_PORT || String(DEFAULTS.port), 10),
|
|
14
|
+
prefix: config.prefix ?? process.env.PROMETHEUS_PREFIX ?? DEFAULTS.prefix,
|
|
15
|
+
interval: config.interval ?? parseInt(process.env.PROMETHEUS_INTERVAL || String(DEFAULTS.interval), 10),
|
|
16
|
+
defaultMetrics: config.defaultMetrics ?? process.env.PROMETHEUS_DEFAULT_METRICS !== "false"
|
|
17
|
+
};
|
|
18
|
+
try {
|
|
19
|
+
const { metrics } = await import("@opentelemetry/api");
|
|
20
|
+
const { MeterProvider } = await import("@opentelemetry/sdk-metrics");
|
|
21
|
+
const { PrometheusExporter } = await import("@opentelemetry/exporter-prometheus");
|
|
22
|
+
const exporter = new PrometheusExporter(
|
|
23
|
+
{
|
|
24
|
+
port: finalConfig.port,
|
|
25
|
+
endpoint: "/metrics"
|
|
26
|
+
},
|
|
27
|
+
() => {
|
|
28
|
+
console.log(
|
|
29
|
+
`[Metrics] Prometheus metrics available at http://localhost:${finalConfig.port}/metrics`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
const meterProvider = new MeterProvider({
|
|
34
|
+
exporter,
|
|
35
|
+
interval: finalConfig.interval
|
|
36
|
+
});
|
|
37
|
+
metrics.setGlobalMeterProvider(meterProvider);
|
|
38
|
+
if (finalConfig.defaultMetrics) {
|
|
39
|
+
try {
|
|
40
|
+
const { collectDefaultMetrics } = await import("@opentelemetry/auto-instrumentations-node");
|
|
41
|
+
collectDefaultMetrics({ meterProvider, prefix: finalConfig.prefix });
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.warn("[Metrics] Failed to setup default metrics:", error);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
port: finalConfig.port,
|
|
48
|
+
endpoint: `/metrics`
|
|
49
|
+
};
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.warn("[Metrics] Failed to setup Prometheus exporter:", error);
|
|
52
|
+
console.log("[Metrics] Metrics will not be exported to Prometheus");
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function getEventMetricsDefinition(prefix = DEFAULTS.prefix) {
|
|
57
|
+
return {
|
|
58
|
+
dispatchLatency: {
|
|
59
|
+
name: `${prefix}dispatch_latency_seconds`,
|
|
60
|
+
help: "Event dispatch latency distribution",
|
|
61
|
+
labels: ["event_name", "priority"],
|
|
62
|
+
buckets: [1e-3, 5e-3, 0.01, 0.05, 0.1, 0.5, 1, 2, 5]
|
|
63
|
+
},
|
|
64
|
+
listenerExecutionTime: {
|
|
65
|
+
name: `${prefix}listener_execution_seconds`,
|
|
66
|
+
help: "Individual listener execution time",
|
|
67
|
+
labels: ["event_name", "listener_name"],
|
|
68
|
+
buckets: [1e-3, 5e-3, 0.01, 0.05, 0.1, 0.5, 1, 2, 5]
|
|
69
|
+
},
|
|
70
|
+
queueDepth: {
|
|
71
|
+
name: `${prefix}queue_depth`,
|
|
72
|
+
help: "Current queue depth by priority",
|
|
73
|
+
labels: ["priority"]
|
|
74
|
+
},
|
|
75
|
+
failureRate: {
|
|
76
|
+
name: `${prefix}failures_total`,
|
|
77
|
+
help: "Total event processing failures",
|
|
78
|
+
labels: ["event_name", "error_type"]
|
|
79
|
+
},
|
|
80
|
+
timeoutCount: {
|
|
81
|
+
name: `${prefix}timeouts_total`,
|
|
82
|
+
help: "Total event timeouts",
|
|
83
|
+
labels: ["event_name"]
|
|
84
|
+
},
|
|
85
|
+
throughput: {
|
|
86
|
+
name: `${prefix}throughput_total`,
|
|
87
|
+
help: "Total events processed",
|
|
88
|
+
labels: ["event_name", "status"]
|
|
89
|
+
},
|
|
90
|
+
circuitBreakerState: {
|
|
91
|
+
name: `${prefix}circuit_breaker_state`,
|
|
92
|
+
help: "Current circuit breaker state (0=CLOSED, 1=HALF_OPEN, 2=OPEN)",
|
|
93
|
+
labels: ["event_name"]
|
|
94
|
+
},
|
|
95
|
+
circuitBreakerTransitions: {
|
|
96
|
+
name: `${prefix}circuit_breaker_transitions_total`,
|
|
97
|
+
help: "Total number of circuit breaker state transitions",
|
|
98
|
+
labels: ["event_name", "from_state", "to_state"]
|
|
99
|
+
},
|
|
100
|
+
circuitBreakerFailures: {
|
|
101
|
+
name: `${prefix}circuit_breaker_failures_total`,
|
|
102
|
+
help: "Total number of failures tracked by circuit breaker",
|
|
103
|
+
labels: ["event_name"]
|
|
104
|
+
},
|
|
105
|
+
circuitBreakerSuccesses: {
|
|
106
|
+
name: `${prefix}circuit_breaker_successes_total`,
|
|
107
|
+
help: "Total number of successes tracked by circuit breaker",
|
|
108
|
+
labels: ["event_name"]
|
|
109
|
+
},
|
|
110
|
+
circuitBreakerOpenDuration: {
|
|
111
|
+
name: `${prefix}circuit_breaker_open_duration_seconds`,
|
|
112
|
+
help: "Duration of circuit breaker OPEN state in seconds",
|
|
113
|
+
labels: ["event_name"],
|
|
114
|
+
buckets: [1, 5, 10, 30, 60, 120, 300]
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
var PROMETHEUS_QUERIES = {
|
|
119
|
+
/** 事件派發延遲 P95 */
|
|
120
|
+
dispatchLatencyP95: "histogram_quantile(0.95, rate(gravito_event_dispatch_latency_seconds_bucket[5m]))",
|
|
121
|
+
/** 事件派發延遲 P99 */
|
|
122
|
+
dispatchLatencyP99: "histogram_quantile(0.99, rate(gravito_event_dispatch_latency_seconds_bucket[5m]))",
|
|
123
|
+
/** 隊列深度(按優先級) */
|
|
124
|
+
queueDepthByPriority: "gravito_event_queue_depth",
|
|
125
|
+
/** 吞吐量(事件/秒) */
|
|
126
|
+
throughput: "rate(gravito_event_throughput_total[1m])",
|
|
127
|
+
/** 失敗率 */
|
|
128
|
+
failureRate: "rate(gravito_event_failures_total[5m]) / rate(gravito_event_throughput_total[5m])",
|
|
129
|
+
/** 監聽器執行時間 P99 */
|
|
130
|
+
listenerLatencyP99: "histogram_quantile(0.99, rate(gravito_event_listener_execution_seconds_bucket[5m]))",
|
|
131
|
+
/** 超時次數 */
|
|
132
|
+
timeoutCount: "rate(gravito_event_timeouts_total[5m])",
|
|
133
|
+
/** 吞吐量異常檢測 */
|
|
134
|
+
throughputAnomaly: "rate(gravito_event_throughput_total[5m]) < 100",
|
|
135
|
+
/** 熔斷器狀態(0=CLOSED, 1=HALF_OPEN, 2=OPEN) */
|
|
136
|
+
circuitBreakerState: "gravito_event_circuit_breaker_state",
|
|
137
|
+
/** 熔斷器開啟率 */
|
|
138
|
+
circuitBreakerOpenRate: 'rate(gravito_event_circuit_breaker_transitions_total{to_state="OPEN"}[5m])',
|
|
139
|
+
/** 熔斷器恢復率 */
|
|
140
|
+
circuitBreakerRecoveryRate: 'rate(gravito_event_circuit_breaker_transitions_total{to_state="CLOSED"}[5m])',
|
|
141
|
+
/** 熔斷器失敗率 */
|
|
142
|
+
circuitBreakerFailureRate: "rate(gravito_event_circuit_breaker_failures_total[5m])",
|
|
143
|
+
/** 熔斷器 OPEN 持續時間 P95 */
|
|
144
|
+
circuitBreakerOpenDurationP95: "histogram_quantile(0.95, rate(gravito_event_circuit_breaker_open_duration_seconds_bucket[5m]))",
|
|
145
|
+
/** 熔斷器 OPEN 持續時間 P99 */
|
|
146
|
+
circuitBreakerOpenDurationP99: "histogram_quantile(0.99, rate(gravito_event_circuit_breaker_open_duration_seconds_bucket[5m]))"
|
|
147
|
+
};
|
|
148
|
+
var PROMETHEUS_ALERT_RULES = {
|
|
149
|
+
/** P99 延遲過高 */
|
|
150
|
+
HighDispatchLatency: {
|
|
151
|
+
expr: "histogram_quantile(0.99, gravito_event_dispatch_latency_seconds) > 0.8",
|
|
152
|
+
for: "5m",
|
|
153
|
+
severity: "critical",
|
|
154
|
+
summary: "\u4E8B\u4EF6\u6D3E\u767C P99 \u5EF6\u9072\u904E\u9AD8",
|
|
155
|
+
description: "P99 \u5EF6\u9072: {{ $value }}s\uFF0C\u5DF2\u8D85\u904E 800ms"
|
|
156
|
+
},
|
|
157
|
+
/** 隊列深度過高 */
|
|
158
|
+
HighQueueDepth: {
|
|
159
|
+
expr: 'gravito_event_queue_depth{priority="high"} > 1000',
|
|
160
|
+
for: "2m",
|
|
161
|
+
severity: "warning",
|
|
162
|
+
summary: "\u9AD8\u512A\u5148\u7D1A\u4E8B\u4EF6\u968A\u5217\u5806\u7A4D",
|
|
163
|
+
description: "\u968A\u5217\u6DF1\u5EA6: {{ $value }}\uFF0C\u61C9\u8ABF\u67E5\u539F\u56E0"
|
|
164
|
+
},
|
|
165
|
+
/** 失敗率過高 */
|
|
166
|
+
HighFailureRate: {
|
|
167
|
+
expr: "(rate(gravito_event_failures_total[5m]) / rate(gravito_event_throughput_total[5m])) > 0.05",
|
|
168
|
+
for: "3m",
|
|
169
|
+
severity: "critical",
|
|
170
|
+
summary: "\u4E8B\u4EF6\u8655\u7406\u5931\u6557\u7387\u904E\u9AD8",
|
|
171
|
+
description: "\u5931\u6557\u7387: {{ $value | humanizePercentage }}\uFF0C\u8D85\u904E 5%"
|
|
172
|
+
},
|
|
173
|
+
/** 監聽器執行時間過長 */
|
|
174
|
+
SlowListener: {
|
|
175
|
+
expr: "histogram_quantile(0.99, gravito_event_listener_execution_seconds) > 1.0",
|
|
176
|
+
for: "5m",
|
|
177
|
+
severity: "warning",
|
|
178
|
+
summary: "\u76E3\u807D\u5668\u57F7\u884C\u6642\u9593\u904E\u9577",
|
|
179
|
+
description: "P99 \u8017\u6642: {{ $value }}s\uFF0C\u76E3\u807D\u5668: {{ $labels.listener_name }}"
|
|
180
|
+
},
|
|
181
|
+
/** 吞吐量異常下降 */
|
|
182
|
+
ThroughputDrop: {
|
|
183
|
+
expr: "rate(gravito_event_throughput_total[5m]) < 100 and increase(gravito_event_throughput_total[1h]) > 0",
|
|
184
|
+
for: "2m",
|
|
185
|
+
severity: "critical",
|
|
186
|
+
summary: "\u4E8B\u4EF6\u541E\u5410\u91CF\u7570\u5E38\u4E0B\u964D",
|
|
187
|
+
description: "\u7576\u524D\u541E\u5410: {{ $value | humanize }} events/sec"
|
|
188
|
+
},
|
|
189
|
+
/** 熔斷器持續開啟 */
|
|
190
|
+
CircuitBreakerOpen: {
|
|
191
|
+
expr: 'gravito_event_circuit_breaker_state{event_name=~".+"} == 2',
|
|
192
|
+
for: "5m",
|
|
193
|
+
severity: "warning",
|
|
194
|
+
summary: "\u7194\u65B7\u5668\u6301\u7E8C\u958B\u555F",
|
|
195
|
+
description: "\u4E8B\u4EF6 {{ $labels.event_name }} \u7194\u65B7\u5668\u5DF2\u958B\u555F\u8D85\u904E 5 \u5206\u9418"
|
|
196
|
+
},
|
|
197
|
+
/** 熔斷器頻繁切換 */
|
|
198
|
+
CircuitBreakerFlapping: {
|
|
199
|
+
expr: "rate(gravito_event_circuit_breaker_transitions_total[5m]) > 10",
|
|
200
|
+
for: "2m",
|
|
201
|
+
severity: "critical",
|
|
202
|
+
summary: "\u7194\u65B7\u5668\u983B\u7E41\u5207\u63DB",
|
|
203
|
+
description: "\u4E8B\u4EF6 {{ $labels.event_name }} \u7194\u65B7\u5668\u72C0\u614B\u5207\u63DB\u904E\u65BC\u983B\u7E41\uFF0C\u5207\u63DB\u901F\u7387: {{ $value }}/sec"
|
|
204
|
+
},
|
|
205
|
+
/** 熔斷器故障率過高 */
|
|
206
|
+
CircuitBreakerHighFailureRate: {
|
|
207
|
+
expr: "rate(gravito_event_circuit_breaker_failures_total[5m]) > rate(gravito_event_circuit_breaker_successes_total[5m])",
|
|
208
|
+
for: "3m",
|
|
209
|
+
severity: "critical",
|
|
210
|
+
summary: "\u7194\u65B7\u5668\u6545\u969C\u7387\u8D85\u904E\u6210\u529F\u7387",
|
|
211
|
+
description: "\u4E8B\u4EF6 {{ $labels.event_name }} \u7684\u5931\u6557\u7387\u5DF2\u8D85\u904E\u6210\u529F\u7387"
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
export {
|
|
215
|
+
PROMETHEUS_ALERT_RULES,
|
|
216
|
+
PROMETHEUS_QUERIES,
|
|
217
|
+
getEventMetricsDefinition,
|
|
218
|
+
setupPrometheusMetrics
|
|
219
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
__require,
|
|
15
|
+
__export
|
|
16
|
+
};
|
|
@@ -312,6 +312,25 @@ interface GravitoContext<V extends GravitoVariables = GravitoVariables> {
|
|
|
312
312
|
* ```
|
|
313
313
|
*/
|
|
314
314
|
readonly native: unknown;
|
|
315
|
+
/**
|
|
316
|
+
* Access the RequestScopeManager for this request
|
|
317
|
+
* Services resolved through this manager are scoped to the HTTP request lifetime.
|
|
318
|
+
*/
|
|
319
|
+
requestScope(): any;
|
|
320
|
+
/**
|
|
321
|
+
* Resolve or create a request-scoped service
|
|
322
|
+
*
|
|
323
|
+
* @param key - Service key (string or symbol)
|
|
324
|
+
* @param factory - Factory function to create the service if not cached
|
|
325
|
+
* @returns The cached or newly created service instance
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```typescript
|
|
329
|
+
* // Subsequent calls in the same request return the same instance
|
|
330
|
+
* const cache = ctx.scoped('product:cache', () => new RequestProductCache())
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
scoped<T>(key: string | symbol, factory: () => T): T;
|
|
315
334
|
}
|
|
316
335
|
/**
|
|
317
336
|
* Next function for middleware chain
|
|
@@ -312,6 +312,25 @@ interface GravitoContext<V extends GravitoVariables = GravitoVariables> {
|
|
|
312
312
|
* ```
|
|
313
313
|
*/
|
|
314
314
|
readonly native: unknown;
|
|
315
|
+
/**
|
|
316
|
+
* Access the RequestScopeManager for this request
|
|
317
|
+
* Services resolved through this manager are scoped to the HTTP request lifetime.
|
|
318
|
+
*/
|
|
319
|
+
requestScope(): any;
|
|
320
|
+
/**
|
|
321
|
+
* Resolve or create a request-scoped service
|
|
322
|
+
*
|
|
323
|
+
* @param key - Service key (string or symbol)
|
|
324
|
+
* @param factory - Factory function to create the service if not cached
|
|
325
|
+
* @returns The cached or newly created service instance
|
|
326
|
+
*
|
|
327
|
+
* @example
|
|
328
|
+
* ```typescript
|
|
329
|
+
* // Subsequent calls in the same request return the same instance
|
|
330
|
+
* const cache = ctx.scoped('product:cache', () => new RequestProductCache())
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
scoped<T>(key: string | symbol, factory: () => T): T;
|
|
315
334
|
}
|
|
316
335
|
/**
|
|
317
336
|
* Next function for middleware chain
|
package/dist/compat.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { C as ContentfulStatusCode, e as Context, e as GravitoContext, c as GravitoErrorHandler, a as GravitoHandler, b as GravitoMiddleware, g as GravitoNext, d as GravitoNotFoundHandler, f as GravitoRequest, G as GravitoVariables, a as Handler, H as HttpMethod, b as MiddlewareHandler, g as Next, S as StatusCode, V as ValidationTarget, G as Variables } from './compat-
|
|
1
|
+
export { C as ContentfulStatusCode, e as Context, e as GravitoContext, c as GravitoErrorHandler, a as GravitoHandler, b as GravitoMiddleware, g as GravitoNext, d as GravitoNotFoundHandler, f as GravitoRequest, G as GravitoVariables, a as Handler, H as HttpMethod, b as MiddlewareHandler, g as Next, S as StatusCode, V as ValidationTarget, G as Variables } from './compat-CI8hiulX.cjs';
|
package/dist/compat.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { C as ContentfulStatusCode, e as Context, e as GravitoContext, c as GravitoErrorHandler, a as GravitoHandler, b as GravitoMiddleware, g as GravitoNext, d as GravitoNotFoundHandler, f as GravitoRequest, G as GravitoVariables, a as Handler, H as HttpMethod, b as MiddlewareHandler, g as Next, S as StatusCode, V as ValidationTarget, G as Variables } from './compat-
|
|
1
|
+
export { C as ContentfulStatusCode, e as Context, e as GravitoContext, c as GravitoErrorHandler, a as GravitoHandler, b as GravitoMiddleware, g as GravitoNext, d as GravitoNotFoundHandler, f as GravitoRequest, G as GravitoVariables, a as Handler, H as HttpMethod, b as MiddlewareHandler, g as Next, S as StatusCode, V as ValidationTarget, G as Variables } from './compat-CI8hiulX.js';
|