@aifabrix/miso-client 3.5.0 → 3.8.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/CHANGELOG.md +263 -0
- package/dist/api/auth-cache.api.d.ts.map +1 -1
- package/dist/api/auth-cache.api.js +27 -5
- package/dist/api/auth-cache.api.js.map +1 -1
- package/dist/api/auth-login.api.d.ts.map +1 -1
- package/dist/api/auth-login.api.js +49 -6
- package/dist/api/auth-login.api.js.map +1 -1
- package/dist/api/auth-token.api.d.ts.map +1 -1
- package/dist/api/auth-token.api.js +99 -7
- package/dist/api/auth-token.api.js.map +1 -1
- package/dist/api/auth-user.api.d.ts.map +1 -1
- package/dist/api/auth-user.api.js +22 -4
- package/dist/api/auth-user.api.js.map +1 -1
- package/dist/api/auth.api.d.ts +2 -9
- package/dist/api/auth.api.d.ts.map +1 -1
- package/dist/api/auth.api.js +1 -66
- package/dist/api/auth.api.js.map +1 -1
- package/dist/api/logs-create.api.d.ts.map +1 -1
- package/dist/api/logs-create.api.js +57 -4
- package/dist/api/logs-create.api.js.map +1 -1
- package/dist/api/logs-export.api.d.ts.map +1 -1
- package/dist/api/logs-export.api.js +7 -1
- package/dist/api/logs-export.api.js.map +1 -1
- package/dist/api/logs-list.api.d.ts.map +1 -1
- package/dist/api/logs-list.api.js +32 -6
- package/dist/api/logs-list.api.js.map +1 -1
- package/dist/api/logs-stats.api.d.ts.map +1 -1
- package/dist/api/logs-stats.api.js +22 -4
- package/dist/api/logs-stats.api.js.map +1 -1
- package/dist/api/permissions.api.d.ts +2 -1
- package/dist/api/permissions.api.d.ts.map +1 -1
- package/dist/api/permissions.api.js +16 -5
- package/dist/api/permissions.api.js.map +1 -1
- package/dist/api/roles.api.d.ts +2 -1
- package/dist/api/roles.api.d.ts.map +1 -1
- package/dist/api/roles.api.js +16 -5
- package/dist/api/roles.api.js.map +1 -1
- package/dist/api/types/logs.types.d.ts +44 -7
- package/dist/api/types/logs.types.d.ts.map +1 -1
- package/dist/express/client-token-endpoint.d.ts.map +1 -1
- package/dist/express/client-token-endpoint.js +42 -5
- package/dist/express/client-token-endpoint.js.map +1 -1
- package/dist/express/error-handler.d.ts.map +1 -1
- package/dist/express/error-handler.js +32 -8
- package/dist/express/error-handler.js.map +1 -1
- package/dist/express/index.d.ts +1 -0
- package/dist/express/index.d.ts.map +1 -1
- package/dist/express/index.js +4 -1
- package/dist/express/index.js.map +1 -1
- package/dist/express/logger-context.middleware.d.ts +46 -0
- package/dist/express/logger-context.middleware.d.ts.map +1 -0
- package/dist/express/logger-context.middleware.js +99 -0
- package/dist/express/logger-context.middleware.js.map +1 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -5
- package/dist/index.js.map +1 -1
- package/dist/services/application-context.service.d.ts +48 -0
- package/dist/services/application-context.service.d.ts.map +1 -0
- package/dist/services/application-context.service.js +141 -0
- package/dist/services/application-context.service.js.map +1 -0
- package/dist/services/auth.service.d.ts.map +1 -1
- package/dist/services/auth.service.js +97 -8
- package/dist/services/auth.service.js.map +1 -1
- package/dist/services/browser-permission.service.d.ts +5 -0
- package/dist/services/browser-permission.service.d.ts.map +1 -1
- package/dist/services/browser-permission.service.js +39 -2
- package/dist/services/browser-permission.service.js.map +1 -1
- package/dist/services/browser-role.service.d.ts +5 -0
- package/dist/services/browser-role.service.d.ts.map +1 -1
- package/dist/services/browser-role.service.js +45 -2
- package/dist/services/browser-role.service.js.map +1 -1
- package/dist/services/logger/index.d.ts +10 -0
- package/dist/services/logger/index.d.ts.map +1 -0
- package/dist/services/logger/index.js +22 -0
- package/dist/services/logger/index.js.map +1 -0
- package/dist/services/logger/logger-chain.d.ts +90 -0
- package/dist/services/logger/logger-chain.d.ts.map +1 -0
- package/dist/services/logger/logger-chain.js +169 -0
- package/dist/services/logger/logger-chain.js.map +1 -0
- package/dist/services/logger/logger-context-storage.d.ts +73 -0
- package/dist/services/logger/logger-context-storage.d.ts.map +1 -0
- package/dist/services/logger/logger-context-storage.js +86 -0
- package/dist/services/logger/logger-context-storage.js.map +1 -0
- package/dist/services/logger/logger-context.d.ts +89 -0
- package/dist/services/logger/logger-context.d.ts.map +1 -0
- package/dist/services/logger/logger-context.js +208 -0
- package/dist/services/logger/logger-context.js.map +1 -0
- package/dist/services/logger/logger.service.d.ts +186 -0
- package/dist/services/logger/logger.service.d.ts.map +1 -0
- package/dist/services/logger/logger.service.js +423 -0
- package/dist/services/logger/logger.service.js.map +1 -0
- package/dist/services/logger/unified-logger.factory.d.ts +87 -0
- package/dist/services/logger/unified-logger.factory.d.ts.map +1 -0
- package/dist/services/logger/unified-logger.factory.js +120 -0
- package/dist/services/logger/unified-logger.factory.js.map +1 -0
- package/dist/services/logger/unified-logger.service.d.ts +89 -0
- package/dist/services/logger/unified-logger.service.d.ts.map +1 -0
- package/dist/services/logger/unified-logger.service.js +186 -0
- package/dist/services/logger/unified-logger.service.js.map +1 -0
- package/dist/services/permission.service.d.ts +1 -0
- package/dist/services/permission.service.d.ts.map +1 -1
- package/dist/services/permission.service.js +10 -2
- package/dist/services/permission.service.js.map +1 -1
- package/dist/services/role.service.d.ts +1 -0
- package/dist/services/role.service.d.ts.map +1 -1
- package/dist/services/role.service.js +10 -2
- package/dist/services/role.service.js.map +1 -1
- package/dist/types/filter.types.d.ts +6 -6
- package/dist/types/filter.types.d.ts.map +1 -1
- package/dist/types/filter.types.js +14 -5
- package/dist/types/filter.types.js.map +1 -1
- package/dist/utils/console-logger.d.ts +21 -0
- package/dist/utils/console-logger.d.ts.map +1 -0
- package/dist/utils/console-logger.js +58 -0
- package/dist/utils/console-logger.js.map +1 -0
- package/dist/utils/controller-url-resolver.d.ts.map +1 -1
- package/dist/utils/controller-url-resolver.js +5 -0
- package/dist/utils/controller-url-resolver.js.map +1 -1
- package/dist/utils/data-client-auth.d.ts.map +1 -1
- package/dist/utils/data-client-auth.js +34 -2
- package/dist/utils/data-client-auth.js.map +1 -1
- package/dist/utils/data-client-auto-init.d.ts.map +1 -1
- package/dist/utils/data-client-auto-init.js +59 -3
- package/dist/utils/data-client-auto-init.js.map +1 -1
- package/dist/utils/data-client-request.d.ts.map +1 -1
- package/dist/utils/data-client-request.js +78 -2
- package/dist/utils/data-client-request.js.map +1 -1
- package/dist/utils/data-client.d.ts.map +1 -1
- package/dist/utils/data-client.js +10 -7
- package/dist/utils/data-client.js.map +1 -1
- package/dist/utils/environment-token.d.ts.map +1 -1
- package/dist/utils/environment-token.js +37 -57
- package/dist/utils/environment-token.js.map +1 -1
- package/dist/utils/error-extractor.d.ts +52 -0
- package/dist/utils/error-extractor.d.ts.map +1 -0
- package/dist/utils/error-extractor.js +136 -0
- package/dist/utils/error-extractor.js.map +1 -0
- package/dist/utils/filter.utils.d.ts +115 -3
- package/dist/utils/filter.utils.d.ts.map +1 -1
- package/dist/utils/filter.utils.js +298 -27
- package/dist/utils/filter.utils.js.map +1 -1
- package/dist/utils/http-client-audit.d.ts +1 -1
- package/dist/utils/http-client-audit.d.ts.map +1 -1
- package/dist/utils/http-client.d.ts +1 -1
- package/dist/utils/http-client.d.ts.map +1 -1
- package/dist/utils/internal-http-client.d.ts +4 -0
- package/dist/utils/internal-http-client.d.ts.map +1 -1
- package/dist/utils/internal-http-client.js +190 -11
- package/dist/utils/internal-http-client.js.map +1 -1
- package/dist/utils/response-validator.d.ts.map +1 -1
- package/dist/utils/response-validator.js +2 -4
- package/dist/utils/response-validator.js.map +1 -1
- package/dist/utils/token-utils.d.ts.map +1 -1
- package/dist/utils/token-utils.js +75 -4
- package/dist/utils/token-utils.js.map +1 -1
- package/package.json +2 -1
- package/dist/services/logger.service.d.ts +0 -191
- package/dist/services/logger.service.d.ts.map +0 -1
- package/dist/services/logger.service.js +0 -488
- package/dist/services/logger.service.js.map +0 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Logger context extraction utilities
|
|
4
|
+
* Provides functions for extracting JWT context, environment metadata, and building LogEntry objects
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.extractJwtContext = extractJwtContext;
|
|
11
|
+
exports.extractEnvironmentMetadata = extractEnvironmentMetadata;
|
|
12
|
+
exports.getLogWithRequest = getLogWithRequest;
|
|
13
|
+
exports.getWithContext = getWithContext;
|
|
14
|
+
exports.getWithToken = getWithToken;
|
|
15
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
16
|
+
const data_masker_1 = require("../../utils/data-masker");
|
|
17
|
+
const request_context_1 = require("../../utils/request-context");
|
|
18
|
+
/**
|
|
19
|
+
* Extract JWT token information
|
|
20
|
+
* @param token - JWT token string
|
|
21
|
+
* @returns Extracted context with userId, applicationId, sessionId, roles, permissions
|
|
22
|
+
*/
|
|
23
|
+
function extractJwtContext(token) {
|
|
24
|
+
if (!token)
|
|
25
|
+
return {};
|
|
26
|
+
try {
|
|
27
|
+
const decoded = jsonwebtoken_1.default.decode(token);
|
|
28
|
+
if (!decoded)
|
|
29
|
+
return {};
|
|
30
|
+
return {
|
|
31
|
+
userId: (decoded.sub || decoded.userId || decoded.user_id),
|
|
32
|
+
applicationId: (decoded.applicationId || decoded.app_id),
|
|
33
|
+
sessionId: (decoded.sessionId || decoded.sid),
|
|
34
|
+
roles: (decoded.roles ||
|
|
35
|
+
decoded.realm_access?.roles ||
|
|
36
|
+
[]),
|
|
37
|
+
permissions: (decoded.permissions ||
|
|
38
|
+
decoded.scope?.split(" ") ||
|
|
39
|
+
[]),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
// JWT parsing failed, return empty context
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Extract metadata from environment (browser or Node.js)
|
|
49
|
+
* @returns Partial LogEntry with environment metadata
|
|
50
|
+
*/
|
|
51
|
+
function extractEnvironmentMetadata() {
|
|
52
|
+
const metadata = {};
|
|
53
|
+
// Try to extract browser metadata
|
|
54
|
+
if (typeof globalThis !== "undefined" && "window" in globalThis) {
|
|
55
|
+
const win = globalThis;
|
|
56
|
+
const navigator = win.window?.navigator;
|
|
57
|
+
const location = win.window?.location;
|
|
58
|
+
metadata.userAgent = navigator?.userAgent;
|
|
59
|
+
metadata.hostname = location?.hostname;
|
|
60
|
+
}
|
|
61
|
+
// Try to extract Node.js metadata
|
|
62
|
+
if (typeof process !== "undefined" && process.env) {
|
|
63
|
+
metadata.hostname = process.env["HOSTNAME"] || "unknown";
|
|
64
|
+
}
|
|
65
|
+
return metadata;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get LogEntry object with request context extracted
|
|
69
|
+
* Extracts IP, method, path, userAgent, correlationId, userId from Express Request
|
|
70
|
+
* Returns structured LogEntry object ready for external logger tables
|
|
71
|
+
*
|
|
72
|
+
* @param req - Express Request object
|
|
73
|
+
* @param message - Log message
|
|
74
|
+
* @param level - Optional log level (defaults to 'info')
|
|
75
|
+
* @param context - Optional additional context
|
|
76
|
+
* @param applicationContextService - ApplicationContextService for application/environment extraction
|
|
77
|
+
* @param generateCorrelationId - Function to generate correlation ID
|
|
78
|
+
* @param maskSensitiveData - Whether to mask sensitive data
|
|
79
|
+
* @param clientId - Client ID to use as fallback when application is empty
|
|
80
|
+
* @returns Complete LogEntry object with all request context extracted
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const logEntry = getLogWithRequest(req, 'User action', 'info', { action: 'login' }, applicationContextService, generateCorrelationId, true, config.clientId);
|
|
85
|
+
* await myCustomLogger.save(logEntry);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
function getLogWithRequest(req, message, level = "info", context, applicationContextService, generateCorrelationId, maskSensitiveData, clientId) {
|
|
89
|
+
const requestContext = (0, request_context_1.extractRequestContext)(req);
|
|
90
|
+
const jwtContext = extractJwtContext(req.headers.authorization?.replace("Bearer ", ""));
|
|
91
|
+
const metadata = extractEnvironmentMetadata();
|
|
92
|
+
const appContext = applicationContextService.getApplicationContext();
|
|
93
|
+
const correlationId = requestContext.correlationId || generateCorrelationId();
|
|
94
|
+
// Mask sensitive data in context if enabled
|
|
95
|
+
const maskedContext = maskSensitiveData && context
|
|
96
|
+
? data_masker_1.DataMasker.maskSensitiveData(context)
|
|
97
|
+
: context;
|
|
98
|
+
// Extract applicationId: try user JWT first, then client token
|
|
99
|
+
let applicationId = jwtContext.applicationId || "";
|
|
100
|
+
if (!applicationId && appContext.applicationId) {
|
|
101
|
+
applicationId = appContext.applicationId;
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
timestamp: new Date().toISOString(),
|
|
105
|
+
level,
|
|
106
|
+
environment: appContext.environment || "unknown",
|
|
107
|
+
application: appContext.application || clientId || "",
|
|
108
|
+
applicationId,
|
|
109
|
+
message,
|
|
110
|
+
context: maskedContext,
|
|
111
|
+
correlationId,
|
|
112
|
+
userId: requestContext.userId || jwtContext.userId,
|
|
113
|
+
sessionId: requestContext.sessionId || jwtContext.sessionId,
|
|
114
|
+
requestId: requestContext.requestId,
|
|
115
|
+
ipAddress: requestContext.ipAddress || metadata.ipAddress,
|
|
116
|
+
userAgent: requestContext.userAgent || metadata.userAgent,
|
|
117
|
+
...metadata,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get LogEntry object with provided context
|
|
122
|
+
* Generates correlation ID automatically and extracts metadata from environment
|
|
123
|
+
*
|
|
124
|
+
* @param context - Context object to include in logs
|
|
125
|
+
* @param message - Log message
|
|
126
|
+
* @param level - Optional log level (defaults to 'info')
|
|
127
|
+
* @param applicationContextService - ApplicationContextService for application/environment extraction
|
|
128
|
+
* @param generateCorrelationId - Function to generate correlation ID
|
|
129
|
+
* @param maskSensitiveData - Whether to mask sensitive data
|
|
130
|
+
* @param clientId - Client ID to use as fallback when application is empty
|
|
131
|
+
* @returns Complete LogEntry object
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const logEntry = getWithContext({ operation: 'sync' }, 'Sync started', 'info', applicationContextService, generateCorrelationId, true, config.clientId);
|
|
136
|
+
* await myCustomLogger.save(logEntry);
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
function getWithContext(context, message, level = "info", applicationContextService, generateCorrelationId, maskSensitiveData, clientId) {
|
|
140
|
+
const metadata = extractEnvironmentMetadata();
|
|
141
|
+
const correlationId = generateCorrelationId();
|
|
142
|
+
const appContext = applicationContextService.getApplicationContext();
|
|
143
|
+
// Mask sensitive data in context if enabled
|
|
144
|
+
const maskedContext = maskSensitiveData
|
|
145
|
+
? data_masker_1.DataMasker.maskSensitiveData(context)
|
|
146
|
+
: context;
|
|
147
|
+
return {
|
|
148
|
+
timestamp: new Date().toISOString(),
|
|
149
|
+
level,
|
|
150
|
+
environment: appContext.environment || "unknown",
|
|
151
|
+
application: appContext.application || clientId || "",
|
|
152
|
+
applicationId: appContext.applicationId || "",
|
|
153
|
+
message,
|
|
154
|
+
context: maskedContext,
|
|
155
|
+
correlationId,
|
|
156
|
+
...metadata,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get LogEntry object with token context extracted
|
|
161
|
+
* Extracts userId, sessionId, applicationId from JWT token
|
|
162
|
+
* Generates correlation ID automatically
|
|
163
|
+
*
|
|
164
|
+
* @param token - JWT token to extract user context from
|
|
165
|
+
* @param message - Log message
|
|
166
|
+
* @param level - Optional log level (defaults to 'info')
|
|
167
|
+
* @param context - Optional additional context
|
|
168
|
+
* @param applicationContextService - ApplicationContextService for application/environment extraction
|
|
169
|
+
* @param generateCorrelationId - Function to generate correlation ID
|
|
170
|
+
* @param maskSensitiveData - Whether to mask sensitive data
|
|
171
|
+
* @param clientId - Client ID to use as fallback when application is empty
|
|
172
|
+
* @returns Complete LogEntry object with user context
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const logEntry = getWithToken(token, 'Token validated', 'audit', undefined, applicationContextService, generateCorrelationId, true, config.clientId);
|
|
177
|
+
* await myCustomLogger.save(logEntry);
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
function getWithToken(token, message, level = "info", context, applicationContextService, generateCorrelationId, maskSensitiveData, clientId) {
|
|
181
|
+
const jwtContext = extractJwtContext(token);
|
|
182
|
+
const metadata = extractEnvironmentMetadata();
|
|
183
|
+
const correlationId = generateCorrelationId();
|
|
184
|
+
const appContext = applicationContextService.getApplicationContext();
|
|
185
|
+
// Mask sensitive data in context if enabled
|
|
186
|
+
const maskedContext = maskSensitiveData && context
|
|
187
|
+
? data_masker_1.DataMasker.maskSensitiveData(context)
|
|
188
|
+
: context;
|
|
189
|
+
// Extract applicationId: try user JWT first, then client token
|
|
190
|
+
let applicationId = jwtContext.applicationId || "";
|
|
191
|
+
if (!applicationId && appContext.applicationId) {
|
|
192
|
+
applicationId = appContext.applicationId;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
timestamp: new Date().toISOString(),
|
|
196
|
+
level,
|
|
197
|
+
environment: appContext.environment || "unknown",
|
|
198
|
+
application: appContext.application || clientId || "",
|
|
199
|
+
applicationId,
|
|
200
|
+
message,
|
|
201
|
+
context: maskedContext,
|
|
202
|
+
correlationId,
|
|
203
|
+
userId: jwtContext.userId,
|
|
204
|
+
sessionId: jwtContext.sessionId,
|
|
205
|
+
...metadata,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=logger-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger-context.js","sourceRoot":"","sources":["../../../src/services/logger/logger-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger service for application logging and audit events
|
|
3
|
+
*/
|
|
4
|
+
import { EventEmitter } from "events";
|
|
5
|
+
import { Request } from "express";
|
|
6
|
+
import { HttpClient } from "../../utils/http-client";
|
|
7
|
+
import { ApiClient } from "../../api";
|
|
8
|
+
import { RedisService } from "../redis.service";
|
|
9
|
+
import { LogEntry } from "../../types/config.types";
|
|
10
|
+
import { LoggerChain } from "./logger-chain";
|
|
11
|
+
import { ApplicationContextService } from "../application-context.service";
|
|
12
|
+
export interface ClientLoggingOptions {
|
|
13
|
+
applicationId?: string;
|
|
14
|
+
userId?: string;
|
|
15
|
+
correlationId?: string;
|
|
16
|
+
requestId?: string;
|
|
17
|
+
sessionId?: string;
|
|
18
|
+
token?: string;
|
|
19
|
+
maskSensitiveData?: boolean;
|
|
20
|
+
ipAddress?: string;
|
|
21
|
+
userAgent?: string;
|
|
22
|
+
sourceKey?: string;
|
|
23
|
+
sourceDisplayName?: string;
|
|
24
|
+
externalSystemKey?: string;
|
|
25
|
+
externalSystemDisplayName?: string;
|
|
26
|
+
recordKey?: string;
|
|
27
|
+
recordDisplayName?: string;
|
|
28
|
+
credentialId?: string;
|
|
29
|
+
credentialType?: string;
|
|
30
|
+
requestSize?: number;
|
|
31
|
+
responseSize?: number;
|
|
32
|
+
durationMs?: number;
|
|
33
|
+
errorCategory?: string;
|
|
34
|
+
httpStatusCategory?: string;
|
|
35
|
+
}
|
|
36
|
+
export declare class LoggerService extends EventEmitter {
|
|
37
|
+
private httpClient;
|
|
38
|
+
private apiClient?;
|
|
39
|
+
private redis;
|
|
40
|
+
private config;
|
|
41
|
+
private maskSensitiveData;
|
|
42
|
+
private correlationCounter;
|
|
43
|
+
private auditLogQueue;
|
|
44
|
+
private applicationContextService;
|
|
45
|
+
private httpLoggingFailures;
|
|
46
|
+
private httpLoggingDisabledUntil;
|
|
47
|
+
private static readonly MAX_FAILURES;
|
|
48
|
+
private static readonly DISABLE_DURATION_MS;
|
|
49
|
+
constructor(httpClient: HttpClient, redis: RedisService);
|
|
50
|
+
/**
|
|
51
|
+
* Set ApiClient instance (used to resolve circular dependency)
|
|
52
|
+
* @param apiClient - ApiClient instance
|
|
53
|
+
*/
|
|
54
|
+
setApiClient(apiClient: ApiClient): void;
|
|
55
|
+
/**
|
|
56
|
+
* Get ApplicationContextService instance
|
|
57
|
+
* Used by UnifiedLoggerService to access application context
|
|
58
|
+
* @returns ApplicationContextService instance
|
|
59
|
+
*/
|
|
60
|
+
getApplicationContextService(): ApplicationContextService;
|
|
61
|
+
/**
|
|
62
|
+
* Enable or disable sensitive data masking
|
|
63
|
+
*/
|
|
64
|
+
setMasking(enabled: boolean): void;
|
|
65
|
+
/**
|
|
66
|
+
* Generate unique correlation ID for request tracking
|
|
67
|
+
* Public method to allow other modules to generate consistent correlation IDs
|
|
68
|
+
*
|
|
69
|
+
* @returns Unique correlation ID string
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const correlationId = loggerService.generateCorrelationId();
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
generateCorrelationId(): string;
|
|
77
|
+
/**
|
|
78
|
+
* Log error message with optional stack trace and enhanced options
|
|
79
|
+
*/
|
|
80
|
+
error(message: string, context?: Record<string, unknown>, stackTrace?: string, options?: ClientLoggingOptions): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Log audit event with enhanced options
|
|
83
|
+
*/
|
|
84
|
+
audit(action: string, resource: string, context?: Record<string, unknown>, options?: ClientLoggingOptions): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Log info message with enhanced options
|
|
87
|
+
*/
|
|
88
|
+
info(message: string, context?: Record<string, unknown>, options?: ClientLoggingOptions): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Log debug message with enhanced options
|
|
91
|
+
*/
|
|
92
|
+
debug(message: string, context?: Record<string, unknown>, options?: ClientLoggingOptions): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Internal log method with enhanced features
|
|
95
|
+
*/
|
|
96
|
+
private log;
|
|
97
|
+
/**
|
|
98
|
+
* Method chaining support for complex logging scenarios
|
|
99
|
+
*/
|
|
100
|
+
withContext(context: Record<string, unknown>): LoggerChain;
|
|
101
|
+
withToken(token: string): LoggerChain;
|
|
102
|
+
withoutMasking(): LoggerChain;
|
|
103
|
+
/**
|
|
104
|
+
* Get LogEntry object with request context extracted
|
|
105
|
+
* Extracts IP, method, path, userAgent, correlationId, userId from Express Request
|
|
106
|
+
* Returns structured LogEntry object ready for external logger tables
|
|
107
|
+
*
|
|
108
|
+
* @param req - Express Request object
|
|
109
|
+
* @param message - Log message
|
|
110
|
+
* @param level - Optional log level (defaults to 'info')
|
|
111
|
+
* @param context - Optional additional context
|
|
112
|
+
* @returns Complete LogEntry object with all request context extracted
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* const logEntry = client.log.getLogWithRequest(req, 'User action', 'info', { action: 'login' });
|
|
117
|
+
* await myCustomLogger.save(logEntry); // Save to own logger table
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
getLogWithRequest(req: Request, message: string, level?: LogEntry["level"], context?: Record<string, unknown>): LogEntry;
|
|
121
|
+
/**
|
|
122
|
+
* Get LogEntry object with provided context
|
|
123
|
+
* Generates correlation ID automatically and extracts metadata from environment
|
|
124
|
+
*
|
|
125
|
+
* @param context - Context object to include in logs
|
|
126
|
+
* @param message - Log message
|
|
127
|
+
* @param level - Optional log level (defaults to 'info')
|
|
128
|
+
* @returns Complete LogEntry object
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const logEntry = client.log.getWithContext({ operation: 'sync' }, 'Sync started');
|
|
133
|
+
* await myCustomLogger.save(logEntry);
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
getWithContext(context: Record<string, unknown>, message: string, level?: LogEntry["level"]): LogEntry;
|
|
137
|
+
/**
|
|
138
|
+
* Get LogEntry object with token context extracted
|
|
139
|
+
* Extracts userId, sessionId, applicationId from JWT token
|
|
140
|
+
* Generates correlation ID automatically
|
|
141
|
+
*
|
|
142
|
+
* @param token - JWT token to extract user context from
|
|
143
|
+
* @param message - Log message
|
|
144
|
+
* @param level - Optional log level (defaults to 'info')
|
|
145
|
+
* @param context - Optional additional context
|
|
146
|
+
* @returns Complete LogEntry object with user context
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* const logEntry = client.log.getWithToken(token, 'Token validated', 'audit');
|
|
151
|
+
* await myCustomLogger.save(logEntry);
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
getWithToken(token: string, message: string, level?: LogEntry["level"], context?: Record<string, unknown>): LogEntry;
|
|
155
|
+
/**
|
|
156
|
+
* Get LogEntry object with request context extracted (alias for getLogWithRequest)
|
|
157
|
+
* Alias for getLogWithRequest() for consistency with existing forRequest() pattern
|
|
158
|
+
*
|
|
159
|
+
* @param req - Express Request object
|
|
160
|
+
* @param message - Log message
|
|
161
|
+
* @param level - Optional log level (defaults to 'info')
|
|
162
|
+
* @param context - Optional additional context
|
|
163
|
+
* @returns Complete LogEntry object
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* const logEntry = client.log.getForRequest(req, 'User action', 'info', { action: 'login' });
|
|
168
|
+
* await myCustomLogger.save(logEntry);
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
getForRequest(req: Request, message: string, level?: LogEntry["level"], context?: Record<string, unknown>): LogEntry;
|
|
172
|
+
/**
|
|
173
|
+
* Create logger chain with request context pre-populated
|
|
174
|
+
* Auto-extracts: IP, method, path, user-agent, correlation ID, user from JWT
|
|
175
|
+
*
|
|
176
|
+
* @param req - Express Request object
|
|
177
|
+
* @returns LoggerChain with request context pre-populated
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* await miso.log.forRequest(req).info("Processing request");
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
forRequest(req: Request): LoggerChain;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=logger.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.service.d.ts","sourceRoot":"","sources":["../../../src/services/logger/logger.service.ts"],"names":[],"mappings":"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"}
|