-
Notifications
You must be signed in to change notification settings - Fork 4k
fix(application-generic): logging levels #8111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,4 +20,4 @@ REDIS_CLUSTER_KEEP_ALIVE= | |
REDIS_CLUSTER_FAMILY= | ||
REDIS_CLUSTER_KEY_PREFIX= | ||
|
||
LOGGING_LEVEL=error | ||
LOG_LEVEL=error |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,4 @@ MONGO_URL=mongodb://127.0.0.1:27017/novu-test | |
PORT=1341 | ||
NODE_ENV=test | ||
|
||
LOGGING_LEVEL=error | ||
LOG_LEVEL=error |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,4 @@ PORT=3003 | |
MONGO_URL=mongodb://127.0.0.1:27017/novu-db | ||
MONGO_MAX_POOL_SIZE=500 | ||
|
||
LOGGING_LEVEL=info | ||
LOG_LEVEL=info |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,4 +12,4 @@ GLOBAL_CONTEXT_PATH= | |
WS_CONTEXT_PATH= | ||
|
||
NEW_RELIC_ENABLED=false | ||
LOGGING_LEVEL=info | ||
LOG_LEVEL=info |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
/* eslint-disable no-console */ | ||
import { NestInterceptor, RequestMethod } from '@nestjs/common'; | ||
import { getLoggerToken, Logger, LoggerErrorInterceptor, LoggerModule, Params, PinoLogger } from 'nestjs-pino'; | ||
import { storage, Store } from 'nestjs-pino/storage'; | ||
|
@@ -10,135 +11,85 @@ export function getErrorInterceptor(): NestInterceptor { | |
} | ||
export { Logger, LoggerModule, PinoLogger, storage, Store, getLoggerToken }; | ||
|
||
const loggingLevelArr = ['error', 'warn', 'info', 'verbose', 'debug']; | ||
|
||
const loggingLevelSet = { | ||
error: 50, | ||
warn: 40, | ||
trace: 10, | ||
debug: 20, | ||
info: 30, | ||
verbose: 20, | ||
debug: 10, | ||
warn: 40, | ||
error: 50, | ||
fatal: 60, | ||
none: 70, | ||
Comment on lines
+15
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alignment with the pino logger levels with additional 'none' in case we want to silence the logs. |
||
}; | ||
|
||
interface ILoggingVariables { | ||
env: string; | ||
level: string; | ||
|
||
hostingPlatform: string; | ||
tenant: string; | ||
} | ||
const loggingLevelArr = Object.keys(loggingLevelSet); | ||
|
||
export function getLogLevel() { | ||
let logLevel = process.env.LOGGING_LEVEL ?? 'info'; | ||
|
||
if (loggingLevelArr.indexOf(logLevel) === -1) { | ||
// eslint-disable-next-line no-console | ||
console.log(`${logLevel}is not a valid log level of ${loggingLevelArr}. Reverting to info.`); | ||
let logLevel = null; | ||
|
||
if (process.env.LOGGING_LEVEL || process.env.LOG_LEVEL) { | ||
logLevel = process.env.LOGGING_LEVEL || process.env.LOG_LEVEL; | ||
Comment on lines
+28
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. backward compatibility for the old LOGGING_LEVEL environment variable. |
||
} else { | ||
console.log(`Environment variable LOG_LEVEL is not set. Falling back to info level.`); | ||
logLevel = 'info'; | ||
} | ||
// eslint-disable-next-line no-console | ||
console.log(`Log Level Chosen: ${logLevel}`); | ||
|
||
return logLevel; | ||
} | ||
|
||
// TODO: should be moved into a config framework | ||
function getLoggingVariables(): ILoggingVariables { | ||
const env = process.env.NODE_ENV ?? 'local'; | ||
|
||
// eslint-disable-next-line no-console | ||
console.log(`Environment: ${env}`); | ||
|
||
const hostingPlatform = process.env.HOSTING_PLATFORM ?? 'Docker'; | ||
|
||
// eslint-disable-next-line no-console | ||
console.log(`Platform: ${hostingPlatform}`); | ||
|
||
const tenant = process.env.TENANT ?? 'OS'; | ||
if (!loggingLevelArr.includes(logLevel)) { | ||
console.log(`${logLevel}is not a valid log level of ${loggingLevelArr}. Falling back to info level.`); | ||
|
||
// eslint-disable-next-line no-console | ||
console.log(`Tenant: ${tenant}`); | ||
return 'info'; | ||
} | ||
|
||
return { | ||
env, | ||
level: getLogLevel(), | ||
hostingPlatform, | ||
tenant, | ||
}; | ||
return logLevel; | ||
} | ||
|
||
export function createNestLoggingModuleOptions(settings: ILoggerSettings): Params { | ||
const values: ILoggingVariables = getLoggingVariables(); | ||
|
||
let redactFields: string[] = sensitiveFields.map((val) => val); | ||
|
||
let redactFields: string[] = sensitiveFields; | ||
redactFields.push('req.headers.authorization'); | ||
|
||
const baseWildCards = '*.'; | ||
const baseArrayWildCards = '*[*].'; | ||
for (let i = 1; i <= 6; i += 1) { | ||
redactFields = redactFields.concat(sensitiveFields.map((val) => baseWildCards.repeat(i) + val)); | ||
|
||
redactFields = redactFields.concat(sensitiveFields.map((val) => baseArrayWildCards.repeat(i) + val)); | ||
} | ||
|
||
const transport = ['local', 'test', 'debug'].includes(process.env.NODE_ENV) ? { target: 'pino-pretty' } : undefined; | ||
|
||
// eslint-disable-next-line no-console | ||
console.log(loggingLevelSet); | ||
|
||
// eslint-disable-next-line no-console | ||
console.log(`Selected Log Transport ${!transport ? 'None' : 'pino-pretty'}`, loggingLevelSet); | ||
const configSet = { | ||
transport: ['local', 'test', 'debug'].includes(process.env.NODE_ENV) ? { target: 'pino-pretty' } : undefined, | ||
platform: process.env.HOSTING_PLATFORM ?? 'Docker', | ||
tenant: process.env.TENANT ?? 'OS', | ||
level: getLogLevel(), | ||
levels: loggingLevelSet, | ||
}; | ||
console.log('Logging Configuration:', { | ||
level: configSet.level, | ||
environment: process.env.NODE_ENV, | ||
transport: !configSet.transport ? 'None' : 'pino-pretty', | ||
platform: configSet.platform, | ||
tenant: configSet.tenant, | ||
levels: JSON.stringify(configSet.levels), | ||
}); | ||
|
||
return { | ||
exclude: [{ path: '*/health-check', method: RequestMethod.GET }], | ||
assignResponse: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. customProps is not needed because of this new flag that was introduced in pino 4.2 version.
|
||
pinoHttp: { | ||
customLevels: loggingLevelSet, | ||
level: values.level, | ||
useOnlyCustomLevels: true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in the end i kept the custom levels, this flag is making sure that they are not overridden by the built-in levels in pino |
||
customLevels: configSet.levels, | ||
level: configSet.level, | ||
redact: { | ||
paths: redactFields, | ||
censor: customRedaction, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What this one was doing originally? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nvm, I see it's a blank function |
||
}, | ||
base: { | ||
pid: process.pid, | ||
serviceName: settings.serviceName, | ||
serviceVersion: settings.version, | ||
platform: values.hostingPlatform, | ||
tenant: values.tenant, | ||
platform: configSet.platform, | ||
tenant: configSet.tenant, | ||
}, | ||
transport, | ||
autoLogging: !['test', 'local'].includes(process.env.NODE_ENV), | ||
/** | ||
* These custom props are only added to 'request completed' and 'request errored' logs. | ||
* Logs generated during request processing won't have these props by default. | ||
* To include these or any other custom props in mid-request logs, | ||
* use `PinoLogger.assign(<props>)` explicitly before logging. | ||
*/ | ||
customProps: (req: any, res: any) => ({ | ||
user: { | ||
userId: req?.user?._id || null, | ||
environmentId: req?.user?.environmentId || null, | ||
organizationId: req?.user?.organizationId || null, | ||
}, | ||
authScheme: req?.authScheme, | ||
rateLimitPolicy: res?.rateLimitPolicy, | ||
}), | ||
transport: configSet.transport, | ||
autoLogging: !['test'].includes(process.env.NODE_ENV), | ||
}, | ||
}; | ||
} | ||
|
||
const customRedaction = (value: any, path: string[]) => { | ||
/* | ||
* Logger. | ||
* if (obj.email && typeof obj.email === 'string') { | ||
* obj.email = '[REDACTED]'; | ||
* } | ||
* | ||
* return JSON.parse(JSON.stringify(obj)); | ||
*/ | ||
}; | ||
|
||
interface ILoggerSettings { | ||
serviceName: string; | ||
version: string; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@merrcury do we need to makes some updates on TF deployment aswell?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, We need to make this change just in secret Manager