sasai-common-utils 1.0.3 → 1.0.5
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/.env +4 -0
- package/package.json +1 -1
- package/src/config/index.js +109 -0
- package/src/features/logger/constants.js +33 -4
- package/src/features/logger/index.js +96 -5
- package/src/features/logger/utils.js +12 -1
- package/src/index.js +26 -98
- package/src/utils/index.js +11 -0
package/.env
ADDED
package/package.json
CHANGED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require("dotenv").config();
|
|
2
|
+
|
|
3
|
+
const authConfig = {
|
|
4
|
+
/**
|
|
5
|
+
* Postgresql Url
|
|
6
|
+
*/
|
|
7
|
+
serviceName: process.env.SERVICE_NAME,
|
|
8
|
+
nodeEnv: process.env.NODE_ENV,
|
|
9
|
+
basePath: process.env.ENV_BASE_PATH,
|
|
10
|
+
dbHost: process.env.DB_HOST,
|
|
11
|
+
dbUser: process.env.DB_USER,
|
|
12
|
+
dbPassword: Buffer.from(process.env.DB_PASSWORD ?? "", "base64").toString("utf-8"),
|
|
13
|
+
dbName: process.env.DB_NAME,
|
|
14
|
+
dbDialect: process.env.DB_DIALECT,
|
|
15
|
+
dbPort: process.env.DB_PORT,
|
|
16
|
+
dbPool: {
|
|
17
|
+
max: 5,
|
|
18
|
+
min: 0,
|
|
19
|
+
acquire: 30000,
|
|
20
|
+
idle: 10000,
|
|
21
|
+
},
|
|
22
|
+
otpByPass: process.env.OTP_BYPASS,
|
|
23
|
+
cdnBaseUrl: process.env.CDN_BASE_URL,
|
|
24
|
+
/***Microservices URLs**/
|
|
25
|
+
userServiceUrl: process.env.USER_SERVICE_URL,
|
|
26
|
+
otpServiceUrl: process.env.OTP_SERVICE_URL,
|
|
27
|
+
configServiceUrl: process.env.CONFIG_SERVICE_URL,
|
|
28
|
+
catalogServiceUrl: process.env.CATALOG_SERVICE_URL,
|
|
29
|
+
paymentServiceUrl: process.env.PAYMENT_SERVICE_URL,
|
|
30
|
+
integratorServiceUrl: process.env.INTEGRATOR_SERVICE_URL,
|
|
31
|
+
vaultServiceUrl: process.env.VAULT_SERVICE_URL,
|
|
32
|
+
activityServiceUrl: process.env.ACTIVITY_SERVICE_URL,
|
|
33
|
+
linksServiceUrl: process.env.LINKS_SERVICE_URL,
|
|
34
|
+
moneyTransferServiceUrl: process.env.MONEY_TRANSFER_SERVICE_URL,
|
|
35
|
+
notificationServiceUrl: process.env.NOTIFY_SERVICE_URL,
|
|
36
|
+
|
|
37
|
+
/***Social URLs**/
|
|
38
|
+
social: {
|
|
39
|
+
googleUserInfoUrl: process.env.GOOGLE_USER_INFO_URL,
|
|
40
|
+
facebookUserInfoUrl: process.env.FACEBOOK_USER_INFO_URL,
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
/***Azure Config**/
|
|
44
|
+
azure: {
|
|
45
|
+
accountName: process.env.AZURE_ACCOUNT_NAME,
|
|
46
|
+
accountAccessKey: Buffer.from(process.env.AZURE_ACCOUNT_ACCESS_KEY ?? "", "base64").toString("utf-8"),
|
|
47
|
+
profileDocStorage: process.env.AZURE_PROFILE_DOC_STORAGE,
|
|
48
|
+
storageContainerName: process.env.AZURE_STORAGE_CONTAINER_NAME,
|
|
49
|
+
storageUrl: process.env.AZURE_STORAGE_URL,
|
|
50
|
+
sasTokenExpiryTime: process.env.AZURE_SAS_TOKEN_EXPIRY_TIME,
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
redis: {
|
|
54
|
+
url: process.env.REDIS_DB_URL,
|
|
55
|
+
user: process.env.REDIS_DB_USER,
|
|
56
|
+
password: Buffer.from(process.env.REDIS_DB_PASS ?? "", "base64").toString("utf-8"),
|
|
57
|
+
name: process.env.REDIS_DB_NAME,
|
|
58
|
+
tls: process.env.REDIS_DB_TLS_URI_PREFIX,
|
|
59
|
+
},
|
|
60
|
+
/***MongoDB Config */
|
|
61
|
+
mongodb: {
|
|
62
|
+
url: process.env.MONGODB_URL,
|
|
63
|
+
},
|
|
64
|
+
kafka: {
|
|
65
|
+
clientId: process.env.KAFKA_CLIENT_ID,
|
|
66
|
+
brokers: process.env.KAFKA_BROKERS,
|
|
67
|
+
groupId: process.env.KAFKA_GROUP_ID,
|
|
68
|
+
userEventTopic: process.env.KAFKA_TOPIC_USER_EVENT,
|
|
69
|
+
bffEvetTopic: process.env.KAFKA_TOPIC_BFF_EVENT,
|
|
70
|
+
bffKafkaConcurrency: process.env.KAFKA_CONCURRENCY,
|
|
71
|
+
},
|
|
72
|
+
strapiCms: {
|
|
73
|
+
url: process.env.STRAPI_CMS_URL,
|
|
74
|
+
authKey: Buffer.from(process.env.STRAPI_CMS_AUTH_KEY ?? "", "base64").toString("utf-8"),
|
|
75
|
+
},
|
|
76
|
+
spgPrivateUser: {
|
|
77
|
+
username: process.env.SPG_PRIVATE_USER_USERNAME,
|
|
78
|
+
password: Buffer.from(process.env.SPG_PRIVATE_USER_PASSWORD ?? "", "base64").toString("utf-8"),
|
|
79
|
+
tenantId: process.env.SPG_PRIVATE_USER_TENANT_ID,
|
|
80
|
+
clientId: process.env.SPG_PRIVATE_USER_CLIENT_ID,
|
|
81
|
+
},
|
|
82
|
+
guestUser: {
|
|
83
|
+
username: process.env.GUEST_USERNAME,
|
|
84
|
+
password: Buffer.from(process.env.GUEST_PASSWORD ?? "", "base64").toString("utf-8"),
|
|
85
|
+
tenantId: process.env.GUEST_TENANT_ID,
|
|
86
|
+
clientId: process.env.GUEST_CLIENT_ID,
|
|
87
|
+
},
|
|
88
|
+
jwt: {
|
|
89
|
+
secretKey: Buffer.from(process.env.JWT_SECRET_KEY ?? "", "base64").toString("utf-8"),
|
|
90
|
+
},
|
|
91
|
+
invite: {
|
|
92
|
+
appLink: process.env.APP_LINK,
|
|
93
|
+
},
|
|
94
|
+
userDetails: {
|
|
95
|
+
expenseCategory: process.env.EXPENSE_CATEGORY,
|
|
96
|
+
serviceType: process.env.SERVICE_TYPE,
|
|
97
|
+
},
|
|
98
|
+
apm: {
|
|
99
|
+
serverUrl: process.env.APM_SERVER_URL,
|
|
100
|
+
apmEnabled: process.env.APM_ENABLED,
|
|
101
|
+
},
|
|
102
|
+
debugging: {
|
|
103
|
+
debugMode: process.env.DEBUG_MODE,
|
|
104
|
+
},
|
|
105
|
+
apiLog: process.env.API_REQ_RESP_LOG,
|
|
106
|
+
logLevel: process.env.LOG_LEVEL,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
module.exports = authConfig;
|
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
const LOG_LEVELS = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
ERROR: "error",
|
|
3
|
+
WARN: "warn",
|
|
4
|
+
INFO: "info",
|
|
5
|
+
DEBUG: "debug",
|
|
5
6
|
};
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
const DEBUG_MODES = {
|
|
9
|
+
FILE: "file",
|
|
10
|
+
CONSOLE: "console",
|
|
11
|
+
BOTH: "both",
|
|
12
|
+
DISABLE: "disable",
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const API_LOG_MODE = {
|
|
16
|
+
TRUE_VALUE: "true",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const API_CALL_TYPE = {
|
|
20
|
+
REQUEST:"REQUEST",
|
|
21
|
+
RESPONSE:"RESPONSE"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const HTTP_STATUS_CODES = {
|
|
25
|
+
SUCCESS: 200,
|
|
26
|
+
BAD_REQUEST: 400,
|
|
27
|
+
NOT_FOUND: 404,
|
|
28
|
+
INTERNAL_SERVER_ERROR: 500,
|
|
29
|
+
UNAUTHORIZED: 401,
|
|
30
|
+
FORBIDDEN: 403,
|
|
31
|
+
BAD_GATEWAY: 502,
|
|
32
|
+
SERVICE_UNAVAILABLE: 503,
|
|
33
|
+
GATEWAY_TIMEOUT_ERROR: 504,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
module.exports = { LOG_LEVELS, DEBUG_MODES, API_CALL_TYPE, API_LOG_MODE, HTTP_STATUS_CODES };
|
|
@@ -1,9 +1,100 @@
|
|
|
1
|
-
const
|
|
1
|
+
const winston = require("winston");
|
|
2
|
+
const { LOG_LEVELS, DEBUG_MODES, HTTP_STATUS_CODES } = require("./constants");
|
|
3
|
+
// const utils = require("./utils");
|
|
4
|
+
const envConfig = require("../../config");
|
|
5
|
+
const { ecsStringify } = require("@elastic/ecs-winston-format");
|
|
2
6
|
const { redactInformation } = require("./redact");
|
|
3
|
-
const
|
|
7
|
+
const jwt = require("jsonwebtoken");
|
|
8
|
+
|
|
9
|
+
const logFormat = winston.format.combine(
|
|
10
|
+
winston.format((info) => redactInformation(info))(), // Redact sensitive data
|
|
11
|
+
winston.format.errors({ stack: true }),
|
|
12
|
+
winston.format.json(),
|
|
13
|
+
winston.format.printf((info) => {
|
|
14
|
+
info.time = info.timestamp;
|
|
15
|
+
delete info.timestamp;
|
|
16
|
+
info.LEVEL = info.level.toUpperCase();
|
|
17
|
+
delete info.level;
|
|
18
|
+
// info.trace = utils.apm?.currentTraceIds?.["trace.id"] || "";
|
|
19
|
+
// info.span = utils.apm?.currentTraceIds?.["transaction.id"] || "";
|
|
20
|
+
return JSON.stringify(info, null, 4);
|
|
21
|
+
}),
|
|
22
|
+
ecsStringify()
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
let silentLogs = false;
|
|
26
|
+
let transports = [];
|
|
27
|
+
|
|
28
|
+
if (envConfig?.debugging?.debugMode === DEBUG_MODES.DISABLE) {
|
|
29
|
+
silentLogs = true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (envConfig?.debugging?.debugMode === DEBUG_MODES.FILE) {
|
|
33
|
+
transports.push(new winston.transports.File({ filename: "app.log" }));
|
|
34
|
+
} else if (envConfig?.debugging?.debugMode === DEBUG_MODES.CONSOLE) {
|
|
35
|
+
transports.push(new winston.transports.Console());
|
|
36
|
+
} else {
|
|
37
|
+
transports.push(new winston.transports.File({ filename: "app.log" }));
|
|
38
|
+
transports.push(new winston.transports.Console());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const defaultLogger = winston.createLogger({
|
|
42
|
+
format: logFormat,
|
|
43
|
+
defaultMeta: { app: envConfig?.serviceName },
|
|
44
|
+
transports,
|
|
45
|
+
silent: silentLogs,
|
|
46
|
+
level: envConfig.logLevel,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const logInfo = (message, data = {}) => {
|
|
50
|
+
data.info = message;
|
|
51
|
+
data.path = data?.url || "";
|
|
52
|
+
const tokenData = jwt.decode(data?.headers?.Authorization?.split(" ")[1], { complete: true })?.payload;
|
|
53
|
+
data.tokenDetails = {
|
|
54
|
+
customerId: tokenData?.customerId || "",
|
|
55
|
+
mid: tokenData?.mid || "",
|
|
56
|
+
tenantId: tokenData?.tenantId || "",
|
|
57
|
+
};
|
|
58
|
+
data.queryParams = data?.query || {};
|
|
59
|
+
if (data?.query) delete data?.query;
|
|
60
|
+
data.requestBody = data?.body || {};
|
|
61
|
+
if (data?.body) delete data.body;
|
|
62
|
+
data.response = data?.data || {};
|
|
63
|
+
if (data?.data) delete data?.data;
|
|
64
|
+
defaultLogger.info(data);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const logError = (data = {}, req = {}) => {
|
|
68
|
+
data = { ...data };
|
|
69
|
+
const errorResponse = data?.error?.response;
|
|
70
|
+
let requestId = req?.headers?.requestid || "";
|
|
71
|
+
let userInfo = req?.user || {};
|
|
72
|
+
data.message = {
|
|
73
|
+
step: data?.step,
|
|
74
|
+
error: data?.error?.message,
|
|
75
|
+
stack: data?.error?.stack,
|
|
76
|
+
statusCode: errorResponse?.status || HTTP_STATUS_CODES.BAD_REQUEST,
|
|
77
|
+
path: errorResponse?.config?.url || req?.originalUrl,
|
|
78
|
+
headers: errorResponse?.config?.headers || {},
|
|
79
|
+
requestBody: errorResponse?.config?.body || req?.body,
|
|
80
|
+
method: errorResponse?.config?.method || req?.method,
|
|
81
|
+
response: errorResponse?.data || {},
|
|
82
|
+
};
|
|
83
|
+
if (data?.step) delete data?.step;
|
|
84
|
+
if (data?.error) delete data.error;
|
|
85
|
+
data["level"] = LOG_LEVELS.ERROR;
|
|
86
|
+
defaultLogger.error(data);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const logDebug = (message, data = {}) => {
|
|
90
|
+
data.message = message;
|
|
91
|
+
defaultLogger.debug(data);
|
|
92
|
+
};
|
|
4
93
|
|
|
5
94
|
module.exports = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
95
|
+
logInfo,
|
|
96
|
+
logError,
|
|
97
|
+
logDebug,
|
|
98
|
+
logger: defaultLogger,
|
|
99
|
+
attachAxiosLogger: require("../axios-logger/attachAxiosLogger"), // Export axios logger here
|
|
9
100
|
};
|
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
* Formats a timestamp for logging.
|
|
3
3
|
* @returns {string} The formatted timestamp.
|
|
4
4
|
*/
|
|
5
|
+
const envConfig = require("../../config");
|
|
6
|
+
|
|
5
7
|
const formatTimestamp = () => new Date().toISOString();
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
const apm = require('elastic-apm-node').start({
|
|
10
|
+
serviceName: envConfig.serviceName,
|
|
11
|
+
serverUrl: envConfig?.apm?.serverUrl,
|
|
12
|
+
// Use if APM Server requires a token
|
|
13
|
+
captureBody: 'all',
|
|
14
|
+
secretToken: "",
|
|
15
|
+
active: envConfig?.apm?.apmEnabled === "true" ? true : false,
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
module.exports = { formatTimestamp, apm };
|
package/src/index.js
CHANGED
|
@@ -1,107 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const jwt = require("jsonwebtoken");
|
|
10
|
-
const axios = require("axios"); // Import axios for interceptors
|
|
11
|
-
const { attachAxiosLogger } = require("./axiosLogger"); // Import attachAxiosLogger function
|
|
12
|
-
|
|
13
|
-
const logFormat = winston.format.combine(
|
|
14
|
-
winston.format(info => redactInformation(info))(), // Prevent logging sensitive data
|
|
15
|
-
winston.format.errors({ stack: true }),
|
|
16
|
-
winston.format.json(),
|
|
17
|
-
winston.format.printf(info => {
|
|
18
|
-
info.time = info.timestamp;
|
|
19
|
-
delete info.timestamp;
|
|
20
|
-
info.LEVEL = info.level.toUpperCase();
|
|
21
|
-
delete info.level;
|
|
22
|
-
info.trace = apmTracing?.currentTraceIds?.["trace.id"] ?? "";
|
|
23
|
-
info.span = apmTracing?.currentTraceIds?.["transaction.id"] ?? "";
|
|
24
|
-
return JSON.stringify(info, null, 4);
|
|
25
|
-
}),
|
|
26
|
-
ecsStringify()
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
let silentLogs = false;
|
|
30
|
-
let transports = [];
|
|
31
|
-
|
|
32
|
-
if (envConfig?.debugging?.debugMode === DEBUG_MODES.DISABLE) {
|
|
33
|
-
silentLogs = true;
|
|
34
|
-
}
|
|
1
|
+
// Logger features
|
|
2
|
+
const {
|
|
3
|
+
logInfo,
|
|
4
|
+
logError,
|
|
5
|
+
logDebug,
|
|
6
|
+
logger,
|
|
7
|
+
attachAxiosLogger,
|
|
8
|
+
} = require("./features/logger");
|
|
35
9
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
} else if (envConfig?.debugging?.debugMode === DEBUG_MODES.CONSOLE) {
|
|
39
|
-
transports.push(new winston.transports.Console());
|
|
40
|
-
} else {
|
|
41
|
-
transports.push(new winston.transports.File({ filename: "app.log" }));
|
|
42
|
-
transports.push(new winston.transports.Console());
|
|
43
|
-
}
|
|
10
|
+
// Express logger feature
|
|
11
|
+
const expressLogger = require("./features/express-logger");
|
|
44
12
|
|
|
45
|
-
//
|
|
46
|
-
const
|
|
47
|
-
format: logFormat,
|
|
48
|
-
defaultMeta: { app: envConfig?.serviceName },
|
|
49
|
-
transports,
|
|
50
|
-
silent: silentLogs,
|
|
51
|
-
level: envConfig.logLevel,
|
|
52
|
-
});
|
|
13
|
+
// Axios logger feature
|
|
14
|
+
const axiosLogger = require("./features/axios-logger");
|
|
53
15
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
data.path = data?.url ?? "";
|
|
57
|
-
const tokenData = jwt.decode(data?.headers?.Authorization?.split(" ")[1], { complete: true })?.payload;
|
|
58
|
-
data.tokenDetails = {
|
|
59
|
-
"customerId": tokenData?.customerId ?? "",
|
|
60
|
-
"mid": tokenData?.mid ?? "",
|
|
61
|
-
"tenantId": tokenData?.tenantId ?? ""
|
|
62
|
-
};
|
|
63
|
-
data.queryParams = data?.query ?? {};
|
|
64
|
-
if (data?.query) delete data?.query;
|
|
65
|
-
data.requestBody = data?.body ?? {};
|
|
66
|
-
if (data?.body) delete data.body;
|
|
67
|
-
data.response = data?.data ?? {};
|
|
68
|
-
if (data?.data) delete data?.data;
|
|
69
|
-
defaultLogger.info(data);
|
|
70
|
-
};
|
|
16
|
+
// Utility functions (if needed in the future)
|
|
17
|
+
const utils = require("./utils");
|
|
71
18
|
|
|
72
|
-
const logError = (data = {}, req = {}) => {
|
|
73
|
-
data = { ...data };
|
|
74
|
-
const errorResponse = data?.error?.response;
|
|
75
|
-
let requestId = req?.headers?.requestid ?? "";
|
|
76
|
-
let userInfo = req?.user ?? {};
|
|
77
|
-
data.message = {
|
|
78
|
-
step: data?.step,
|
|
79
|
-
error: data?.error?.message,
|
|
80
|
-
stack: data?.error?.stack,
|
|
81
|
-
statusCode: errorResponse?.status ?? HTTP_STATUS_CODES.BAD_REQUEST,
|
|
82
|
-
path: errorResponse?.config?.url ?? req?.originalUrl,
|
|
83
|
-
headers: errorResponse?.config?.headers ?? {},
|
|
84
|
-
requestBody: errorResponse?.config?.body ?? req?.body,
|
|
85
|
-
method: errorResponse?.config?.method ?? req?.method,
|
|
86
|
-
response: errorResponse?.data ?? {}
|
|
87
|
-
};
|
|
88
|
-
if (data?.step) delete data?.step;
|
|
89
|
-
if (data?.error) delete data.error;
|
|
90
|
-
data["level"] = LOG_LEVELS.ERROR;
|
|
91
|
-
defaultLogger.error(data);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const logDebug = (message, data = {}) => {
|
|
95
|
-
data.message = message;
|
|
96
|
-
defaultLogger.debug(data);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
// Export the logging methods and default logger instance
|
|
100
19
|
module.exports = {
|
|
20
|
+
// Logger-related exports
|
|
101
21
|
logInfo,
|
|
102
22
|
logError,
|
|
103
23
|
logDebug,
|
|
104
|
-
logger
|
|
105
|
-
attachAxiosLogger
|
|
106
|
-
};
|
|
24
|
+
logger,
|
|
25
|
+
attachAxiosLogger,
|
|
107
26
|
|
|
27
|
+
// Express-related logging
|
|
28
|
+
expressLogger,
|
|
29
|
+
|
|
30
|
+
// Axios-related logging
|
|
31
|
+
axiosLogger,
|
|
32
|
+
|
|
33
|
+
// Future utilities
|
|
34
|
+
utils,
|
|
35
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const envConfig = require('./src/config'); // dependency `elastic-apm-node`
|
|
2
|
+
|
|
3
|
+
const apm = require('elastic-apm-node').start({
|
|
4
|
+
serviceName: envConfig.serviceName,
|
|
5
|
+
serverUrl: envConfig?.apm?.serverUrl,
|
|
6
|
+
// Use if APM Server requires a token
|
|
7
|
+
captureBody: 'all',
|
|
8
|
+
secretToken: "",
|
|
9
|
+
active: envConfig?.apm?.apmEnabled === "true" ? true : false,
|
|
10
|
+
})
|
|
11
|
+
module.exports = apm
|