@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.
Files changed (214) hide show
  1. package/README.md +482 -0
  2. package/lib/cjs/InMemoryPerfSink.d.ts +51 -0
  3. package/lib/cjs/InMemoryPerfSink.d.ts.map +1 -0
  4. package/lib/cjs/InMemoryPerfSink.js +100 -0
  5. package/lib/cjs/InMemoryPerfSink.js.map +1 -0
  6. package/lib/cjs/PromMetricSink.d.ts +26 -0
  7. package/lib/cjs/PromMetricSink.d.ts.map +1 -0
  8. package/lib/cjs/PromMetricSink.js +68 -0
  9. package/lib/cjs/PromMetricSink.js.map +1 -0
  10. package/lib/cjs/bootstrap.d.ts +13 -0
  11. package/lib/cjs/bootstrap.d.ts.map +1 -0
  12. package/lib/cjs/bootstrap.js +57 -0
  13. package/lib/cjs/bootstrap.js.map +1 -0
  14. package/lib/cjs/config/telemetry.d.ts +63 -0
  15. package/lib/cjs/config/telemetry.d.ts.map +1 -0
  16. package/lib/cjs/config/telemetry.js +78 -0
  17. package/lib/cjs/config/telemetry.js.map +1 -0
  18. package/lib/cjs/controllers/Metrics.d.ts +26 -0
  19. package/lib/cjs/controllers/Metrics.d.ts.map +1 -0
  20. package/lib/cjs/controllers/Metrics.js +63 -0
  21. package/lib/cjs/controllers/Metrics.js.map +1 -0
  22. package/lib/cjs/controllers/Telemetry.d.ts +92 -0
  23. package/lib/cjs/controllers/Telemetry.d.ts.map +1 -0
  24. package/lib/cjs/controllers/Telemetry.js +226 -0
  25. package/lib/cjs/controllers/Telemetry.js.map +1 -0
  26. package/lib/cjs/dto/index.d.ts +21 -0
  27. package/lib/cjs/dto/index.d.ts.map +1 -0
  28. package/lib/cjs/dto/index.js +64 -0
  29. package/lib/cjs/dto/index.js.map +1 -0
  30. package/lib/cjs/endpoints.d.ts +32 -0
  31. package/lib/cjs/endpoints.d.ts.map +1 -0
  32. package/lib/cjs/endpoints.js +38 -0
  33. package/lib/cjs/endpoints.js.map +1 -0
  34. package/lib/cjs/health.d.ts +55 -0
  35. package/lib/cjs/health.d.ts.map +1 -0
  36. package/lib/cjs/health.js +111 -0
  37. package/lib/cjs/health.js.map +1 -0
  38. package/lib/cjs/index.d.ts +16 -0
  39. package/lib/cjs/index.d.ts.map +1 -0
  40. package/lib/cjs/index.js +32 -0
  41. package/lib/cjs/index.js.map +1 -0
  42. package/lib/cjs/metrics.d.ts +16 -0
  43. package/lib/cjs/metrics.d.ts.map +1 -0
  44. package/lib/cjs/metrics.js +32 -0
  45. package/lib/cjs/metrics.js.map +1 -0
  46. package/lib/cjs/middleware.d.ts +81 -0
  47. package/lib/cjs/middleware.d.ts.map +1 -0
  48. package/lib/cjs/middleware.js +210 -0
  49. package/lib/cjs/middleware.js.map +1 -0
  50. package/lib/cjs/package.json +1 -0
  51. package/lib/cjs/policies/PublicPolicy.d.ts +16 -0
  52. package/lib/cjs/policies/PublicPolicy.d.ts.map +1 -0
  53. package/lib/cjs/policies/PublicPolicy.js +34 -0
  54. package/lib/cjs/policies/PublicPolicy.js.map +1 -0
  55. package/lib/cjs/policies/TelemetryTokenPolicy.d.ts +19 -0
  56. package/lib/cjs/policies/TelemetryTokenPolicy.d.ts.map +1 -0
  57. package/lib/cjs/policies/TelemetryTokenPolicy.js +65 -0
  58. package/lib/cjs/policies/TelemetryTokenPolicy.js.map +1 -0
  59. package/lib/cjs/requestStats.d.ts +81 -0
  60. package/lib/cjs/requestStats.d.ts.map +1 -0
  61. package/lib/cjs/requestStats.js +134 -0
  62. package/lib/cjs/requestStats.js.map +1 -0
  63. package/lib/cjs/responses.d.ts +23 -0
  64. package/lib/cjs/responses.d.ts.map +1 -0
  65. package/lib/cjs/responses.js +35 -0
  66. package/lib/cjs/responses.js.map +1 -0
  67. package/lib/cjs/routeStats.d.ts +43 -0
  68. package/lib/cjs/routeStats.d.ts.map +1 -0
  69. package/lib/cjs/routeStats.js +59 -0
  70. package/lib/cjs/routeStats.js.map +1 -0
  71. package/lib/cjs/schemas/HealthResponse.schema.d.ts +30 -0
  72. package/lib/cjs/schemas/HealthResponse.schema.d.ts.map +1 -0
  73. package/lib/cjs/schemas/HealthResponse.schema.js +15 -0
  74. package/lib/cjs/schemas/HealthResponse.schema.js.map +1 -0
  75. package/lib/cjs/schemas/PerfResponse.schema.d.ts +56 -0
  76. package/lib/cjs/schemas/PerfResponse.schema.d.ts.map +1 -0
  77. package/lib/cjs/schemas/PerfResponse.schema.js +36 -0
  78. package/lib/cjs/schemas/PerfResponse.schema.js.map +1 -0
  79. package/lib/cjs/schemas/ReadyResponse.schema.d.ts +36 -0
  80. package/lib/cjs/schemas/ReadyResponse.schema.d.ts.map +1 -0
  81. package/lib/cjs/schemas/ReadyResponse.schema.js +23 -0
  82. package/lib/cjs/schemas/ReadyResponse.schema.js.map +1 -0
  83. package/lib/cjs/schemas/RequestStatsSnapshot.schema.d.ts +79 -0
  84. package/lib/cjs/schemas/RequestStatsSnapshot.schema.d.ts.map +1 -0
  85. package/lib/cjs/schemas/RequestStatsSnapshot.schema.js +30 -0
  86. package/lib/cjs/schemas/RequestStatsSnapshot.schema.js.map +1 -0
  87. package/lib/cjs/schemas/RoutesResponse.schema.d.ts +100 -0
  88. package/lib/cjs/schemas/RoutesResponse.schema.d.ts.map +1 -0
  89. package/lib/cjs/schemas/RoutesResponse.schema.js +25 -0
  90. package/lib/cjs/schemas/RoutesResponse.schema.js.map +1 -0
  91. package/lib/cjs/schemas/StatsResponse.schema.d.ts +158 -0
  92. package/lib/cjs/schemas/StatsResponse.schema.d.ts.map +1 -0
  93. package/lib/cjs/schemas/StatsResponse.schema.js +19 -0
  94. package/lib/cjs/schemas/StatsResponse.schema.js.map +1 -0
  95. package/lib/cjs/schemas/TimelineResponse.schema.d.ts +109 -0
  96. package/lib/cjs/schemas/TimelineResponse.schema.d.ts.map +1 -0
  97. package/lib/cjs/schemas/TimelineResponse.schema.js +28 -0
  98. package/lib/cjs/schemas/TimelineResponse.schema.js.map +1 -0
  99. package/lib/cjs/store.d.ts +58 -0
  100. package/lib/cjs/store.d.ts.map +1 -0
  101. package/lib/cjs/store.js +108 -0
  102. package/lib/cjs/store.js.map +1 -0
  103. package/lib/cjs/timeline.d.ts +48 -0
  104. package/lib/cjs/timeline.d.ts.map +1 -0
  105. package/lib/cjs/timeline.js +70 -0
  106. package/lib/cjs/timeline.js.map +1 -0
  107. package/lib/mjs/InMemoryPerfSink.d.ts +51 -0
  108. package/lib/mjs/InMemoryPerfSink.d.ts.map +1 -0
  109. package/lib/mjs/InMemoryPerfSink.js +97 -0
  110. package/lib/mjs/InMemoryPerfSink.js.map +1 -0
  111. package/lib/mjs/PromMetricSink.d.ts +26 -0
  112. package/lib/mjs/PromMetricSink.d.ts.map +1 -0
  113. package/lib/mjs/PromMetricSink.js +65 -0
  114. package/lib/mjs/PromMetricSink.js.map +1 -0
  115. package/lib/mjs/bootstrap.d.ts +13 -0
  116. package/lib/mjs/bootstrap.d.ts.map +1 -0
  117. package/lib/mjs/bootstrap.js +54 -0
  118. package/lib/mjs/bootstrap.js.map +1 -0
  119. package/lib/mjs/config/telemetry.d.ts +63 -0
  120. package/lib/mjs/config/telemetry.d.ts.map +1 -0
  121. package/lib/mjs/config/telemetry.js +76 -0
  122. package/lib/mjs/config/telemetry.js.map +1 -0
  123. package/lib/mjs/controllers/Metrics.d.ts +26 -0
  124. package/lib/mjs/controllers/Metrics.d.ts.map +1 -0
  125. package/lib/mjs/controllers/Metrics.js +60 -0
  126. package/lib/mjs/controllers/Metrics.js.map +1 -0
  127. package/lib/mjs/controllers/Telemetry.d.ts +92 -0
  128. package/lib/mjs/controllers/Telemetry.d.ts.map +1 -0
  129. package/lib/mjs/controllers/Telemetry.js +223 -0
  130. package/lib/mjs/controllers/Telemetry.js.map +1 -0
  131. package/lib/mjs/dto/index.d.ts +21 -0
  132. package/lib/mjs/dto/index.d.ts.map +1 -0
  133. package/lib/mjs/dto/index.js +58 -0
  134. package/lib/mjs/dto/index.js.map +1 -0
  135. package/lib/mjs/endpoints.d.ts +32 -0
  136. package/lib/mjs/endpoints.d.ts.map +1 -0
  137. package/lib/mjs/endpoints.js +34 -0
  138. package/lib/mjs/endpoints.js.map +1 -0
  139. package/lib/mjs/health.d.ts +55 -0
  140. package/lib/mjs/health.d.ts.map +1 -0
  141. package/lib/mjs/health.js +107 -0
  142. package/lib/mjs/health.js.map +1 -0
  143. package/lib/mjs/index.d.ts +16 -0
  144. package/lib/mjs/index.d.ts.map +1 -0
  145. package/lib/mjs/index.js +16 -0
  146. package/lib/mjs/index.js.map +1 -0
  147. package/lib/mjs/metrics.d.ts +16 -0
  148. package/lib/mjs/metrics.d.ts.map +1 -0
  149. package/lib/mjs/metrics.js +16 -0
  150. package/lib/mjs/metrics.js.map +1 -0
  151. package/lib/mjs/middleware.d.ts +81 -0
  152. package/lib/mjs/middleware.d.ts.map +1 -0
  153. package/lib/mjs/middleware.js +207 -0
  154. package/lib/mjs/middleware.js.map +1 -0
  155. package/lib/mjs/package.json +1 -0
  156. package/lib/mjs/policies/PublicPolicy.d.ts +16 -0
  157. package/lib/mjs/policies/PublicPolicy.d.ts.map +1 -0
  158. package/lib/mjs/policies/PublicPolicy.js +31 -0
  159. package/lib/mjs/policies/PublicPolicy.js.map +1 -0
  160. package/lib/mjs/policies/TelemetryTokenPolicy.d.ts +19 -0
  161. package/lib/mjs/policies/TelemetryTokenPolicy.d.ts.map +1 -0
  162. package/lib/mjs/policies/TelemetryTokenPolicy.js +62 -0
  163. package/lib/mjs/policies/TelemetryTokenPolicy.js.map +1 -0
  164. package/lib/mjs/requestStats.d.ts +81 -0
  165. package/lib/mjs/requestStats.d.ts.map +1 -0
  166. package/lib/mjs/requestStats.js +130 -0
  167. package/lib/mjs/requestStats.js.map +1 -0
  168. package/lib/mjs/responses.d.ts +23 -0
  169. package/lib/mjs/responses.d.ts.map +1 -0
  170. package/lib/mjs/responses.js +30 -0
  171. package/lib/mjs/responses.js.map +1 -0
  172. package/lib/mjs/routeStats.d.ts +43 -0
  173. package/lib/mjs/routeStats.d.ts.map +1 -0
  174. package/lib/mjs/routeStats.js +55 -0
  175. package/lib/mjs/routeStats.js.map +1 -0
  176. package/lib/mjs/schemas/HealthResponse.schema.d.ts +30 -0
  177. package/lib/mjs/schemas/HealthResponse.schema.d.ts.map +1 -0
  178. package/lib/mjs/schemas/HealthResponse.schema.js +13 -0
  179. package/lib/mjs/schemas/HealthResponse.schema.js.map +1 -0
  180. package/lib/mjs/schemas/PerfResponse.schema.d.ts +56 -0
  181. package/lib/mjs/schemas/PerfResponse.schema.d.ts.map +1 -0
  182. package/lib/mjs/schemas/PerfResponse.schema.js +34 -0
  183. package/lib/mjs/schemas/PerfResponse.schema.js.map +1 -0
  184. package/lib/mjs/schemas/ReadyResponse.schema.d.ts +36 -0
  185. package/lib/mjs/schemas/ReadyResponse.schema.d.ts.map +1 -0
  186. package/lib/mjs/schemas/ReadyResponse.schema.js +21 -0
  187. package/lib/mjs/schemas/ReadyResponse.schema.js.map +1 -0
  188. package/lib/mjs/schemas/RequestStatsSnapshot.schema.d.ts +79 -0
  189. package/lib/mjs/schemas/RequestStatsSnapshot.schema.d.ts.map +1 -0
  190. package/lib/mjs/schemas/RequestStatsSnapshot.schema.js +28 -0
  191. package/lib/mjs/schemas/RequestStatsSnapshot.schema.js.map +1 -0
  192. package/lib/mjs/schemas/RoutesResponse.schema.d.ts +100 -0
  193. package/lib/mjs/schemas/RoutesResponse.schema.d.ts.map +1 -0
  194. package/lib/mjs/schemas/RoutesResponse.schema.js +20 -0
  195. package/lib/mjs/schemas/RoutesResponse.schema.js.map +1 -0
  196. package/lib/mjs/schemas/StatsResponse.schema.d.ts +158 -0
  197. package/lib/mjs/schemas/StatsResponse.schema.d.ts.map +1 -0
  198. package/lib/mjs/schemas/StatsResponse.schema.js +14 -0
  199. package/lib/mjs/schemas/StatsResponse.schema.js.map +1 -0
  200. package/lib/mjs/schemas/TimelineResponse.schema.d.ts +109 -0
  201. package/lib/mjs/schemas/TimelineResponse.schema.d.ts.map +1 -0
  202. package/lib/mjs/schemas/TimelineResponse.schema.js +23 -0
  203. package/lib/mjs/schemas/TimelineResponse.schema.js.map +1 -0
  204. package/lib/mjs/store.d.ts +58 -0
  205. package/lib/mjs/store.d.ts.map +1 -0
  206. package/lib/mjs/store.js +105 -0
  207. package/lib/mjs/store.js.map +1 -0
  208. package/lib/mjs/timeline.d.ts +48 -0
  209. package/lib/mjs/timeline.d.ts.map +1 -0
  210. package/lib/mjs/timeline.js +66 -0
  211. package/lib/mjs/timeline.js.map +1 -0
  212. package/lib/tsconfig.cjs.tsbuildinfo +1 -0
  213. package/lib/tsconfig.mjs.tsbuildinfo +1 -0
  214. package/package.json +69 -0
