@takentrade/takentrade-libs 4.1.1 → 4.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -55
- package/dist/auth/guards/index.d.ts +1 -0
- package/dist/auth/guards/index.js +1 -0
- package/dist/auth/guards/tnt-base-auth.guard.d.ts +15 -0
- package/dist/auth/guards/tnt-base-auth.guard.js +56 -0
- package/dist/bullmq/config/bull.config.js +1 -1
- package/dist/cache/cache.module.d.ts +6 -2
- package/dist/cache/cache.module.js +10 -3
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -21
- package/dist/metrics/circuit-breaker-metrics.service.d.ts +0 -61
- package/dist/metrics/circuit-breaker-metrics.service.js +0 -149
- package/dist/metrics/index.d.ts +0 -5
- package/dist/metrics/index.js +0 -21
- package/dist/metrics/metrics-registry.d.ts +0 -50
- package/dist/metrics/metrics-registry.js +0 -156
- package/dist/metrics/metrics-updater.d.ts +0 -32
- package/dist/metrics/metrics-updater.js +0 -102
- package/dist/metrics/metrics.controller.d.ts +0 -11
- package/dist/metrics/metrics.controller.js +0 -32
- package/dist/metrics/metrics.interface.d.ts +0 -53
- package/dist/metrics/metrics.interface.js +0 -23
- package/dist/metrics/metrics.module.d.ts +0 -11
- package/dist/metrics/metrics.module.js +0 -39
- package/dist/metrics/metrics.service.d.ts +0 -50
- package/dist/metrics/metrics.service.js +0 -165
- package/dist/monitoring/alerting.service.d.ts +0 -82
- package/dist/monitoring/alerting.service.js +0 -290
- package/dist/monitoring/index.d.ts +0 -5
- package/dist/monitoring/index.js +0 -21
- package/dist/monitoring/monitoring.interface.d.ts +0 -102
- package/dist/monitoring/monitoring.interface.js +0 -10
- package/dist/monitoring/monitoring.module.d.ts +0 -8
- package/dist/monitoring/monitoring.module.js +0 -44
- package/dist/monitoring/sentry.service.d.ts +0 -65
- package/dist/monitoring/sentry.service.js +0 -218
- package/dist/monitoring/uptime.service.d.ts +0 -59
- package/dist/monitoring/uptime.service.js +0 -213
- package/dist/resilience/circuit-breaker-event-handler.d.ts +0 -16
- package/dist/resilience/circuit-breaker-event-handler.js +0 -70
- package/dist/resilience/circuit-breaker-factory.d.ts +0 -19
- package/dist/resilience/circuit-breaker-factory.js +0 -51
- package/dist/resilience/circuit-breaker-stats.service.d.ts +0 -37
- package/dist/resilience/circuit-breaker-stats.service.js +0 -69
- package/dist/resilience/circuit-breaker.interface.d.ts +0 -59
- package/dist/resilience/circuit-breaker.interface.js +0 -25
- package/dist/resilience/circuit-breaker.module.d.ts +0 -2
- package/dist/resilience/circuit-breaker.module.js +0 -21
- package/dist/resilience/circuit-breaker.service.d.ts +0 -119
- package/dist/resilience/circuit-breaker.service.js +0 -234
- package/dist/resilience/index.d.ts +0 -3
- package/dist/resilience/index.js +0 -19
|
@@ -1,218 +0,0 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
-
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;
|
|
22
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
-
};
|
|
24
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
-
var ownKeys = function(o) {
|
|
26
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
-
var ar = [];
|
|
28
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
-
return ar;
|
|
30
|
-
};
|
|
31
|
-
return ownKeys(o);
|
|
32
|
-
};
|
|
33
|
-
return function (mod) {
|
|
34
|
-
if (mod && mod.__esModule) return mod;
|
|
35
|
-
var result = {};
|
|
36
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
-
__setModuleDefault(result, mod);
|
|
38
|
-
return result;
|
|
39
|
-
};
|
|
40
|
-
})();
|
|
41
|
-
var SentryService_1;
|
|
42
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
-
exports.SentryService = void 0;
|
|
44
|
-
const common_1 = require("@nestjs/common");
|
|
45
|
-
const Sentry = __importStar(require("@sentry/node"));
|
|
46
|
-
require("@sentry/tracing");
|
|
47
|
-
let SentryService = SentryService_1 = class SentryService {
|
|
48
|
-
logger = new common_1.Logger(SentryService_1.name);
|
|
49
|
-
initialized = false;
|
|
50
|
-
constructor(config) {
|
|
51
|
-
if (config?.dsn) {
|
|
52
|
-
this.initialize(config);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Initialize Sentry
|
|
57
|
-
*/
|
|
58
|
-
initialize(config) {
|
|
59
|
-
try {
|
|
60
|
-
Sentry.init({
|
|
61
|
-
dsn: config.dsn,
|
|
62
|
-
environment: config.environment || process.env.NODE_ENV || 'development',
|
|
63
|
-
release: config.release,
|
|
64
|
-
sampleRate: config.sampleRate ?? 1.0,
|
|
65
|
-
tracesSampleRate: config.tracesSampleRate ?? 0.1,
|
|
66
|
-
debug: config.debug ?? false,
|
|
67
|
-
beforeSend: config.beforeSend,
|
|
68
|
-
});
|
|
69
|
-
this.initialized = true;
|
|
70
|
-
this.logger.log('Sentry initialized successfully');
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
this.logger.error('Failed to initialize Sentry:', error);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Capture an exception
|
|
78
|
-
*/
|
|
79
|
-
captureException(error, context) {
|
|
80
|
-
if (!this.initialized) {
|
|
81
|
-
this.logger.warn('Sentry not initialized, error not captured');
|
|
82
|
-
return undefined;
|
|
83
|
-
}
|
|
84
|
-
return Sentry.captureException(error, {
|
|
85
|
-
tags: context?.tags,
|
|
86
|
-
user: context?.user,
|
|
87
|
-
extra: context?.extra,
|
|
88
|
-
level: context?.level,
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Capture a message
|
|
93
|
-
*/
|
|
94
|
-
captureMessage(message, level = 'info', context) {
|
|
95
|
-
if (!this.initialized) {
|
|
96
|
-
this.logger.warn('Sentry not initialized, message not captured');
|
|
97
|
-
return undefined;
|
|
98
|
-
}
|
|
99
|
-
return Sentry.captureMessage(message, {
|
|
100
|
-
level,
|
|
101
|
-
tags: context?.tags,
|
|
102
|
-
user: context?.user,
|
|
103
|
-
extra: context?.extra,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Add a breadcrumb
|
|
108
|
-
*/
|
|
109
|
-
addBreadcrumb(breadcrumb) {
|
|
110
|
-
if (!this.initialized) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
Sentry.addBreadcrumb({
|
|
114
|
-
type: breadcrumb.type,
|
|
115
|
-
level: breadcrumb.level,
|
|
116
|
-
message: breadcrumb.message,
|
|
117
|
-
category: breadcrumb.category,
|
|
118
|
-
data: breadcrumb.data,
|
|
119
|
-
timestamp: breadcrumb.timestamp,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Set user context
|
|
124
|
-
*/
|
|
125
|
-
setUser(user) {
|
|
126
|
-
if (!this.initialized) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
Sentry.setUser(user);
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Set a tag
|
|
133
|
-
*/
|
|
134
|
-
setTag(key, value) {
|
|
135
|
-
if (!this.initialized) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
Sentry.setTag(key, value);
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Set multiple tags
|
|
142
|
-
*/
|
|
143
|
-
setTags(tags) {
|
|
144
|
-
if (!this.initialized) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
Sentry.setTags(tags);
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Set context
|
|
151
|
-
*/
|
|
152
|
-
setContext(name, context) {
|
|
153
|
-
if (!this.initialized) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
Sentry.setContext(name, context);
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Start a transaction for performance monitoring
|
|
160
|
-
* Note: Use Sentry.startTransaction directly in newer versions
|
|
161
|
-
*/
|
|
162
|
-
startTransaction(name, op) {
|
|
163
|
-
if (!this.initialized) {
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
// In Sentry v7+, use withScope instead
|
|
167
|
-
return { name, op };
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Configure scope (use withScope in newer versions)
|
|
171
|
-
*/
|
|
172
|
-
configureScope(callback) {
|
|
173
|
-
if (!this.initialized) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
// In Sentry v7+, use withScope
|
|
177
|
-
Sentry.withScope(callback);
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Flush events
|
|
181
|
-
*/
|
|
182
|
-
async flush(timeout = 2000) {
|
|
183
|
-
if (!this.initialized) {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
return await Sentry.flush(timeout);
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Close Sentry client
|
|
190
|
-
*/
|
|
191
|
-
async close(timeout = 2000) {
|
|
192
|
-
if (!this.initialized) {
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
return await Sentry.close(timeout);
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Check if Sentry is initialized
|
|
199
|
-
*/
|
|
200
|
-
isInitialized() {
|
|
201
|
-
return this.initialized;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Cleanup on module destroy
|
|
205
|
-
*/
|
|
206
|
-
async onModuleDestroy() {
|
|
207
|
-
if (this.initialized) {
|
|
208
|
-
this.logger.log('Flushing Sentry events...');
|
|
209
|
-
await this.flush();
|
|
210
|
-
await this.close();
|
|
211
|
-
this.logger.log('Sentry service shut down');
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
exports.SentryService = SentryService;
|
|
216
|
-
exports.SentryService = SentryService = SentryService_1 = __decorate([
|
|
217
|
-
(0, common_1.Injectable)()
|
|
218
|
-
], SentryService);
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { HealthCheck, HealthCheckResult, UptimeConfig, UptimeReport } from './monitoring.interface';
|
|
2
|
-
/**
|
|
3
|
-
* Uptime Monitoring Service
|
|
4
|
-
*
|
|
5
|
-
* Tracks service availability and generates SLA reports
|
|
6
|
-
*/
|
|
7
|
-
export declare class UptimeService {
|
|
8
|
-
private readonly logger;
|
|
9
|
-
private healthChecks;
|
|
10
|
-
private healthResults;
|
|
11
|
-
private downtimeTracking;
|
|
12
|
-
private config;
|
|
13
|
-
private checkIntervals;
|
|
14
|
-
constructor(config?: UptimeConfig);
|
|
15
|
-
/**
|
|
16
|
-
* Register a health check
|
|
17
|
-
*/
|
|
18
|
-
registerHealthCheck(check: HealthCheck): void;
|
|
19
|
-
/**
|
|
20
|
-
* Start periodic health check
|
|
21
|
-
*/
|
|
22
|
-
private startHealthCheck;
|
|
23
|
-
/**
|
|
24
|
-
* Run a health check
|
|
25
|
-
*/
|
|
26
|
-
runHealthCheck(name: string): Promise<HealthCheckResult>;
|
|
27
|
-
/**
|
|
28
|
-
* Get current health status
|
|
29
|
-
*/
|
|
30
|
-
getHealthStatus(name?: string): Promise<HealthCheckResult[]>;
|
|
31
|
-
/**
|
|
32
|
-
* Get uptime percentage
|
|
33
|
-
*/
|
|
34
|
-
getUptime(name: string, periodMs?: number): number;
|
|
35
|
-
/**
|
|
36
|
-
* Get SLA report
|
|
37
|
-
*/
|
|
38
|
-
getSLAReport(name: string, period?: string): UptimeReport;
|
|
39
|
-
/**
|
|
40
|
-
* Parse period string to milliseconds
|
|
41
|
-
*/
|
|
42
|
-
private parsePeriod;
|
|
43
|
-
/**
|
|
44
|
-
* Stop all health checks
|
|
45
|
-
*/
|
|
46
|
-
stopAllHealthChecks(): void;
|
|
47
|
-
/**
|
|
48
|
-
* Stop specific health check
|
|
49
|
-
*/
|
|
50
|
-
stopHealthCheck(name: string): void;
|
|
51
|
-
/**
|
|
52
|
-
* Get all registered health checks
|
|
53
|
-
*/
|
|
54
|
-
getHealthChecks(): string[];
|
|
55
|
-
/**
|
|
56
|
-
* Cleanup on destroy
|
|
57
|
-
*/
|
|
58
|
-
onModuleDestroy(): void;
|
|
59
|
-
}
|
|
@@ -1,213 +0,0 @@
|
|
|
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 UptimeService_1;
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.UptimeService = void 0;
|
|
11
|
-
const common_1 = require("@nestjs/common");
|
|
12
|
-
/**
|
|
13
|
-
* Uptime Monitoring Service
|
|
14
|
-
*
|
|
15
|
-
* Tracks service availability and generates SLA reports
|
|
16
|
-
*/
|
|
17
|
-
let UptimeService = UptimeService_1 = class UptimeService {
|
|
18
|
-
logger = new common_1.Logger(UptimeService_1.name);
|
|
19
|
-
healthChecks = new Map();
|
|
20
|
-
healthResults = new Map();
|
|
21
|
-
downtimeTracking = new Map();
|
|
22
|
-
config;
|
|
23
|
-
checkIntervals = new Map();
|
|
24
|
-
constructor(config) {
|
|
25
|
-
this.config = config || { enabled: true, checkInterval: 60000 };
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Register a health check
|
|
29
|
-
*/
|
|
30
|
-
registerHealthCheck(check) {
|
|
31
|
-
this.healthChecks.set(check.name, check);
|
|
32
|
-
this.healthResults.set(check.name, []);
|
|
33
|
-
this.downtimeTracking.set(check.name, 0);
|
|
34
|
-
if (this.config.enabled) {
|
|
35
|
-
this.startHealthCheck(check);
|
|
36
|
-
}
|
|
37
|
-
this.logger.log(`Health check '${check.name}' registered`);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Start periodic health check
|
|
41
|
-
*/
|
|
42
|
-
startHealthCheck(check) {
|
|
43
|
-
const interval = check.interval || this.config.checkInterval || 60000;
|
|
44
|
-
const timer = setInterval(async () => {
|
|
45
|
-
await this.runHealthCheck(check.name);
|
|
46
|
-
}, interval);
|
|
47
|
-
this.checkIntervals.set(check.name, timer);
|
|
48
|
-
// Run immediately
|
|
49
|
-
this.runHealthCheck(check.name);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Run a health check
|
|
53
|
-
*/
|
|
54
|
-
async runHealthCheck(name) {
|
|
55
|
-
const check = this.healthChecks.get(name);
|
|
56
|
-
if (!check) {
|
|
57
|
-
throw new Error(`Health check '${name}' not found`);
|
|
58
|
-
}
|
|
59
|
-
const startTime = Date.now();
|
|
60
|
-
let result;
|
|
61
|
-
try {
|
|
62
|
-
const timeout = check.timeout || 5000;
|
|
63
|
-
await Promise.race([
|
|
64
|
-
check.check(),
|
|
65
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error('Health check timeout')), timeout)),
|
|
66
|
-
]);
|
|
67
|
-
result = {
|
|
68
|
-
name,
|
|
69
|
-
status: 'healthy',
|
|
70
|
-
responseTime: Date.now() - startTime,
|
|
71
|
-
timestamp: new Date(),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
catch (error) {
|
|
75
|
-
result = {
|
|
76
|
-
name,
|
|
77
|
-
status: 'unhealthy',
|
|
78
|
-
responseTime: Date.now() - startTime,
|
|
79
|
-
error: error instanceof Error ? error.message : String(error),
|
|
80
|
-
timestamp: new Date(),
|
|
81
|
-
};
|
|
82
|
-
// Track downtime
|
|
83
|
-
const currentDowntime = this.downtimeTracking.get(name) || 0;
|
|
84
|
-
this.downtimeTracking.set(name, currentDowntime + (check.interval || this.config.checkInterval || 60000));
|
|
85
|
-
this.logger.warn(`Health check '${name}' failed: ${result.error}`);
|
|
86
|
-
}
|
|
87
|
-
// Store result
|
|
88
|
-
const results = this.healthResults.get(name) || [];
|
|
89
|
-
results.push(result);
|
|
90
|
-
// Keep only last 1000 results
|
|
91
|
-
if (results.length > 1000) {
|
|
92
|
-
results.shift();
|
|
93
|
-
}
|
|
94
|
-
this.healthResults.set(name, results);
|
|
95
|
-
return result;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Get current health status
|
|
99
|
-
*/
|
|
100
|
-
async getHealthStatus(name) {
|
|
101
|
-
if (name) {
|
|
102
|
-
const results = this.healthResults.get(name);
|
|
103
|
-
return results ? [results[results.length - 1]] : [];
|
|
104
|
-
}
|
|
105
|
-
// Get latest result for all checks
|
|
106
|
-
const allResults = [];
|
|
107
|
-
for (const [checkName, results] of this.healthResults.entries()) {
|
|
108
|
-
if (results.length > 0) {
|
|
109
|
-
allResults.push(results[results.length - 1]);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return allResults;
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Get uptime percentage
|
|
116
|
-
*/
|
|
117
|
-
getUptime(name, periodMs) {
|
|
118
|
-
const results = this.healthResults.get(name);
|
|
119
|
-
if (!results || results.length === 0) {
|
|
120
|
-
return 100;
|
|
121
|
-
}
|
|
122
|
-
const now = Date.now();
|
|
123
|
-
const period = periodMs || 24 * 60 * 60 * 1000; // 24 hours default
|
|
124
|
-
const startTime = now - period;
|
|
125
|
-
const relevantResults = results.filter((r) => r.timestamp.getTime() >= startTime);
|
|
126
|
-
if (relevantResults.length === 0) {
|
|
127
|
-
return 100;
|
|
128
|
-
}
|
|
129
|
-
const healthyCount = relevantResults.filter((r) => r.status === 'healthy').length;
|
|
130
|
-
return (healthyCount / relevantResults.length) * 100;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Get SLA report
|
|
134
|
-
*/
|
|
135
|
-
getSLAReport(name, period = '30d') {
|
|
136
|
-
const periodMs = this.parsePeriod(period);
|
|
137
|
-
const now = new Date();
|
|
138
|
-
const startTime = new Date(now.getTime() - periodMs);
|
|
139
|
-
const results = this.healthResults.get(name) || [];
|
|
140
|
-
const relevantResults = results.filter((r) => r.timestamp.getTime() >= startTime.getTime());
|
|
141
|
-
const healthyCount = relevantResults.filter((r) => r.status === 'healthy').length;
|
|
142
|
-
const uptime = relevantResults.length > 0
|
|
143
|
-
? (healthyCount / relevantResults.length) * 100
|
|
144
|
-
: 100;
|
|
145
|
-
const downtime = this.downtimeTracking.get(name) || 0;
|
|
146
|
-
const incidents = relevantResults.filter((r) => r.status === 'unhealthy').length;
|
|
147
|
-
return {
|
|
148
|
-
service: name,
|
|
149
|
-
uptime,
|
|
150
|
-
downtime,
|
|
151
|
-
incidents,
|
|
152
|
-
period,
|
|
153
|
-
startTime,
|
|
154
|
-
endTime: now,
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Parse period string to milliseconds
|
|
159
|
-
*/
|
|
160
|
-
parsePeriod(period) {
|
|
161
|
-
const match = period.match(/^(\d+)([hdwm])$/);
|
|
162
|
-
if (!match) {
|
|
163
|
-
throw new Error(`Invalid period format: ${period}`);
|
|
164
|
-
}
|
|
165
|
-
const value = parseInt(match[1], 10);
|
|
166
|
-
const unit = match[2];
|
|
167
|
-
const multipliers = {
|
|
168
|
-
h: 60 * 60 * 1000,
|
|
169
|
-
d: 24 * 60 * 60 * 1000,
|
|
170
|
-
w: 7 * 24 * 60 * 60 * 1000,
|
|
171
|
-
m: 30 * 24 * 60 * 60 * 1000,
|
|
172
|
-
};
|
|
173
|
-
return value * multipliers[unit];
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Stop all health checks
|
|
177
|
-
*/
|
|
178
|
-
stopAllHealthChecks() {
|
|
179
|
-
for (const [name, timer] of this.checkIntervals.entries()) {
|
|
180
|
-
clearInterval(timer);
|
|
181
|
-
this.logger.log(`Health check '${name}' stopped`);
|
|
182
|
-
}
|
|
183
|
-
this.checkIntervals.clear();
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Stop specific health check
|
|
187
|
-
*/
|
|
188
|
-
stopHealthCheck(name) {
|
|
189
|
-
const timer = this.checkIntervals.get(name);
|
|
190
|
-
if (timer) {
|
|
191
|
-
clearInterval(timer);
|
|
192
|
-
this.checkIntervals.delete(name);
|
|
193
|
-
this.logger.log(`Health check '${name}' stopped`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Get all registered health checks
|
|
198
|
-
*/
|
|
199
|
-
getHealthChecks() {
|
|
200
|
-
return Array.from(this.healthChecks.keys());
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Cleanup on destroy
|
|
204
|
-
*/
|
|
205
|
-
onModuleDestroy() {
|
|
206
|
-
this.stopAllHealthChecks();
|
|
207
|
-
this.logger.log('Uptime service shut down');
|
|
208
|
-
}
|
|
209
|
-
};
|
|
210
|
-
exports.UptimeService = UptimeService;
|
|
211
|
-
exports.UptimeService = UptimeService = UptimeService_1 = __decorate([
|
|
212
|
-
(0, common_1.Injectable)()
|
|
213
|
-
], UptimeService);
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import CircuitBreaker from 'opossum';
|
|
2
|
-
/**
|
|
3
|
-
* Circuit Breaker Event Handler
|
|
4
|
-
*
|
|
5
|
-
* Handles all circuit breaker events and provides logging
|
|
6
|
-
*/
|
|
7
|
-
export declare class CircuitBreakerEventHandler {
|
|
8
|
-
private readonly logger;
|
|
9
|
-
/**
|
|
10
|
-
* Set up event listeners for a circuit breaker
|
|
11
|
-
*
|
|
12
|
-
* @param breaker - Circuit breaker instance
|
|
13
|
-
* @param name - Circuit breaker name
|
|
14
|
-
*/
|
|
15
|
-
setupEventListeners(breaker: CircuitBreaker, name: string): void;
|
|
16
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CircuitBreakerEventHandler = void 0;
|
|
4
|
-
const common_1 = require("@nestjs/common");
|
|
5
|
-
const circuit_breaker_interface_1 = require("./circuit-breaker.interface");
|
|
6
|
-
/**
|
|
7
|
-
* Circuit Breaker Event Handler
|
|
8
|
-
*
|
|
9
|
-
* Handles all circuit breaker events and provides logging
|
|
10
|
-
*/
|
|
11
|
-
class CircuitBreakerEventHandler {
|
|
12
|
-
logger = new common_1.Logger(CircuitBreakerEventHandler.name);
|
|
13
|
-
/**
|
|
14
|
-
* Set up event listeners for a circuit breaker
|
|
15
|
-
*
|
|
16
|
-
* @param breaker - Circuit breaker instance
|
|
17
|
-
* @param name - Circuit breaker name
|
|
18
|
-
*/
|
|
19
|
-
setupEventListeners(breaker, name) {
|
|
20
|
-
// Success event
|
|
21
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.SUCCESS, (result, latency) => {
|
|
22
|
-
this.logger.debug(`[${name}] Success - Latency: ${latency}ms`);
|
|
23
|
-
});
|
|
24
|
-
// Failure event
|
|
25
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.FAILURE, (error) => {
|
|
26
|
-
this.logger.warn(`[${name}] Failure - Error: ${error.message}`);
|
|
27
|
-
});
|
|
28
|
-
// Timeout event
|
|
29
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.TIMEOUT, () => {
|
|
30
|
-
this.logger.warn(`[${name}] Timeout - Request exceeded timeout threshold`);
|
|
31
|
-
});
|
|
32
|
-
// Reject event (circuit is open)
|
|
33
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.REJECT, () => {
|
|
34
|
-
this.logger.warn(`[${name}] Reject - Circuit is open, request rejected`);
|
|
35
|
-
});
|
|
36
|
-
// Circuit opened
|
|
37
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.OPEN, () => {
|
|
38
|
-
this.logger.error(`[${name}] Circuit OPENED - Too many failures detected`);
|
|
39
|
-
});
|
|
40
|
-
// Circuit closed
|
|
41
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.CLOSE, () => {
|
|
42
|
-
this.logger.log(`[${name}] Circuit CLOSED - Service recovered`);
|
|
43
|
-
});
|
|
44
|
-
// Circuit half-open
|
|
45
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.HALF_OPEN, () => {
|
|
46
|
-
this.logger.log(`[${name}] Circuit HALF-OPEN - Testing service recovery`);
|
|
47
|
-
});
|
|
48
|
-
// Fallback executed
|
|
49
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.FALLBACK, (result) => {
|
|
50
|
-
this.logger.debug(`[${name}] Fallback executed`);
|
|
51
|
-
});
|
|
52
|
-
// Semaphore locked (too many concurrent requests)
|
|
53
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.SEMAPHORE_LOCKED, () => {
|
|
54
|
-
this.logger.warn(`[${name}] Semaphore locked - Too many concurrent requests`);
|
|
55
|
-
});
|
|
56
|
-
// Health check failed
|
|
57
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.HEALTH_CHECK_FAILED, () => {
|
|
58
|
-
this.logger.warn(`[${name}] Health check failed`);
|
|
59
|
-
});
|
|
60
|
-
// Cache hit
|
|
61
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.CACHE_HIT, () => {
|
|
62
|
-
this.logger.debug(`[${name}] Cache hit`);
|
|
63
|
-
});
|
|
64
|
-
// Cache miss
|
|
65
|
-
breaker.on(circuit_breaker_interface_1.CircuitBreakerEvent.CACHE_MISS, () => {
|
|
66
|
-
this.logger.debug(`[${name}] Cache miss`);
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
exports.CircuitBreakerEventHandler = CircuitBreakerEventHandler;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { CircuitBreakerOptions, CircuitBreakerInstance } from './circuit-breaker.interface';
|
|
2
|
-
/**
|
|
3
|
-
* Circuit Breaker Factory
|
|
4
|
-
*
|
|
5
|
-
* Responsible for creating and configuring circuit breaker instances
|
|
6
|
-
*/
|
|
7
|
-
export declare class CircuitBreakerFactory {
|
|
8
|
-
private readonly logger;
|
|
9
|
-
private readonly eventHandler;
|
|
10
|
-
/**
|
|
11
|
-
* Create a new circuit breaker instance
|
|
12
|
-
*
|
|
13
|
-
* @param name - Unique identifier for the circuit breaker
|
|
14
|
-
* @param action - The async function to be protected
|
|
15
|
-
* @param options - Circuit breaker configuration options
|
|
16
|
-
* @returns Circuit breaker instance
|
|
17
|
-
*/
|
|
18
|
-
create<T = any, R = any>(name: string, action: (...args: T[]) => Promise<R>, options?: CircuitBreakerOptions): CircuitBreakerInstance<T, R>;
|
|
19
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.CircuitBreakerFactory = void 0;
|
|
7
|
-
const common_1 = require("@nestjs/common");
|
|
8
|
-
const opossum_1 = __importDefault(require("opossum"));
|
|
9
|
-
const circuit_breaker_event_handler_1 = require("./circuit-breaker-event-handler");
|
|
10
|
-
/**
|
|
11
|
-
* Circuit Breaker Factory
|
|
12
|
-
*
|
|
13
|
-
* Responsible for creating and configuring circuit breaker instances
|
|
14
|
-
*/
|
|
15
|
-
class CircuitBreakerFactory {
|
|
16
|
-
logger = new common_1.Logger(CircuitBreakerFactory.name);
|
|
17
|
-
eventHandler = new circuit_breaker_event_handler_1.CircuitBreakerEventHandler();
|
|
18
|
-
/**
|
|
19
|
-
* Create a new circuit breaker instance
|
|
20
|
-
*
|
|
21
|
-
* @param name - Unique identifier for the circuit breaker
|
|
22
|
-
* @param action - The async function to be protected
|
|
23
|
-
* @param options - Circuit breaker configuration options
|
|
24
|
-
* @returns Circuit breaker instance
|
|
25
|
-
*/
|
|
26
|
-
create(name, action, options = {}) {
|
|
27
|
-
const defaultOptions = {
|
|
28
|
-
timeout: 10000, // 10 seconds
|
|
29
|
-
errorThresholdPercentage: 50, // 50% error rate
|
|
30
|
-
resetTimeout: 30000, // 30 seconds
|
|
31
|
-
rollingCountTimeout: 10000, // 10 seconds
|
|
32
|
-
rollingCountBuckets: 10,
|
|
33
|
-
capacity: 100,
|
|
34
|
-
enableSnapshots: true,
|
|
35
|
-
volumeThreshold: 5, // Minimum number of requests before circuit can open
|
|
36
|
-
name,
|
|
37
|
-
...options,
|
|
38
|
-
};
|
|
39
|
-
const breaker = new opossum_1.default(action, defaultOptions);
|
|
40
|
-
// Set up event listeners for monitoring and logging
|
|
41
|
-
this.eventHandler.setupEventListeners(breaker, name);
|
|
42
|
-
const instance = {
|
|
43
|
-
breaker,
|
|
44
|
-
name,
|
|
45
|
-
options: defaultOptions,
|
|
46
|
-
};
|
|
47
|
-
this.logger.log(`Circuit breaker '${name}' created successfully`);
|
|
48
|
-
return instance;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
exports.CircuitBreakerFactory = CircuitBreakerFactory;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import CircuitBreaker from 'opossum';
|
|
2
|
-
import { CircuitBreakerStats, CircuitState, CircuitBreakerInstance } from './circuit-breaker.interface';
|
|
3
|
-
/**
|
|
4
|
-
* Circuit Breaker Statistics Service
|
|
5
|
-
*
|
|
6
|
-
* Handles statistics and state management for circuit breakers
|
|
7
|
-
*/
|
|
8
|
-
export declare class CircuitBreakerStatsService {
|
|
9
|
-
/**
|
|
10
|
-
* Get statistics for a circuit breaker
|
|
11
|
-
*
|
|
12
|
-
* @param instance - Circuit breaker instance
|
|
13
|
-
* @returns Circuit breaker statistics
|
|
14
|
-
*/
|
|
15
|
-
getStats(instance: CircuitBreakerInstance): CircuitBreakerStats;
|
|
16
|
-
/**
|
|
17
|
-
* Get all circuit breaker statistics
|
|
18
|
-
*
|
|
19
|
-
* @param breakers - Map of circuit breaker instances
|
|
20
|
-
* @returns Map of circuit breaker names to their statistics
|
|
21
|
-
*/
|
|
22
|
-
getAllStats(breakers: Map<string, CircuitBreakerInstance>): Map<string, CircuitBreakerStats>;
|
|
23
|
-
/**
|
|
24
|
-
* Get the current state of a circuit breaker
|
|
25
|
-
*
|
|
26
|
-
* @param breaker - Circuit breaker instance
|
|
27
|
-
* @returns Current circuit state
|
|
28
|
-
*/
|
|
29
|
-
getState(breaker: CircuitBreaker): CircuitState;
|
|
30
|
-
/**
|
|
31
|
-
* Check if a circuit breaker is open
|
|
32
|
-
*
|
|
33
|
-
* @param breaker - Circuit breaker instance
|
|
34
|
-
* @returns True if circuit is open
|
|
35
|
-
*/
|
|
36
|
-
isOpen(breaker: CircuitBreaker): boolean;
|
|
37
|
-
}
|