@application-kit/observability 0.2.0 → 0.3.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.
Files changed (143) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +62 -18
  3. package/dist/cjs/cqrs/cqrs-logger.d.ts +1 -1
  4. package/dist/cjs/cqrs/cqrs-logger.js +1 -1
  5. package/dist/cjs/cqrs/index.d.ts +0 -2
  6. package/dist/cjs/cqrs/index.js +0 -2
  7. package/dist/cjs/health/cli/health-cli-commands.d.ts +10 -0
  8. package/dist/cjs/health/cli/health-cli-commands.js +46 -0
  9. package/dist/cjs/health/cli/health-cli-options.interface.d.ts +3 -0
  10. package/dist/cjs/health/cli/health-cli.d.ts +4 -0
  11. package/dist/cjs/health/cli/health-cli.js +32 -0
  12. package/dist/cjs/health/cli/health-cli.module.d.ts +5 -0
  13. package/dist/cjs/health/cli/health-cli.module.js +23 -0
  14. package/dist/cjs/health/cli/index.d.ts +4 -0
  15. package/dist/cjs/health/cli/index.js +20 -0
  16. package/dist/cjs/health/graphql/health-check.type.d.ts +3 -0
  17. package/dist/cjs/health/graphql/health-check.type.js +24 -0
  18. package/dist/cjs/health/graphql/health-graphql.module.d.ts +5 -0
  19. package/dist/cjs/health/graphql/health-graphql.module.js +26 -0
  20. package/dist/cjs/health/graphql/health.resolver.d.ts +11 -0
  21. package/dist/cjs/health/graphql/health.resolver.js +55 -0
  22. package/dist/cjs/health/graphql/index.d.ts +3 -0
  23. package/dist/cjs/health/graphql/index.js +19 -0
  24. package/dist/cjs/health/health-checks.d.ts +10 -0
  25. package/dist/cjs/health/health-checks.js +53 -0
  26. package/dist/cjs/health/health-http.module.d.ts +5 -0
  27. package/dist/cjs/health/health-http.module.js +26 -0
  28. package/dist/cjs/health/health-module-options.interface.d.ts +9 -0
  29. package/dist/cjs/health/health-module-options.interface.js +2 -0
  30. package/dist/cjs/health/health.config.d.ts +8 -0
  31. package/dist/cjs/health/health.config.js +39 -0
  32. package/dist/cjs/health/health.controller.d.ts +14 -0
  33. package/dist/cjs/health/health.controller.js +78 -0
  34. package/dist/cjs/health/health.environment.d.ts +5 -0
  35. package/dist/cjs/health/health.environment.js +38 -0
  36. package/dist/cjs/health/health.module.d.ts +5 -0
  37. package/dist/cjs/health/health.module.js +28 -0
  38. package/dist/cjs/health/index.d.ts +8 -0
  39. package/dist/cjs/health/index.js +24 -0
  40. package/dist/cjs/health/migrations.health-indicator.d.ts +9 -0
  41. package/dist/cjs/health/migrations.health-indicator.js +40 -0
  42. package/dist/cjs/logging/index.d.ts +8 -0
  43. package/dist/cjs/logging/index.js +24 -0
  44. package/dist/cjs/logging/infrastructure-paths.d.ts +4 -0
  45. package/dist/cjs/logging/infrastructure-paths.js +9 -0
  46. package/dist/cjs/logging/logger.environment.d.ts +4 -0
  47. package/dist/cjs/logging/logger.environment.js +24 -0
  48. package/dist/cjs/logging/observability-logger.interface.js +2 -0
  49. package/dist/cjs/logging/pino-logger-options.interface.d.ts +5 -0
  50. package/dist/cjs/logging/pino-logger-options.interface.js +2 -0
  51. package/dist/cjs/logging/pino-logger.config.d.ts +15 -0
  52. package/dist/cjs/logging/pino-logger.config.js +104 -0
  53. package/dist/cjs/logging/resolve-request-id.d.ts +4 -0
  54. package/dist/cjs/logging/resolve-request-id.js +10 -0
  55. package/dist/cjs/logging/resolve-support-id.d.ts +3 -0
  56. package/dist/cjs/logging/resolve-support-id.js +8 -0
  57. package/dist/cjs/metrics/index.d.ts +3 -0
  58. package/dist/cjs/metrics/index.js +3 -0
  59. package/dist/cjs/metrics/metrics-hooks.d.ts +2 -0
  60. package/dist/cjs/metrics/metrics-hooks.js +37 -0
  61. package/dist/cjs/metrics/metrics-http.module.d.ts +5 -0
  62. package/dist/cjs/metrics/metrics-http.module.js +29 -0
  63. package/dist/cjs/metrics/metrics.controller.d.ts +7 -0
  64. package/dist/cjs/metrics/metrics.controller.js +42 -0
  65. package/dist/cjs/shared/active-span-context.d.ts +2 -0
  66. package/dist/cjs/shared/active-span-context.js +9 -0
  67. package/dist/cjs/shared/with-class-decorator.d.ts +2 -0
  68. package/dist/cjs/shared/with-class-decorator.js +14 -0
  69. package/dist/esm/cqrs/cqrs-logger.d.ts +1 -1
  70. package/dist/esm/cqrs/cqrs-logger.js +1 -1
  71. package/dist/esm/cqrs/index.d.ts +0 -2
  72. package/dist/esm/cqrs/index.js +0 -2
  73. package/dist/esm/health/cli/health-cli-commands.d.ts +10 -0
  74. package/dist/esm/health/cli/health-cli-commands.js +43 -0
  75. package/dist/esm/health/cli/health-cli-options.interface.d.ts +3 -0
  76. package/dist/esm/health/cli/health-cli.d.ts +4 -0
  77. package/dist/esm/health/cli/health-cli.js +28 -0
  78. package/dist/esm/health/cli/health-cli.module.d.ts +5 -0
  79. package/dist/esm/health/cli/health-cli.module.js +20 -0
  80. package/dist/esm/health/cli/index.d.ts +4 -0
  81. package/dist/esm/health/cli/index.js +4 -0
  82. package/dist/esm/health/graphql/health-check.type.d.ts +3 -0
  83. package/dist/esm/health/graphql/health-check.type.js +21 -0
  84. package/dist/esm/health/graphql/health-graphql.module.d.ts +5 -0
  85. package/dist/esm/health/graphql/health-graphql.module.js +23 -0
  86. package/dist/esm/health/graphql/health.resolver.d.ts +11 -0
  87. package/dist/esm/health/graphql/health.resolver.js +52 -0
  88. package/dist/esm/health/graphql/index.d.ts +3 -0
  89. package/dist/esm/health/graphql/index.js +3 -0
  90. package/dist/esm/health/health-checks.d.ts +10 -0
  91. package/dist/esm/health/health-checks.js +50 -0
  92. package/dist/esm/health/health-http.module.d.ts +5 -0
  93. package/dist/esm/health/health-http.module.js +23 -0
  94. package/dist/esm/health/health-module-options.interface.d.ts +9 -0
  95. package/dist/esm/health/health-module-options.interface.js +1 -0
  96. package/dist/esm/health/health.config.d.ts +8 -0
  97. package/dist/esm/health/health.config.js +36 -0
  98. package/dist/esm/health/health.controller.d.ts +14 -0
  99. package/dist/esm/health/health.controller.js +75 -0
  100. package/dist/esm/health/health.environment.d.ts +5 -0
  101. package/dist/esm/health/health.environment.js +34 -0
  102. package/dist/esm/health/health.module.d.ts +5 -0
  103. package/dist/esm/health/health.module.js +25 -0
  104. package/dist/esm/health/index.d.ts +8 -0
  105. package/dist/esm/health/index.js +8 -0
  106. package/dist/esm/health/migrations.health-indicator.d.ts +9 -0
  107. package/dist/esm/health/migrations.health-indicator.js +37 -0
  108. package/dist/esm/logging/index.d.ts +8 -0
  109. package/dist/esm/logging/index.js +8 -0
  110. package/dist/esm/logging/infrastructure-paths.d.ts +4 -0
  111. package/dist/esm/logging/infrastructure-paths.js +5 -0
  112. package/dist/esm/logging/logger.environment.d.ts +4 -0
  113. package/dist/esm/logging/logger.environment.js +20 -0
  114. package/dist/esm/logging/observability-logger.interface.js +1 -0
  115. package/dist/esm/logging/pino-logger-options.interface.d.ts +5 -0
  116. package/dist/esm/logging/pino-logger-options.interface.js +1 -0
  117. package/dist/esm/logging/pino-logger.config.d.ts +15 -0
  118. package/dist/esm/logging/pino-logger.config.js +99 -0
  119. package/dist/esm/logging/resolve-request-id.d.ts +4 -0
  120. package/dist/esm/logging/resolve-request-id.js +6 -0
  121. package/dist/esm/logging/resolve-support-id.d.ts +3 -0
  122. package/dist/esm/logging/resolve-support-id.js +4 -0
  123. package/dist/esm/metrics/index.d.ts +3 -0
  124. package/dist/esm/metrics/index.js +3 -0
  125. package/dist/esm/metrics/metrics-hooks.d.ts +2 -0
  126. package/dist/esm/metrics/metrics-hooks.js +33 -0
  127. package/dist/esm/metrics/metrics-http.module.d.ts +5 -0
  128. package/dist/esm/metrics/metrics-http.module.js +26 -0
  129. package/dist/esm/metrics/metrics.controller.d.ts +7 -0
  130. package/dist/esm/metrics/metrics.controller.js +39 -0
  131. package/dist/esm/shared/active-span-context.d.ts +2 -0
  132. package/dist/esm/shared/active-span-context.js +5 -0
  133. package/dist/esm/shared/with-class-decorator.d.ts +2 -0
  134. package/dist/esm/shared/with-class-decorator.js +10 -0
  135. package/package.json +111 -5
  136. /package/dist/cjs/{cqrs/observability-logger.interface.js → health/cli/health-cli-options.interface.js} +0 -0
  137. /package/dist/cjs/{cqrs → logging}/constants.d.ts +0 -0
  138. /package/dist/cjs/{cqrs → logging}/constants.js +0 -0
  139. /package/dist/cjs/{cqrs → logging}/observability-logger.interface.d.ts +0 -0
  140. /package/dist/esm/{cqrs/observability-logger.interface.js → health/cli/health-cli-options.interface.js} +0 -0
  141. /package/dist/esm/{cqrs → logging}/constants.d.ts +0 -0
  142. /package/dist/esm/{cqrs → logging}/constants.js +0 -0
  143. /package/dist/esm/{cqrs → logging}/observability-logger.interface.d.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @application-kit/observability
