@spinajs/telemetry 2.0.482
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/README.md +482 -0
- package/lib/cjs/InMemoryPerfSink.d.ts +51 -0
- package/lib/cjs/InMemoryPerfSink.d.ts.map +1 -0
- package/lib/cjs/InMemoryPerfSink.js +100 -0
- package/lib/cjs/InMemoryPerfSink.js.map +1 -0
- package/lib/cjs/PromMetricSink.d.ts +26 -0
- package/lib/cjs/PromMetricSink.d.ts.map +1 -0
- package/lib/cjs/PromMetricSink.js +68 -0
- package/lib/cjs/PromMetricSink.js.map +1 -0
- package/lib/cjs/bootstrap.d.ts +13 -0
- package/lib/cjs/bootstrap.d.ts.map +1 -0
- package/lib/cjs/bootstrap.js +57 -0
- package/lib/cjs/bootstrap.js.map +1 -0
- package/lib/cjs/config/telemetry.d.ts +63 -0
- package/lib/cjs/config/telemetry.d.ts.map +1 -0
- package/lib/cjs/config/telemetry.js +78 -0
- package/lib/cjs/config/telemetry.js.map +1 -0
- package/lib/cjs/controllers/Metrics.d.ts +26 -0
- package/lib/cjs/controllers/Metrics.d.ts.map +1 -0
- package/lib/cjs/controllers/Metrics.js +63 -0
- package/lib/cjs/controllers/Metrics.js.map +1 -0
- package/lib/cjs/controllers/Telemetry.d.ts +92 -0
- package/lib/cjs/controllers/Telemetry.d.ts.map +1 -0
- package/lib/cjs/controllers/Telemetry.js +226 -0
- package/lib/cjs/controllers/Telemetry.js.map +1 -0
- package/lib/cjs/dto/index.d.ts +21 -0
- package/lib/cjs/dto/index.d.ts.map +1 -0
- package/lib/cjs/dto/index.js +64 -0
- package/lib/cjs/dto/index.js.map +1 -0
- package/lib/cjs/endpoints.d.ts +32 -0
- package/lib/cjs/endpoints.d.ts.map +1 -0
- package/lib/cjs/endpoints.js +38 -0
- package/lib/cjs/endpoints.js.map +1 -0
- package/lib/cjs/health.d.ts +55 -0
- package/lib/cjs/health.d.ts.map +1 -0
- package/lib/cjs/health.js +111 -0
- package/lib/cjs/health.js.map +1 -0
- package/lib/cjs/index.d.ts +16 -0
- package/lib/cjs/index.d.ts.map +1 -0
- package/lib/cjs/index.js +32 -0
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/metrics.d.ts +16 -0
- package/lib/cjs/metrics.d.ts.map +1 -0
- package/lib/cjs/metrics.js +32 -0
- package/lib/cjs/metrics.js.map +1 -0
- package/lib/cjs/middleware.d.ts +81 -0
- package/lib/cjs/middleware.d.ts.map +1 -0
- package/lib/cjs/middleware.js +210 -0
- package/lib/cjs/middleware.js.map +1 -0
- package/lib/cjs/package.json +1 -0
- package/lib/cjs/policies/PublicPolicy.d.ts +16 -0
- package/lib/cjs/policies/PublicPolicy.d.ts.map +1 -0
- package/lib/cjs/policies/PublicPolicy.js +34 -0
- package/lib/cjs/policies/PublicPolicy.js.map +1 -0
- package/lib/cjs/policies/TelemetryTokenPolicy.d.ts +19 -0
- package/lib/cjs/policies/TelemetryTokenPolicy.d.ts.map +1 -0
- package/lib/cjs/policies/TelemetryTokenPolicy.js +65 -0
- package/lib/cjs/policies/TelemetryTokenPolicy.js.map +1 -0
- package/lib/cjs/requestStats.d.ts +81 -0
- package/lib/cjs/requestStats.d.ts.map +1 -0
- package/lib/cjs/requestStats.js +134 -0
- package/lib/cjs/requestStats.js.map +1 -0
- package/lib/cjs/responses.d.ts +23 -0
- package/lib/cjs/responses.d.ts.map +1 -0
- package/lib/cjs/responses.js +35 -0
- package/lib/cjs/responses.js.map +1 -0
- package/lib/cjs/routeStats.d.ts +43 -0
- package/lib/cjs/routeStats.d.ts.map +1 -0
- package/lib/cjs/routeStats.js +59 -0
- package/lib/cjs/routeStats.js.map +1 -0
- package/lib/cjs/schemas/HealthResponse.schema.d.ts +30 -0
- package/lib/cjs/schemas/HealthResponse.schema.d.ts.map +1 -0
- package/lib/cjs/schemas/HealthResponse.schema.js +15 -0
- package/lib/cjs/schemas/HealthResponse.schema.js.map +1 -0
- package/lib/cjs/schemas/PerfResponse.schema.d.ts +56 -0
- package/lib/cjs/schemas/PerfResponse.schema.d.ts.map +1 -0
- package/lib/cjs/schemas/PerfResponse.schema.js +36 -0
- package/lib/cjs/schemas/PerfResponse.schema.js.map +1 -0
- package/lib/cjs/schemas/ReadyResponse.schema.d.ts +36 -0
- package/lib/cjs/schemas/ReadyResponse.schema.d.ts.map +1 -0
- package/lib/cjs/schemas/ReadyResponse.schema.js +23 -0
- package/lib/cjs/schemas/ReadyResponse.schema.js.map +1 -0
- package/lib/cjs/schemas/RequestStatsSnapshot.schema.d.ts +79 -0
- package/lib/cjs/schemas/RequestStatsSnapshot.schema.d.ts.map +1 -0
- package/lib/cjs/schemas/RequestStatsSnapshot.schema.js +30 -0
- package/lib/cjs/schemas/RequestStatsSnapshot.schema.js.map +1 -0
- package/lib/cjs/schemas/RoutesResponse.schema.d.ts +100 -0
- package/lib/cjs/schemas/RoutesResponse.schema.d.ts.map +1 -0
- package/lib/cjs/schemas/RoutesResponse.schema.js +25 -0
- package/lib/cjs/schemas/RoutesResponse.schema.js.map +1 -0
- package/lib/cjs/schemas/StatsResponse.schema.d.ts +158 -0
- package/lib/cjs/schemas/StatsResponse.schema.d.ts.map +1 -0
- package/lib/cjs/schemas/StatsResponse.schema.js +19 -0
- package/lib/cjs/schemas/StatsResponse.schema.js.map +1 -0
- package/lib/cjs/schemas/TimelineResponse.schema.d.ts +109 -0
- package/lib/cjs/schemas/TimelineResponse.schema.d.ts.map +1 -0
- package/lib/cjs/schemas/TimelineResponse.schema.js +28 -0
- package/lib/cjs/schemas/TimelineResponse.schema.js.map +1 -0
- package/lib/cjs/store.d.ts +58 -0
- package/lib/cjs/store.d.ts.map +1 -0
- package/lib/cjs/store.js +108 -0
- package/lib/cjs/store.js.map +1 -0
- package/lib/cjs/timeline.d.ts +48 -0
- package/lib/cjs/timeline.d.ts.map +1 -0
- package/lib/cjs/timeline.js +70 -0
- package/lib/cjs/timeline.js.map +1 -0
- package/lib/mjs/InMemoryPerfSink.d.ts +51 -0
- package/lib/mjs/InMemoryPerfSink.d.ts.map +1 -0
- package/lib/mjs/InMemoryPerfSink.js +97 -0
- package/lib/mjs/InMemoryPerfSink.js.map +1 -0
- package/lib/mjs/PromMetricSink.d.ts +26 -0
- package/lib/mjs/PromMetricSink.d.ts.map +1 -0
- package/lib/mjs/PromMetricSink.js +65 -0
- package/lib/mjs/PromMetricSink.js.map +1 -0
- package/lib/mjs/bootstrap.d.ts +13 -0
- package/lib/mjs/bootstrap.d.ts.map +1 -0
- package/lib/mjs/bootstrap.js +54 -0
- package/lib/mjs/bootstrap.js.map +1 -0
- package/lib/mjs/config/telemetry.d.ts +63 -0
- package/lib/mjs/config/telemetry.d.ts.map +1 -0
- package/lib/mjs/config/telemetry.js +76 -0
- package/lib/mjs/config/telemetry.js.map +1 -0
- package/lib/mjs/controllers/Metrics.d.ts +26 -0
- package/lib/mjs/controllers/Metrics.d.ts.map +1 -0
- package/lib/mjs/controllers/Metrics.js +60 -0
- package/lib/mjs/controllers/Metrics.js.map +1 -0
- package/lib/mjs/controllers/Telemetry.d.ts +92 -0
- package/lib/mjs/controllers/Telemetry.d.ts.map +1 -0
- package/lib/mjs/controllers/Telemetry.js +223 -0
- package/lib/mjs/controllers/Telemetry.js.map +1 -0
- package/lib/mjs/dto/index.d.ts +21 -0
- package/lib/mjs/dto/index.d.ts.map +1 -0
- package/lib/mjs/dto/index.js +58 -0
- package/lib/mjs/dto/index.js.map +1 -0
- package/lib/mjs/endpoints.d.ts +32 -0
- package/lib/mjs/endpoints.d.ts.map +1 -0
- package/lib/mjs/endpoints.js +34 -0
- package/lib/mjs/endpoints.js.map +1 -0
- package/lib/mjs/health.d.ts +55 -0
- package/lib/mjs/health.d.ts.map +1 -0
- package/lib/mjs/health.js +107 -0
- package/lib/mjs/health.js.map +1 -0
- package/lib/mjs/index.d.ts +16 -0
- package/lib/mjs/index.d.ts.map +1 -0
- package/lib/mjs/index.js +16 -0
- package/lib/mjs/index.js.map +1 -0
- package/lib/mjs/metrics.d.ts +16 -0
- package/lib/mjs/metrics.d.ts.map +1 -0
- package/lib/mjs/metrics.js +16 -0
- package/lib/mjs/metrics.js.map +1 -0
- package/lib/mjs/middleware.d.ts +81 -0
- package/lib/mjs/middleware.d.ts.map +1 -0
- package/lib/mjs/middleware.js +207 -0
- package/lib/mjs/middleware.js.map +1 -0
- package/lib/mjs/package.json +1 -0
- package/lib/mjs/policies/PublicPolicy.d.ts +16 -0
- package/lib/mjs/policies/PublicPolicy.d.ts.map +1 -0
- package/lib/mjs/policies/PublicPolicy.js +31 -0
- package/lib/mjs/policies/PublicPolicy.js.map +1 -0
- package/lib/mjs/policies/TelemetryTokenPolicy.d.ts +19 -0
- package/lib/mjs/policies/TelemetryTokenPolicy.d.ts.map +1 -0
- package/lib/mjs/policies/TelemetryTokenPolicy.js +62 -0
- package/lib/mjs/policies/TelemetryTokenPolicy.js.map +1 -0
- package/lib/mjs/requestStats.d.ts +81 -0
- package/lib/mjs/requestStats.d.ts.map +1 -0
- package/lib/mjs/requestStats.js +130 -0
- package/lib/mjs/requestStats.js.map +1 -0
- package/lib/mjs/responses.d.ts +23 -0
- package/lib/mjs/responses.d.ts.map +1 -0
- package/lib/mjs/responses.js +30 -0
- package/lib/mjs/responses.js.map +1 -0
- package/lib/mjs/routeStats.d.ts +43 -0
- package/lib/mjs/routeStats.d.ts.map +1 -0
- package/lib/mjs/routeStats.js +55 -0
- package/lib/mjs/routeStats.js.map +1 -0
- package/lib/mjs/schemas/HealthResponse.schema.d.ts +30 -0
- package/lib/mjs/schemas/HealthResponse.schema.d.ts.map +1 -0
- package/lib/mjs/schemas/HealthResponse.schema.js +13 -0
- package/lib/mjs/schemas/HealthResponse.schema.js.map +1 -0
- package/lib/mjs/schemas/PerfResponse.schema.d.ts +56 -0
- package/lib/mjs/schemas/PerfResponse.schema.d.ts.map +1 -0
- package/lib/mjs/schemas/PerfResponse.schema.js +34 -0
- package/lib/mjs/schemas/PerfResponse.schema.js.map +1 -0
- package/lib/mjs/schemas/ReadyResponse.schema.d.ts +36 -0
- package/lib/mjs/schemas/ReadyResponse.schema.d.ts.map +1 -0
- package/lib/mjs/schemas/ReadyResponse.schema.js +21 -0
- package/lib/mjs/schemas/ReadyResponse.schema.js.map +1 -0
- package/lib/mjs/schemas/RequestStatsSnapshot.schema.d.ts +79 -0
- package/lib/mjs/schemas/RequestStatsSnapshot.schema.d.ts.map +1 -0
- package/lib/mjs/schemas/RequestStatsSnapshot.schema.js +28 -0
- package/lib/mjs/schemas/RequestStatsSnapshot.schema.js.map +1 -0
- package/lib/mjs/schemas/RoutesResponse.schema.d.ts +100 -0
- package/lib/mjs/schemas/RoutesResponse.schema.d.ts.map +1 -0
- package/lib/mjs/schemas/RoutesResponse.schema.js +20 -0
- package/lib/mjs/schemas/RoutesResponse.schema.js.map +1 -0
- package/lib/mjs/schemas/StatsResponse.schema.d.ts +158 -0
- package/lib/mjs/schemas/StatsResponse.schema.d.ts.map +1 -0
- package/lib/mjs/schemas/StatsResponse.schema.js +14 -0
- package/lib/mjs/schemas/StatsResponse.schema.js.map +1 -0
- package/lib/mjs/schemas/TimelineResponse.schema.d.ts +109 -0
- package/lib/mjs/schemas/TimelineResponse.schema.d.ts.map +1 -0
- package/lib/mjs/schemas/TimelineResponse.schema.js +23 -0
- package/lib/mjs/schemas/TimelineResponse.schema.js.map +1 -0
- package/lib/mjs/store.d.ts +58 -0
- package/lib/mjs/store.d.ts.map +1 -0
- package/lib/mjs/store.js +105 -0
- package/lib/mjs/store.js.map +1 -0
- package/lib/mjs/timeline.d.ts +48 -0
- package/lib/mjs/timeline.d.ts.map +1 -0
- package/lib/mjs/timeline.js +66 -0
- package/lib/mjs/timeline.js.map +1 -0
- package/lib/tsconfig.cjs.tsbuildinfo +1 -0
- package/lib/tsconfig.mjs.tsbuildinfo +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { IRequestStatsSnapshot } from './requestStats.js';
|
|
2
|
+
/**
|
|
3
|
+
* Serializable snapshot of a {@link Timeline}: a map of bucket-key -> stats.
|
|
4
|
+
*/
|
|
5
|
+
export type ITimelineSnapshot = Record<string, IRequestStatsSnapshot>;
|
|
6
|
+
/**
|
|
7
|
+
* Port of swagger-stats' `swsTimeline` — a rolling ring of `length` buckets,
|
|
8
|
+
* each spanning `bucketMs`, keyed by `floor(timestamp / bucketMs)`. Each bucket
|
|
9
|
+
* holds its own {@link RequestStats}.
|
|
10
|
+
*
|
|
11
|
+
* Deterministic: every method takes the current timestamp so tests can drive
|
|
12
|
+
* it without touching the real clock.
|
|
13
|
+
*/
|
|
14
|
+
export declare class Timeline {
|
|
15
|
+
/**
|
|
16
|
+
* Number of buckets retained in the ring.
|
|
17
|
+
*/
|
|
18
|
+
readonly length: number;
|
|
19
|
+
/**
|
|
20
|
+
* Bucket width in milliseconds.
|
|
21
|
+
*/
|
|
22
|
+
readonly bucketMs: number;
|
|
23
|
+
/**
|
|
24
|
+
* Apdex threshold ( ms ) propagated to each bucket's RequestStats.
|
|
25
|
+
*/
|
|
26
|
+
readonly apdexThreshold: number;
|
|
27
|
+
private buckets;
|
|
28
|
+
constructor(length?: number, bucketMs?: number, apdexThreshold?: number);
|
|
29
|
+
/**
|
|
30
|
+
* The bucket key for a timestamp.
|
|
31
|
+
*/
|
|
32
|
+
keyFor(timestamp: number): number;
|
|
33
|
+
private ensureBucket;
|
|
34
|
+
/**
|
|
35
|
+
* Open the bucket for `now` and expire buckets older than `length` buckets.
|
|
36
|
+
*/
|
|
37
|
+
tick(now?: number): void;
|
|
38
|
+
/**
|
|
39
|
+
* Route a completed response into the bucket for its timestamp ( ticking to
|
|
40
|
+
* open the current bucket + expire old ones first ).
|
|
41
|
+
*/
|
|
42
|
+
record(statusCode: number, durationMs: number, timestamp?: number): void;
|
|
43
|
+
/**
|
|
44
|
+
* A plain-object snapshot of every live bucket, keyed by bucket key.
|
|
45
|
+
*/
|
|
46
|
+
toJSON(): ITimelineSnapshot;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/timeline.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAgB,MAAM,mBAAmB,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;AAKtE;;;;;;;GAOG;AACH,qBAAa,QAAQ;IACnB;;OAEG;IACH,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,SAAgB,QAAQ,EAAE,MAAM,CAAC;IAEjC;;OAEG;IACH,SAAgB,cAAc,EAAE,MAAM,CAAC;IAEvC,OAAO,CAAC,OAAO,CAAmC;gBAEtC,MAAM,GAAE,MAAuB,EAAE,QAAQ,GAAE,MAA0B,EAAE,cAAc,CAAC,EAAE,MAAM;IAM1G;;OAEG;IACI,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAIxC,OAAO,CAAC,YAAY;IASpB;;OAEG;IACI,IAAI,CAAC,GAAG,GAAE,MAAmB,GAAG,IAAI;IAU3C;;;OAGG;IACI,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,GAAE,MAAmB,GAAG,IAAI;IAO3F;;OAEG;IACI,MAAM,IAAI,iBAAiB;CAOnC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Timeline = void 0;
|
|
4
|
+
const requestStats_js_1 = require("./requestStats.js");
|
|
5
|
+
const DEFAULT_LENGTH = 60;
|
|
6
|
+
const DEFAULT_BUCKET_MS = 60_000;
|
|
7
|
+
/**
|
|
8
|
+
* Port of swagger-stats' `swsTimeline` — a rolling ring of `length` buckets,
|
|
9
|
+
* each spanning `bucketMs`, keyed by `floor(timestamp / bucketMs)`. Each bucket
|
|
10
|
+
* holds its own {@link RequestStats}.
|
|
11
|
+
*
|
|
12
|
+
* Deterministic: every method takes the current timestamp so tests can drive
|
|
13
|
+
* it without touching the real clock.
|
|
14
|
+
*/
|
|
15
|
+
class Timeline {
|
|
16
|
+
constructor(length = DEFAULT_LENGTH, bucketMs = DEFAULT_BUCKET_MS, apdexThreshold) {
|
|
17
|
+
this.buckets = new Map();
|
|
18
|
+
this.length = length;
|
|
19
|
+
this.bucketMs = bucketMs;
|
|
20
|
+
this.apdexThreshold = apdexThreshold ?? new requestStats_js_1.RequestStats().apdexThreshold;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The bucket key for a timestamp.
|
|
24
|
+
*/
|
|
25
|
+
keyFor(timestamp) {
|
|
26
|
+
return Math.floor(timestamp / this.bucketMs);
|
|
27
|
+
}
|
|
28
|
+
ensureBucket(key) {
|
|
29
|
+
let bucket = this.buckets.get(key);
|
|
30
|
+
if (!bucket) {
|
|
31
|
+
bucket = new requestStats_js_1.RequestStats(this.apdexThreshold);
|
|
32
|
+
this.buckets.set(key, bucket);
|
|
33
|
+
}
|
|
34
|
+
return bucket;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Open the bucket for `now` and expire buckets older than `length` buckets.
|
|
38
|
+
*/
|
|
39
|
+
tick(now = Date.now()) {
|
|
40
|
+
const current = this.keyFor(now);
|
|
41
|
+
this.ensureBucket(current);
|
|
42
|
+
const oldest = current - this.length + 1;
|
|
43
|
+
for (const key of [...this.buckets.keys()]) {
|
|
44
|
+
if (key < oldest)
|
|
45
|
+
this.buckets.delete(key);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Route a completed response into the bucket for its timestamp ( ticking to
|
|
50
|
+
* open the current bucket + expire old ones first ).
|
|
51
|
+
*/
|
|
52
|
+
record(statusCode, durationMs, timestamp = Date.now()) {
|
|
53
|
+
this.tick(timestamp);
|
|
54
|
+
const bucket = this.ensureBucket(this.keyFor(timestamp));
|
|
55
|
+
bucket.countRequest();
|
|
56
|
+
bucket.countResponse(statusCode, durationMs);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A plain-object snapshot of every live bucket, keyed by bucket key.
|
|
60
|
+
*/
|
|
61
|
+
toJSON() {
|
|
62
|
+
const out = {};
|
|
63
|
+
for (const [key, stats] of this.buckets) {
|
|
64
|
+
out[String(key)] = stats.toJSON();
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.Timeline = Timeline;
|
|
70
|
+
//# sourceMappingURL=timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.js","sourceRoot":"","sources":["../../src/timeline.ts"],"names":[],"mappings":";;;AAAA,uDAAwE;AAOxE,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC;;;;;;;GAOG;AACH,MAAa,QAAQ;IAkBnB,YAAY,SAAiB,cAAc,EAAE,WAAmB,iBAAiB,EAAE,cAAuB;QAFlG,YAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;QAGhD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,cAAc,IAAI,IAAI,8BAAY,EAAE,CAAC,cAAc,CAAC;IAC5E,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,SAAiB;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAEO,YAAY,CAAC,GAAW;QAC9B,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,8BAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC/C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,IAAI,CAAC,MAAc,IAAI,CAAC,GAAG,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAE3B,MAAM,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QACzC,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC3C,IAAI,GAAG,GAAG,MAAM;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,UAAkB,EAAE,UAAkB,EAAE,YAAoB,IAAI,CAAC,GAAG,EAAE;QAClF,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,YAAY,EAAE,CAAC;QACtB,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACI,MAAM;QACX,MAAM,GAAG,GAAsB,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACxC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACpC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AA1ED,4BA0EC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { PerfSink, IPerfMetric } from '@spinajs/log';
|
|
2
|
+
/** One aggregated span row. */
|
|
3
|
+
export interface IPerfSpanEntry {
|
|
4
|
+
name: string;
|
|
5
|
+
count: number;
|
|
6
|
+
totalMs: number;
|
|
7
|
+
avgMs: number;
|
|
8
|
+
maxMs: number;
|
|
9
|
+
}
|
|
10
|
+
/** One aggregated counter / value row. */
|
|
11
|
+
export interface IPerfEventEntry {
|
|
12
|
+
name: string;
|
|
13
|
+
count: number;
|
|
14
|
+
total: number;
|
|
15
|
+
}
|
|
16
|
+
/** Serializable snapshot served by `GET /telemetry/perf`. */
|
|
17
|
+
export interface IPerfSnapshot {
|
|
18
|
+
/** True once the name cap was hit and new names stopped being tracked. */
|
|
19
|
+
truncated: boolean;
|
|
20
|
+
spans: IPerfSpanEntry[];
|
|
21
|
+
events: IPerfEventEntry[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A {@link PerfSink} that keeps a bounded, JSON-readable aggregate of every
|
|
25
|
+
* measurement, backing `GET /telemetry/perf`.
|
|
26
|
+
*
|
|
27
|
+
* This exists alongside `PromMetricSink` rather than replacing it: prom
|
|
28
|
+
* histograms are the right shape for Prometheus but their bucket counts cannot
|
|
29
|
+
* be read back as a mean or a max, which is what a JSON snapshot needs.
|
|
30
|
+
*
|
|
31
|
+
* Per-request rollups are intentionally NOT implemented here — `onScopeEnd`
|
|
32
|
+
* totals share the span names, so folding them in would double-count against
|
|
33
|
+
* the same rows. The per-request view lives in `perf_scope_total_ms` on the
|
|
34
|
+
* prometheus side.
|
|
35
|
+
*/
|
|
36
|
+
export declare class InMemoryPerfSink extends PerfSink {
|
|
37
|
+
protected Enabled: boolean;
|
|
38
|
+
protected MaxNames: number;
|
|
39
|
+
private spans;
|
|
40
|
+
private events;
|
|
41
|
+
private truncated;
|
|
42
|
+
collect(metric: IPerfMetric): void;
|
|
43
|
+
toJSON(): IPerfSnapshot;
|
|
44
|
+
/**
|
|
45
|
+
* Whether a NEW name may be tracked. Spans and events share one budget so the
|
|
46
|
+
* total retained-name count is what `maxNames` bounds.
|
|
47
|
+
*/
|
|
48
|
+
private track;
|
|
49
|
+
private create;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=InMemoryPerfSink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InMemoryPerfSink.d.ts","sourceRoot":"","sources":["../../src/InMemoryPerfSink.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAErD,+BAA+B;AAC/B,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,qBAEa,gBAAiB,SAAQ,QAAQ;IAE5C,SAAS,CAAC,OAAO,EAAG,OAAO,CAAC;IAG5B,SAAS,CAAC,QAAQ,EAAG,MAAM,CAAC;IAE5B,OAAO,CAAC,KAAK,CAAwE;IACrF,OAAO,CAAC,MAAM,CAAuD;IACrE,OAAO,CAAC,SAAS,CAAS;IAEnB,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAsBlC,MAAM,IAAI,aAAa;IAgB9B;;;OAGG;IACH,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,MAAM;CAIf"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Singleton, Injectable } from '@spinajs/di';
|
|
11
|
+
import { Config } from '@spinajs/configuration';
|
|
12
|
+
import { PerfSink } from '@spinajs/log';
|
|
13
|
+
/**
|
|
14
|
+
* A {@link PerfSink} that keeps a bounded, JSON-readable aggregate of every
|
|
15
|
+
* measurement, backing `GET /telemetry/perf`.
|
|
16
|
+
*
|
|
17
|
+
* This exists alongside `PromMetricSink` rather than replacing it: prom
|
|
18
|
+
* histograms are the right shape for Prometheus but their bucket counts cannot
|
|
19
|
+
* be read back as a mean or a max, which is what a JSON snapshot needs.
|
|
20
|
+
*
|
|
21
|
+
* Per-request rollups are intentionally NOT implemented here — `onScopeEnd`
|
|
22
|
+
* totals share the span names, so folding them in would double-count against
|
|
23
|
+
* the same rows. The per-request view lives in `perf_scope_total_ms` on the
|
|
24
|
+
* prometheus side.
|
|
25
|
+
*/
|
|
26
|
+
let InMemoryPerfSink = class InMemoryPerfSink extends PerfSink {
|
|
27
|
+
constructor() {
|
|
28
|
+
super(...arguments);
|
|
29
|
+
this.spans = new Map();
|
|
30
|
+
this.events = new Map();
|
|
31
|
+
this.truncated = false;
|
|
32
|
+
}
|
|
33
|
+
collect(metric) {
|
|
34
|
+
if (this.Enabled === false)
|
|
35
|
+
return;
|
|
36
|
+
if (!metric || typeof metric.name !== 'string')
|
|
37
|
+
return;
|
|
38
|
+
if (metric.kind === 'span') {
|
|
39
|
+
const entry = this.spans.get(metric.name) ?? (this.track(metric.name) ? this.create(this.spans, metric.name, { count: 0, totalMs: 0, maxMs: 0 }) : undefined);
|
|
40
|
+
if (!entry)
|
|
41
|
+
return;
|
|
42
|
+
const durationMs = metric.durationMs ?? 0;
|
|
43
|
+
entry.count += 1;
|
|
44
|
+
entry.totalMs += durationMs;
|
|
45
|
+
if (durationMs > entry.maxMs)
|
|
46
|
+
entry.maxMs = durationMs;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const entry = this.events.get(metric.name) ?? (this.track(metric.name) ? this.create(this.events, metric.name, { count: 0, total: 0 }) : undefined);
|
|
50
|
+
if (!entry)
|
|
51
|
+
return;
|
|
52
|
+
entry.count += 1;
|
|
53
|
+
entry.total += metric.value ?? 1;
|
|
54
|
+
}
|
|
55
|
+
toJSON() {
|
|
56
|
+
const spans = [];
|
|
57
|
+
for (const [name, e] of this.spans) {
|
|
58
|
+
spans.push({ name, count: e.count, totalMs: e.totalMs, avgMs: e.count > 0 ? e.totalMs / e.count : 0, maxMs: e.maxMs });
|
|
59
|
+
}
|
|
60
|
+
spans.sort((a, b) => b.totalMs - a.totalMs);
|
|
61
|
+
const events = [];
|
|
62
|
+
for (const [name, e] of this.events) {
|
|
63
|
+
events.push({ name, count: e.count, total: e.total });
|
|
64
|
+
}
|
|
65
|
+
events.sort((a, b) => b.total - a.total);
|
|
66
|
+
return { truncated: this.truncated, spans, events };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Whether a NEW name may be tracked. Spans and events share one budget so the
|
|
70
|
+
* total retained-name count is what `maxNames` bounds.
|
|
71
|
+
*/
|
|
72
|
+
track(_name) {
|
|
73
|
+
if (this.spans.size + this.events.size >= (this.MaxNames ?? 200)) {
|
|
74
|
+
this.truncated = true;
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
create(map, name, initial) {
|
|
80
|
+
map.set(name, initial);
|
|
81
|
+
return initial;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
__decorate([
|
|
85
|
+
Config('telemetry.perf.enabled', { defaultValue: true }),
|
|
86
|
+
__metadata("design:type", Boolean)
|
|
87
|
+
], InMemoryPerfSink.prototype, "Enabled", void 0);
|
|
88
|
+
__decorate([
|
|
89
|
+
Config('telemetry.perf.maxNames', { defaultValue: 200 }),
|
|
90
|
+
__metadata("design:type", Number)
|
|
91
|
+
], InMemoryPerfSink.prototype, "MaxNames", void 0);
|
|
92
|
+
InMemoryPerfSink = __decorate([
|
|
93
|
+
Singleton(),
|
|
94
|
+
Injectable(PerfSink)
|
|
95
|
+
], InMemoryPerfSink);
|
|
96
|
+
export { InMemoryPerfSink };
|
|
97
|
+
//# sourceMappingURL=InMemoryPerfSink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InMemoryPerfSink.js","sourceRoot":"","sources":["../../src/InMemoryPerfSink.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { PerfSink, IPerfMetric, IPerfRollup } from "@spinajs/log";
|
|
2
|
+
import { Counter, Histogram } from "prom-client";
|
|
3
|
+
import { Metrics } from "./metrics.js";
|
|
4
|
+
/** Duration histogram buckets ( ms ), mirroring the http telemetry middleware. */
|
|
5
|
+
export declare const PERF_DURATION_BUCKETS_MS: number[];
|
|
6
|
+
/**
|
|
7
|
+
* {@link PerfSink} that forwards perf measurements to the shared prom-client
|
|
8
|
+
* {@link Metrics} registry — the prom side of the dual-sink. Span durations go
|
|
9
|
+
* to `perf_span_duration_ms{name}`; counter/value events increment
|
|
10
|
+
* `perf_events_total{name}`; per-request scope totals go to their own
|
|
11
|
+
* `perf_scope_total_ms{name}` histogram so they don't conflate with the
|
|
12
|
+
* per-span distribution. Labels are restricted to `name` ( plus the metric's
|
|
13
|
+
* own low-cardinality labels are folded into the name label space via a single
|
|
14
|
+
* `name` label to stay bounded ).
|
|
15
|
+
*/
|
|
16
|
+
export declare class PromMetricSink extends PerfSink {
|
|
17
|
+
protected metrics: Metrics;
|
|
18
|
+
protected duration: Histogram<string>;
|
|
19
|
+
protected events: Counter<string>;
|
|
20
|
+
protected scopeTotal: Histogram<string>;
|
|
21
|
+
private defined;
|
|
22
|
+
private ensure;
|
|
23
|
+
collect(metric: IPerfMetric): void;
|
|
24
|
+
onScopeEnd(rollup: IPerfRollup): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=PromMetricSink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromMetricSink.d.ts","sourceRoot":"","sources":["../../src/PromMetricSink.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,OAAO,EAAa,MAAM,cAAc,CAAC;AAElD,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,UAA6D,CAAC;AAEnG;;;;;;;;;GASG;AACH,qBAEa,cAAe,SAAQ,QAAQ;IAC1C,SAAS,CAAC,OAAO,EAAG,OAAO,CAAC;IAC5B,SAAS,CAAC,QAAQ,EAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACvC,SAAS,CAAC,MAAM,EAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnC,SAAS,CAAC,UAAU,EAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,MAAM;IAcP,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IASlC,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;CAQ7C"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Singleton, Injectable, DI } from "@spinajs/di";
|
|
8
|
+
import { PerfSink } from "@spinajs/log";
|
|
9
|
+
import { Metrics } from "./metrics.js";
|
|
10
|
+
/** Duration histogram buckets ( ms ), mirroring the http telemetry middleware. */
|
|
11
|
+
export const PERF_DURATION_BUCKETS_MS = [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000];
|
|
12
|
+
/**
|
|
13
|
+
* {@link PerfSink} that forwards perf measurements to the shared prom-client
|
|
14
|
+
* {@link Metrics} registry — the prom side of the dual-sink. Span durations go
|
|
15
|
+
* to `perf_span_duration_ms{name}`; counter/value events increment
|
|
16
|
+
* `perf_events_total{name}`; per-request scope totals go to their own
|
|
17
|
+
* `perf_scope_total_ms{name}` histogram so they don't conflate with the
|
|
18
|
+
* per-span distribution. Labels are restricted to `name` ( plus the metric's
|
|
19
|
+
* own low-cardinality labels are folded into the name label space via a single
|
|
20
|
+
* `name` label to stay bounded ).
|
|
21
|
+
*/
|
|
22
|
+
let PromMetricSink = class PromMetricSink extends PerfSink {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
this.defined = false;
|
|
26
|
+
}
|
|
27
|
+
ensure() {
|
|
28
|
+
if (this.defined)
|
|
29
|
+
return;
|
|
30
|
+
this.metrics = DI.get(Metrics) ?? DI.resolve(Metrics);
|
|
31
|
+
const map = this.metrics.defineMetrics("perf", [
|
|
32
|
+
{ name: "span_duration_ms", help: "Perf span duration in ms", type: "histogram", labelNames: ["name"], buckets: PERF_DURATION_BUCKETS_MS },
|
|
33
|
+
{ name: "events_total", help: "Perf counter/value events", type: "counter", labelNames: ["name"] },
|
|
34
|
+
{ name: "scope_total_ms", help: "Perf per-request scope total duration in ms", type: "histogram", labelNames: ["name"], buckets: PERF_DURATION_BUCKETS_MS },
|
|
35
|
+
]);
|
|
36
|
+
this.duration = map["span_duration_ms"];
|
|
37
|
+
this.events = map["events_total"];
|
|
38
|
+
this.scopeTotal = map["scope_total_ms"];
|
|
39
|
+
this.defined = true;
|
|
40
|
+
}
|
|
41
|
+
collect(metric) {
|
|
42
|
+
this.ensure();
|
|
43
|
+
if (metric.kind === "span") {
|
|
44
|
+
this.duration.observe({ name: metric.name }, metric.durationMs ?? 0);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.events.inc({ name: metric.name }, metric.value ?? 1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
onScopeEnd(rollup) {
|
|
51
|
+
this.ensure();
|
|
52
|
+
for (const [name, e] of Object.entries(rollup.byName)) {
|
|
53
|
+
// per-request totals: record the aggregate duration once per request, into
|
|
54
|
+
// its own histogram so it doesn't conflate with the per-span distribution.
|
|
55
|
+
if (e.totalMs > 0)
|
|
56
|
+
this.scopeTotal.observe({ name }, e.totalMs);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
PromMetricSink = __decorate([
|
|
61
|
+
Singleton(),
|
|
62
|
+
Injectable(PerfSink)
|
|
63
|
+
], PromMetricSink);
|
|
64
|
+
export { PromMetricSink };
|
|
65
|
+
//# sourceMappingURL=PromMetricSink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PromMetricSink.js","sourceRoot":"","sources":["../../src/PromMetricSink.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,QAAQ,EAA4B,MAAM,cAAc,CAAC;AAElE,OAAO,EAAE,OAAO,EAAa,MAAM,cAAc,CAAC;AAElD,kFAAkF;AAClF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAEnG;;;;;;;;;GASG;AAGI,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,QAAQ;IAArC;;QAKG,YAAO,GAAG,KAAK,CAAC;IAiC1B,CAAC;IA/BS,MAAM;QACZ,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,GAAG,GAAc,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE;YACxD,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,0BAA0B,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE;YAC1I,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,2BAA2B,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE;YAClG,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,6CAA6C,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE;SAC5J,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,kBAAkB,CAAsB,CAAC;QAC7D,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,cAAc,CAAoB,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,gBAAgB,CAAsB,CAAC;QAC7D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAEM,OAAO,CAAC,MAAmB;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC;QACvE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAEM,UAAU,CAAC,MAAmB;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACtD,2EAA2E;YAC3E,2EAA2E;YAC3E,IAAI,CAAC,CAAC,OAAO,GAAG,CAAC;gBAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;CACF,CAAA;AAtCY,cAAc;IAF1B,SAAS,EAAE;IACX,UAAU,CAAC,QAAQ,CAAC;GACR,cAAc,CAsC1B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Bootstrapper } from '@spinajs/di';
|
|
2
|
+
/**
|
|
3
|
+
* Wires the telemetry collection layer at startup:
|
|
4
|
+
*
|
|
5
|
+
* - registers prom-client's default process metrics against the PRIVATE
|
|
6
|
+
* registry ( never the global default one ), when configured,
|
|
7
|
+
* - builds the perf sinks and refreshes the Perf facade's sink list, so the
|
|
8
|
+
* perf bridge is live in apps that use telemetry WITHOUT @spinajs/http.
|
|
9
|
+
*/
|
|
10
|
+
export declare class TelemetryBootstrapper extends Bootstrapper {
|
|
11
|
+
bootstrap(): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAM,MAAM,aAAa,CAAC;AAM3D;;;;;;;GAOG;AACH,qBACa,qBAAsB,SAAQ,YAAY;IAC9C,SAAS,IAAI,IAAI;CAiCzB"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { Injectable, Bootstrapper, DI } from '@spinajs/di';
|
|
8
|
+
import { Configuration } from '@spinajs/configuration';
|
|
9
|
+
import { Perf, PerfSink } from '@spinajs/log';
|
|
10
|
+
import { Metrics } from './metrics.js';
|
|
11
|
+
/**
|
|
12
|
+
* Wires the telemetry collection layer at startup:
|
|
13
|
+
*
|
|
14
|
+
* - registers prom-client's default process metrics against the PRIVATE
|
|
15
|
+
* registry ( never the global default one ), when configured,
|
|
16
|
+
* - builds the perf sinks and refreshes the Perf facade's sink list, so the
|
|
17
|
+
* perf bridge is live in apps that use telemetry WITHOUT @spinajs/http.
|
|
18
|
+
*/
|
|
19
|
+
let TelemetryBootstrapper = class TelemetryBootstrapper extends Bootstrapper {
|
|
20
|
+
bootstrap() {
|
|
21
|
+
const cfg = DI.get(Configuration);
|
|
22
|
+
const metrics = DI.get(Metrics) ?? DI.resolve(Metrics);
|
|
23
|
+
if (cfg?.get('telemetry.collectDefaultMetrics', true)) {
|
|
24
|
+
metrics.collectDefault();
|
|
25
|
+
}
|
|
26
|
+
// Build the sinks through the ARRAY, never with a direct
|
|
27
|
+
// `DI.resolve( PromMetricSink )`. A direct resolve caches the instance under
|
|
28
|
+
// its own type name only; the later `Array.ofType( PerfSink )` — which is
|
|
29
|
+
// what the Perf facade uses — then hits that cache entry on its fast path,
|
|
30
|
+
// returns it WITHOUT adding it to the `PerfSink` list, and the facade stays
|
|
31
|
+
// blind to that sink. Resolving the array first creates them together.
|
|
32
|
+
const sinks = DI.resolve(Array.ofType(PerfSink));
|
|
33
|
+
// The array cache does not double as a per-type cache, so publish each
|
|
34
|
+
// instance under its own type name too. Without this a later
|
|
35
|
+
// `@Autoinject( InMemoryPerfSink )` ( the telemetry controller does exactly
|
|
36
|
+
// that ) would build a SECOND, permanently empty sink.
|
|
37
|
+
//
|
|
38
|
+
// `override` MUST be true: without it `asValue` APPENDS to an existing cache
|
|
39
|
+
// entry instead of replacing it, while the resolve fast path keeps handing
|
|
40
|
+
// out the entry it already had. So anything that resolved a sink directly
|
|
41
|
+
// BEFORE this bootstrapper ran — an earlier-ordered consumer bootstrapper,
|
|
42
|
+
// or an app still calling `DI.resolve( PromMetricSink )` — would pin
|
|
43
|
+
// `@Autoinject` to that earlier, permanently empty instance.
|
|
44
|
+
for (const sink of sinks) {
|
|
45
|
+
DI.register(sink).asValue(sink.constructor.name, true);
|
|
46
|
+
}
|
|
47
|
+
Perf.refreshSinks();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
TelemetryBootstrapper = __decorate([
|
|
51
|
+
Injectable(Bootstrapper)
|
|
52
|
+
], TelemetryBootstrapper);
|
|
53
|
+
export { TelemetryBootstrapper };
|
|
54
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/bootstrap.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;;;;;GAOG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,YAAY;IAC9C,SAAS;QACd,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEvD,IAAI,GAAG,EAAE,GAAG,CAAU,iCAAiC,EAAE,IAAI,CAAC,EAAE,CAAC;YAC/D,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,CAAC;QAED,yDAAyD;QACzD,6EAA6E;QAC7E,0EAA0E;QAC1E,2EAA2E;QAC3E,4EAA4E;QAC5E,uEAAuE;QACvE,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEjD,uEAAuE;QACvE,6DAA6D;QAC7D,4EAA4E;QAC5E,uDAAuD;QACvD,EAAE;QACF,6EAA6E;QAC7E,2EAA2E;QAC3E,0EAA0E;QAC1E,2EAA2E;QAC3E,qEAAqE;QACrE,6DAA6D;QAC7D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;CACF,CAAA;AAlCY,qBAAqB;IADjC,UAAU,CAAC,YAAY,CAAC;GACZ,qBAAqB,CAkCjC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
declare const config: {
|
|
2
|
+
system: {
|
|
3
|
+
dirs: {
|
|
4
|
+
controllers: string[];
|
|
5
|
+
};
|
|
6
|
+
};
|
|
7
|
+
telemetry: {
|
|
8
|
+
auth: {
|
|
9
|
+
token: string;
|
|
10
|
+
/**
|
|
11
|
+
* Policy class name per endpoint. Each route resolves its policy by
|
|
12
|
+
* reading the config key below, so access can be tightened or loosened
|
|
13
|
+
* per endpoint without touching code.
|
|
14
|
+
*/
|
|
15
|
+
policies: {
|
|
16
|
+
metrics: string;
|
|
17
|
+
stats: string;
|
|
18
|
+
timeline: string;
|
|
19
|
+
routes: string;
|
|
20
|
+
perf: string;
|
|
21
|
+
health: string;
|
|
22
|
+
ready: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Register prom-client's process / heap / cpu / event-loop metrics against
|
|
27
|
+
* the private registry at bootstrap.
|
|
28
|
+
*/
|
|
29
|
+
collectDefaultMetrics: boolean;
|
|
30
|
+
/** Metric name prefix for the http telemetry metrics. */
|
|
31
|
+
prefix: string;
|
|
32
|
+
/** Duration histogram buckets in ms. */
|
|
33
|
+
buckets: number[];
|
|
34
|
+
/** Apdex satisfied threshold in ms; tolerated is 4x this. */
|
|
35
|
+
apdexThresholdMs: number;
|
|
36
|
+
timeline: {
|
|
37
|
+
/** Number of buckets retained in the ring. */
|
|
38
|
+
length: number;
|
|
39
|
+
/** Bucket width in ms. */
|
|
40
|
+
bucketMs: number;
|
|
41
|
+
};
|
|
42
|
+
routes: {
|
|
43
|
+
enabled: boolean;
|
|
44
|
+
/** Cap on distinct method+route keys held in memory. */
|
|
45
|
+
maxEntries: number;
|
|
46
|
+
};
|
|
47
|
+
perf: {
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
/** Cap on distinct perf measurement names held in memory. */
|
|
50
|
+
maxNames: number;
|
|
51
|
+
};
|
|
52
|
+
health: {
|
|
53
|
+
/** Per-check timeout in ms. A timed-out check counts as down. */
|
|
54
|
+
timeoutMs: number;
|
|
55
|
+
/** When true a degraded overall status returns 503 rather than 200. */
|
|
56
|
+
failOnDegraded: boolean;
|
|
57
|
+
/** Reported by /telemetry/health. Omitted from the response when unset. */
|
|
58
|
+
version: string | undefined;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
export default config;
|
|
63
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../../src/config/telemetry.ts"],"names":[],"mappings":"AAcA,QAAA,MAAM,MAAM;;;;;;;;;YAYN;;;;eAIG;;;;;;;;;;;QAcL;;;WAGG;;QAGH,yDAAyD;;QAGzD,wCAAwC;;QAGxC,6DAA6D;;;YAI3D,8CAA8C;;YAE9C,0BAA0B;;;;;YAM1B,wDAAwD;;;;;YAMxD,6DAA6D;;;;YAK7D,iEAAiE;;YAEjE,uEAAuE;;YAEvE,2EAA2E;qBACrD,MAAM,GAAG,SAAS;;;CAG7C,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { join, normalize, resolve } from 'path';
|
|
2
|
+
function dir(path) {
|
|
3
|
+
const inCommonJs = typeof module !== 'undefined';
|
|
4
|
+
return resolve(normalize(join(process.env.WORKSPACE_ROOT_PATH ?? process.cwd(), 'node_modules', '@spinajs', 'telemetry', 'lib', inCommonJs ? 'cjs' : 'mjs', path)));
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Duration histogram bucket boundaries ( ms ) for http request timing. Kept in
|
|
8
|
+
* sync with DURATION_BUCKETS_MS in middleware.ts, which is the compile-time
|
|
9
|
+
* default when no configuration is present.
|
|
10
|
+
*/
|
|
11
|
+
const DURATION_BUCKETS_MS = [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000];
|
|
12
|
+
const config = {
|
|
13
|
+
system: {
|
|
14
|
+
dirs: {
|
|
15
|
+
controllers: [dir('controllers')],
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
telemetry: {
|
|
19
|
+
auth: {
|
|
20
|
+
// set this in your project
|
|
21
|
+
token: '',
|
|
22
|
+
/**
|
|
23
|
+
* Policy class name per endpoint. Each route resolves its policy by
|
|
24
|
+
* reading the config key below, so access can be tightened or loosened
|
|
25
|
+
* per endpoint without touching code.
|
|
26
|
+
*/
|
|
27
|
+
policies: {
|
|
28
|
+
metrics: 'TelemetryTokenPolicy',
|
|
29
|
+
stats: 'TelemetryTokenPolicy',
|
|
30
|
+
timeline: 'TelemetryTokenPolicy',
|
|
31
|
+
routes: 'TelemetryTokenPolicy',
|
|
32
|
+
perf: 'TelemetryTokenPolicy',
|
|
33
|
+
// probe endpoints must be reachable without credentials
|
|
34
|
+
health: 'PublicPolicy',
|
|
35
|
+
ready: 'PublicPolicy',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
/**
|
|
39
|
+
* Register prom-client's process / heap / cpu / event-loop metrics against
|
|
40
|
+
* the private registry at bootstrap.
|
|
41
|
+
*/
|
|
42
|
+
collectDefaultMetrics: true,
|
|
43
|
+
/** Metric name prefix for the http telemetry metrics. */
|
|
44
|
+
prefix: 'http',
|
|
45
|
+
/** Duration histogram buckets in ms. */
|
|
46
|
+
buckets: DURATION_BUCKETS_MS,
|
|
47
|
+
/** Apdex satisfied threshold in ms; tolerated is 4x this. */
|
|
48
|
+
apdexThresholdMs: 25,
|
|
49
|
+
timeline: {
|
|
50
|
+
/** Number of buckets retained in the ring. */
|
|
51
|
+
length: 60,
|
|
52
|
+
/** Bucket width in ms. */
|
|
53
|
+
bucketMs: 60_000,
|
|
54
|
+
},
|
|
55
|
+
routes: {
|
|
56
|
+
enabled: true,
|
|
57
|
+
/** Cap on distinct method+route keys held in memory. */
|
|
58
|
+
maxEntries: 500,
|
|
59
|
+
},
|
|
60
|
+
perf: {
|
|
61
|
+
enabled: true,
|
|
62
|
+
/** Cap on distinct perf measurement names held in memory. */
|
|
63
|
+
maxNames: 200,
|
|
64
|
+
},
|
|
65
|
+
health: {
|
|
66
|
+
/** Per-check timeout in ms. A timed-out check counts as down. */
|
|
67
|
+
timeoutMs: 2000,
|
|
68
|
+
/** When true a degraded overall status returns 503 rather than 200. */
|
|
69
|
+
failOnDegraded: false,
|
|
70
|
+
/** Reported by /telemetry/health. Omitted from the response when unset. */
|
|
71
|
+
version: undefined,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
export default config;
|
|
76
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../../src/config/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEhD,SAAS,GAAG,CAAC,IAAY;IACvB,MAAM,UAAU,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;IACjD,OAAO,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACtK,CAAC;AAED;;;;GAIG;AACH,MAAM,mBAAmB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAEpF,MAAM,MAAM,GAAG;IACb,MAAM,EAAE;QACN,IAAI,EAAE;YACJ,WAAW,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;SAClC;KACF;IAED,SAAS,EAAE;QACT,IAAI,EAAE;YACJ,2BAA2B;YAC3B,KAAK,EAAE,EAAE;YAET;;;;eAIG;YACH,QAAQ,EAAE;gBACR,OAAO,EAAE,sBAAsB;gBAC/B,KAAK,EAAE,sBAAsB;gBAC7B,QAAQ,EAAE,sBAAsB;gBAChC,MAAM,EAAE,sBAAsB;gBAC9B,IAAI,EAAE,sBAAsB;gBAE5B,wDAAwD;gBACxD,MAAM,EAAE,cAAc;gBACtB,KAAK,EAAE,cAAc;aACtB;SACF;QAED;;;WAGG;QACH,qBAAqB,EAAE,IAAI;QAE3B,yDAAyD;QACzD,MAAM,EAAE,MAAM;QAEd,wCAAwC;QACxC,OAAO,EAAE,mBAAmB;QAE5B,6DAA6D;QAC7D,gBAAgB,EAAE,EAAE;QAEpB,QAAQ,EAAE;YACR,8CAA8C;YAC9C,MAAM,EAAE,EAAE;YACV,0BAA0B;YAC1B,QAAQ,EAAE,MAAM;SACjB;QAED,MAAM,EAAE;YACN,OAAO,EAAE,IAAI;YACb,wDAAwD;YACxD,UAAU,EAAE,GAAG;SAChB;QAED,IAAI,EAAE;YACJ,OAAO,EAAE,IAAI;YACb,6DAA6D;YAC7D,QAAQ,EAAE,GAAG;SACd;QAED,MAAM,EAAE;YACN,iEAAiE;YACjE,SAAS,EAAE,IAAI;YACf,uEAAuE;YACvE,cAAc,EAAE,KAAK;YACrB,2EAA2E;YAC3E,OAAO,EAAE,SAA+B;SACzC;KACF;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseController } from '@spinajs/http';
|
|
2
|
+
import { Metrics } from './../metrics.js';
|
|
3
|
+
import { PrometheusResponse } from './../responses.js';
|
|
4
|
+
import './../policies/TelemetryTokenPolicy.js';
|
|
5
|
+
import './../policies/PublicPolicy.js';
|
|
6
|
+
/**
|
|
7
|
+
* Prometheus scrape endpoint.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately kept at the bare `/metrics` path rather than under the
|
|
10
|
+
* `/telemetry` prefix used by the JSON api — this is the path existing
|
|
11
|
+
* `scrape_configs` already point at.
|
|
12
|
+
*/
|
|
13
|
+
export declare class MetricsController extends BaseController {
|
|
14
|
+
protected MetricsService: Metrics;
|
|
15
|
+
/**
|
|
16
|
+
* Prometheus exposition text for every metric on the registry: the `http_*`
|
|
17
|
+
* request metrics, the `perf_*` bridge metrics, any application metrics
|
|
18
|
+
* declared through `Metrics.defineMetrics`, and — when
|
|
19
|
+
* `telemetry.collectDefaultMetrics` is on — the `process_*` / `nodejs_*` set.
|
|
20
|
+
*
|
|
21
|
+
* @response 200 {string} Prometheus exposition text ( text/plain )
|
|
22
|
+
* @response 403 Access token missing or invalid
|
|
23
|
+
*/
|
|
24
|
+
getMetrics(): Promise<PrometheusResponse>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=Metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Metrics.d.ts","sourceRoot":"","sources":["../../../src/controllers/Metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,cAAc,EAAe,MAAM,eAAe,CAAC;AAGtE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAUvD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,+BAA+B,CAAC;AAEvC;;;;;;GAMG;AACH,qBACa,iBAAkB,SAAQ,cAAc;IAEnD,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC;IAElC;;;;;;;;OAQG;IAGU,UAAU;CAGxB"}
|