@application-kit/observability 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/CHANGELOG.md +16 -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-options.interface.d.ts +3 -0
  8. package/dist/cjs/health/cli/health-cli.d.ts +13 -0
  9. package/dist/cjs/health/cli/health-cli.js +56 -0
  10. package/dist/cjs/health/cli/health-cli.module.d.ts +5 -0
  11. package/dist/cjs/health/cli/health-cli.module.js +23 -0
  12. package/dist/cjs/health/cli/index.d.ts +3 -0
  13. package/dist/cjs/health/cli/index.js +19 -0
  14. package/dist/cjs/health/graphql/health-check.type.d.ts +3 -0
  15. package/dist/cjs/health/graphql/health-check.type.js +24 -0
  16. package/dist/cjs/health/graphql/health-graphql.module.d.ts +5 -0
  17. package/dist/cjs/health/graphql/health-graphql.module.js +26 -0
  18. package/dist/cjs/health/graphql/health.resolver.d.ts +11 -0
  19. package/dist/cjs/health/graphql/health.resolver.js +55 -0
  20. package/dist/cjs/health/graphql/index.d.ts +3 -0
  21. package/dist/cjs/health/graphql/index.js +19 -0
  22. package/dist/cjs/health/health-checks.d.ts +10 -0
  23. package/dist/cjs/health/health-checks.js +53 -0
  24. package/dist/cjs/health/health-http.module.d.ts +5 -0
  25. package/dist/cjs/health/health-http.module.js +26 -0
  26. package/dist/cjs/health/health-module-options.interface.d.ts +9 -0
  27. package/dist/cjs/health/health-module-options.interface.js +2 -0
  28. package/dist/cjs/health/health.config.d.ts +8 -0
  29. package/dist/cjs/health/health.config.js +39 -0
  30. package/dist/cjs/health/health.controller.d.ts +14 -0
  31. package/dist/cjs/health/health.controller.js +78 -0
  32. package/dist/cjs/health/health.environment.d.ts +5 -0
  33. package/dist/cjs/health/health.environment.js +38 -0
  34. package/dist/cjs/health/health.module.d.ts +5 -0
  35. package/dist/cjs/health/health.module.js +28 -0
  36. package/dist/cjs/health/index.d.ts +8 -0
  37. package/dist/cjs/health/index.js +24 -0
  38. package/dist/cjs/health/migrations.health-indicator.d.ts +9 -0
  39. package/dist/cjs/health/migrations.health-indicator.js +40 -0
  40. package/dist/cjs/logging/index.d.ts +8 -0
  41. package/dist/cjs/logging/index.js +24 -0
  42. package/dist/cjs/logging/infrastructure-paths.d.ts +4 -0
  43. package/dist/cjs/logging/infrastructure-paths.js +9 -0
  44. package/dist/cjs/logging/logger.environment.d.ts +4 -0
  45. package/dist/cjs/logging/logger.environment.js +24 -0
  46. package/dist/cjs/logging/observability-logger.interface.js +2 -0
  47. package/dist/cjs/logging/pino-logger-options.interface.d.ts +5 -0
  48. package/dist/cjs/logging/pino-logger-options.interface.js +2 -0
  49. package/dist/cjs/logging/pino-logger.config.d.ts +15 -0
  50. package/dist/cjs/logging/pino-logger.config.js +104 -0
  51. package/dist/cjs/logging/resolve-request-id.d.ts +4 -0
  52. package/dist/cjs/logging/resolve-request-id.js +10 -0
  53. package/dist/cjs/logging/resolve-support-id.d.ts +3 -0
  54. package/dist/cjs/logging/resolve-support-id.js +8 -0
  55. package/dist/cjs/metrics/index.d.ts +3 -0
  56. package/dist/cjs/metrics/index.js +3 -0
  57. package/dist/cjs/metrics/metrics-hooks.d.ts +2 -0
  58. package/dist/cjs/metrics/metrics-hooks.js +37 -0
  59. package/dist/cjs/metrics/metrics-http.module.d.ts +5 -0
  60. package/dist/cjs/metrics/metrics-http.module.js +29 -0
  61. package/dist/cjs/metrics/metrics.controller.d.ts +7 -0
  62. package/dist/cjs/metrics/metrics.controller.js +42 -0
  63. package/dist/cjs/shared/active-span-context.d.ts +2 -0
  64. package/dist/cjs/shared/active-span-context.js +9 -0
  65. package/dist/cjs/shared/with-class-decorator.d.ts +2 -0
  66. package/dist/cjs/shared/with-class-decorator.js +14 -0
  67. package/dist/esm/cqrs/cqrs-logger.d.ts +1 -1
  68. package/dist/esm/cqrs/cqrs-logger.js +1 -1
  69. package/dist/esm/cqrs/index.d.ts +0 -2
  70. package/dist/esm/cqrs/index.js +0 -2
  71. package/dist/esm/health/cli/health-cli-options.interface.d.ts +3 -0
  72. package/dist/esm/health/cli/health-cli.d.ts +13 -0
  73. package/dist/esm/health/cli/health-cli.js +52 -0
  74. package/dist/esm/health/cli/health-cli.module.d.ts +5 -0
  75. package/dist/esm/health/cli/health-cli.module.js +20 -0
  76. package/dist/esm/health/cli/index.d.ts +3 -0
  77. package/dist/esm/health/cli/index.js +3 -0
  78. package/dist/esm/health/graphql/health-check.type.d.ts +3 -0
  79. package/dist/esm/health/graphql/health-check.type.js +21 -0
  80. package/dist/esm/health/graphql/health-graphql.module.d.ts +5 -0
  81. package/dist/esm/health/graphql/health-graphql.module.js +23 -0
  82. package/dist/esm/health/graphql/health.resolver.d.ts +11 -0
  83. package/dist/esm/health/graphql/health.resolver.js +52 -0
  84. package/dist/esm/health/graphql/index.d.ts +3 -0
  85. package/dist/esm/health/graphql/index.js +3 -0
  86. package/dist/esm/health/health-checks.d.ts +10 -0
  87. package/dist/esm/health/health-checks.js +50 -0
  88. package/dist/esm/health/health-http.module.d.ts +5 -0
  89. package/dist/esm/health/health-http.module.js +23 -0
  90. package/dist/esm/health/health-module-options.interface.d.ts +9 -0
  91. package/dist/esm/health/health-module-options.interface.js +1 -0
  92. package/dist/esm/health/health.config.d.ts +8 -0
  93. package/dist/esm/health/health.config.js +36 -0
  94. package/dist/esm/health/health.controller.d.ts +14 -0
  95. package/dist/esm/health/health.controller.js +75 -0
  96. package/dist/esm/health/health.environment.d.ts +5 -0
  97. package/dist/esm/health/health.environment.js +34 -0
  98. package/dist/esm/health/health.module.d.ts +5 -0
  99. package/dist/esm/health/health.module.js +25 -0
  100. package/dist/esm/health/index.d.ts +8 -0
  101. package/dist/esm/health/index.js +8 -0
  102. package/dist/esm/health/migrations.health-indicator.d.ts +9 -0
  103. package/dist/esm/health/migrations.health-indicator.js +37 -0
  104. package/dist/esm/logging/index.d.ts +8 -0
  105. package/dist/esm/logging/index.js +8 -0
  106. package/dist/esm/logging/infrastructure-paths.d.ts +4 -0
  107. package/dist/esm/logging/infrastructure-paths.js +5 -0
  108. package/dist/esm/logging/logger.environment.d.ts +4 -0
  109. package/dist/esm/logging/logger.environment.js +20 -0
  110. package/dist/esm/logging/observability-logger.interface.js +1 -0
  111. package/dist/esm/logging/pino-logger-options.interface.d.ts +5 -0
  112. package/dist/esm/logging/pino-logger-options.interface.js +1 -0
  113. package/dist/esm/logging/pino-logger.config.d.ts +15 -0
  114. package/dist/esm/logging/pino-logger.config.js +99 -0
  115. package/dist/esm/logging/resolve-request-id.d.ts +4 -0
  116. package/dist/esm/logging/resolve-request-id.js +6 -0
  117. package/dist/esm/logging/resolve-support-id.d.ts +3 -0
  118. package/dist/esm/logging/resolve-support-id.js +4 -0
  119. package/dist/esm/metrics/index.d.ts +3 -0
  120. package/dist/esm/metrics/index.js +3 -0
  121. package/dist/esm/metrics/metrics-hooks.d.ts +2 -0
  122. package/dist/esm/metrics/metrics-hooks.js +33 -0
  123. package/dist/esm/metrics/metrics-http.module.d.ts +5 -0
  124. package/dist/esm/metrics/metrics-http.module.js +26 -0
  125. package/dist/esm/metrics/metrics.controller.d.ts +7 -0
  126. package/dist/esm/metrics/metrics.controller.js +39 -0
  127. package/dist/esm/shared/active-span-context.d.ts +2 -0
  128. package/dist/esm/shared/active-span-context.js +5 -0
  129. package/dist/esm/shared/with-class-decorator.d.ts +2 -0
  130. package/dist/esm/shared/with-class-decorator.js +10 -0
  131. package/package.json +111 -5
  132. /package/dist/cjs/{cqrs/observability-logger.interface.js → health/cli/health-cli-options.interface.js} +0 -0
  133. /package/dist/cjs/{cqrs → logging}/constants.d.ts +0 -0
  134. /package/dist/cjs/{cqrs → logging}/constants.js +0 -0
  135. /package/dist/cjs/{cqrs → logging}/observability-logger.interface.d.ts +0 -0
  136. /package/dist/esm/{cqrs/observability-logger.interface.js → health/cli/health-cli-options.interface.js} +0 -0
  137. /package/dist/esm/{cqrs → logging}/constants.d.ts +0 -0
  138. /package/dist/esm/{cqrs → logging}/constants.js +0 -0
  139. /package/dist/esm/{cqrs → logging}/observability-logger.interface.d.ts +0 -0
