@nest-omni/core 3.1.2-7 → 3.1.2-8

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 (63) hide show
  1. package/common/utils.d.ts +1 -0
  2. package/common/utils.js +6 -0
  3. package/http-client/config/http-client.config.d.ts +6 -0
  4. package/http-client/config/http-client.config.js +87 -0
  5. package/http-client/config/index.d.ts +1 -0
  6. package/http-client/config/index.js +17 -0
  7. package/http-client/decorators/http-client.decorators.d.ts +72 -0
  8. package/http-client/decorators/http-client.decorators.js +204 -0
  9. package/http-client/decorators/index.d.ts +1 -0
  10. package/http-client/decorators/index.js +17 -0
  11. package/http-client/entities/http-log.entity.d.ts +98 -0
  12. package/http-client/entities/http-log.entity.js +143 -0
  13. package/http-client/entities/index.d.ts +1 -0
  14. package/http-client/entities/index.js +17 -0
  15. package/http-client/errors/http-client.errors.d.ts +56 -0
  16. package/http-client/errors/http-client.errors.js +149 -0
  17. package/http-client/errors/index.d.ts +1 -0
  18. package/http-client/errors/index.js +17 -0
  19. package/http-client/examples/advanced-usage.example.d.ts +23 -0
  20. package/http-client/examples/advanced-usage.example.js +319 -0
  21. package/http-client/examples/basic-usage.example.d.ts +61 -0
  22. package/http-client/examples/basic-usage.example.js +171 -0
  23. package/http-client/examples/index.d.ts +3 -0
  24. package/http-client/examples/index.js +19 -0
  25. package/http-client/examples/multi-api-configuration.example.d.ts +98 -0
  26. package/http-client/examples/multi-api-configuration.example.js +353 -0
  27. package/http-client/http-client.module.d.ts +11 -0
  28. package/http-client/http-client.module.js +254 -0
  29. package/http-client/index.d.ts +10 -0
  30. package/http-client/index.js +27 -0
  31. package/http-client/interfaces/api-client-config.interface.d.ts +152 -0
  32. package/http-client/interfaces/api-client-config.interface.js +12 -0
  33. package/http-client/interfaces/http-client-config.interface.d.ts +123 -0
  34. package/http-client/interfaces/http-client-config.interface.js +2 -0
  35. package/http-client/services/api-client-registry.service.d.ts +40 -0
  36. package/http-client/services/api-client-registry.service.js +411 -0
  37. package/http-client/services/cache.service.d.ts +24 -0
  38. package/http-client/services/cache.service.js +264 -0
  39. package/http-client/services/circuit-breaker.service.d.ts +33 -0
  40. package/http-client/services/circuit-breaker.service.js +180 -0
  41. package/http-client/services/http-client.service.d.ts +43 -0
  42. package/http-client/services/http-client.service.js +384 -0
  43. package/http-client/services/http-log-query.service.d.ts +56 -0
  44. package/http-client/services/http-log-query.service.js +414 -0
  45. package/http-client/services/index.d.ts +7 -0
  46. package/http-client/services/index.js +23 -0
  47. package/http-client/services/log-cleanup.service.d.ts +64 -0
  48. package/http-client/services/log-cleanup.service.js +268 -0
  49. package/http-client/services/logging.service.d.ts +36 -0
  50. package/http-client/services/logging.service.js +445 -0
  51. package/http-client/utils/call-stack-extractor.util.d.ts +29 -0
  52. package/http-client/utils/call-stack-extractor.util.js +138 -0
  53. package/http-client/utils/context-extractor.util.d.ts +44 -0
  54. package/http-client/utils/context-extractor.util.js +173 -0
  55. package/http-client/utils/curl-generator.util.d.ts +9 -0
  56. package/http-client/utils/curl-generator.util.js +169 -0
  57. package/http-client/utils/index.d.ts +4 -0
  58. package/http-client/utils/index.js +20 -0
  59. package/http-client/utils/retry-recorder.util.d.ts +30 -0
  60. package/http-client/utils/retry-recorder.util.js +143 -0
  61. package/index.d.ts +1 -0
  62. package/index.js +1 -0
  63. package/package.json +1 -1
