sasai-common-utils 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +21 -0
- package/src/features/axios-logger/axiosLogger.js +64 -0
- package/src/features/axios-logger/index.js +5 -0
- package/src/features/express-logger/expressLogger.js +45 -0
- package/src/features/express-logger/index.js +5 -0
- package/src/features/logger/config.js +6 -0
- package/src/features/logger/constants.js +7 -0
- package/src/features/logger/index.js +9 -0
- package/src/features/logger/logger.js +25 -0
- package/src/features/logger/redact.js +13 -0
- package/src/features/logger/utils.js +7 -0
- package/src/index.js +15 -0
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sasai-common-utils",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Reusable utility library for common logging and other shared features.",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@elastic/ecs-winston-format": "^1.5.3",
|
|
14
|
+
"jsonwebtoken": "^9.0.2",
|
|
15
|
+
"winston": "^3.17.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"eslint": "^9.15.0",
|
|
19
|
+
"jest": "^29.7.0"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const { LOG_LEVELS } = require("../logger/constants");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Logs Axios requests.
|
|
5
|
+
* @param {Object} request - Axios request object.
|
|
6
|
+
* @param {Object} logger - Logger instance.
|
|
7
|
+
*/
|
|
8
|
+
const logRequest = (request, logger) => {
|
|
9
|
+
const { method, url, headers, data, params } = request;
|
|
10
|
+
const logObject = { method, url, headers, body: data, params };
|
|
11
|
+
logger.log(LOG_LEVELS.INFO, "Axios Request", logObject);
|
|
12
|
+
return request;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Logs Axios responses.
|
|
17
|
+
* @param {Object} response - Axios response object.
|
|
18
|
+
* @param {Object} logger - Logger instance.
|
|
19
|
+
*/
|
|
20
|
+
const logResponse = (response, logger) => {
|
|
21
|
+
const { status, config, data } = response;
|
|
22
|
+
const { method, url, headers, data: requestBody } = config;
|
|
23
|
+
const logObject = { status, method, url, headers, requestBody, responseBody: data };
|
|
24
|
+
logger.log(LOG_LEVELS.INFO, "Axios Response", logObject);
|
|
25
|
+
return response;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Logs Axios errors.
|
|
30
|
+
* @param {Object} error - Axios error object.
|
|
31
|
+
* @param {Object} logger - Logger instance.
|
|
32
|
+
*/
|
|
33
|
+
const logError = (error, logger) => {
|
|
34
|
+
const { response, config } = error;
|
|
35
|
+
const { method, url } = config || {};
|
|
36
|
+
const logObject = {
|
|
37
|
+
method,
|
|
38
|
+
url,
|
|
39
|
+
status: response?.status,
|
|
40
|
+
message: error.message,
|
|
41
|
+
stack: error.stack,
|
|
42
|
+
};
|
|
43
|
+
logger.log(LOG_LEVELS.ERROR, "Axios Error", logObject);
|
|
44
|
+
return Promise.reject(error);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Attaches logging interceptors to an Axios instance.
|
|
49
|
+
* @param {Object} axiosInstance - Axios instance.
|
|
50
|
+
* @param {Object} logger - Logger instance.
|
|
51
|
+
*/
|
|
52
|
+
const attachAxiosLogger = (axiosInstance, logger) => {
|
|
53
|
+
axiosInstance.interceptors.request.use(
|
|
54
|
+
(request) => logRequest(request, logger),
|
|
55
|
+
(error) => logError(error, logger)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
axiosInstance.interceptors.response.use(
|
|
59
|
+
(response) => logResponse(response, logger),
|
|
60
|
+
(error) => logError(error, logger)
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
module.exports = { attachAxiosLogger };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const { LOG_LEVELS } = require("../logger/constants");
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Logs incoming HTTP requests.
|
|
5
|
+
* @param {Object} request - Express request object.
|
|
6
|
+
* @param {Object} logger - Logger instance.
|
|
7
|
+
*/
|
|
8
|
+
const logRequest = (request, logger) => {
|
|
9
|
+
const { method, url, headers, body, query, params } = request;
|
|
10
|
+
const logObject = { method, url, headers, body, query, params };
|
|
11
|
+
logger.log(LOG_LEVELS.INFO, "Incoming Request", logObject);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Logs outgoing HTTP responses.
|
|
16
|
+
* @param {Object} response - Express response object.
|
|
17
|
+
* @param {Object} logger - Logger instance.
|
|
18
|
+
*/
|
|
19
|
+
const logResponse = (response, logger) => {
|
|
20
|
+
const originalJson = response.json;
|
|
21
|
+
|
|
22
|
+
// Override res.json to intercept response data
|
|
23
|
+
response.json = function (data) {
|
|
24
|
+
const { statusCode } = response;
|
|
25
|
+
const { method, url, headers, body } = response.req;
|
|
26
|
+
const logObject = { statusCode, method, url, headers, body, data };
|
|
27
|
+
logger.log(LOG_LEVELS.INFO, "Outgoing Response", logObject);
|
|
28
|
+
|
|
29
|
+
// Call the original res.json
|
|
30
|
+
return originalJson.call(this, data);
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Express middleware for logging requests and responses.
|
|
36
|
+
* @param {Object} logger - Logger instance.
|
|
37
|
+
* @returns {Function} Middleware function.
|
|
38
|
+
*/
|
|
39
|
+
const logExpressApis = (logger) => (request, response, next) => {
|
|
40
|
+
logRequest(request, logger);
|
|
41
|
+
logResponse(response, logger);
|
|
42
|
+
next();
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
module.exports = { logExpressApis };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const winston = require("winston");
|
|
2
|
+
const { redactInformation } = require("./redact");
|
|
3
|
+
const { ecsStringify } = require("@elastic/ecs-winston-format");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Initializes the logger with the given configuration.
|
|
7
|
+
* @param {Object} options - Logger configuration options.
|
|
8
|
+
*/
|
|
9
|
+
const createLogger = (options = {}) => {
|
|
10
|
+
const logFormat = winston.format.combine(
|
|
11
|
+
winston.format(info => redactInformation(info))(),
|
|
12
|
+
winston.format.errors({ stack: true }),
|
|
13
|
+
winston.format.json(),
|
|
14
|
+
ecsStringify()
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
return winston.createLogger({
|
|
18
|
+
level: options?.logLevel || "info",
|
|
19
|
+
format: logFormat,
|
|
20
|
+
defaultMeta: { service: options?.serviceName || "sasai-service" },
|
|
21
|
+
transports: options.transports || [new winston.transports.Console()],
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
module.exports = createLogger;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redacts sensitive information from log entries.
|
|
3
|
+
* @param {Object} info - Log information.
|
|
4
|
+
* @returns {Object} The redacted log entry.
|
|
5
|
+
*/
|
|
6
|
+
const redactInformation = (info) => {
|
|
7
|
+
if (info?.password) {
|
|
8
|
+
info.password = "[REDACTED]";
|
|
9
|
+
}
|
|
10
|
+
return info;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
module.exports = { redactInformation };
|
package/src/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Logger Feature
|
|
2
|
+
const { createLogger, LOG_LEVELS } = require("./features/logger");
|
|
3
|
+
|
|
4
|
+
// Express Logger Feature
|
|
5
|
+
const { logExpressApis } = require("./features/express-logger");
|
|
6
|
+
|
|
7
|
+
// Axios Logger Feature
|
|
8
|
+
const { attachAxiosLogger } = require("./features/axios-logger");
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
createLogger,
|
|
12
|
+
LOG_LEVELS,
|
|
13
|
+
logExpressApis,
|
|
14
|
+
attachAxiosLogger,
|
|
15
|
+
};
|