@@ -0,0 +1,5 @@
1
+ export declare class HealthEnvironment {
2
+ HEALTH_DISK_THRESHOLD_PERCENT: number;
3
+ HEALTH_MEMORY_HEAP_MB: number;
4
+ HEALTH_MEMORY_RSS_MB: number;
5
+ }
@@ -0,0 +1,34 @@
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 { Expose, Type } from 'class-transformer';
11
+ import { IsNumber } from 'class-validator';
12
+ export class HealthEnvironment {
13
+ HEALTH_DISK_THRESHOLD_PERCENT = 0.8;
14
+ HEALTH_MEMORY_HEAP_MB = 500;
15
+ HEALTH_MEMORY_RSS_MB = 800;
16
+ }
17
+ __decorate([
18
+ Expose(),
19
+ IsNumber(),
20
+ Type(() => Number),
21
+ __metadata("design:type", Object)
22
+ ], HealthEnvironment.prototype, "HEALTH_DISK_THRESHOLD_PERCENT", void 0);
23
+ __decorate([
24
+ Expose(),
25
+ IsNumber(),
26
+ Type(() => Number),
27
+ __metadata("design:type", Object)
28
+ ], HealthEnvironment.prototype, "HEALTH_MEMORY_HEAP_MB", void 0);
29
+ __decorate([
30
+ Expose(),
31
+ IsNumber(),
32
+ Type(() => Number),
33
+ __metadata("design:type", Object)
34
+ ], HealthEnvironment.prototype, "HEALTH_MEMORY_RSS_MB", void 0);
@@ -0,0 +1,5 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ import type { HealthModuleOptionsInterface } from './health-module-options.interface.js';
3
+ export declare class HealthModule {
4
+ static forRoot(options?: HealthModuleOptionsInterface): DynamicModule;
5
+ }
@@ -0,0 +1,25 @@
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 { Module } from '@nestjs/common';
8
+ import { TerminusModule } from '@nestjs/terminus';
9
+ import { HealthChecks } from './health-checks.js';
10
+ let HealthModule = class HealthModule {
11
+ static forRoot(options = {}) {
12
+ const terminus = TerminusModule.forRoot(options.terminus);
13
+ return {
14
+ exports: [HealthChecks, terminus],
15
+ global: true,
16
+ imports: [...options.imports ?? [], terminus],
17
+ module: this,
18
+ providers: [HealthChecks],
19
+ };
20
+ }
21
+ };
22
+ HealthModule = __decorate([
23
+ Module({})
24
+ ], HealthModule);
25
+ export { HealthModule };
@@ -0,0 +1,8 @@
1
+ export * from './health-checks.js';
2
+ export * from './health-http.module.js';
3
+ export * from './health-module-options.interface.js';
4
+ export * from './health.config.js';
5
+ export * from './health.controller.js';
6
+ export * from './health.environment.js';
7
+ export * from './health.module.js';
8
+ export * from './migrations.health-indicator.js';
@@ -0,0 +1,8 @@
1
+ export * from './health-checks.js';
2
+ export * from './health-http.module.js';
3
+ export * from './health-module-options.interface.js';
4
+ export * from './health.config.js';
5
+ export * from './health.controller.js';
6
+ export * from './health.environment.js';
7
+ export * from './health.module.js';
8
+ export * from './migrations.health-indicator.js';
@@ -0,0 +1,9 @@
1
+ import type { HealthIndicatorResult } from '@nestjs/terminus';
2
+ import { HealthIndicatorService } from '@nestjs/terminus';
3
+ import { DataSource } from 'typeorm';
4
+ export declare class MigrationsHealthIndicator {
5
+ private readonly healthIndicatorService;
6
+ private readonly dataSource;
7
+ constructor(healthIndicatorService: HealthIndicatorService, dataSource: DataSource);
8
+ isUpToDate(key: string): Promise<HealthIndicatorResult>;
9
+ }
@@ -0,0 +1,37 @@
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 { Inject, Injectable } from '@nestjs/common';
14
+ import { HealthIndicatorService } from '@nestjs/terminus';
15
+ import { InjectDataSource } from '@nestjs/typeorm';
16
+ import { DataSource } from 'typeorm';
17
+ let MigrationsHealthIndicator = class MigrationsHealthIndicator {
18
+ healthIndicatorService;
19
+ dataSource;
20
+ constructor(healthIndicatorService, dataSource) {
21
+ this.healthIndicatorService = healthIndicatorService;
22
+ this.dataSource = dataSource;
23
+ }
24
+ async isUpToDate(key) {
25
+ const hasPendingMigrations = await this.dataSource.showMigrations();
26
+ const indicator = this.healthIndicatorService.check(key);
27
+ return hasPendingMigrations ? indicator.down({ pendingMigrations: true }) : indicator.up();
28
+ }
29
+ };
30
+ MigrationsHealthIndicator = __decorate([
31
+ Injectable(),
32
+ __param(0, Inject(HealthIndicatorService)),
33
+ __param(1, InjectDataSource()),
34
+ __metadata("design:paramtypes", [HealthIndicatorService,
35
+ DataSource])
36
+ ], MigrationsHealthIndicator);
37
+ export { MigrationsHealthIndicator };
@@ -0,0 +1,8 @@
1
+ export * from './constants.js';
2
+ export * from './infrastructure-paths.js';
3
+ export * from './logger.environment.js';
4
+ export * from './observability-logger.interface.js';
5
+ export * from './pino-logger-options.interface.js';
6
+ export * from './pino-logger.config.js';
7
+ export * from './resolve-request-id.js';
8
+ export * from './resolve-support-id.js';
@@ -0,0 +1,8 @@
1
+ export * from './constants.js';
2
+ export * from './infrastructure-paths.js';
3
+ export * from './logger.environment.js';
4
+ export * from './observability-logger.interface.js';
5
+ export * from './pino-logger-options.interface.js';
6
+ export * from './pino-logger.config.js';
7
+ export * from './resolve-request-id.js';
8
+ export * from './resolve-support-id.js';
@@ -0,0 +1,4 @@
1
+ export declare const HEALTH_ROUTE = "health";
2
+ export declare const METRICS_ROUTE = "metrics";
3
+ export declare const INFRASTRUCTURE_PATHS: readonly string[];
4
+ export declare const isInfrastructurePath: (path: string) => boolean;
@@ -0,0 +1,5 @@
1
+ export const HEALTH_ROUTE = 'health';
2
+ export const METRICS_ROUTE = 'metrics';
3
+ export const INFRASTRUCTURE_PATHS = [`/${HEALTH_ROUTE}`, `/${METRICS_ROUTE}`];
4
+ export const isInfrastructurePath = (path) => INFRASTRUCTURE_PATHS
5
+ .some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
@@ -0,0 +1,4 @@
1
+ import type { LevelWithSilent } from 'pino';
2
+ export declare class LoggerEnvironment {
3
+ LOG_LEVEL: LevelWithSilent;
4
+ }
@@ -0,0 +1,20 @@
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 { Expose } from 'class-transformer';
11
+ import { IsIn } from 'class-validator';
12
+ const LOG_LEVELS = ['trace', 'debug', 'info', 'warn', 'error', 'fatal', 'silent'];
13
+ export class LoggerEnvironment {
14
+ LOG_LEVEL = 'warn';
15
+ }
16
+ __decorate([
17
+ Expose(),
18
+ IsIn(LOG_LEVELS),
19
+ __metadata("design:type", String)
20
+ ], LoggerEnvironment.prototype, "LOG_LEVEL", void 0);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { ClientIpSourceInterface } from '../http/resolve-client-ip.js';
2
+ export type ClientIpResolver = (request: ClientIpSourceInterface) => string;
3
+ export interface PinoLoggerOptionsInterface {
4
+ readonly resolveClientIp?: ClientIpResolver;
5
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { Params } from 'nestjs-pino';
2
+ import type { Level } from 'pino';
3
+ import type { PinoLoggerOptionsInterface } from './pino-logger-options.interface.js';
4
+ import { LoggerEnvironment } from './logger.environment.js';
5
+ export declare const responseLogLevel: (request: {
6
+ url?: string | undefined;
7
+ }, response: {
8
+ statusCode: number;
9
+ }, error?: Error) => Level;
10
+ export declare const traceContextMixin: () => Record<string, number | string>;
11
+ export declare class PinoLoggerConfig {
12
+ private readonly environment;
13
+ constructor(environment: LoggerEnvironment);
14
+ createOptions(options?: PinoLoggerOptionsInterface): Params;
15
+ }
@@ -0,0 +1,99 @@
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 { Inject, Injectable } from '@nestjs/common';
14
+ import { resolveClientIp } from '../http/resolve-client-ip.js';
15
+ import { activeSpanContext } from '../shared/active-span-context.js';
16
+ import { isInfrastructurePath } from './infrastructure-paths.js';
17
+ import { LoggerEnvironment } from './logger.environment.js';
18
+ const HTTP_STATUS_CLIENT_ERROR = 400;
19
+ const HTTP_STATUS_SERVER_ERROR = 500;
20
+ const isInfrastructureRequest = (url) => {
21
+ const path = url?.split('?', 1)[0];
22
+ return path !== undefined && isInfrastructurePath(path);
23
+ };
24
+ const failureLevel = (statusCode, error) => {
25
+ if (error !== undefined || statusCode >= HTTP_STATUS_SERVER_ERROR) {
26
+ return 'error';
27
+ }
28
+ return statusCode >= HTTP_STATUS_CLIENT_ERROR ? 'warn' : undefined;
29
+ };
30
+ export const responseLogLevel = (request, response, error) => failureLevel(response.statusCode, error)
31
+ ?? (isInfrastructureRequest(request.url) ? 'debug' : 'info');
32
+ export const traceContextMixin = () => {
33
+ const spanContext = activeSpanContext();
34
+ if (spanContext === undefined) {
35
+ return {};
36
+ }
37
+ return { span_id: spanContext.spanId, trace_flags: spanContext.traceFlags, trace_id: spanContext.traceId };
38
+ };
39
+ const SEVERITY_BY_LEVEL = {
40
+ debug: 'DEBUG',
41
+ error: 'ERROR',
42
+ fatal: 'CRITICAL',
43
+ info: 'INFO',
44
+ trace: 'DEBUG',
45
+ warn: 'WARNING',
46
+ };
47
+ const REDACTED_LOG_PATHS = [
48
+ '*.*.password',
49
+ '*.password',
50
+ 'password',
51
+ 'req.headers.authorization',
52
+ 'req.headers.cookie',
53
+ ];
54
+ const rawSocketPort = (request) => request.raw?.socket?.remotePort;
55
+ const remotePort = (request) => request.socket?.remotePort
56
+ ?? rawSocketPort(request);
57
+ let PinoLoggerConfig = class PinoLoggerConfig {
58
+ environment;
59
+ constructor(environment) {
60
+ this.environment = environment;
61
+ }
62
+ createOptions(options = {}) {
63
+ const clientIp = options.resolveClientIp ?? resolveClientIp;
64
+ return {
65
+ pinoHttp: {
66
+ autoLogging: true,
67
+ customLogLevel: responseLogLevel,
68
+ formatters: {
69
+ level: (label, number) => ({
70
+ level: number,
71
+ severity: SEVERITY_BY_LEVEL[label] ?? SEVERITY_BY_LEVEL.info,
72
+ }),
73
+ },
74
+ level: this.environment.LOG_LEVEL,
75
+ mixin: traceContextMixin,
76
+ quietReqLogger: true,
77
+ redact: [...REDACTED_LOG_PATHS],
78
+ serializers: {
79
+ req: (request) => ({
80
+ headers: request.headers,
81
+ id: request.id,
82
+ method: request.method,
83
+ params: request.raw?.params,
84
+ query: request.query,
85
+ remoteAddress: clientIp(request),
86
+ remotePort: remotePort(request),
87
+ url: request.url,
88
+ }),
89
+ },
90
+ },
91
+ };
92
+ }
93
+ };
94
+ PinoLoggerConfig = __decorate([
95
+ Injectable(),
96
+ __param(0, Inject(LoggerEnvironment)),
97
+ __metadata("design:paramtypes", [LoggerEnvironment])
98
+ ], PinoLoggerConfig);
99
+ export { PinoLoggerConfig };
@@ -0,0 +1,4 @@
1
+ export declare const REQUEST_ID_HEADER = "x-request-id";
2
+ export declare const resolveRequestId: (request: {
3
+ headers?: Record<string, string | string[] | undefined> | undefined;
4
+ }) => string;
@@ -0,0 +1,6 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ export const REQUEST_ID_HEADER = 'x-request-id';
3
+ export const resolveRequestId = (request) => {
4
+ const header = request.headers?.[REQUEST_ID_HEADER];
5
+ return typeof header === 'string' && header !== '' ? header : randomUUID();
6
+ };
@@ -0,0 +1,3 @@
1
+ export declare const resolveSupportId: (request: {
2
+ id?: string | undefined;
3
+ }) => string;
@@ -0,0 +1,4 @@
1
+ import { activeSpanContext } from '../shared/active-span-context.js';
2
+ export const resolveSupportId = (request) => activeSpanContext()?.traceId
3
+ ?? request.id
4
+ ?? '';
@@ -1,4 +1,7 @@
1
1
  export * from './graphql-metrics.js';
2
2
  export * from './http-metrics.js';
3
+ export * from './metrics-hooks.js';
3
4
  export * from './metrics-http-server.js';
5
+ export * from './metrics-http.module.js';
6
+ export * from './metrics.controller.js';
4
7
  export * from './metrics.registry.js';
@@ -1,4 +1,7 @@
1
1
  export * from './graphql-metrics.js';
2
2
  export * from './http-metrics.js';
3
+ export * from './metrics-hooks.js';
3
4
  export * from './metrics-http-server.js';
5
+ export * from './metrics-http.module.js';
6
+ export * from './metrics.controller.js';
4
7
  export * from './metrics.registry.js';
@@ -0,0 +1,2 @@
1
+ import type { NestFastifyApplication } from '@nestjs/platform-fastify';
2
+ export declare const setupMetricsHooks: (app: NestFastifyApplication) => void;
@@ -0,0 +1,33 @@
1
+ import { asMercuriusHook, GraphqlMetrics } from './graphql-metrics.js';
2
+ import { HttpMetrics, resolveRouteLabel } from './http-metrics.js';
3
+ const hasMercurius = (fastify) => 'graphql' in fastify;
4
+ const setupGraphqlHooks = (fastify, metrics) => {
5
+ fastify.addHook('onReady', (done) => {
6
+ if (hasMercurius(fastify)) {
7
+ fastify.graphql.addHook('preParsing', asMercuriusHook((_schema, _source, context) => {
8
+ metrics.start(context);
9
+ }));
10
+ fastify.graphql.addHook('preExecution', asMercuriusHook((_schema, document, context) => {
11
+ metrics.describe(context, document);
12
+ }));
13
+ fastify.graphql.addHook('onResolution', asMercuriusHook((result, context) => {
14
+ metrics.finish(context, (result.errors?.length ?? 0) > 0);
15
+ }));
16
+ }
17
+ done();
18
+ });
19
+ };
20
+ export const setupMetricsHooks = (app) => {
21
+ const metrics = app.get(HttpMetrics);
22
+ const fastify = app.getHttpAdapter().getInstance();
23
+ fastify.addHook('onResponse', (request, reply, done) => {
24
+ metrics.observe({
25
+ durationSeconds: reply.elapsedTime / 1000,
26
+ method: request.method,
27
+ route: resolveRouteLabel(request.routeOptions.url),
28
+ status: reply.statusCode,
29
+ });
30
+ done();
31
+ });
32
+ setupGraphqlHooks(fastify, app.get(GraphqlMetrics));
33
+ };
@@ -0,0 +1,5 @@
1
+ import type { DynamicModule } from '@nestjs/common';
2
+ import type { HealthCarrierOptionsInterface } from '../health/health-module-options.interface.js';
3
+ export declare class MetricsHttpModule {
4
+ static forRoot(options?: HealthCarrierOptionsInterface): DynamicModule;
5
+ }
@@ -0,0 +1,26 @@
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 { Module } from '@nestjs/common';
8
+ import { withClassDecorator } from '../shared/with-class-decorator.js';
9
+ import { GraphqlMetrics } from './graphql-metrics.js';
10
+ import { HttpMetrics } from './http-metrics.js';
11
+ import { MetricsController } from './metrics.controller.js';
12
+ import { MetricsRegistry } from './metrics.registry.js';
13
+ let MetricsHttpModule = class MetricsHttpModule {
14
+ static forRoot(options = {}) {
15
+ return {
16
+ controllers: [withClassDecorator(MetricsController, options.publicRoute)],
17
+ exports: [GraphqlMetrics, HttpMetrics, MetricsRegistry],
18
+ module: this,
19
+ providers: [GraphqlMetrics, HttpMetrics, MetricsRegistry],
20
+ };
21
+ }
22
+ };
23
+ MetricsHttpModule = __decorate([
24
+ Module({})
25
+ ], MetricsHttpModule);
26
+ export { MetricsHttpModule };
@@ -0,0 +1,7 @@
1
+ import type { FastifyReply } from 'fastify';
2
+ import { MetricsRegistry } from './metrics.registry.js';
3
+ export declare class MetricsController {
4
+ private readonly metricsRegistry;
5
+ constructor(metricsRegistry: MetricsRegistry);
6
+ scrape(reply: FastifyReply): Promise<string>;
7
+ }
@@ -0,0 +1,39 @@
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 { Controller, Get, Header, Inject, Res } from '@nestjs/common';
14
+ import { METRICS_ROUTE } from '../logging/infrastructure-paths.js';
15
+ import { MetricsRegistry } from './metrics.registry.js';
16
+ let MetricsController = class MetricsController {
17
+ metricsRegistry;
18
+ constructor(metricsRegistry) {
19
+ this.metricsRegistry = metricsRegistry;
20
+ }
21
+ async scrape(reply) {
22
+ void reply.header('Content-Type', this.metricsRegistry.contentType);
23
+ return this.metricsRegistry.render();
24
+ }
25
+ };
26
+ __decorate([
27
+ Get(),
28
+ Header('Cache-Control', 'no-store'),
29
+ __param(0, Res({ passthrough: true })),
30
+ __metadata("design:type", Function),
31
+ __metadata("design:paramtypes", [Object]),
32
+ __metadata("design:returntype", Promise)
33
+ ], MetricsController.prototype, "scrape", null);
34
+ MetricsController = __decorate([
35
+ Controller(METRICS_ROUTE),
36
+ __param(0, Inject(MetricsRegistry)),
37
+ __metadata("design:paramtypes", [MetricsRegistry])
38
+ ], MetricsController);
39
+ export { MetricsController };
@@ -0,0 +1,2 @@
1
+ import type { SpanContext } from '@opentelemetry/api';
2
+ export declare const activeSpanContext: () => SpanContext | undefined;
@@ -0,0 +1,5 @@
1
+ import { isSpanContextValid, trace } from '@opentelemetry/api';
2
+ export const activeSpanContext = () => {
3
+ const spanContext = trace.getActiveSpan()?.spanContext();
4
+ return spanContext !== undefined && isSpanContextValid(spanContext) ? spanContext : undefined;
5
+ };
@@ -0,0 +1,2 @@
1
+ import type { Type } from '@nestjs/common';
2
+ export declare const withClassDecorator: <T extends Type>(base: T, decorator: ClassDecorator | undefined) => T;
@@ -0,0 +1,10 @@
1
+ export const withClassDecorator = (base, decorator) => {
2
+ if (decorator === undefined) {
3
+ return base;
4
+ }
5
+ const decorated = class extends base {
6
+ };
7
+ Object.defineProperty(decorated, 'name', { value: base.name });
8
+ decorator(decorated);
9
+ return decorated;
10
+ };