2
2
 
3
+ ## 0.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 3ed0384: `HealthCliModule`: команда `health` снова регистрируется в группе потребителя. В 0.3.0 она была унаследована подклассом-группой,
8
+ а сканер nestjs-console видит только собственные методы класса — CLI отвечал `too many arguments for '<группа>'`, и проверка
9
+ по крону не выполнялась.
10
+
11
+ ## 0.3.0
12
+
13
+ ### Minor Changes
14
+
15
+ - 5311ebc: Входы `/logging`, `/health` (+ `/health/graphql`, `/health/cli`) и веб-часть `/metrics`.
16
+
17
+ - `/logging`: `PinoLoggerConfig` и `LoggerEnvironment` — опции nestjs-pino (уровень по исходу ответа, severity,
18
+ trace-миксин, redact, IP клиента через `resolveClientIp`), `resolveRequestId`/`REQUEST_ID_HEADER`, `resolveSupportId`,
19
+ `INFRASTRUCTURE_PATHS`/`isInfrastructurePath`.
20
+ - `/health`: `HealthModule.forRoot` (terminus + состав чека), `HealthHttpModule.forRoot` (`/health`, `/health/live`,
21
+ `/health/ready`), `HealthConfig`/`HealthEnvironment`, `MigrationsHealthIndicator`; носители GraphQL и CLI — подвходами.
22
+ - `/metrics`: `MetricsHttpModule.forRoot` с `GET /metrics` и `setupMetricsHooks(app)` — хуки Fastify и mercurius.
23
+
24
+ **Ломающее:** токен `OBSERVABILITY_LOGGER` и `ObservabilityLoggerInterface` переехали из `/cqrs` во вход `/logging` —
25
+ импорт потребителя меняется на `@application-kit/observability/logging`.
26
+
3
27
  ## 0.2.0