@@ -0,0 +1,60 @@
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 { BasePath, BaseController, Get, Policy } from '@spinajs/http';
11
+ import { Autoinject } from '@spinajs/di';
12
+ import { Metrics } from './../metrics.js';
13
+ import { PrometheusResponse } from './../responses.js';
14
+ // Importing the policy modules runs their @Injectable decorators, which is what
15
+ // puts the classes in the DI container under the names the routes below name as
16
+ // STRINGS ( via `telemetry.auth.policies.*` ). Nothing else forces them to load:
17
+ // this controller is mounted by the config-declared directory scan, and that
18
+ // configuration is auto-discovered from node_modules — so an app never has to
19
+ // import the package barrel. And http FAILS OPEN on an unresolvable policy name
20
+ // ( it logs `No policy named ...`, drops it, and a route left with no policies
21
+ // calls next() ), which would serve /metrics unauthenticated.
22
+ import './../policies/TelemetryTokenPolicy.js';
23
+ import './../policies/PublicPolicy.js';
24
+ /**
25
+ * Prometheus scrape endpoint.
26
+ *
27
+ * Deliberately kept at the bare `/metrics` path rather than under the
28
+ * `/telemetry` prefix used by the JSON api — this is the path existing
29
+ * `scrape_configs` already point at.
30
+ */
31
+ let MetricsController = class MetricsController extends BaseController {
32
+ /**
33
+ * Prometheus exposition text for every metric on the registry: the `http_*`
34
+ * request metrics, the `perf_*` bridge metrics, any application metrics
35
+ * declared through `Metrics.defineMetrics`, and — when
36
+ * `telemetry.collectDefaultMetrics` is on — the `process_*` / `nodejs_*` set.
37
+ *
38
+ * @response 200 {string} Prometheus exposition text ( text/plain )
39
+ * @response 403 Access token missing or invalid
40
+ */
41
+ async getMetrics() {
42
+ return new PrometheusResponse(this.MetricsService);
43
+ }
44
+ };
45
+ __decorate([
46
+ Autoinject(Metrics),
47
+ __metadata("design:type", Metrics)
48
+ ], MetricsController.prototype, "MetricsService", void 0);
49
+ __decorate([
50
+ Get('/'),
51
+ Policy('telemetry.auth.policies.metrics'),
52
+ __metadata("design:type", Function),
53
+ __metadata("design:paramtypes", []),
54
+ __metadata("design:returntype", Promise)
55
+ ], MetricsController.prototype, "getMetrics", null);
56
+ MetricsController = __decorate([
57
+ BasePath('metrics')
58
+ ], MetricsController);
59
+ export { MetricsController };
60
+ //# sourceMappingURL=Metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Metrics.js","sourceRoot":"","sources":["../../../src/controllers/Metrics.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,gFAAgF;AAChF,gFAAgF;AAChF,iFAAiF;AACjF,6EAA6E;AAC7E,8EAA8E;AAC9E,gFAAgF;AAChF,+EAA+E;AAC/E,8DAA8D;AAC9D,OAAO,uCAAuC,CAAC;AAC/C,OAAO,+BAA+B,CAAC;AAEvC;;;;;;GAMG;AAEI,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,cAAc;IAInD;;;;;;;;OAQG;IAGU,AAAN,KAAK,CAAC,UAAU;QACrB,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACrD,CAAC;CACF,CAAA;AAhBW;IADT,UAAU,CAAC,OAAO,CAAC;8BACM,OAAO;yDAAC;AAarB;IAFZ,GAAG,CAAC,GAAG,CAAC;IACR,MAAM,CAAC,iCAAiC,CAAC;;;;mDAGzC;AAjBU,iBAAiB;IAD7B,QAAQ,CAAC,SAAS,CAAC;GACP,iBAAiB,CAkB7B"}
@@ -0,0 +1,92 @@
1
+ import { BaseController, Ok } from '@spinajs/http';
2
+ import { TelemetryStore } from './../store.js';
3
+ import { InMemoryPerfSink } from './../InMemoryPerfSink.js';
4
+ import { HealthCheckRunner } from './../health.js';
5
+ import { ServiceUnavailable } from './../responses.js';
6
+ import './../dto/index.js';
7
+ import './../policies/TelemetryTokenPolicy.js';
8
+ import './../policies/PublicPolicy.js';
9
+ /**
10
+ * JSON telemetry API. Machine-facing — consumed by dashboards, uptime monitors
11
+ * and orchestrator probes.
12
+ *
13
+ * The prometheus scrape endpoint deliberately lives on its own controller at
14
+ * the bare `/metrics` path, not under this prefix.
15
+ */
16
+ export declare class TelemetryController extends BaseController {
17
+ protected Store: TelemetryStore;
18
+ protected PerfSink: InMemoryPerfSink;
19
+ protected Health: HealthCheckRunner;
20
+ protected Version: string;
21
+ /**
22
+ * Lifetime request statistics plus the rolling timeline.
23
+ *
24
+ * @returns {StatsResponse} Lifetime stats and the per-bucket timeline
25
+ * @response 403 Access token missing or invalid
26
+ */
27
+ getStats(): Promise<Ok<{
28
+ all: import("../requestStats.js").IRequestStatsSnapshot;
29
+ timeline: import("../timeline.js").ITimelineSnapshot;
30
+ }>>;
31
+ /**
32
+ * The rolling timeline alone, with each bucket annotated with the wall-clock
33
+ * window it covers so consumers do not have to reverse the bucket key.
34
+ *
35
+ * @param buckets - how many of the most recent buckets to return; all of them when omitted
36
+ * @returns {TimelineResponse} The annotated timeline
37
+ * @response 400 `buckets` was not a positive integer
38
+ * @response 403 Access token missing or invalid
39
+ */
40
+ getTimeline(buckets?: string): Promise<Ok<{
41
+ bucketMs: number;
42
+ length: number;
43
+ buckets: {
44
+ key: number;
45
+ from: number;
46
+ to: number;
47
+ stats: import("../requestStats.js").IRequestStatsSnapshot;
48
+ }[];
49
+ }>>;
50
+ /**
51
+ * Per method+route request breakdown.
52
+ *
53
+ * No percentiles — query them from prometheus against the `route`-labelled
54
+ * `http_request_duration_ms` histogram, which carries the same label values.
55
+ *
56
+ * @returns {RoutesResponse} Per-route request statistics
57
+ * @response 403 Access token missing or invalid
58
+ */
59
+ getRoutes(): Promise<Ok<import("../routeStats.js").IRouteStatsSnapshot>>;
60
+ /**
61
+ * Aggregated performance measurements collected through the `Perf` facade —
62
+ * every `Perf.measure`, `@Measure`, `Perf.count` and `Perf.value` in the
63
+ * process, including the ORM's `orm.query` spans.
64
+ *
65
+ * @returns {PerfResponse} Aggregated spans and events
66
+ * @response 403 Access token missing or invalid
67
+ */
68
+ getPerf(): Promise<Ok<import("./../InMemoryPerfSink.js").IPerfSnapshot>>;
69
+ /**
70
+ * Liveness. Runs no checks, so it can never be made slow or flaky by a
71
+ * dependency — if this answers, the process is alive.
72
+ *
73
+ * @returns {HealthResponse} Process liveness information
74
+ */
75
+ getHealth(): Promise<Ok<{
76
+ version?: string | undefined;
77
+ status: string;
78
+ startedAt: number;
79
+ uptimeMs: number;
80
+ pid: number;
81
+ node: string;
82
+ }>>;
83
+ /**
84
+ * Readiness. Runs every registered `HealthCheck`, each raced against
85
+ * `telemetry.health.timeoutMs`.
86
+ *
87
+ * @returns {ReadyResponse} Overall readiness and the per-check results
88
+ * @response 503 At least one check is down ( or degraded, when `telemetry.health.failOnDegraded` is set )
89
+ */
90
+ getReady(): Promise<ServiceUnavailable<import("./../health.js").IReadyReport> | Ok<import("./../health.js").IReadyReport>>;
91
+ }
92
+ //# sourceMappingURL=Telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Telemetry.d.ts","sourceRoot":"","sources":["../../../src/controllers/Telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,cAAc,EAAsB,EAAE,EAAE,MAAM,eAAe,CAAC;AAKjF,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAIvD,OAAO,mBAAmB,CAAC;AAW3B,OAAO,uCAAuC,CAAC;AAC/C,OAAO,+BAA+B,CAAC;AAEvC;;;;;;GAMG;AACH,qBACa,mBAAoB,SAAQ,cAAc;IAErD,SAAS,CAAC,KAAK,EAAE,cAAc,CAAC;IAGhC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IAGrC,SAAS,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAGpC,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IAE1B;;;;;OAKG;IAGU,QAAQ;;;;IAarB;;;;;;;;OAQG;IAGU,WAAW,CAAU,OAAO,CAAC,EAAE,MAAM;;;;;;;;;;IA0ClD;;;;;;;;OAQG;IAGU,SAAS;IAItB;;;;;;;OAOG;IAGU,OAAO;IAIpB;;;;;OAKG;IAGU,SAAS;;;;;;;;IAetB;;;;;;OAMG;IAGU,QAAQ;CAStB"}
@@ -0,0 +1,223 @@
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
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { BasePath, BaseController, Get, Policy, Query, Ok } from '@spinajs/http';
14
+ import { Autoinject } from '@spinajs/di';
15
+ import { Config } from '@spinajs/configuration';
16
+ import { BadRequest } from '@spinajs/exceptions';
17
+ import { TelemetryStore } from './../store.js';
18
+ import { InMemoryPerfSink } from './../InMemoryPerfSink.js';
19
+ import { HealthCheckRunner } from './../health.js';
20
+ import { ServiceUnavailable } from './../responses.js';
21
+ // Importing the DTO barrel runs the @Schema decorators, which is what makes the
22
+ // response schemas resolvable by name in the generated OpenAPI document.
23
+ import './../dto/index.js';
24
+ // Same reason, for security rather than documentation: importing the policy
25
+ // modules runs their @Injectable decorators, which is what puts the classes in
26
+ // the DI container under the names the routes below name as STRINGS ( via
27
+ // `telemetry.auth.policies.*` ). Nothing else forces them to load — this
28
+ // controller is mounted by the config-declared directory scan, and that
29
+ // configuration is auto-discovered from node_modules, so an app never has to
30
+ // import the package barrel. And http FAILS OPEN on an unresolvable policy name
31
+ // ( it logs `No policy named ...`, drops it, and a route left with no policies
32
+ // calls next() ), which would serve these endpoints unauthenticated.
33
+ import './../policies/TelemetryTokenPolicy.js';
34
+ import './../policies/PublicPolicy.js';
35
+ /**
36
+ * JSON telemetry API. Machine-facing — consumed by dashboards, uptime monitors
37
+ * and orchestrator probes.
38
+ *
39
+ * The prometheus scrape endpoint deliberately lives on its own controller at
40
+ * the bare `/metrics` path, not under this prefix.
41
+ */
42
+ let TelemetryController = class TelemetryController extends BaseController {
43
+ /**
44
+ * Lifetime request statistics plus the rolling timeline.
45
+ *
46
+ * @returns {StatsResponse} Lifetime stats and the per-bucket timeline
47
+ * @response 403 Access token missing or invalid
48
+ */
49
+ async getStats() {
50
+ const stats = this.Store.RequestStats;
51
+ // Rates are not maintained on the hot path — they are derived here, over the
52
+ // whole collection window, or `req_rate` / `err_rate` would always read 0.
53
+ stats.updateRates(Date.now() - this.Store.StartedAt);
54
+ return new Ok({
55
+ all: stats.toJSON(),
56
+ timeline: this.Store.Timeline.toJSON(),
57
+ });
58
+ }
59
+ /**
60
+ * The rolling timeline alone, with each bucket annotated with the wall-clock
61
+ * window it covers so consumers do not have to reverse the bucket key.
62
+ *
63
+ * @param buckets - how many of the most recent buckets to return; all of them when omitted
64
+ * @returns {TimelineResponse} The annotated timeline
65
+ * @response 400 `buckets` was not a positive integer
66
+ * @response 403 Access token missing or invalid
67
+ */
68
+ async getTimeline(buckets) {
69
+ const timeline = this.Store.Timeline;
70
+ const snapshot = timeline.toJSON();
71
+ let keys = Object.keys(snapshot)
72
+ .map((k) => Number(k))
73
+ .sort((a, b) => a - b);
74
+ // Only a genuinely ABSENT `buckets` means "all of them". An explicitly empty
75
+ // `?buckets=` is a supplied value that is not a positive integer, so it is
76
+ // rejected like every other invalid one rather than silently meaning "all".
77
+ if (buckets !== undefined && buckets !== null) {
78
+ // Taken as a string and parsed here rather than declared `number` and left
79
+ // to the decorator's schema: a query value arrives as a string, and how the
80
+ // framework coerces a non-numeric one ( `Number( 'abc' )` -> NaN, rejected
81
+ // by the arg validator with a generic message ) is not something this
82
+ // endpoint's contract should depend on.
83
+ //
84
+ // `Number( '' )` is 0, not NaN, so the empty string falls through to the
85
+ // `count < 1` rejection below on its own.
86
+ const count = Number(buckets);
87
+ if (!Number.isInteger(count) || count < 1) {
88
+ throw new BadRequest('buckets must be a positive integer');
89
+ }
90
+ // The most recent N — the tail of an ascending key order.
91
+ keys = keys.slice(-count);
92
+ }
93
+ return new Ok({
94
+ bucketMs: timeline.bucketMs,
95
+ length: timeline.length,
96
+ buckets: keys.map((key) => ({
97
+ key,
98
+ from: key * timeline.bucketMs,
99
+ to: (key + 1) * timeline.bucketMs,
100
+ stats: snapshot[String(key)],
101
+ })),
102
+ });
103
+ }
104
+ /**
105
+ * Per method+route request breakdown.
106
+ *
107
+ * No percentiles — query them from prometheus against the `route`-labelled
108
+ * `http_request_duration_ms` histogram, which carries the same label values.
109
+ *
110
+ * @returns {RoutesResponse} Per-route request statistics
111
+ * @response 403 Access token missing or invalid
112
+ */
113
+ async getRoutes() {
114
+ return new Ok(this.Store.RouteStats.toJSON());
115
+ }
116
+ /**
117
+ * Aggregated performance measurements collected through the `Perf` facade —
118
+ * every `Perf.measure`, `@Measure`, `Perf.count` and `Perf.value` in the
119
+ * process, including the ORM's `orm.query` spans.
120
+ *
121
+ * @returns {PerfResponse} Aggregated spans and events
122
+ * @response 403 Access token missing or invalid
123
+ */
124
+ async getPerf() {
125
+ return new Ok(this.PerfSink.toJSON());
126
+ }
127
+ /**
128
+ * Liveness. Runs no checks, so it can never be made slow or flaky by a
129
+ * dependency — if this answers, the process is alive.
130
+ *
131
+ * @returns {HealthResponse} Process liveness information
132
+ */
133
+ async getHealth() {
134
+ const uptimeMs = Math.round(process.uptime() * 1000);
135
+ return new Ok({
136
+ status: 'up',
137
+ startedAt: Date.now() - uptimeMs,
138
+ uptimeMs,
139
+ pid: process.pid,
140
+ node: process.version,
141
+ // omitted rather than reported as null when `telemetry.health.version` is unset
142
+ ...(this.Version ? { version: this.Version } : {}),
143
+ });
144
+ }
145
+ /**
146
+ * Readiness. Runs every registered `HealthCheck`, each raced against
147
+ * `telemetry.health.timeoutMs`.
148
+ *
149
+ * @returns {ReadyResponse} Overall readiness and the per-check results
150
+ * @response 503 At least one check is down ( or degraded, when `telemetry.health.failOnDegraded` is set )
151
+ */
152
+ async getReady() {
153
+ const report = await this.Health.run();
154
+ if (this.Health.isFailing(report.status)) {
155
+ return new ServiceUnavailable(report);
156
+ }
157
+ return new Ok(report);
158
+ }
159
+ };
160
+ __decorate([
161
+ Autoinject(TelemetryStore),
162
+ __metadata("design:type", TelemetryStore)
163
+ ], TelemetryController.prototype, "Store", void 0);
164
+ __decorate([
165
+ Autoinject(InMemoryPerfSink),
166
+ __metadata("design:type", InMemoryPerfSink)
167
+ ], TelemetryController.prototype, "PerfSink", void 0);
168
+ __decorate([
169
+ Autoinject(HealthCheckRunner),
170
+ __metadata("design:type", HealthCheckRunner)
171
+ ], TelemetryController.prototype, "Health", void 0);
172
+ __decorate([
173
+ Config('telemetry.health.version'),
174
+ __metadata("design:type", String)
175
+ ], TelemetryController.prototype, "Version", void 0);
176
+ __decorate([
177
+ Get('stats'),
178
+ Policy('telemetry.auth.policies.stats'),
179
+ __metadata("design:type", Function),
180
+ __metadata("design:paramtypes", []),
181
+ __metadata("design:returntype", Promise)
182
+ ], TelemetryController.prototype, "getStats", null);
183
+ __decorate([
184
+ Get('timeline'),
185
+ Policy('telemetry.auth.policies.timeline'),
186
+ __param(0, Query()),
187
+ __metadata("design:type", Function),
188
+ __metadata("design:paramtypes", [String]),
189
+ __metadata("design:returntype", Promise)
190
+ ], TelemetryController.prototype, "getTimeline", null);
191
+ __decorate([
192
+ Get('routes'),
193
+ Policy('telemetry.auth.policies.routes'),
194
+ __metadata("design:type", Function),
195
+ __metadata("design:paramtypes", []),
196
+ __metadata("design:returntype", Promise)
197
+ ], TelemetryController.prototype, "getRoutes", null);
198
+ __decorate([
199
+ Get('perf'),
200
+ Policy('telemetry.auth.policies.perf'),
201
+ __metadata("design:type", Function),
202
+ __metadata("design:paramtypes", []),
203
+ __metadata("design:returntype", Promise)
204
+ ], TelemetryController.prototype, "getPerf", null);
205
+ __decorate([
206
+ Get('health'),
207
+ Policy('telemetry.auth.policies.health'),
208
+ __metadata("design:type", Function),
209
+ __metadata("design:paramtypes", []),
210
+ __metadata("design:returntype", Promise)
211
+ ], TelemetryController.prototype, "getHealth", null);
212
+ __decorate([
213
+ Get('ready'),
214
+ Policy('telemetry.auth.policies.ready'),
215
+ __metadata("design:type", Function),
216
+ __metadata("design:paramtypes", []),
217
+ __metadata("design:returntype", Promise)
218
+ ], TelemetryController.prototype, "getReady", null);
219
+ TelemetryController = __decorate([
220
+ BasePath('telemetry')
221
+ ], TelemetryController);
222
+ export { TelemetryController };
223
+ //# sourceMappingURL=Telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Telemetry.js","sourceRoot":"","sources":["../../../src/controllers/Telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Response shapes for the telemetry endpoints.
3
+ *
4
+ * These classes are never instantiated — they exist so `@Schema` registers each
5
+ * JSON schema under the class name, which is how http-swagger resolves a
6
+ * `@returns {StatsResponse}` JSDoc tag into a `#/components/schemas/...`
7
+ * component. The controller imports this module so the decorators run.
8
+ */
9
+ export declare class StatsResponse {
10
+ }
11
+ export declare class TimelineResponse {
12
+ }
13
+ export declare class RoutesResponse {
14
+ }
15
+ export declare class PerfResponse {
16
+ }
17
+ export declare class HealthResponse {
18
+ }
19
+ export declare class ReadyResponse {
20
+ }
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dto/index.ts"],"names":[],"mappings":"AASA;;;;;;;GAOG;AAEH,qBACa,aAAa;CAAG;AAE7B,qBACa,gBAAgB;CAAG;AAEhC,qBACa,cAAc;CAAG;AAE9B,qBACa,YAAY;CAAG;AAE5B,qBACa,cAAc;CAAG;AAE9B,qBACa,aAAa;CAAG"}
@@ -0,0 +1,58 @@
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 { Schema } from '@spinajs/validation';
8
+ import StatsResponseSchema from './../schemas/StatsResponse.schema.js';
9
+ import TimelineResponseSchema from './../schemas/TimelineResponse.schema.js';
10
+ import RoutesResponseSchema from './../schemas/RoutesResponse.schema.js';
11
+ import PerfResponseSchema from './../schemas/PerfResponse.schema.js';
12
+ import HealthResponseSchema from './../schemas/HealthResponse.schema.js';
13
+ import ReadyResponseSchema from './../schemas/ReadyResponse.schema.js';
14
+ /**
15
+ * Response shapes for the telemetry endpoints.
16
+ *
17
+ * These classes are never instantiated — they exist so `@Schema` registers each
18
+ * JSON schema under the class name, which is how http-swagger resolves a
19
+ * `@returns {StatsResponse}` JSDoc tag into a `#/components/schemas/...`
20
+ * component. The controller imports this module so the decorators run.
21
+ */
22
+ let StatsResponse = class StatsResponse {
23
+ };
24
+ StatsResponse = __decorate([
25
+ Schema(StatsResponseSchema)
26
+ ], StatsResponse);
27
+ export { StatsResponse };
28
+ let TimelineResponse = class TimelineResponse {
29
+ };
30
+ TimelineResponse = __decorate([
31
+ Schema(TimelineResponseSchema)
32
+ ], TimelineResponse);
33
+ export { TimelineResponse };
34
+ let RoutesResponse = class RoutesResponse {
35
+ };
36
+ RoutesResponse = __decorate([
37
+ Schema(RoutesResponseSchema)
38
+ ], RoutesResponse);
39
+ export { RoutesResponse };
40
+ let PerfResponse = class PerfResponse {
41
+ };
42
+ PerfResponse = __decorate([
43
+ Schema(PerfResponseSchema)
44
+ ], PerfResponse);
45
+ export { PerfResponse };
46
+ let HealthResponse = class HealthResponse {
47
+ };
48
+ HealthResponse = __decorate([
49
+ Schema(HealthResponseSchema)
50
+ ], HealthResponse);
51
+ export { HealthResponse };
52
+ let ReadyResponse = class ReadyResponse {
53
+ };
54
+ ReadyResponse = __decorate([
55
+ Schema(ReadyResponseSchema)
56
+ ], ReadyResponse);
57
+ export { ReadyResponse };
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/dto/index.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,mBAAmB,MAAM,sCAAsC,CAAC;AACvE,OAAO,sBAAsB,MAAM,yCAAyC,CAAC;AAC7E,OAAO,oBAAoB,MAAM,uCAAuC,CAAC;AACzE,OAAO,kBAAkB,MAAM,qCAAqC,CAAC;AACrE,OAAO,oBAAoB,MAAM,uCAAuC,CAAC;AACzE,OAAO,mBAAmB,MAAM,sCAAsC,CAAC;AAEvE;;;;;;;GAOG;AAGI,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,aAAa;IADzB,MAAM,CAAC,mBAAmB,CAAC;GACf,aAAa,CAAG;;AAGtB,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;CAAG,CAAA;AAAnB,gBAAgB;IAD5B,MAAM,CAAC,sBAAsB,CAAC;GAClB,gBAAgB,CAAG;;AAGzB,IAAM,cAAc,GAApB,MAAM,cAAc;CAAG,CAAA;AAAjB,cAAc;IAD1B,MAAM,CAAC,oBAAoB,CAAC;GAChB,cAAc,CAAG;;AAGvB,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,YAAY;IADxB,MAAM,CAAC,kBAAkB,CAAC;GACd,YAAY,CAAG;;AAGrB,IAAM,cAAc,GAApB,MAAM,cAAc;CAAG,CAAA;AAAjB,cAAc;IAD1B,MAAM,CAAC,oBAAoB,CAAC;GAChB,cAAc,CAAG;;AAGvB,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,aAAa;IADzB,MAAM,CAAC,mBAAmB,CAAC;GACf,aAAa,CAAG"}
@@ -0,0 +1,32 @@
1
+ import { Metrics } from './metrics.js';
2
+ import { TelemetryStore } from './store.js';
3
+ /**
4
+ * Minimal request/response shapes the endpoint handlers rely on. Kept
5
+ * intentionally structural ( `setHeader` / `end` ) so the handlers are not
6
+ * coupled to express beyond what a plain Node `ServerResponse` provides.
7
+ */
8
+ export interface IMinimalResponse {
9
+ setHeader(name: string, value: string): void;
10
+ statusCode?: number;
11
+ end(body?: string): void;
12
+ }
13
+ export type MinimalRequest = unknown;
14
+ /**
15
+ * Build the Prometheus `/metrics` scrape handler.
16
+ *
17
+ * Sets `Content-Type` from the registry and writes the ( async-rendered )
18
+ * exposition text.
19
+ */
20
+ export declare function metricsHandler(metrics: Metrics): (req: MinimalRequest, res: IMinimalResponse) => Promise<void>;
21
+ /**
22
+ * Build the JSON stats handler.
23
+ *
24
+ * Writes `{ all: RequestStats.toJSON(), timeline: Timeline.toJSON() }` read
25
+ * from the shared telemetry store — the same counters `GET /telemetry/stats`
26
+ * serves. The rate fields differ though: only the controller endpoint calls
27
+ * `RequestStats.updateRates( ... )`, and because that MUTATES the shared
28
+ * `RequestStats`, the `req_rate` / `err_rate` this handler emits are whatever
29
+ * the last `/telemetry/stats` call left behind ( `0` if nobody has called it ).
30
+ */
31
+ export declare function statsHandler(store: TelemetryStore): (req: MinimalRequest, res: IMinimalResponse) => void;
32
+ //# sourceMappingURL=endpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC;AAErC;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,CAM9G;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,gBAAgB,KAAK,IAAI,CASxG"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Build the Prometheus `/metrics` scrape handler.
3
+ *
4
+ * Sets `Content-Type` from the registry and writes the ( async-rendered )
5
+ * exposition text.
6
+ */
7
+ export function metricsHandler(metrics) {
8
+ return async (_req, res) => {
9
+ const body = await metrics.render();
10
+ res.setHeader('Content-Type', metrics.contentType());
11
+ res.end(body);
12
+ };
13
+ }
14
+ /**
15
+ * Build the JSON stats handler.
16
+ *
17
+ * Writes `{ all: RequestStats.toJSON(), timeline: Timeline.toJSON() }` read
18
+ * from the shared telemetry store — the same counters `GET /telemetry/stats`
19
+ * serves. The rate fields differ though: only the controller endpoint calls
20
+ * `RequestStats.updateRates( ... )`, and because that MUTATES the shared
21
+ * `RequestStats`, the `req_rate` / `err_rate` this handler emits are whatever
22
+ * the last `/telemetry/stats` call left behind ( `0` if nobody has called it ).
23
+ */
24
+ export function statsHandler(store) {
25
+ return (_req, res) => {
26
+ const body = JSON.stringify({
27
+ all: store.RequestStats.toJSON(),
28
+ timeline: store.Timeline.toJSON(),
29
+ });
30
+ res.setHeader('Content-Type', 'application/json');
31
+ res.end(body);
32
+ };
33
+ }
34
+ //# sourceMappingURL=endpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/endpoints.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO,KAAK,EAAE,IAAoB,EAAE,GAAqB,EAAiB,EAAE;QAC1E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;QACpC,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;QACrD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAAC,KAAqB;IAChD,OAAO,CAAC,IAAoB,EAAE,GAAqB,EAAQ,EAAE;QAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;YAC1B,GAAG,EAAE,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE;YAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE;SAClC,CAAC,CAAC;QACH,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { AsyncService } from '@spinajs/di';
2
+ /** Outcome of a single health check. */
3
+ export type HealthStatus = 'up' | 'degraded' | 'down';
4
+ /** What a {@link HealthCheck} returns. */
5
+ export interface IHealthResult {
6
+ status: HealthStatus;
7
+ message?: string;
8
+ data?: Record<string, unknown>;
9
+ }
10
+ /** One check's line in the readiness report. */
11
+ export interface IHealthCheckReport extends IHealthResult {
12
+ name: string;
13
+ /** How long the check took, in ms. */
14
+ durationMs: number;
15
+ }
16
+ /** The body served by `GET /telemetry/ready`. */
17
+ export interface IReadyReport {
18
+ status: HealthStatus;
19
+ checks: IHealthCheckReport[];
20
+ }
21
+ /**
22
+ * A readiness probe for one dependency.
23
+ *
24
+ * Register a concrete subclass with `@Injectable( HealthCheck )` and it is
25
+ * discovered by {@link HealthCheckRunner} via `Array.ofType( HealthCheck )`.
26
+ * `@spinajs/telemetry` deliberately ships NO concrete checks — a database check
27
+ * belongs where the database dependency already is, not in the observability
28
+ * package.
29
+ *
30
+ * `check()` may throw; a throw counts as `down`.
31
+ */
32
+ export declare abstract class HealthCheck extends AsyncService {
33
+ /** Stable identifier for this check, used as the report key. */
34
+ abstract Name: string;
35
+ abstract check(): Promise<IHealthResult>;
36
+ }
37
+ /**
38
+ * Runs every registered {@link HealthCheck} concurrently, each raced against a
39
+ * per-check timeout, and reduces the results to one overall status.
40
+ *
41
+ * The timeout is the point of the class: a readiness endpoint that can hang is
42
+ * worse than no readiness endpoint, because a kubelet probe blocks on it.
43
+ */
44
+ export declare class HealthCheckRunner {
45
+ protected Checks: HealthCheck[];
46
+ protected TimeoutMs: number;
47
+ protected FailOnDegraded: boolean;
48
+ /**
49
+ * True when the overall status should be served as HTTP 503.
50
+ */
51
+ isFailing(status: HealthStatus): boolean;
52
+ run(): Promise<IReadyReport>;
53
+ private runOne;
54
+ }
55
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAqC,MAAM,aAAa,CAAC;AAG9E,wCAAwC;AACxC,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,UAAU,GAAG,MAAM,CAAC;AAEtD,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED;;;;;;;;;;GAUG;AACH,8BAAsB,WAAY,SAAQ,YAAY;IACpD,gEAAgE;IAChE,SAAgB,IAAI,EAAE,MAAM,CAAC;aAEb,KAAK,IAAI,OAAO,CAAC,aAAa,CAAC;CAChD;AAkBD;;;;;;GAMG;AACH,qBAEa,iBAAiB;IAE5B,SAAS,CAAC,MAAM,EAAG,WAAW,EAAE,CAAC;IAGjC,SAAS,CAAC,SAAS,EAAG,MAAM,CAAC;IAG7B,SAAS,CAAC,cAAc,EAAG,OAAO,CAAC;IAEnC;;OAEG;IACI,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO;IAKlC,GAAG,IAAI,OAAO,CAAC,YAAY,CAAC;YAe3B,MAAM;CAqBrB"}