@@ -0,0 +1,384 @@
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var HttpClientService_1;
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.HttpClientService = void 0;
23
+ const common_1 = require("@nestjs/common");
24
+ const axios_retry_1 = require("axios-retry");
25
+ const cache_1 = require("../../cache");
26
+ const circuit_breaker_service_1 = require("./circuit-breaker.service");
27
+ const logging_service_1 = require("./logging.service");
28
+ const cache_service_1 = require("./cache.service");
29
+ const decorators_1 = require("../decorators");
30
+ const context_extractor_util_1 = require("../utils/context-extractor.util");
31
+ const curl_generator_util_1 = require("../utils/curl-generator.util");
32
+ const retry_recorder_util_1 = require("../utils/retry-recorder.util");
33
+ const request_id_util_1 = require("../../../../http-client/src/utils/request-id.util");
34
+ let HttpClientService = HttpClientService_1 = class HttpClientService {
35
+ constructor(circuitBreakerService, loggingService, cacheService, config = {}) {
36
+ this.circuitBreakerService = circuitBreakerService;
37
+ this.loggingService = loggingService;
38
+ this.cacheService = cacheService;
39
+ this.logger = new common_1.Logger(HttpClientService_1.name);
40
+ this.requestStats = {
41
+ totalRequests: 0,
42
+ successfulRequests: 0,
43
+ failedRequests: 0,
44
+ totalResponseTime: 0,
45
+ requestsByMethod: {},
46
+ requestsByStatus: {},
47
+ };
48
+ this.defaultConfig = this.mergeWithDefaults(config);
49
+ this.axiosInstance = this.createAxiosInstance();
50
+ }
51
+ request(config, decoratorContext) {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ var _a, _b, _c, _d, _e, _f, _g;
54
+ const startTime = Date.now();
55
+ const retryRecorder = retry_recorder_util_1.RetryRecorder.create();
56
+ let requestId;
57
+ let circuitBreakerState;
58
+ let cacheHit = false;
59
+ try {
60
+ const enhancedConfig = this.applyDecoratorConfig(config, decoratorContext);
61
+ const decoratorConfigs = decoratorContext
62
+ ? decorators_1.HttpDecoratorUtils.getAllDecoratorConfigs(decoratorContext.target, decoratorContext.propertyKey)
63
+ : {};
64
+ const loggingOptions = decoratorConfigs.logging || this.defaultConfig.logging;
65
+ if (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.enabled) {
66
+ requestId = this.loggingService.logRequestStart(enhancedConfig, loggingOptions);
67
+ enhancedConfig.metadata = enhancedConfig.metadata || {};
68
+ enhancedConfig.metadata.requestId = requestId;
69
+ }
70
+ const cacheConfig = decoratorConfigs.cache || this.defaultConfig.cache;
71
+ if ((cacheConfig === null || cacheConfig === void 0 ? void 0 : cacheConfig.enabled) &&
72
+ this.shouldCacheRequest(enhancedConfig, cacheConfig)) {
73
+ const cachedResponse = yield this.cacheService.get(enhancedConfig, cacheConfig);
74
+ if (cachedResponse) {
75
+ cacheHit = true;
76
+ if (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.enabled) {
77
+ const databaseLogging = (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.databaseLog) ||
78
+ ((_b = (_a = this.defaultConfig.logging) === null || _a === void 0 ? void 0 : _a.databaseLogging) === null || _b === void 0 ? void 0 : _b.enabled);
79
+ this.loggingService.logRequestSuccess(cachedResponse, startTime, requestId, loggingOptions, databaseLogging, undefined, cacheHit, undefined, decoratorContext);
80
+ }
81
+ return cachedResponse.data;
82
+ }
83
+ }
84
+ const timeout = decoratorConfigs.timeout || this.defaultConfig.timeout;
85
+ if (timeout) {
86
+ enhancedConfig.timeout = timeout;
87
+ }
88
+ const proxyConfig = decoratorConfigs.proxy || this.defaultConfig.proxy;
89
+ if (proxyConfig === null || proxyConfig === void 0 ? void 0 : proxyConfig.enabled) {
90
+ enhancedConfig.proxy = {
91
+ host: proxyConfig.host,
92
+ port: proxyConfig.port,
93
+ protocol: proxyConfig.protocol,
94
+ auth: proxyConfig.auth,
95
+ };
96
+ }
97
+ if ((_c = this.defaultConfig.retry) === null || _c === void 0 ? void 0 : _c.enabled) {
98
+ const originalOnRetry = this.defaultConfig.retry.onRetry;
99
+ this.defaultConfig.retry.onRetry = (retryCount, error, requestConfig) => {
100
+ const retryRecord = retry_recorder_util_1.RetryRecorder.recordRetry(retryCount, error, requestConfig, this.calculateRetryDelay(retryCount, this.defaultConfig.retry));
101
+ retryRecorder.addRecord(retryRecord);
102
+ if (originalOnRetry) {
103
+ originalOnRetry(retryCount, error, requestConfig);
104
+ }
105
+ };
106
+ }
107
+ const response = yield this.executeWithFeatures(enhancedConfig, decoratorConfigs, requestId, startTime, retryRecorder, (state) => {
108
+ circuitBreakerState = state;
109
+ });
110
+ if ((cacheConfig === null || cacheConfig === void 0 ? void 0 : cacheConfig.enabled) &&
111
+ this.shouldCacheRequest(enhancedConfig, cacheConfig)) {
112
+ yield this.cacheService.set(enhancedConfig, response, cacheConfig);
113
+ }
114
+ if (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.enabled) {
115
+ const databaseLogging = (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.databaseLog) ||
116
+ ((_e = (_d = this.defaultConfig.logging) === null || _d === void 0 ? void 0 : _d.databaseLogging) === null || _e === void 0 ? void 0 : _e.enabled);
117
+ this.loggingService.logRequestSuccess(response, startTime, requestId, loggingOptions, databaseLogging, retryRecorder.getRecords(), cacheHit, circuitBreakerState, decoratorContext);
118
+ }
119
+ return response.data;
120
+ }
121
+ catch (error) {
122
+ const loggingOptions = decoratorContext
123
+ ? decorators_1.HttpDecoratorUtils.getLoggingOptions(decoratorContext.target, decoratorContext.propertyKey)
124
+ : this.defaultConfig.logging;
125
+ if (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.enabled) {
126
+ const databaseLogging = (loggingOptions === null || loggingOptions === void 0 ? void 0 : loggingOptions.databaseLog) ||
127
+ ((_g = (_f = this.defaultConfig.logging) === null || _f === void 0 ? void 0 : _f.databaseLogging) === null || _g === void 0 ? void 0 : _g.enabled);
128
+ this.loggingService.logRequestError(error, startTime, requestId, retryRecorder.getRecords().length || 1, loggingOptions, databaseLogging, retryRecorder.getRecords(), cacheHit, circuitBreakerState, decoratorContext);
129
+ }
130
+ throw error;
131
+ }
132
+ });
133
+ }
134
+ generateCurlCommand(config) {
135
+ return curl_generator_util_1.CurlGenerator.generateSimplifiedCurl(config);
136
+ }
137
+ generateDebugCurlCommand(config, response) {
138
+ return curl_generator_util_1.CurlGenerator.generateDebugCurl(config, response);
139
+ }
140
+ getStats() {
141
+ const avgResponseTime = this.requestStats.totalRequests > 0
142
+ ? this.requestStats.totalResponseTime / this.requestStats.totalRequests
143
+ : 0;
144
+ return Object.assign(Object.assign({}, this.requestStats), { averageResponseTime: avgResponseTime, successRate: this.requestStats.totalRequests > 0
145
+ ? (this.requestStats.successfulRequests /
146
+ this.requestStats.totalRequests) *
147
+ 100
148
+ : 0, circuitBreakerStats: this.circuitBreakerService.getAllStates(), cacheStats: this.cacheService.getStats() });
149
+ }
150
+ resetStats() {
151
+ this.requestStats = {
152
+ totalRequests: 0,
153
+ successfulRequests: 0,
154
+ failedRequests: 0,
155
+ totalResponseTime: 0,
156
+ requestsByMethod: {},
157
+ requestsByStatus: {},
158
+ };
159
+ }
160
+ get(url, config) {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ return this.request(Object.assign(Object.assign({}, config), { method: 'GET', url }));
163
+ });
164
+ }
165
+ post(url, data, config) {
166
+ return __awaiter(this, void 0, void 0, function* () {
167
+ return this.request(Object.assign(Object.assign({}, config), { method: 'POST', url, data }));
168
+ });
169
+ }
170
+ put(url, data, config) {
171
+ return __awaiter(this, void 0, void 0, function* () {
172
+ return this.request(Object.assign(Object.assign({}, config), { method: 'PUT', url, data }));
173
+ });
174
+ }
175
+ patch(url, data, config) {
176
+ return __awaiter(this, void 0, void 0, function* () {
177
+ return this.request(Object.assign(Object.assign({}, config), { method: 'PATCH', url, data }));
178
+ });
179
+ }
180
+ delete(url, config) {
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ return this.request(Object.assign(Object.assign({}, config), { method: 'DELETE', url }));
183
+ });
184
+ }
185
+ createAxiosInstance() {
186
+ var _a, _b;
187
+ const instance = require('axios').create({
188
+ baseURL: this.defaultConfig.baseURL,
189
+ timeout: this.defaultConfig.timeout,
190
+ proxy: ((_a = this.defaultConfig.proxy) === null || _a === void 0 ? void 0 : _a.enabled)
191
+ ? {
192
+ host: this.defaultConfig.proxy.host,
193
+ port: this.defaultConfig.proxy.port,
194
+ protocol: this.defaultConfig.proxy.protocol,
195
+ auth: this.defaultConfig.proxy.auth,
196
+ }
197
+ : undefined,
198
+ });
199
+ if ((_b = this.defaultConfig.retry) === null || _b === void 0 ? void 0 : _b.enabled) {
200
+ (0, axios_retry_1.default)(instance, {
201
+ retries: this.defaultConfig.retry.retries || 3,
202
+ retryDelay: this.defaultConfig.retry.retryDelay ||
203
+ ((retryCount) => Math.pow(2, retryCount) * 1000),
204
+ retryCondition: this.defaultConfig.retry.retryCondition ||
205
+ ((error) => {
206
+ if (!error.response)
207
+ return true;
208
+ const status = error.response.status;
209
+ return status >= 500 || status === 429;
210
+ }),
211
+ shouldResetTimeout: this.defaultConfig.retry.shouldResetTimeout !== false,
212
+ onRetry: this.defaultConfig.retry.onRetry ||
213
+ ((retryCount, error, requestConfig) => {
214
+ var _a;
215
+ this.logger.warn(`Retrying request (attempt ${retryCount}): ${(_a = requestConfig.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()} ${requestConfig.url}`);
216
+ }),
217
+ });
218
+ }
219
+ instance.interceptors.request.use((config) => {
220
+ config.headers = config.headers || {};
221
+ const context = context_extractor_util_1.ContextExtractor.getHttpContext();
222
+ const requestId = context.requestId || (0, request_id_util_1.generateRequestId)();
223
+ config.headers['X-Request-ID'] = requestId;
224
+ if (context.userId) {
225
+ config.headers['X-User-ID'] = context.userId;
226
+ }
227
+ config.metadata = config.metadata || {};
228
+ config.metadata.requestId = requestId;
229
+ return config;
230
+ }, (error) => {
231
+ this.logger.error('Request interceptor error', error);
232
+ return Promise.reject(error);
233
+ });
234
+ instance.interceptors.response.use((response) => {
235
+ this.updateStats(response);
236
+ return response;
237
+ }, (error) => {
238
+ this.updateErrorStats(error);
239
+ return Promise.reject(error);
240
+ });
241
+ return instance;
242
+ }
243
+ executeWithFeatures(config, decoratorConfigs, requestId, startTime, retryRecorder, onCircuitBreakerStateChange) {
244
+ return __awaiter(this, void 0, void 0, function* () {
245
+ const requestFn = () => this.axiosInstance.request(config);
246
+ const circuitBreakerConfig = decoratorConfigs.circuitBreaker || this.defaultConfig.circuitBreaker;
247
+ if (circuitBreakerConfig === null || circuitBreakerConfig === void 0 ? void 0 : circuitBreakerConfig.enabled) {
248
+ const circuitBreakerKey = this.generateCircuitBreakerKey(config);
249
+ return this.circuitBreakerService.executeWithCircuitBreaker(circuitBreakerKey, requestFn, circuitBreakerConfig);
250
+ }
251
+ else {
252
+ return requestFn();
253
+ }
254
+ });
255
+ }
256
+ calculateRetryDelay(retryCount, retryConfig) {
257
+ if (retryConfig.retryDelay) {
258
+ return retryConfig.retryDelay(retryCount);
259
+ }
260
+ return Math.pow(2, retryCount) * 1000;
261
+ }
262
+ applyDecoratorConfig(config, decoratorContext) {
263
+ if (!decoratorContext)
264
+ return Object.assign({}, config);
265
+ const httpClientConfig = decorators_1.HttpDecoratorUtils.getHttpClientOptions(decoratorContext.target);
266
+ return Object.assign(Object.assign({}, config), httpClientConfig);
267
+ }
268
+ shouldCacheRequest(config, cacheConfig) {
269
+ var _a;
270
+ const method = (_a = config.method) === null || _a === void 0 ? void 0 : _a.toLowerCase();
271
+ return cacheConfig.cacheableMethods.includes(method || 'get');
272
+ }
273
+ generateCircuitBreakerKey(config) {
274
+ var _a;
275
+ const method = ((_a = config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'UNKNOWN';
276
+ const url = new URL(config.url || '', this.defaultConfig.baseURL || 'http://localhost');
277
+ return `${method}:${url.host}${url.pathname}`;
278
+ }
279
+ updateStats(response) {
280
+ var _a, _b;
281
+ this.requestStats.totalRequests++;
282
+ this.requestStats.successfulRequests++;
283
+ const method = ((_a = response.config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'UNKNOWN';
284
+ const status = response.status;
285
+ this.requestStats.requestsByMethod[method] =
286
+ (this.requestStats.requestsByMethod[method] || 0) + 1;
287
+ this.requestStats.requestsByStatus[status] =
288
+ (this.requestStats.requestsByStatus[status] || 0) + 1;
289
+ if ((_b = response.config.metadata) === null || _b === void 0 ? void 0 : _b.startTime) {
290
+ const responseTime = Date.now() -
291
+ response.config.metadata
292
+ .startTime;
293
+ this.requestStats.totalResponseTime += responseTime;
294
+ }
295
+ }
296
+ updateErrorStats(error) {
297
+ var _a;
298
+ this.requestStats.totalRequests++;
299
+ this.requestStats.failedRequests++;
300
+ if (error.config) {
301
+ const method = ((_a = error.config.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || 'UNKNOWN';
302
+ this.requestStats.requestsByMethod[method] =
303
+ (this.requestStats.requestsByMethod[method] || 0) + 1;
304
+ if (error.response) {
305
+ const status = error.response.status;
306
+ this.requestStats.requestsByStatus[status] =
307
+ (this.requestStats.requestsByStatus[status] || 0) + 1;
308
+ }
309
+ }
310
+ }
311
+ mergeWithDefaults(config) {
312
+ const defaults = {
313
+ baseURL: process.env.HTTP_CLIENT_BASE_URL,
314
+ timeout: 30000,
315
+ retry: {
316
+ enabled: true,
317
+ retries: 3,
318
+ retryDelay: (retryCount) => Math.pow(2, retryCount) * 1000,
319
+ retryCondition: (error) => {
320
+ if (!error.response)
321
+ return true;
322
+ const status = error.response.status;
323
+ return status >= 500 || status === 429;
324
+ },
325
+ shouldResetTimeout: true,
326
+ },
327
+ circuitBreaker: {
328
+ enabled: true,
329
+ failureThreshold: 5,
330
+ recoveryTimeoutMs: 60000,
331
+ monitoringPeriodMs: 10000,
332
+ minimumThroughputThreshold: 10,
333
+ countHalfOpenCalls: true,
334
+ },
335
+ cache: {
336
+ enabled: true,
337
+ defaultTtl: 300000,
338
+ cacheableMethods: ['get'],
339
+ cacheableStatusCodes: [200, 201, 202, 204, 301, 302, 304],
340
+ options: {
341
+ layers: [cache_1.CacheLayer.MEMORY, cache_1.CacheLayer.REDIS],
342
+ },
343
+ },
344
+ logging: {
345
+ enabled: true,
346
+ logRequests: true,
347
+ logResponses: true,
348
+ logErrors: true,
349
+ logHeaders: true,
350
+ logBody: true,
351
+ maxBodyLength: 1000,
352
+ sanitizeHeaders: ['authorization', 'apikey', 'password', 'token'],
353
+ logLevel: 'info',
354
+ databaseLogging: {
355
+ enabled: false,
356
+ dataSource: 'default',
357
+ tableName: 'http_logs',
358
+ },
359
+ },
360
+ };
361
+ return this.deepMerge(defaults, config);
362
+ }
363
+ deepMerge(target, source) {
364
+ const result = Object.assign({}, target);
365
+ for (const key in source) {
366
+ if (source[key] &&
367
+ typeof source[key] === 'object' &&
368
+ !Array.isArray(source[key])) {
369
+ result[key] = this.deepMerge(result[key] || {}, source[key]);
370
+ }
371
+ else {
372
+ result[key] = source[key];
373
+ }
374
+ }
375
+ return result;
376
+ }
377
+ };
378
+ exports.HttpClientService = HttpClientService;
379
+ exports.HttpClientService = HttpClientService = HttpClientService_1 = __decorate([
380
+ (0, common_1.Injectable)(),
381
+ __metadata("design:paramtypes", [circuit_breaker_service_1.HttpCircuitBreakerService,
382
+ logging_service_1.HttpLoggingService,
383
+ cache_service_1.HttpCacheService, Object])
384
+ ], HttpClientService);
@@ -0,0 +1,56 @@
1
+ import { DataSource } from 'typeorm';
2
+ import { HttpLogEntity, HttpLogQueryOptions, HttpLogStats } from '../entities/http-log.entity';
3
+ export declare class HttpLogQueryService {
4
+ private readonly dataSource?;
5
+ private readonly logger;
6
+ private logRepository;
7
+ constructor(dataSource?: DataSource);
8
+ findLogs(options?: HttpLogQueryOptions): Promise<{
9
+ logs: HttpLogEntity[];
10
+ total: number;
11
+ page: number;
12
+ limit: number;
13
+ totalPages: number;
14
+ }>;
15
+ findLogById(id: string, includeDetails?: boolean): Promise<HttpLogEntity | null>;
16
+ findLogByRequestId(requestId: string): Promise<HttpLogEntity | null>;
17
+ findErrorLogs(options?: {
18
+ startDate?: Date;
19
+ endDate?: Date;
20
+ errorCode?: string;
21
+ statusCode?: number;
22
+ page?: number;
23
+ limit?: number;
24
+ }): Promise<{
25
+ logs: HttpLogEntity[];
26
+ total: number;
27
+ }>;
28
+ findSlowRequests(minResponseTime?: number, options?: {
29
+ page?: number;
30
+ limit?: number;
31
+ }): Promise<{
32
+ logs: HttpLogEntity[];
33
+ total: number;
34
+ }>;
35
+ findRetryLogs(options?: {
36
+ minRetries?: number;
37
+ page?: number;
38
+ limit?: number;
39
+ }): Promise<{
40
+ logs: HttpLogEntity[];
41
+ total: number;
42
+ }>;
43
+ getStats(options?: {
44
+ startDate?: Date;
45
+ endDate?: Date;
46
+ userId?: string;
47
+ serviceName?: string;
48
+ groupBy?: 'hour' | 'day' | 'week';
49
+ }): Promise<HttpLogStats>;
50
+ deleteOldLogs(daysToKeep?: number): Promise<number>;
51
+ clearAllLogs(): Promise<number>;
52
+ private initializeRepository;
53
+ private calculatePercentiles;
54
+ private formatStats;
55
+ private buildQuery;
56
+ }