4
28
 
5
29
  ### Minor Changes
package/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # @application-kit/observability
2
2
 
3
- Наблюдаемость NestJS-процесса: метрики Prometheus (`/metrics`), логирование команд и запросов CQRS-шин (`/cqrs`)
4
- и реальный IP клиента за прокси (`/http`). Пакет не знает ни маршрутов, ни схемы,
5
- ни портов приложения: ярлыки и порт приходят параметрами, а хуки веб-сервера и контроллер скрейпа остаются у потребителя.
3
+ Наблюдаемость NestJS-процесса: метрики Prometheus и контроллер скрейпа (`/metrics`), health-чек и пробы оркестратора
4
+ (`/health`), опции pino с request-id и trace-контекстом (`/logging`), логирование команд и запросов CQRS-шин (`/cqrs`)
5
+ и реальный IP клиента за прокси (`/http`). Пакет не знает ни продукта, ни guard'ов, ни прокси приложения: имя
6
+ CLI-команды, декоратор публичного маршрута и доверенные заголовки приходят параметрами.
6
7
 
7
8
  ## Установка
8
9
 
@@ -10,16 +11,19 @@
10
11
  yarn add @application-kit/observability
11
12
  ```
12
13
 
13
- Peer-зависимости: `@nestjs/common`, `@prometheus-io/client`; optional — `graphql` (нужен только GraphQL-гистограмме,
14
- из него берутся типы документа) и `@nestjs/cqrs` (нужен только входу `/cqrs`).
14
+ Peer-зависимости: `@nestjs/common`, `@prometheus-io/client`; остальные optional и нужны только своему входу — см. таблицу.
15
15
 
16
16
  ## Входы
17
17
 
18
18
  | Вход | Для чего | Тянет |
19
19
  |------|----------|-------|
20
20
  | `@application-kit/observability/cqrs` | логирование команд и запросов обеих шин | `@nestjs/common`, `@nestjs/cqrs` |
21
+ | `@application-kit/observability/health` | состав чека, пробы `/health/live` и `/health/ready`, `GET /health` | `@nestjs/terminus`, `@nestjs/typeorm`, `typeorm`, `@application-kit/typeorm`, `class-validator`, `class-transformer` |
22
+ | `@application-kit/observability/health/graphql` | `query { health { status } }` | `/health` + `@nestjs/graphql` |
23
+ | `@application-kit/observability/health/cli` | CLI-команда `<группа> health` | `/health` + `nestjs-console` |
21
24
  | `@application-kit/observability/http` | `resolveClientIp` — IP клиента за прокси | ничего |
22
- | `@application-kit/observability/metrics` | реестр, гистограммы HTTP и GraphQL, сервер `/metrics` | `@nestjs/common`, `@prometheus-io/client` |
25
+ | `@application-kit/observability/logging` | опции nestjs-pino, request-id, support-id, служебные пути, токен логгера | `@opentelemetry/api`, `class-validator`, `class-transformer`; типы — `nestjs-pino`, `pino` |
26
+ | `@application-kit/observability/metrics` | реестр, гистограммы HTTP и GraphQL, `GET /metrics`, хуки Fastify, сервер `/metrics` | `@nestjs/common`, `@prometheus-io/client`; типы — `fastify`, `@nestjs/platform-fastify` |
23
27
 
24
28
  Корневого входа нет: каждый вход несёт свои peer-зависимости, и лишнего потребитель не ставит.
25
29
 
@@ -35,18 +39,16 @@ Peer-зависимости: `@nestjs/common`, `@prometheus-io/client`; optional
35
39
  `asMercuriusHook` оборачивает синхронный обработчик в async-хук Mercurius.
36
40
  - `DURATION_BUCKETS_SECONDS` — общие границы гистограмм, от 5 мс до 10 с.
37
41
 
42
+ Web-процесс подключает `MetricsHttpModule.forRoot({ publicRoute })` — реестр, обе гистограммы и `GET /metrics`
43
+ (путь — `METRICS_ROUTE` входа `/logging`), — и вешает хуки после создания приложения: HTTP — `onResponse` Fastify
44
+ (видит и 404, и ошибки парсинга, которых не видит интерцептор Nest), GraphQL — хуки mercurius в `onReady`.
45
+
38
46
  ```ts
