ai / api /utils /LoggingSystem.js
Marco Beretta
LibreChat upload repo
3b6afc0
raw
history blame
No virus
3.45 kB
const pino = require('pino');
const logger = pino({
level: 'info',
redact: {
paths: [
// List of Paths to redact from the logs (https://getpino.io/#/docs/redaction)
'env.OPENAI_API_KEY',
'env.BINGAI_TOKEN',
'env.CHATGPT_TOKEN',
'env.MEILI_MASTER_KEY',
'env.GOOGLE_CLIENT_SECRET',
'env.JWT_SECRET',
'env.JWT_SECRET_DEV',
'env.JWT_SECRET_PROD',
'newUser.password',
], // See example to filter object class instances
censor: '***', // Redaction character
},
});
// Sanitize outside the logger paths. This is useful for sanitizing variables directly with Regex and patterns.
const redactPatterns = [
// Array of regular expressions for redacting patterns
/api[-_]?key/i,
/password/i,
/token/i,
/secret/i,
/key/i,
/certificate/i,
/client[-_]?id/i,
/authorization[-_]?code/i,
/authorization[-_]?login[-_]?hint/i,
/authorization[-_]?acr[-_]?values/i,
/authorization[-_]?response[-_]?mode/i,
/authorization[-_]?nonce/i,
];
/*
// Example of redacting sensitive data from object class instances
function redactSensitiveData(obj) {
if (obj instanceof User) {
return {
...obj.toObject(),
password: '***', // Redact the password field
};
}
return obj;
}
// Example of redacting sensitive data from object class instances
logger.info({ newUser: redactSensitiveData(newUser) }, 'newUser');
*/
const levels = {
TRACE: 10,
DEBUG: 20,
INFO: 30,
WARN: 40,
ERROR: 50,
FATAL: 60,
};
let level = levels.INFO;
module.exports = {
levels,
setLevel: (l) => (level = l),
log: {
trace: (msg) => {
if (level <= levels.TRACE) {
return;
}
logger.trace(msg);
},
debug: (msg) => {
if (level <= levels.DEBUG) {
return;
}
logger.debug(msg);
},
info: (msg) => {
if (level <= levels.INFO) {
return;
}
logger.info(msg);
},
warn: (msg) => {
if (level <= levels.WARN) {
return;
}
logger.warn(msg);
},
error: (msg) => {
if (level <= levels.ERROR) {
return;
}
logger.error(msg);
},
fatal: (msg) => {
if (level <= levels.FATAL) {
return;
}
logger.fatal(msg);
},
// Custom loggers
parameters: (parameters) => {
if (level <= levels.TRACE) {
return;
}
logger.debug({ parameters }, 'Function Parameters');
},
functionName: (name) => {
if (level <= levels.TRACE) {
return;
}
logger.debug(`EXECUTING: ${name}`);
},
flow: (flow) => {
if (level <= levels.INFO) {
return;
}
logger.debug(`BEGIN FLOW: ${flow}`);
},
variable: ({ name, value }) => {
if (level <= levels.DEBUG) {
return;
}
// Check if the variable name matches any of the redact patterns and redact the value
let sanitizedValue = value;
for (const pattern of redactPatterns) {
if (pattern.test(name)) {
sanitizedValue = '***';
break;
}
}
logger.debug({ variable: { name, value: sanitizedValue } }, `VARIABLE ${name}`);
},
request: () => (req, res, next) => {
if (level < levels.DEBUG) {
return next();
}
logger.debug({ query: req.query, body: req.body }, `Hit URL ${req.url} with following`);
return next();
},
},
};