@omnitronix/game-engine-sdk 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap/index.d.ts +15 -0
- package/dist/bootstrap/index.d.ts.map +1 -0
- package/dist/bootstrap/index.js +156 -0
- package/dist/common/api-docs/setup-documentation.d.ts +3 -0
- package/dist/common/api-docs/setup-documentation.d.ts.map +1 -0
- package/dist/common/api-docs/setup-documentation.js +27 -0
- package/dist/common/application-bootstrap-options.interface.d.ts +4 -0
- package/dist/common/application-bootstrap-options.interface.d.ts.map +1 -0
- package/dist/common/application-bootstrap-options.interface.js +2 -0
- package/dist/common/error-handling/all-exceptions.filter.d.ts +22 -0
- package/dist/common/error-handling/all-exceptions.filter.d.ts.map +1 -0
- package/dist/common/error-handling/all-exceptions.filter.js +131 -0
- package/dist/common/error-handling/domain.exception.d.ts +8 -0
- package/dist/common/error-handling/domain.exception.d.ts.map +1 -0
- package/dist/common/error-handling/domain.exception.js +14 -0
- package/dist/common/error-handling/error-code-mapper.d.ts +6 -0
- package/dist/common/error-handling/error-code-mapper.d.ts.map +1 -0
- package/dist/common/error-handling/error-code-mapper.js +93 -0
- package/dist/common/error-handling/internal-error-code.d.ts +67 -0
- package/dist/common/error-handling/internal-error-code.d.ts.map +1 -0
- package/dist/common/error-handling/internal-error-code.js +80 -0
- package/dist/common/index.d.ts +21 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +51 -0
- package/dist/common/logger/logger.d.ts +24 -0
- package/dist/common/logger/logger.d.ts.map +1 -0
- package/dist/common/logger/logger.js +137 -0
- package/dist/common/logger/logger.module.d.ts +3 -0
- package/dist/common/logger/logger.module.d.ts.map +1 -0
- package/dist/common/logger/logger.module.js +19 -0
- package/dist/common/logger/logging.middleware.d.ts +8 -0
- package/dist/common/logger/logging.middleware.d.ts.map +1 -0
- package/dist/common/logger/logging.middleware.js +44 -0
- package/dist/common/metrics/database-metrics.service.d.ts +8 -0
- package/dist/common/metrics/database-metrics.service.d.ts.map +1 -0
- package/dist/common/metrics/database-metrics.service.js +39 -0
- package/dist/common/metrics/helpers/metrics.helpers.d.ts +5 -0
- package/dist/common/metrics/helpers/metrics.helpers.d.ts.map +1 -0
- package/dist/common/metrics/helpers/metrics.helpers.js +38 -0
- package/dist/common/metrics/metrics.module.d.ts +3 -0
- package/dist/common/metrics/metrics.module.d.ts.map +1 -0
- package/dist/common/metrics/metrics.module.js +207 -0
- package/dist/common/metrics/metrics.port.d.ts +22 -0
- package/dist/common/metrics/metrics.port.d.ts.map +1 -0
- package/dist/common/metrics/metrics.port.js +4 -0
- package/dist/common/metrics/prometheus.service.d.ts +25 -0
- package/dist/common/metrics/prometheus.service.d.ts.map +1 -0
- package/dist/common/metrics/prometheus.service.js +105 -0
- package/dist/common/retry/retry-policies.d.ts +8 -0
- package/dist/common/retry/retry-policies.d.ts.map +1 -0
- package/dist/common/retry/retry-policies.js +43 -0
- package/dist/common/retry/retry-policy.d.ts +25 -0
- package/dist/common/retry/retry-policy.d.ts.map +1 -0
- package/dist/common/retry/retry-policy.js +65 -0
- package/dist/common/secrets-provider/secrets-provider.aws.d.ts +13 -0
- package/dist/common/secrets-provider/secrets-provider.aws.d.ts.map +1 -0
- package/dist/common/secrets-provider/secrets-provider.aws.js +72 -0
- package/dist/common/secrets-provider/secrets-provider.d.ts +5 -0
- package/dist/common/secrets-provider/secrets-provider.d.ts.map +1 -0
- package/dist/common/secrets-provider/secrets-provider.js +4 -0
- package/dist/common/secrets-provider/secrets-provider.local.d.ts +8 -0
- package/dist/common/secrets-provider/secrets-provider.local.d.ts.map +1 -0
- package/dist/common/secrets-provider/secrets-provider.local.js +75 -0
- package/dist/common/secrets-provider/secrets-provider.module.d.ts +5 -0
- package/dist/common/secrets-provider/secrets-provider.module.d.ts.map +1 -0
- package/dist/common/secrets-provider/secrets-provider.module.js +47 -0
- package/dist/esm/bootstrap/index.js +120 -0
- package/dist/esm/common/api-docs/setup-documentation.js +23 -0
- package/dist/esm/common/application-bootstrap-options.interface.js +1 -0
- package/dist/esm/common/error-handling/all-exceptions.filter.js +128 -0
- package/dist/esm/common/error-handling/domain.exception.js +10 -0
- package/dist/esm/common/error-handling/error-code-mapper.js +89 -0
- package/dist/esm/common/error-handling/internal-error-code.js +77 -0
- package/dist/esm/common/index.js +25 -0
- package/dist/esm/common/logger/logger.js +133 -0
- package/dist/esm/common/logger/logger.module.js +16 -0
- package/dist/esm/common/logger/logging.middleware.js +41 -0
- package/dist/esm/common/metrics/database-metrics.service.js +36 -0
- package/dist/esm/common/metrics/helpers/metrics.helpers.js +32 -0
- package/dist/esm/common/metrics/metrics.module.js +204 -0
- package/dist/esm/common/metrics/metrics.port.js +1 -0
- package/dist/esm/common/metrics/prometheus.service.js +102 -0
- package/dist/esm/common/retry/retry-policies.js +39 -0
- package/dist/esm/common/retry/retry-policy.js +61 -0
- package/dist/esm/common/secrets-provider/secrets-provider.aws.js +69 -0
- package/dist/esm/common/secrets-provider/secrets-provider.js +1 -0
- package/dist/esm/common/secrets-provider/secrets-provider.local.js +39 -0
- package/dist/esm/common/secrets-provider/secrets-provider.module.js +44 -0
- package/dist/esm/generated/game-engine-registry_pb.js +28 -0
- package/dist/esm/generated/game-engine_pb.js +57 -0
- package/dist/esm/grpc/connect-router.middleware.js +16 -0
- package/dist/esm/grpc/game-engine.grpc.in-adapter.js +109 -0
- package/dist/esm/grpc/index.js +2 -0
- package/dist/esm/health/application/ports/in/health-in.port.js +1 -0
- package/dist/esm/health/application/ports/out/database-health.out-port.js +1 -0
- package/dist/esm/health/application/ports/out/shutdown.out-port.js +1 -0
- package/dist/esm/health/application/ports/out/system-health.out-port.js +1 -0
- package/dist/esm/health/application/services/health.service.js +81 -0
- package/dist/esm/health/domain/health.js +7 -0
- package/dist/esm/health/health.module.js +65 -0
- package/dist/esm/health/index.js +15 -0
- package/dist/esm/health/infrastructure/adapters/in/health.http.in-adapter.js +96 -0
- package/dist/esm/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.js +45 -0
- package/dist/esm/health/infrastructure/adapters/out/system/system-health.out-adapter.js +43 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/registration/adapters/game-engine-registry.grpc.out-adapter.js +59 -0
- package/dist/esm/registration/index.js +3 -0
- package/dist/esm/registration/ports/game-engine-registry.out-port.js +1 -0
- package/dist/esm/registration/services/game-engine-auto-register.service.js +78 -0
- package/dist/esm/types.js +8 -0
- package/dist/generated/game-engine-registry_pb.d.ts +76 -0
- package/dist/generated/game-engine-registry_pb.d.ts.map +1 -0
- package/dist/generated/game-engine-registry_pb.js +31 -0
- package/dist/generated/game-engine_pb.d.ts +171 -0
- package/dist/generated/game-engine_pb.d.ts.map +1 -0
- package/dist/generated/game-engine_pb.js +60 -0
- package/dist/grpc/connect-router.middleware.d.ts +7 -0
- package/dist/grpc/connect-router.middleware.d.ts.map +1 -0
- package/dist/grpc/connect-router.middleware.js +19 -0
- package/dist/grpc/game-engine.grpc.in-adapter.d.ts +21 -0
- package/dist/grpc/game-engine.grpc.in-adapter.d.ts.map +1 -0
- package/dist/grpc/game-engine.grpc.in-adapter.js +112 -0
- package/dist/grpc/index.d.ts +3 -0
- package/dist/grpc/index.d.ts.map +1 -0
- package/dist/grpc/index.js +7 -0
- package/dist/health/application/ports/in/health-in.port.d.ts +7 -0
- package/dist/health/application/ports/in/health-in.port.d.ts.map +1 -0
- package/dist/health/application/ports/in/health-in.port.js +4 -0
- package/dist/health/application/ports/out/database-health.out-port.d.ts +6 -0
- package/dist/health/application/ports/out/database-health.out-port.d.ts.map +1 -0
- package/dist/health/application/ports/out/database-health.out-port.js +4 -0
- package/dist/health/application/ports/out/shutdown.out-port.d.ts +6 -0
- package/dist/health/application/ports/out/shutdown.out-port.d.ts.map +1 -0
- package/dist/health/application/ports/out/shutdown.out-port.js +4 -0
- package/dist/health/application/ports/out/system-health.out-port.d.ts +7 -0
- package/dist/health/application/ports/out/system-health.out-port.d.ts.map +1 -0
- package/dist/health/application/ports/out/system-health.out-port.js +4 -0
- package/dist/health/application/services/health.service.d.ts +13 -0
- package/dist/health/application/services/health.service.d.ts.map +1 -0
- package/dist/health/application/services/health.service.js +84 -0
- package/dist/health/domain/health.d.ts +15 -0
- package/dist/health/domain/health.d.ts.map +1 -0
- package/dist/health/domain/health.js +11 -0
- package/dist/health/health.module.d.ts +10 -0
- package/dist/health/health.module.d.ts.map +1 -0
- package/dist/health/health.module.js +68 -0
- package/dist/health/index.d.ts +11 -0
- package/dist/health/index.d.ts.map +1 -0
- package/dist/health/index.js +28 -0
- package/dist/health/infrastructure/adapters/in/health.http.in-adapter.d.ts +16 -0
- package/dist/health/infrastructure/adapters/in/health.http.in-adapter.d.ts.map +1 -0
- package/dist/health/infrastructure/adapters/in/health.http.in-adapter.js +99 -0
- package/dist/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.d.ts +13 -0
- package/dist/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.d.ts.map +1 -0
- package/dist/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.js +48 -0
- package/dist/health/infrastructure/adapters/out/system/system-health.out-adapter.d.ts +12 -0
- package/dist/health/infrastructure/adapters/out/system/system-health.out-adapter.d.ts.map +1 -0
- package/dist/health/infrastructure/adapters/out/system/system-health.out-adapter.js +46 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/registration/adapters/game-engine-registry.grpc.out-adapter.d.ts +12 -0
- package/dist/registration/adapters/game-engine-registry.grpc.out-adapter.d.ts.map +1 -0
- package/dist/registration/adapters/game-engine-registry.grpc.out-adapter.js +62 -0
- package/dist/registration/index.d.ts +4 -0
- package/dist/registration/index.d.ts.map +1 -0
- package/dist/registration/index.js +9 -0
- package/dist/registration/ports/game-engine-registry.out-port.d.ts +9 -0
- package/dist/registration/ports/game-engine-registry.out-port.d.ts.map +1 -0
- package/dist/registration/ports/game-engine-registry.out-port.js +4 -0
- package/dist/registration/services/game-engine-auto-register.service.d.ts +14 -0
- package/dist/registration/services/game-engine-auto-register.service.d.ts.map +1 -0
- package/dist/registration/services/game-engine-auto-register.service.js +81 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/package.json +159 -0
|
@@ -0,0 +1,207 @@
|
|
|
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.MetricsModule = void 0;
|
|
10
|
+
const all_exceptions_filter_1 = require("../error-handling/all-exceptions.filter");
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const nestjs_prometheus_1 = require("@willsoto/nestjs-prometheus");
|
|
13
|
+
const metrics_port_1 = require("./metrics.port");
|
|
14
|
+
const prometheus_service_1 = require("./prometheus.service");
|
|
15
|
+
let MetricsModule = class MetricsModule {
|
|
16
|
+
};
|
|
17
|
+
exports.MetricsModule = MetricsModule;
|
|
18
|
+
exports.MetricsModule = MetricsModule = __decorate([
|
|
19
|
+
(0, common_1.Module)({
|
|
20
|
+
providers: [
|
|
21
|
+
{
|
|
22
|
+
provide: metrics_port_1.METRICS_PORT,
|
|
23
|
+
useClass: prometheus_service_1.PrometheusService,
|
|
24
|
+
},
|
|
25
|
+
all_exceptions_filter_1.ExceptionsFilter,
|
|
26
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
27
|
+
name: 'rgs_http_server_requests_duration_ms',
|
|
28
|
+
help: 'Duration of HTTP requests in milliseconds',
|
|
29
|
+
labelNames: ['method', 'route', 'status_code', 'operator_code'],
|
|
30
|
+
buckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000],
|
|
31
|
+
}),
|
|
32
|
+
(0, nestjs_prometheus_1.makeGaugeProvider)({
|
|
33
|
+
name: 'rgs_ws_connections',
|
|
34
|
+
help: 'Current number of WebSocket connections',
|
|
35
|
+
labelNames: ['state', 'operator_code'],
|
|
36
|
+
}),
|
|
37
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
38
|
+
name: 'rgs_ws_messages_total',
|
|
39
|
+
help: 'Total WebSocket messages sent or received',
|
|
40
|
+
labelNames: ['type', 'operator_code', 'event_name'],
|
|
41
|
+
}),
|
|
42
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
43
|
+
name: 'rgs_ws_event_duration_ms',
|
|
44
|
+
help: 'Duration of WebSocket event processing in milliseconds',
|
|
45
|
+
labelNames: ['event_name', 'operator_code'],
|
|
46
|
+
buckets: [5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000],
|
|
47
|
+
}),
|
|
48
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
49
|
+
name: 'rgs_sessions_total',
|
|
50
|
+
help: 'Total number of game sessions by final status',
|
|
51
|
+
labelNames: ['operator_code', 'game_code', 'jurisdiction', 'status'],
|
|
52
|
+
}),
|
|
53
|
+
(0, nestjs_prometheus_1.makeGaugeProvider)({
|
|
54
|
+
name: 'rgs_sessions_active',
|
|
55
|
+
help: 'Current number of active game sessions',
|
|
56
|
+
labelNames: ['operator_code', 'game_code', 'jurisdiction'],
|
|
57
|
+
}),
|
|
58
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
59
|
+
name: 'rgs_session_duration_ms',
|
|
60
|
+
help: 'Game session duration from init to end in milliseconds',
|
|
61
|
+
labelNames: ['operator_code', 'game_code', 'jurisdiction', 'end_status'],
|
|
62
|
+
buckets: [10000, 30000, 60000, 120000, 300000, 600000, 1800000, 3600000],
|
|
63
|
+
}),
|
|
64
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
65
|
+
name: 'rgs_rounds_completed_total',
|
|
66
|
+
help: 'Total game rounds completed',
|
|
67
|
+
labelNames: ['operator_code', 'game_code', 'jurisdiction', 'result'],
|
|
68
|
+
}),
|
|
69
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
70
|
+
name: 'rgs_wager_minor_units',
|
|
71
|
+
help: 'Wager amounts in minor units',
|
|
72
|
+
labelNames: ['operator_code', 'game_code', 'jurisdiction', 'currency'],
|
|
73
|
+
buckets: [10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000],
|
|
74
|
+
}),
|
|
75
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
76
|
+
name: 'rgs_win_minor_units',
|
|
77
|
+
help: 'Win amounts in minor units',
|
|
78
|
+
labelNames: ['operator_code', 'game_code', 'jurisdiction', 'currency'],
|
|
79
|
+
buckets: [10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000],
|
|
80
|
+
}),
|
|
81
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
82
|
+
name: 'rgs_wallet_requests_total',
|
|
83
|
+
help: 'Total wallet API requests',
|
|
84
|
+
labelNames: ['operation_type', 'operator_code', 'currency', 'status'],
|
|
85
|
+
}),
|
|
86
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
87
|
+
name: 'rgs_wallet_requests_duration_ms',
|
|
88
|
+
help: 'Duration of wallet API requests in milliseconds',
|
|
89
|
+
labelNames: ['operation_type', 'operator_code', 'status'],
|
|
90
|
+
buckets: [10, 50, 100, 250, 500, 1000, 2000, 5000, 10000],
|
|
91
|
+
}),
|
|
92
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
93
|
+
name: 'game_engine_command_duration_ms',
|
|
94
|
+
help: 'Duration of game engine command processing in milliseconds',
|
|
95
|
+
labelNames: ['command_type', 'game_code', 'game_version'],
|
|
96
|
+
buckets: [1, 5, 10, 25, 50, 100, 250, 500, 1000],
|
|
97
|
+
}),
|
|
98
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
99
|
+
name: 'game_engine_commands_total',
|
|
100
|
+
help: 'Total game engine commands processed',
|
|
101
|
+
labelNames: ['command_type', 'game_code', 'game_version'],
|
|
102
|
+
}),
|
|
103
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
104
|
+
name: 'game_engine_errors_total',
|
|
105
|
+
help: 'Total game engine errors or exceptions',
|
|
106
|
+
labelNames: ['game_code', 'game_version', 'error_type'],
|
|
107
|
+
}),
|
|
108
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
109
|
+
name: 'game_engine_rng_calls_total',
|
|
110
|
+
help: 'Total RNG calls made by game engine',
|
|
111
|
+
labelNames: ['game_code', 'game_version'],
|
|
112
|
+
}),
|
|
113
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
114
|
+
name: 'rgs_event_store_write_duration_ms',
|
|
115
|
+
help: 'Event store write duration',
|
|
116
|
+
labelNames: ['aggregate_type', 'event_count_bucket'],
|
|
117
|
+
buckets: [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2000],
|
|
118
|
+
}),
|
|
119
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
120
|
+
name: 'rgs_event_store_read_duration_ms',
|
|
121
|
+
help: 'Event store read duration',
|
|
122
|
+
labelNames: ['aggregate_type', 'stream_version_bucket'],
|
|
123
|
+
buckets: [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2000],
|
|
124
|
+
}),
|
|
125
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
126
|
+
name: 'rgs_aggregate_reconstruction_duration_ms',
|
|
127
|
+
help: 'Aggregate reconstruction time',
|
|
128
|
+
labelNames: ['aggregate_type', 'events_count_bucket'],
|
|
129
|
+
buckets: [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2000],
|
|
130
|
+
}),
|
|
131
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
132
|
+
name: 'rgs_aggregate_reconstruction_events',
|
|
133
|
+
help: 'Number of events in reconstruction',
|
|
134
|
+
labelNames: ['aggregate_type'],
|
|
135
|
+
buckets: [1, 5, 10, 25, 50, 100, 250, 500],
|
|
136
|
+
}),
|
|
137
|
+
(0, nestjs_prometheus_1.makeGaugeProvider)({
|
|
138
|
+
name: 'rgs_db_connection_pool_size',
|
|
139
|
+
help: 'Connection pool size',
|
|
140
|
+
labelNames: ['pool_type', 'state'],
|
|
141
|
+
}),
|
|
142
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
143
|
+
name: 'rgs_db_connection_errors_total',
|
|
144
|
+
help: 'Database connection errors',
|
|
145
|
+
labelNames: ['error_type'],
|
|
146
|
+
}),
|
|
147
|
+
(0, nestjs_prometheus_1.makeGaugeProvider)({
|
|
148
|
+
name: 'rgs_games_total',
|
|
149
|
+
help: 'Total games in catalog',
|
|
150
|
+
labelNames: ['status'],
|
|
151
|
+
}),
|
|
152
|
+
(0, nestjs_prometheus_1.makeGaugeProvider)({
|
|
153
|
+
name: 'rgs_game_configs_total',
|
|
154
|
+
help: 'Total game configurations per jurisdiction',
|
|
155
|
+
labelNames: ['jurisdiction'],
|
|
156
|
+
}),
|
|
157
|
+
(0, nestjs_prometheus_1.makeGaugeProvider)({
|
|
158
|
+
name: 'rgs_enabled_games_per_operator',
|
|
159
|
+
help: 'Enabled games count per operator',
|
|
160
|
+
labelNames: ['operator_code', 'jurisdiction'],
|
|
161
|
+
}),
|
|
162
|
+
(0, nestjs_prometheus_1.makeGaugeProvider)({
|
|
163
|
+
name: 'rng_buffer_capacity',
|
|
164
|
+
help: 'Capacity of the RNG buffer',
|
|
165
|
+
labelNames: ['rng_range', 'engine_type', 'game_code'],
|
|
166
|
+
}),
|
|
167
|
+
(0, nestjs_prometheus_1.makeGaugeProvider)({
|
|
168
|
+
name: 'rng_buffer_fill_level',
|
|
169
|
+
help: 'Current fill level of the RNG buffer',
|
|
170
|
+
labelNames: ['rng_range', 'engine_type', 'game_code'],
|
|
171
|
+
}),
|
|
172
|
+
(0, nestjs_prometheus_1.makeGaugeProvider)({
|
|
173
|
+
name: 'rng_buffer_fill_ratio',
|
|
174
|
+
help: 'Current fill ratio of the RNG buffer',
|
|
175
|
+
labelNames: ['rng_range', 'engine_type', 'game_code'],
|
|
176
|
+
}),
|
|
177
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
178
|
+
name: 'rng_buffer_refill_requests_total',
|
|
179
|
+
help: 'Total number of RNG buffer refill requests',
|
|
180
|
+
labelNames: ['rng_range', 'engine_type', 'reason', 'game_code'],
|
|
181
|
+
}),
|
|
182
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
183
|
+
name: 'rng_buffer_refill_failures_total',
|
|
184
|
+
help: 'Total number of failed RNG buffer refill requests',
|
|
185
|
+
labelNames: ['rng_range', 'engine_type', 'reason', 'error', 'game_code'],
|
|
186
|
+
}),
|
|
187
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
188
|
+
name: 'rng_buffer_refill_duration_ms',
|
|
189
|
+
help: 'Duration of RNG buffer refill operations in milliseconds',
|
|
190
|
+
labelNames: ['rng_range', 'engine_type', 'game_code'],
|
|
191
|
+
buckets: [1, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000],
|
|
192
|
+
}),
|
|
193
|
+
(0, nestjs_prometheus_1.makeCounterProvider)({
|
|
194
|
+
name: 'rng_buffer_starvation_events_total',
|
|
195
|
+
help: 'Total number of RNG buffer starvation events',
|
|
196
|
+
labelNames: ['rng_range', 'engine_type', 'game_code'],
|
|
197
|
+
}),
|
|
198
|
+
(0, nestjs_prometheus_1.makeHistogramProvider)({
|
|
199
|
+
name: 'rng_buffer_latency_ms',
|
|
200
|
+
help: 'Latency of RNG buffer operations in milliseconds',
|
|
201
|
+
labelNames: ['rng_range', 'engine_type', 'game_code'],
|
|
202
|
+
buckets: [1, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000],
|
|
203
|
+
}),
|
|
204
|
+
],
|
|
205
|
+
exports: [metrics_port_1.METRICS_PORT],
|
|
206
|
+
})
|
|
207
|
+
], MetricsModule);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface Counter {
|
|
2
|
+
inc(labels?: Record<string, string | number>, value?: number): void;
|
|
3
|
+
}
|
|
4
|
+
export interface Gauge {
|
|
5
|
+
set(labels: Record<string, string | number>, value: number): void;
|
|
6
|
+
set(value: number): void;
|
|
7
|
+
inc(labels?: Record<string, string | number>, value?: number): void;
|
|
8
|
+
dec(labels?: Record<string, string | number>, value?: number): void;
|
|
9
|
+
}
|
|
10
|
+
export interface Histogram {
|
|
11
|
+
observe(labels: Record<string, string | number>, value?: number): void;
|
|
12
|
+
observe(value: number): void;
|
|
13
|
+
}
|
|
14
|
+
export interface MetricsPort {
|
|
15
|
+
getCounter(name: string): Counter;
|
|
16
|
+
getGauge(name: string): Gauge;
|
|
17
|
+
getHistogram(name: string): Histogram;
|
|
18
|
+
getMetrics(): Promise<string>;
|
|
19
|
+
initializeMetricsFromDatabase(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export declare const METRICS_PORT: unique symbol;
|
|
22
|
+
//# sourceMappingURL=metrics.port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.port.d.ts","sourceRoot":"","sources":["../../../src/common/metrics/metrics.port.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrE;AAED,MAAM,WAAW,KAAK;IACpB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAClE,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpE,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrE;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvE,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAC9B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,eAAO,MAAM,YAAY,eAAyB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Counter as PromCounter, Gauge as PromGauge, Histogram as PromHistogram } from 'prom-client';
|
|
2
|
+
import { Counter, Gauge, Histogram, MetricsPort } from './metrics.port';
|
|
3
|
+
export declare class PrometheusService implements MetricsPort {
|
|
4
|
+
private readonly engineCommandsTotal;
|
|
5
|
+
private readonly engineErrorsTotal;
|
|
6
|
+
private readonly engineRngCallsTotal;
|
|
7
|
+
private readonly engineCommandDuration;
|
|
8
|
+
private readonly rngBufferCapacity;
|
|
9
|
+
private readonly rngBufferFillLevel;
|
|
10
|
+
private readonly rngBufferFillRatio;
|
|
11
|
+
private readonly rngBufferRefillRequestsTotal;
|
|
12
|
+
private readonly rngBufferRefillFailuresTotal;
|
|
13
|
+
private readonly rngBufferRefillDuration;
|
|
14
|
+
private readonly rngBufferStarvationEventsTotal;
|
|
15
|
+
private readonly rngBufferLatency;
|
|
16
|
+
private metricsRegistry;
|
|
17
|
+
constructor(engineCommandsTotal: PromCounter, engineErrorsTotal: PromCounter, engineRngCallsTotal: PromCounter, engineCommandDuration: PromHistogram, rngBufferCapacity: PromGauge, rngBufferFillLevel: PromGauge, rngBufferFillRatio: PromGauge, rngBufferRefillRequestsTotal: PromCounter, rngBufferRefillFailuresTotal: PromCounter, rngBufferRefillDuration: PromHistogram, rngBufferStarvationEventsTotal: PromCounter, rngBufferLatency: PromHistogram);
|
|
18
|
+
initializeMetricsFromDatabase(): Promise<void>;
|
|
19
|
+
private initializeRegistry;
|
|
20
|
+
getCounter(name: string): Counter;
|
|
21
|
+
getGauge(name: string): Gauge;
|
|
22
|
+
getHistogram(name: string): Histogram;
|
|
23
|
+
getMetrics(): Promise<string>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=prometheus.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prometheus.service.d.ts","sourceRoot":"","sources":["../../../src/common/metrics/prometheus.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,IAAI,WAAW,EACtB,KAAK,IAAI,SAAS,EAClB,SAAS,IAAI,aAAa,EAC3B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAExE,qBACa,iBAAkB,YAAW,WAAW;IAKjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAEtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IAExC,OAAO,CAAC,QAAQ,CAAC,8BAA8B;IAE/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IA1BnC,OAAO,CAAC,eAAe,CAAmE;gBAIvE,mBAAmB,EAAE,WAAW,EAEhC,iBAAiB,EAAE,WAAW,EAE9B,mBAAmB,EAAE,WAAW,EAEhC,qBAAqB,EAAE,aAAa,EAEpC,iBAAiB,EAAE,SAAS,EAE5B,kBAAkB,EAAE,SAAS,EAE7B,kBAAkB,EAAE,SAAS,EAE7B,4BAA4B,EAAE,WAAW,EAEzC,4BAA4B,EAAE,WAAW,EAEzC,uBAAuB,EAAE,aAAa,EAEtC,8BAA8B,EAAE,WAAW,EAE3C,gBAAgB,EAAE,aAAa;IAKlD,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9C,OAAO,CAAC,kBAAkB;IAkB1B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IAQ7B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;IAQ/B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;CAGpC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
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.PrometheusService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const nestjs_prometheus_1 = require("@willsoto/nestjs-prometheus");
|
|
18
|
+
const prom_client_1 = require("prom-client");
|
|
19
|
+
let PrometheusService = class PrometheusService {
|
|
20
|
+
constructor(engineCommandsTotal, engineErrorsTotal, engineRngCallsTotal, engineCommandDuration, rngBufferCapacity, rngBufferFillLevel, rngBufferFillRatio, rngBufferRefillRequestsTotal, rngBufferRefillFailuresTotal, rngBufferRefillDuration, rngBufferStarvationEventsTotal, rngBufferLatency) {
|
|
21
|
+
this.engineCommandsTotal = engineCommandsTotal;
|
|
22
|
+
this.engineErrorsTotal = engineErrorsTotal;
|
|
23
|
+
this.engineRngCallsTotal = engineRngCallsTotal;
|
|
24
|
+
this.engineCommandDuration = engineCommandDuration;
|
|
25
|
+
this.rngBufferCapacity = rngBufferCapacity;
|
|
26
|
+
this.rngBufferFillLevel = rngBufferFillLevel;
|
|
27
|
+
this.rngBufferFillRatio = rngBufferFillRatio;
|
|
28
|
+
this.rngBufferRefillRequestsTotal = rngBufferRefillRequestsTotal;
|
|
29
|
+
this.rngBufferRefillFailuresTotal = rngBufferRefillFailuresTotal;
|
|
30
|
+
this.rngBufferRefillDuration = rngBufferRefillDuration;
|
|
31
|
+
this.rngBufferStarvationEventsTotal = rngBufferStarvationEventsTotal;
|
|
32
|
+
this.rngBufferLatency = rngBufferLatency;
|
|
33
|
+
this.metricsRegistry = new Map();
|
|
34
|
+
this.initializeRegistry();
|
|
35
|
+
}
|
|
36
|
+
initializeMetricsFromDatabase() {
|
|
37
|
+
throw new Error('Method not implemented.');
|
|
38
|
+
}
|
|
39
|
+
initializeRegistry() {
|
|
40
|
+
this.metricsRegistry.set('game_engine_commands_total', this.engineCommandsTotal);
|
|
41
|
+
this.metricsRegistry.set('game_engine_errors_total', this.engineErrorsTotal);
|
|
42
|
+
this.metricsRegistry.set('game_engine_rng_calls_total', this.engineRngCallsTotal);
|
|
43
|
+
this.metricsRegistry.set('game_engine_command_duration_ms', this.engineCommandDuration);
|
|
44
|
+
this.metricsRegistry.set('rng_buffer_capacity', this.rngBufferCapacity);
|
|
45
|
+
this.metricsRegistry.set('rng_buffer_fill_level', this.rngBufferFillLevel);
|
|
46
|
+
this.metricsRegistry.set('rng_buffer_fill_ratio', this.rngBufferFillRatio);
|
|
47
|
+
this.metricsRegistry.set('rng_buffer_refill_requests_total', this.rngBufferRefillRequestsTotal);
|
|
48
|
+
this.metricsRegistry.set('rng_buffer_refill_failures_total', this.rngBufferRefillFailuresTotal);
|
|
49
|
+
this.metricsRegistry.set('rng_buffer_refill_duration_ms', this.rngBufferRefillDuration);
|
|
50
|
+
this.metricsRegistry.set('rng_buffer_starvation_events_total', this.rngBufferStarvationEventsTotal);
|
|
51
|
+
this.metricsRegistry.set('rng_buffer_latency_ms', this.rngBufferLatency);
|
|
52
|
+
}
|
|
53
|
+
getCounter(name) {
|
|
54
|
+
const metric = this.metricsRegistry.get(name);
|
|
55
|
+
if (!metric) {
|
|
56
|
+
throw new Error(`Counter ${name} not found in metrics registry`);
|
|
57
|
+
}
|
|
58
|
+
return metric;
|
|
59
|
+
}
|
|
60
|
+
getGauge(name) {
|
|
61
|
+
const metric = this.metricsRegistry.get(name);
|
|
62
|
+
if (!metric) {
|
|
63
|
+
throw new Error(`Gauge ${name} not found in metrics registry`);
|
|
64
|
+
}
|
|
65
|
+
return metric;
|
|
66
|
+
}
|
|
67
|
+
getHistogram(name) {
|
|
68
|
+
const metric = this.metricsRegistry.get(name);
|
|
69
|
+
if (!metric) {
|
|
70
|
+
throw new Error(`Histogram ${name} not found in metrics registry`);
|
|
71
|
+
}
|
|
72
|
+
return metric;
|
|
73
|
+
}
|
|
74
|
+
async getMetrics() {
|
|
75
|
+
return '';
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
exports.PrometheusService = PrometheusService;
|
|
79
|
+
exports.PrometheusService = PrometheusService = __decorate([
|
|
80
|
+
(0, common_1.Injectable)(),
|
|
81
|
+
__param(0, (0, nestjs_prometheus_1.InjectMetric)('game_engine_commands_total')),
|
|
82
|
+
__param(1, (0, nestjs_prometheus_1.InjectMetric)('game_engine_errors_total')),
|
|
83
|
+
__param(2, (0, nestjs_prometheus_1.InjectMetric)('game_engine_rng_calls_total')),
|
|
84
|
+
__param(3, (0, nestjs_prometheus_1.InjectMetric)('game_engine_command_duration_ms')),
|
|
85
|
+
__param(4, (0, nestjs_prometheus_1.InjectMetric)('rng_buffer_capacity')),
|
|
86
|
+
__param(5, (0, nestjs_prometheus_1.InjectMetric)('rng_buffer_fill_level')),
|
|
87
|
+
__param(6, (0, nestjs_prometheus_1.InjectMetric)('rng_buffer_fill_ratio')),
|
|
88
|
+
__param(7, (0, nestjs_prometheus_1.InjectMetric)('rng_buffer_refill_requests_total')),
|
|
89
|
+
__param(8, (0, nestjs_prometheus_1.InjectMetric)('rng_buffer_refill_failures_total')),
|
|
90
|
+
__param(9, (0, nestjs_prometheus_1.InjectMetric)('rng_buffer_refill_duration_ms')),
|
|
91
|
+
__param(10, (0, nestjs_prometheus_1.InjectMetric)('rng_buffer_starvation_events_total')),
|
|
92
|
+
__param(11, (0, nestjs_prometheus_1.InjectMetric)('rng_buffer_latency_ms')),
|
|
93
|
+
__metadata("design:paramtypes", [prom_client_1.Counter,
|
|
94
|
+
prom_client_1.Counter,
|
|
95
|
+
prom_client_1.Counter,
|
|
96
|
+
prom_client_1.Histogram,
|
|
97
|
+
prom_client_1.Gauge,
|
|
98
|
+
prom_client_1.Gauge,
|
|
99
|
+
prom_client_1.Gauge,
|
|
100
|
+
prom_client_1.Counter,
|
|
101
|
+
prom_client_1.Counter,
|
|
102
|
+
prom_client_1.Histogram,
|
|
103
|
+
prom_client_1.Counter,
|
|
104
|
+
prom_client_1.Histogram])
|
|
105
|
+
], PrometheusService);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RetryPolicy } from './retry-policy';
|
|
2
|
+
export declare const HTTP_RETRYABLE_ERRORS: string[];
|
|
3
|
+
export declare class RetryPolicies {
|
|
4
|
+
static walletOperation(): RetryPolicy;
|
|
5
|
+
static externalApi(): RetryPolicy;
|
|
6
|
+
static database(): RetryPolicy;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=retry-policies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-policies.d.ts","sourceRoot":"","sources":["../../../src/common/retry/retry-policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,eAAO,MAAM,qBAAqB,UAQjC,CAAC;AAEF,qBAAa,aAAa;IACxB,MAAM,CAAC,eAAe,IAAI,WAAW;IAUrC,MAAM,CAAC,WAAW,IAAI,WAAW;IAUjC,MAAM,CAAC,QAAQ,IAAI,WAAW;CAS/B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RetryPolicies = exports.HTTP_RETRYABLE_ERRORS = void 0;
|
|
4
|
+
const retry_policy_1 = require("./retry-policy");
|
|
5
|
+
exports.HTTP_RETRYABLE_ERRORS = [
|
|
6
|
+
'TIMEOUT',
|
|
7
|
+
'ETIMEDOUT',
|
|
8
|
+
'ECONNRESET',
|
|
9
|
+
'ECONNREFUSED',
|
|
10
|
+
'EAI_AGAIN',
|
|
11
|
+
'ENOTFOUND',
|
|
12
|
+
'NETWORK',
|
|
13
|
+
];
|
|
14
|
+
class RetryPolicies {
|
|
15
|
+
static walletOperation() {
|
|
16
|
+
return new retry_policy_1.RetryPolicy({
|
|
17
|
+
maxAttempts: 5,
|
|
18
|
+
delayMs: 200,
|
|
19
|
+
backoffMultiplier: 2,
|
|
20
|
+
maxDelayMs: 3000,
|
|
21
|
+
retryableErrors: exports.HTTP_RETRYABLE_ERRORS,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
static externalApi() {
|
|
25
|
+
return new retry_policy_1.RetryPolicy({
|
|
26
|
+
maxAttempts: 3,
|
|
27
|
+
delayMs: 100,
|
|
28
|
+
backoffMultiplier: 2,
|
|
29
|
+
maxDelayMs: 1000,
|
|
30
|
+
retryableErrors: exports.HTTP_RETRYABLE_ERRORS,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
static database() {
|
|
34
|
+
return new retry_policy_1.RetryPolicy({
|
|
35
|
+
maxAttempts: 3,
|
|
36
|
+
delayMs: 50,
|
|
37
|
+
backoffMultiplier: 2,
|
|
38
|
+
maxDelayMs: 500,
|
|
39
|
+
retryableErrors: ['deadlock', 'serialization', 'timeout'],
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.RetryPolicies = RetryPolicies;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface RetryOptions {
|
|
2
|
+
maxAttempts: number;
|
|
3
|
+
delayMs: number;
|
|
4
|
+
backoffMultiplier?: number;
|
|
5
|
+
maxDelayMs?: number;
|
|
6
|
+
retryableErrors?: string[];
|
|
7
|
+
onRetry?: (attempt: number, error: Error) => void;
|
|
8
|
+
operationName?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class RetryPolicy {
|
|
11
|
+
private readonly logger;
|
|
12
|
+
private readonly maxAttempts;
|
|
13
|
+
private readonly delayMs;
|
|
14
|
+
private readonly backoffMultiplier;
|
|
15
|
+
private readonly maxDelayMs;
|
|
16
|
+
private readonly retryableErrors?;
|
|
17
|
+
private readonly onRetry?;
|
|
18
|
+
private readonly operationName?;
|
|
19
|
+
constructor(options: RetryOptions);
|
|
20
|
+
execute<T>(fn: () => Promise<T>): Promise<T>;
|
|
21
|
+
private isRetryable;
|
|
22
|
+
private calculateDelay;
|
|
23
|
+
private sleep;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=retry-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../../../src/common/retry/retry-policy.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;gBAE5B,OAAO,EAAE,YAAY;IAUpB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA4CzD,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,cAAc;YAMR,KAAK;CAGpB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RetryPolicy = void 0;
|
|
4
|
+
const logger_1 = require("../logger/logger");
|
|
5
|
+
class RetryPolicy {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.logger = new logger_1.Logger(RetryPolicy.name);
|
|
8
|
+
this.maxAttempts = Math.max(1, options.maxAttempts);
|
|
9
|
+
this.delayMs = Math.max(0, options.delayMs);
|
|
10
|
+
this.backoffMultiplier = options.backoffMultiplier ?? 1;
|
|
11
|
+
this.maxDelayMs = options.maxDelayMs ?? Number.POSITIVE_INFINITY;
|
|
12
|
+
this.retryableErrors = options.retryableErrors;
|
|
13
|
+
this.onRetry = options.onRetry;
|
|
14
|
+
this.operationName = options.operationName;
|
|
15
|
+
}
|
|
16
|
+
async execute(fn) {
|
|
17
|
+
let lastError = null;
|
|
18
|
+
for (let attempt = 1; attempt <= this.maxAttempts; attempt++) {
|
|
19
|
+
try {
|
|
20
|
+
const result = await fn();
|
|
21
|
+
if (attempt > 1) {
|
|
22
|
+
this.logger.log(`${this.operationName ?? 'operation'} succeeded on attempt ${attempt}`);
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const err = error;
|
|
28
|
+
lastError = err;
|
|
29
|
+
if (!this.isRetryable(err)) {
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
if (attempt === this.maxAttempts) {
|
|
33
|
+
this.logger.error(`${this.operationName ?? 'operation'} failed after ${attempt} attempts: ${err.message}`, err);
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
const delay = this.calculateDelay(attempt);
|
|
37
|
+
this.logger.warn(`${this.operationName ?? 'operation'} failed on attempt ${attempt}/${this.maxAttempts} with error: ${err.message}. Retrying in ${delay}ms...`);
|
|
38
|
+
if (this.onRetry) {
|
|
39
|
+
try {
|
|
40
|
+
this.onRetry(attempt, err);
|
|
41
|
+
}
|
|
42
|
+
catch { }
|
|
43
|
+
}
|
|
44
|
+
await this.sleep(delay);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
throw lastError ?? new Error('RetryPolicy failed without error');
|
|
48
|
+
}
|
|
49
|
+
isRetryable(error) {
|
|
50
|
+
if (!this.retryableErrors || this.retryableErrors.length === 0)
|
|
51
|
+
return true;
|
|
52
|
+
const causeCode = error?.cause?.code ?? '';
|
|
53
|
+
const text = `${error?.code ?? ''} ${error?.name ?? ''} ${error.message} ${causeCode}`;
|
|
54
|
+
return this.retryableErrors.some(pattern => text.includes(pattern));
|
|
55
|
+
}
|
|
56
|
+
calculateDelay(attempt) {
|
|
57
|
+
const factor = Math.max(1, this.backoffMultiplier);
|
|
58
|
+
const raw = this.delayMs * Math.pow(factor, attempt - 1);
|
|
59
|
+
return Math.min(raw, this.maxDelayMs);
|
|
60
|
+
}
|
|
61
|
+
async sleep(ms) {
|
|
62
|
+
await new Promise(resolve => setTimeout(resolve, ms));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.RetryPolicy = RetryPolicy;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ConfigService } from '@nestjs/config';
|
|
2
|
+
import { SecretsProvider } from './secrets-provider';
|
|
3
|
+
export declare class AwsSecretsProvider implements SecretsProvider {
|
|
4
|
+
private readonly configService;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
private secretsCache;
|
|
7
|
+
private secretsManager;
|
|
8
|
+
constructor(configService: ConfigService);
|
|
9
|
+
register(): Promise<void>;
|
|
10
|
+
private loadSecrets;
|
|
11
|
+
get(secretName: string): Promise<string>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=secrets-provider.aws.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets-provider.aws.d.ts","sourceRoot":"","sources":["../../../src/common/secrets-provider/secrets-provider.aws.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,qBACa,kBAAmB,YAAW,eAAe;IAKrB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJjE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,cAAc,CAAiB;gBAEa,aAAa,EAAE,aAAa;IAM1E,QAAQ;YAIA,WAAW;IAiCnB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAO/C"}
|
|
@@ -0,0 +1,72 @@
|
|
|
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
|
+
var AwsSecretsProvider_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AwsSecretsProvider = void 0;
|
|
17
|
+
const client_secrets_manager_1 = require("@aws-sdk/client-secrets-manager");
|
|
18
|
+
const common_1 = require("@nestjs/common");
|
|
19
|
+
const config_1 = require("@nestjs/config");
|
|
20
|
+
const logger_1 = require("../logger/logger");
|
|
21
|
+
let AwsSecretsProvider = AwsSecretsProvider_1 = class AwsSecretsProvider {
|
|
22
|
+
constructor(configService) {
|
|
23
|
+
this.configService = configService;
|
|
24
|
+
this.logger = new logger_1.Logger(AwsSecretsProvider_1.name);
|
|
25
|
+
this.secretsCache = new Map();
|
|
26
|
+
this.secretsManager = new client_secrets_manager_1.SecretsManager({
|
|
27
|
+
region: this.configService.get('AWS_REGION') || 'eu-central-1',
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
async register() {
|
|
31
|
+
await this.loadSecrets();
|
|
32
|
+
}
|
|
33
|
+
async loadSecrets() {
|
|
34
|
+
const envName = this.configService.get('AWS_SECRET_ID');
|
|
35
|
+
if (!envName) {
|
|
36
|
+
throw new Error(`AWS_SECRET_ID is not defined in environment variables`);
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
this.logger.log(`Fetching secrets from AWS Secrets Manager: ${envName}`);
|
|
40
|
+
const response = await this.secretsManager.getSecretValue({
|
|
41
|
+
SecretId: envName,
|
|
42
|
+
});
|
|
43
|
+
if (!response.SecretString) {
|
|
44
|
+
throw new Error(`Secret ${envName} found but has no value.`);
|
|
45
|
+
}
|
|
46
|
+
const secretsObject = JSON.parse(response.SecretString);
|
|
47
|
+
if (typeof secretsObject !== 'object' || secretsObject === null) {
|
|
48
|
+
throw new Error(`Secret ${envName} is not a valid JSON object.`);
|
|
49
|
+
}
|
|
50
|
+
Object.entries(secretsObject).forEach(([key, value]) => {
|
|
51
|
+
this.secretsCache.set(key, String(value));
|
|
52
|
+
});
|
|
53
|
+
this.logger.log(`Successfully loaded secrets from AWS Secrets Manager.`);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.logger.error(`Failed to retrieve secrets from AWS: ${error.message}`);
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async get(secretName) {
|
|
61
|
+
if (!this.secretsCache.has(secretName)) {
|
|
62
|
+
throw new Error(`Secret ${secretName} not found in cache.`);
|
|
63
|
+
}
|
|
64
|
+
return this.secretsCache.get(secretName);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.AwsSecretsProvider = AwsSecretsProvider;
|
|
68
|
+
exports.AwsSecretsProvider = AwsSecretsProvider = AwsSecretsProvider_1 = __decorate([
|
|
69
|
+
(0, common_1.Injectable)(),
|
|
70
|
+
__param(0, (0, common_1.Inject)(config_1.ConfigService)),
|
|
71
|
+
__metadata("design:paramtypes", [config_1.ConfigService])
|
|
72
|
+
], AwsSecretsProvider);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets-provider.d.ts","sourceRoot":"","sources":["../../../src/common/secrets-provider/secrets-provider.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,eAA4B,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SecretsProvider } from './secrets-provider';
|
|
2
|
+
export declare class LocalSecretsProvider implements SecretsProvider {
|
|
3
|
+
private secretsCache;
|
|
4
|
+
constructor();
|
|
5
|
+
private loadSecrets;
|
|
6
|
+
get(secretName: string): Promise<string>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=secrets-provider.local.d.ts.map
|