39
- app.register(async (instance) => {
40
- instance.addHook('onResponse', (request, reply, done) => {
41
- httpMetrics.observe({
42
- durationSeconds: reply.elapsedTime / 1000,
43
- method: request.method,
44
- route: resolveRouteLabel(request.routeOptions.url),
45
- status: reply.statusCode,
46
- })
47
- done()
48
- })
49
- })
47
+ @Module({ imports: [MetricsHttpModule.forRoot({ publicRoute: Public() })] })
48
+ export class WebModule {}
49
+
50
+ const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter())
51
+ setupMetricsHooks(app)
50
52
  ```
51
53
 
52
54
  ## Сервер `/metrics` без веб-слоя
@@ -66,7 +68,8 @@ const server = startMetricsServer({ onError: (error) => logger.error(error), por
66
68
  длительность и исход шина не публикует). В лог идёт ИМЯ класса, не полезная нагрузка; ошибка хендлера пишется на `error`
67
69
  и пробрасывается дальше.
68
70
 
69
- Логгер приложение приносит глобально токеном `OBSERVABILITY_LOGGER` — подходит любой логгер с `info(payload, message)`
71
+ Логгер приложение приносит глобально токеном `OBSERVABILITY_LOGGER` (вход `/logging`; им же пишут носители health-чека)
72
+ — подходит любой логгер с `info(payload, message)`
70
73
  и `error(payload, message)`, например `PinoLogger` из `nestjs-pino`:
71
74
 
72
75
  ```ts
@@ -81,6 +84,47 @@ export class CommonModule {}
81
84
  export class AppModule {}
82
85
  ```
83
86
 
87
+ ## Логирование HTTP (`/logging`)
88
+
89
+ - `PinoLoggerConfig.createOptions({ resolveClientIp })` — опции `LoggerModule` из nestjs-pino: уровень из
90
+ `LoggerEnvironment.LOG_LEVEL` (дефолт `warn`), уровень строки ответа по исходу (`responseLogLevel`: 5xx и исключение —
91
+ `error`, 4xx — `warn`, успешный служебный запрос — `debug`), `severity` для бэкенда логов, `trace_id`/`span_id` в каждой
92
+ строке (`traceContextMixin`), redact паролей и заголовков `authorization`/`cookie`, адрес клиента в `req.remoteAddress`.
93
+ Без `resolveClientIp` заголовкам не верят — см. «IP клиента за прокси».
94
+ - `REQUEST_ID_HEADER` и `resolveRequestId` — `genReqId` Fastify: `x-request-id` от прокси либо свой UUID.
95
+ - `resolveSupportId(request)` — идентификатор для пользователя и поддержки: trace_id активного спана, вне трассы — `request.id`.
96
+ - `INFRASTRUCTURE_PATHS`, `isInfrastructurePath` — служебные маршруты (`/health`, `/metrics`) для тишины логов и трасс;
97
+ контроллеры входов `/health` и `/metrics` берут путь отсюда же.
98
+
99
+ `LoggerEnvironment` и `HealthEnvironment` регистрирует приложение своим загрузчиком конфигов, как `DatabaseEnvironment`
100
+ из `@application-kit/typeorm/nest`.
101
+
102
+ ## Health-чек (`/health`)
103
+
104
+ `HealthModule.forRoot({ imports, logger })` — глобальное ядро процесса: terminus и `HealthChecks` (ping БД, heap, RSS,
105
+ диск по корню; пороги — `HealthConfig`/`HealthEnvironment`). Носители подключаются там, где нужны, и берут состав
106
+ отсюда — вердикт не зависит от того, каким путём спросили:
107
+
108
+ - `HealthHttpModule.forRoot({ publicRoute })` — `GET /health` (полный чек), `/health/live` (пустая, без зависимостей) и
109
+ `/health/ready` (ping БД и применённые миграции). SQL проб идёт в области `runAsInfrastructureQuery` и логируется на `debug`.
110
+ - `HealthGraphqlModule.forRoot({ publicRoute })` (вход `/health/graphql`) — `query { health { status } }`; отказ —
111
+ `status: "error"` и запись в лог.
112
+ - `HealthCliModule.forRoot({ command })` (вход `/health/cli`) — `<command> health`, вердикт в лог.
113
+
114
+ `publicRoute` — декоратор класса потребителя (например `Public()` его guard'а); он ложится на подкласс носителя,
115
+ классы пакета не мутируются.
116
+
117
+ ```ts
118
+ @Module({
119
+ imports: [
120
+ HealthModule.forRoot({ imports: [healthConfigsModule], logger: Logger }),
121
+ HealthHttpModule.forRoot({ publicRoute: Public() }),
122
+ HealthGraphqlModule.forRoot({ publicRoute: Public() }),
123
+ ],
124
+ })
125
+ export class WebModule {}
126
+ ```
127
+
84
128
  ## IP клиента за прокси
85
129
 
86
130
  `resolveClientIp(request, { trustedHeaders })` принимает `IncomingMessage`, `FastifyRequest` или его обёртку из
@@ -1,6 +1,6 @@
1
1
  import { OnApplicationBootstrap } from '@nestjs/common';
2
2
  import { CommandBus, QueryBus } from '@nestjs/cqrs';
3
- import type { ObservabilityLoggerInterface } from './observability-logger.interface.js';
3
+ import type { ObservabilityLoggerInterface } from '../logging/observability-logger.interface.js';
4
4
  export declare class CqrsLogger implements OnApplicationBootstrap {
5
5
  private readonly commandBus;
6
6
  private readonly queryBus;
@@ -16,7 +16,7 @@ exports.CqrsLogger = void 0;
16
16
  const common_1 = require("@nestjs/common");
17
17
  const cqrs_1 = require("@nestjs/cqrs");
18
18
  const node_perf_hooks_1 = require("node:perf_hooks");
19
- const constants_js_1 = require("./constants.js");
19
+ const constants_js_1 = require("../logging/constants.js");
20
20
  const KIND_COMMAND = 'command';
21
21
  const KIND_QUERY = 'query';
22
22
  let CqrsLogger = class CqrsLogger {
@@ -1,4 +1,2 @@
1
- export * from './constants.js';
2
1
  export * from './cqrs-logger.js';
3
2
  export * from './cqrs-logger.module.js';
4
- export * from './observability-logger.interface.js';
@@ -14,7 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./constants.js"), exports);
18
17
  __exportStar(require("./cqrs-logger.js"), exports);
19
18
  __exportStar(require("./cqrs-logger.module.js"), exports);
20
- __exportStar(require("./observability-logger.interface.js"), exports);
@@ -0,0 +1,10 @@
1
+ import { HealthCheckService } from '@nestjs/terminus';
2
+ import type { ObservabilityLoggerInterface } from '../../logging/observability-logger.interface.js';
3
+ import { HealthChecks } from '../health-checks.js';
4
+ export declare class HealthCliCommands {
5
+ private readonly health;
6
+ private readonly logger;
7
+ private readonly healthChecks;
8
+ constructor(health: HealthCheckService, logger: ObservabilityLoggerInterface, healthChecks: HealthChecks);
9
+ getHealth(): Promise<void>;
10
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.HealthCliCommands = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const terminus_1 = require("@nestjs/terminus");
18
+ const constants_js_1 = require("../../logging/constants.js");
19
+ const health_checks_js_1 = require("../health-checks.js");
20
+ let HealthCliCommands = class HealthCliCommands {
21
+ health;
22
+ logger;
23
+ healthChecks;
24
+ constructor(health, logger, healthChecks) {
25
+ this.health = health;
26
+ this.logger = logger;
27
+ this.healthChecks = healthChecks;
28
+ }
29
+ async getHealth() {
30
+ try {
31
+ const healthResult = await this.health.check(this.healthChecks.build());
32
+ this.logger.info({ healthResult }, healthResult.status);
33
+ }
34
+ catch (error) {
35
+ const healthResult = error instanceof common_1.ServiceUnavailableException ? error.getResponse() : 'unknown';
36
+ this.logger.error({ healthResult }, 'error');
37
+ }
38
+ }
39
+ };
40
+ exports.HealthCliCommands = HealthCliCommands;
41
+ exports.HealthCliCommands = HealthCliCommands = __decorate([
42
+ __param(0, (0, common_1.Inject)(terminus_1.HealthCheckService)),
43
+ __param(1, (0, common_1.Inject)(constants_js_1.OBSERVABILITY_LOGGER)),
44
+ __param(2, (0, common_1.Inject)(health_checks_js_1.HealthChecks)),
45
+ __metadata("design:paramtypes", [terminus_1.HealthCheckService, Object, health_checks_js_1.HealthChecks])
46
+ ], HealthCliCommands);
@@ -0,0 +1,3 @@
1
+ export interface HealthCliOptionsInterface {
2
+ readonly command: string;
3
+ }
@@ -0,0 +1,4 @@
1
+ import type { Type } from '@nestjs/common';
2
+ import type { HealthCliOptionsInterface } from './health-cli-options.interface.js';
3
+ import { HealthCliCommands } from './health-cli-commands.js';
4
+ export declare const createHealthCli: (options: HealthCliOptionsInterface) => Type<HealthCliCommands>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.createHealthCli = void 0;
13
+ const nestjs_console_1 = require("nestjs-console");
14
+ const health_cli_commands_js_1 = require("./health-cli-commands.js");
15
+ const createHealthCli = (options) => {
16
+ let HealthCli = class HealthCli extends health_cli_commands_js_1.HealthCliCommands {
17
+ async getHealth() {
18
+ await super.getHealth();
19
+ }
20
+ };
21
+ __decorate([
22
+ (0, nestjs_console_1.Command)({ command: 'health' }),
23
+ __metadata("design:type", Function),
24
+ __metadata("design:paramtypes", []),
25
+ __metadata("design:returntype", Promise)
26
+ ], HealthCli.prototype, "getHealth", null);
27
+ HealthCli = __decorate([
28
+ (0, nestjs_console_1.Console)({ command: options.command })
29
+ ], HealthCli);
30
+ return HealthCli;
31
+ };
32
+ exports.createHealthCli = createHealthCli;
@@ -0,0 +1,5 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ import type { HealthCliOptionsInterface } from './health-cli-options.interface.js';
3
+ export declare class HealthCliModule {
4
+ static forRoot(options: HealthCliOptionsInterface): DynamicModule;
5
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.HealthCliModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const health_cli_js_1 = require("./health-cli.js");
12
+ let HealthCliModule = class HealthCliModule {
13
+ static forRoot(options) {
14
+ return {
15
+ module: this,
16
+ providers: [(0, health_cli_js_1.createHealthCli)(options)],
17
+ };
18
+ }
19
+ };
20
+ exports.HealthCliModule = HealthCliModule;
21
+ exports.HealthCliModule = HealthCliModule = __decorate([
22
+ (0, common_1.Module)({})
23
+ ], HealthCliModule);
@@ -0,0 +1,4 @@
1
+ export * from './health-cli.js';
2
+ export * from './health-cli-commands.js';
3
+ export * from './health-cli-options.interface.js';
4
+ export * from './health-cli.module.js';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./health-cli.js"), exports);
18
+ __exportStar(require("./health-cli-commands.js"), exports);
19
+ __exportStar(require("./health-cli-options.interface.js"), exports);
20
+ __exportStar(require("./health-cli.module.js"), exports);
@@ -0,0 +1,3 @@
1
+ export declare class HealthCheckType {
2
+ status: string;
3
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.HealthCheckType = void 0;
13
+ const graphql_1 = require("@nestjs/graphql");
14
+ let HealthCheckType = class HealthCheckType {
15
+ status;
16
+ };
17
+ exports.HealthCheckType = HealthCheckType;
18
+ __decorate([
19
+ (0, graphql_1.Field)(() => String),
20
+ __metadata("design:type", String)
21
+ ], HealthCheckType.prototype, "status", void 0);
22
+ exports.HealthCheckType = HealthCheckType = __decorate([
23
+ (0, graphql_1.ObjectType)('HealthCheck')
24
+ ], HealthCheckType);
@@ -0,0 +1,5 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ import type { HealthCarrierOptionsInterface } from '../health-module-options.interface.js';
3
+ export declare class HealthGraphqlModule {
4
+ static forRoot(options?: HealthCarrierOptionsInterface): DynamicModule;
5
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.HealthGraphqlModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const graphql_1 = require("@nestjs/graphql");
12
+ const with_class_decorator_js_1 = require("../../shared/with-class-decorator.js");
13
+ const health_resolver_js_1 = require("./health.resolver.js");
14
+ let HealthGraphqlModule = class HealthGraphqlModule {
15
+ static forRoot(options = {}) {
16
+ const consumerDecorators = options.publicRoute === undefined ? [] : [options.publicRoute];
17
+ return {
18
+ module: this,
19
+ providers: [(0, with_class_decorator_js_1.withClassDecorator)(health_resolver_js_1.HealthResolver, (0, common_1.applyDecorators)((0, graphql_1.Resolver)(), ...consumerDecorators))],
20
+ };
21
+ }
22
+ };
23
+ exports.HealthGraphqlModule = HealthGraphqlModule;
24
+ exports.HealthGraphqlModule = HealthGraphqlModule = __decorate([
25
+ (0, common_1.Module)({})
26
+ ], HealthGraphqlModule);
@@ -0,0 +1,11 @@
1
+ import { HealthCheckService } from '@nestjs/terminus';
2
+ import type { ObservabilityLoggerInterface } from '../../logging/observability-logger.interface.js';
3
+ import { HealthChecks } from '../health-checks.js';
4
+ import { HealthCheckType } from './health-check.type.js';
5
+ export declare class HealthResolver {
6
+ private readonly healthCheck;
7
+ private readonly logger;
8
+ private readonly healthChecks;
9
+ constructor(healthCheck: HealthCheckService, logger: ObservabilityLoggerInterface, healthChecks: HealthChecks);
10
+ health(): Promise<HealthCheckType>;
11
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.HealthResolver = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const graphql_1 = require("@nestjs/graphql");
18
+ const terminus_1 = require("@nestjs/terminus");
19
+ const constants_js_1 = require("../../logging/constants.js");
20
+ const health_checks_js_1 = require("../health-checks.js");
21
+ const health_check_type_js_1 = require("./health-check.type.js");
22
+ let HealthResolver = class HealthResolver {
23
+ healthCheck;
24
+ logger;
25
+ healthChecks;
26
+ constructor(healthCheck, logger, healthChecks) {
27
+ this.healthCheck = healthCheck;
28
+ this.logger = logger;
29
+ this.healthChecks = healthChecks;
30
+ }
31
+ async health() {
32
+ try {
33
+ const health = await this.healthCheck.check(this.healthChecks.build());
34
+ return { status: health.status };
35
+ }
36
+ catch (error) {
37
+ this.logger.error({ err: error }, 'GraphQL health check failed');
38
+ return { status: 'error' };
39
+ }
40
+ }
41
+ };
42
+ exports.HealthResolver = HealthResolver;
43
+ __decorate([
44
+ (0, graphql_1.Query)(() => health_check_type_js_1.HealthCheckType),
45
+ __metadata("design:type", Function),
46
+ __metadata("design:paramtypes", []),
47
+ __metadata("design:returntype", Promise)
48
+ ], HealthResolver.prototype, "health", null);
49
+ exports.HealthResolver = HealthResolver = __decorate([
50
+ (0, graphql_1.Resolver)({ isAbstract: true }),
51
+ __param(0, (0, common_1.Inject)(terminus_1.HealthCheckService)),
52
+ __param(1, (0, common_1.Inject)(constants_js_1.OBSERVABILITY_LOGGER)),
53
+ __param(2, (0, common_1.Inject)(health_checks_js_1.HealthChecks)),
54
+ __metadata("design:paramtypes", [terminus_1.HealthCheckService, Object, health_checks_js_1.HealthChecks])
55
+ ], HealthResolver);
@@ -0,0 +1,3 @@
1
+ export * from './health-check.type.js';
2
+ export * from './health-graphql.module.js';
3
+ export * from './health.resolver.js';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./health-check.type.js"), exports);
18
+ __exportStar(require("./health-graphql.module.js"), exports);
19
+ __exportStar(require("./health.resolver.js"), exports);
@@ -0,0 +1,10 @@
1
+ import { DiskHealthIndicator, HealthIndicatorFunction, MemoryHealthIndicator, TypeOrmHealthIndicator } from '@nestjs/terminus';
2
+ import { HealthConfig } from './health.config.js';
3
+ export declare class HealthChecks {
4
+ private readonly database;
5
+ private readonly memory;
6
+ private readonly disk;
7
+ private readonly config;
8
+ constructor(database: TypeOrmHealthIndicator, memory: MemoryHealthIndicator, disk: DiskHealthIndicator, config: HealthConfig);
9
+ build(): HealthIndicatorFunction[];
10
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.HealthChecks = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const terminus_1 = require("@nestjs/terminus");
18
+ const health_config_js_1 = require("./health.config.js");
19
+ let HealthChecks = class HealthChecks {
20
+ database;
21
+ memory;
22
+ disk;
23
+ config;
24
+ constructor(database, memory, disk, config) {
25
+ this.database = database;
26
+ this.memory = memory;
27
+ this.disk = disk;
28
+ this.config = config;
29
+ }
30
+ build() {
31
+ return [
32
+ async () => this.database.pingCheck('typeorm'),
33
+ async () => this.memory.checkHeap('memory_heap', this.config.memoryHeapBytes),
34
+ async () => this.memory.checkRSS('memory_rss', this.config.memoryRssBytes),
35
+ async () => this.disk.checkStorage('disk', {
36
+ path: '/',
37
+ thresholdPercent: this.config.diskThresholdPercent,
38
+ }),
39
+ ];
40
+ }
41
+ };
42
+ exports.HealthChecks = HealthChecks;
43
+ exports.HealthChecks = HealthChecks = __decorate([
44
+ (0, common_1.Injectable)(),
45
+ __param(0, (0, common_1.Inject)(terminus_1.TypeOrmHealthIndicator)),
46
+ __param(1, (0, common_1.Inject)(terminus_1.MemoryHealthIndicator)),
47
+ __param(2, (0, common_1.Inject)(terminus_1.DiskHealthIndicator)),
48
+ __param(3, (0, common_1.Inject)(health_config_js_1.HealthConfig)),
49
+ __metadata("design:paramtypes", [terminus_1.TypeOrmHealthIndicator,
50
+ terminus_1.MemoryHealthIndicator,
51
+ terminus_1.DiskHealthIndicator,
52
+ health_config_js_1.HealthConfig])
53
+ ], HealthChecks);
@@ -0,0 +1,5 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ import type { HealthCarrierOptionsInterface } from './health-module-options.interface.js';
3
+ export declare class HealthHttpModule {
4
+ static forRoot(options?: HealthCarrierOptionsInterface): DynamicModule;
5
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.HealthHttpModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const with_class_decorator_js_1 = require("../shared/with-class-decorator.js");
12
+ const health_controller_js_1 = require("./health.controller.js");
13
+ const migrations_health_indicator_js_1 = require("./migrations.health-indicator.js");
14
+ let HealthHttpModule = class HealthHttpModule {
15
+ static forRoot(options = {}) {
16
+ return {
17
+ controllers: [(0, with_class_decorator_js_1.withClassDecorator)(health_controller_js_1.HealthController, options.publicRoute)],
18
+ module: this,
19
+ providers: [migrations_health_indicator_js_1.MigrationsHealthIndicator],
20
+ };
21
+ }
22
+ };
23
+ exports.HealthHttpModule = HealthHttpModule;
24
+ exports.HealthHttpModule = HealthHttpModule = __decorate([
25
+ (0, common_1.Module)({})
26
+ ], HealthHttpModule);
@@ -0,0 +1,9 @@
1
+ import type { ModuleMetadata } from '@nestjs/common';
2
+ import type { TerminusModuleOptions } from '@nestjs/terminus';
3
+ export interface HealthCarrierOptionsInterface {
4
+ readonly publicRoute?: ClassDecorator;
5
+ }
6
+ export interface HealthModuleOptionsInterface {
7
+ readonly imports?: ModuleMetadata['imports'];
8
+ readonly terminus?: TerminusModuleOptions;
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });