Skip to content

Commit ce85343

Browse files
fix(application-generic): logging levels (#8111)
1 parent 5eedbc4 commit ce85343

25 files changed

+75
-135
lines changed

.github/workflows/on-pr.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ jobs:
159159
- name: Run Lint, Build, Test
160160
uses: mansagroup/nrwl-nx-action@v3
161161
env:
162-
LOGGING_LEVEL: 'info'
162+
LOG_LEVEL: 'info'
163163
with:
164164
targets: lint,build,test
165165
projects: ${{join(fromJson(needs.get-affected.outputs.test-packages), ',')}}

.idea/runConfigurations/WORKER___TEST.xml

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/api/src/.env.development

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ REDIS_CLUSTER_KEY_PREFIX=
4040
NEW_RELIC_ENABLED=true
4141
NEW_RELIC_APP_NAME="[DEV] - api"
4242
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=true
43-
LOGGING_LEVEL=info
43+
LOG_LEVEL=info
4444

4545
VERCEL_REDIRECT_URI=https://dashboard.novu-staging.co/auth/login
4646
VERCEL_BASE_URL=https://api.vercel.com

apps/api/src/.env.production

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ REDIS_CLUSTER_KEY_PREFIX=
2727

2828
NEW_RELIC_ENABLED=true
2929
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=true
30-
LOGGING_LEVEL=info
30+
LOG_LEVEL=info
3131

3232
VERCEL_REDIRECT_URI=https://dashboard.novu.co/auth/login
3333
VERCEL_BASE_URL=https://api.vercel.com

apps/api/src/.env.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ MAX_NOVU_INTEGRATION_MAIL_REQUESTS=300
7474
INTERCOM_IDENTITY_VERIFICATION_SECRET_KEY=
7575
NOVU_EMAIL_INTEGRATION_API_KEY=test
7676

77-
LOGGING_LEVEL=error
77+
LOG_LEVEL=error
7878

7979
LAUNCH_DARKLY_SDK_KEY=
8080

apps/api/src/.example.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ VERCEL_BASE_URL=https://api.vercel.com
5858
STORE_NOTIFICATION_CONTENT=true
5959

6060
INTERCOM_IDENTITY_VERIFICATION_SECRET_KEY=
61-
LOGGING_LEVEL=info
61+
LOG_LEVEL=info
6262

6363
LAUNCH_DARKLY_SDK_KEY=
6464

apps/inbound-mail/.example.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ REDIS_DB_INDEX="2"
66
REDIS_HOST="localhost"
77
REDIS_PORT="6379"
88

9-
LOGGING_LEVEL=info
9+
LOG_LEVEL=info
1010
## This value should be set to true if it is the first time you are running the with the database
1111
MONGO_AUTO_CREATE_INDEXES=false

apps/inbound-mail/src/.env.development

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ REDIS_CLUSTER_KEY_PREFIX=
2424
NEW_RELIC_ENABLED=true
2525
NEW_RELIC_APP_NAME="[DEV] - INBOUND-MAIL"
2626
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=true
27-
LOGGING_LEVEL=info
27+
LOG_LEVEL=info

apps/inbound-mail/src/.env.production

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ REDIS_CLUSTER_KEY_PREFIX=
2121

2222
NEW_RELIC_ENABLED=true
2323
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=true
24-
LOGGING_LEVEL=info
24+
LOG_LEVEL=info

apps/inbound-mail/src/.env.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ REDIS_CLUSTER_KEEP_ALIVE=
2020
REDIS_CLUSTER_FAMILY=
2121
REDIS_CLUSTER_KEY_PREFIX=
2222

23-
LOGGING_LEVEL=error
23+
LOG_LEVEL=error

apps/webhook/src/.env.development

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ MONGO_URL=mongodb://127.0.0.1:27017/novu-db
55
NEW_RELIC_ENABLED=true
66
NEW_RELIC_APP_NAME="[DEV] - WEBHOOK"
77
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=true
8-
LOGGING_LEVEL=info
8+
LOG_LEVEL=info

apps/webhook/src/.env.production

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ WIDGET_BASE_URL=https://widget.novu.co
66

77
NEW_RELIC_ENABLED=true
88
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=true
9-
LOGGING_LEVEL=info
9+
LOG_LEVEL=info
1010
MONGO_MIN_POOL_SIZE=50

apps/webhook/src/.env.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ MONGO_URL=mongodb://127.0.0.1:27017/novu-test
22
PORT=1341
33
NODE_ENV=test
44

5-
LOGGING_LEVEL=error
5+
LOG_LEVEL=error

apps/webhook/src/.example.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ PORT=3003
33
MONGO_URL=mongodb://127.0.0.1:27017/novu-db
44
MONGO_MAX_POOL_SIZE=500
55

6-
LOGGING_LEVEL=info
6+
LOG_LEVEL=info

apps/worker/src/.env.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ NEW_RELIC_APP_NAME="[TEST] - worker"
6969
# Segment Analytics
7070
# SEGMENT_TOKEN=
7171

72-
LOGGING_LEVEL=error
72+
LOG_LEVEL=error
7373

7474
# Launch Darkly
7575
LAUNCH_DARKLY_SDK_KEY=

apps/ws/src/.env.development

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ WS_CONTEXT_PATH=
1313
NEW_RELIC_ENABLED=true
1414
NEW_RELIC_APP_NAME="[DEV] - ws"
1515
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=true
16-
LOGGING_LEVEL=info
16+
LOG_LEVEL=info
1717

1818
MONGO_AUTO_CREATE_INDEXES=true
1919

apps/ws/src/.env.production

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ WS_CONTEXT_PATH=
1010

1111
NEW_RELIC_ENABLED=true
1212
NEW_RELIC_APPLICATION_LOGGING_FORWARDING_ENABLED=true
13-
LOGGING_LEVEL=info
13+
LOG_LEVEL=info
1414
MONGO_MIN_POOL_SIZE=50
1515

1616
## This value should be set to true if it is the first time you are running the with the database

apps/ws/src/.env.test

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ REDIS_CACHE_SERVICE_PORT=6379
1313
GLOBAL_CONTEXT_PATH=
1414
WS_CONTEXT_PATH=
1515

16-
LOGGING_LEVEL=info
16+
LOG_LEVEL=info
1717
MONGO_AUTO_CREATE_INDEXES=true

apps/ws/src/.example.env

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ GLOBAL_CONTEXT_PATH=
1212
WS_CONTEXT_PATH=
1313

1414
NEW_RELIC_ENABLED=false
15-
LOGGING_LEVEL=info
15+
LOG_LEVEL=info

libs/application-generic/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
"mixpanel": "^0.17.0",
8686
"nanoid": "^3.1.20",
8787
"nestjs-otel": "6.1.1",
88-
"nestjs-pino": "4.1.0",
88+
"nestjs-pino": "4.2.0",
8989
"node-fetch": "^3.2.10",
9090
"pino-http": "^8.3.3",
9191
"pino-pretty": "^9.4.0",

libs/application-generic/src/logging/LogDecorator.ts

+4-10
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@ const DEFAULT_OPTIONS: IOptions = {
1313
};
1414

1515
export const LogDecorator = (options = DEFAULT_OPTIONS) => {
16-
return (
17-
target: any,
18-
propertyName: string,
19-
descriptor: TypedPropertyDescriptor<any>,
20-
): void => {
16+
return (target: any, propertyName: string, descriptor: TypedPropertyDescriptor<any>): void => {
2117
const logger = options?.logger || new Logger(target?.constructor?.name);
2218
const method = descriptor?.value;
2319

@@ -30,21 +26,19 @@ export const LogDecorator = (options = DEFAULT_OPTIONS) => {
3026
...((options?.transform ? options?.transform(args) : args) || {}),
3127
},
3228
},
33-
`"${target?.constructor?.name}.${propertyName}" invoke`,
29+
`"${target?.constructor?.name}.${propertyName}" invoke`
3430
);
3531

3632
const data = await method.apply(this, args);
3733

38-
const executeTime = options?.timestamp
39-
? `${Date.now() - currentTime}`
40-
: '';
34+
const executeTime = options?.timestamp ? `${Date.now() - currentTime}` : '';
4135

4236
logger.debug(
4337
{
4438
executionTimeMs: executeTime,
4539
result: { ...(options?.transform ? options?.transform(data) : data) },
4640
},
47-
`"${target?.constructor?.name}.${propertyName}" result`,
41+
`"${target?.constructor?.name}.${propertyName}" result`
4842
);
4943

5044
return data;

libs/application-generic/src/logging/index.ts

+42-91
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable no-console */
12
import { NestInterceptor, RequestMethod } from '@nestjs/common';
23
import { getLoggerToken, Logger, LoggerErrorInterceptor, LoggerModule, Params, PinoLogger } from 'nestjs-pino';
34
import { storage, Store } from 'nestjs-pino/storage';
@@ -10,135 +11,85 @@ export function getErrorInterceptor(): NestInterceptor {
1011
}
1112
export { Logger, LoggerModule, PinoLogger, storage, Store, getLoggerToken };
1213

13-
const loggingLevelArr = ['error', 'warn', 'info', 'verbose', 'debug'];
14-
1514
const loggingLevelSet = {
16-
error: 50,
17-
warn: 40,
15+
trace: 10,
16+
debug: 20,
1817
info: 30,
19-
verbose: 20,
20-
debug: 10,
18+
warn: 40,
19+
error: 50,
20+
fatal: 60,
21+
none: 70,
2122
};
22-
23-
interface ILoggingVariables {
24-
env: string;
25-
level: string;
26-
27-
hostingPlatform: string;
28-
tenant: string;
29-
}
23+
const loggingLevelArr = Object.keys(loggingLevelSet);
3024

3125
export function getLogLevel() {
32-
let logLevel = process.env.LOGGING_LEVEL ?? 'info';
33-
34-
if (loggingLevelArr.indexOf(logLevel) === -1) {
35-
// eslint-disable-next-line no-console
36-
console.log(`${logLevel}is not a valid log level of ${loggingLevelArr}. Reverting to info.`);
26+
let logLevel = null;
3727

28+
if (process.env.LOGGING_LEVEL || process.env.LOG_LEVEL) {
29+
logLevel = process.env.LOGGING_LEVEL || process.env.LOG_LEVEL;
30+
} else {
31+
console.log(`Environment variable LOG_LEVEL is not set. Falling back to info level.`);
3832
logLevel = 'info';
3933
}
40-
// eslint-disable-next-line no-console
41-
console.log(`Log Level Chosen: ${logLevel}`);
42-
43-
return logLevel;
44-
}
45-
46-
// TODO: should be moved into a config framework
47-
function getLoggingVariables(): ILoggingVariables {
48-
const env = process.env.NODE_ENV ?? 'local';
49-
50-
// eslint-disable-next-line no-console
51-
console.log(`Environment: ${env}`);
52-
53-
const hostingPlatform = process.env.HOSTING_PLATFORM ?? 'Docker';
54-
55-
// eslint-disable-next-line no-console
56-
console.log(`Platform: ${hostingPlatform}`);
5734

58-
const tenant = process.env.TENANT ?? 'OS';
35+
if (!loggingLevelArr.includes(logLevel)) {
36+
console.log(`${logLevel}is not a valid log level of ${loggingLevelArr}. Falling back to info level.`);
5937

60-
// eslint-disable-next-line no-console
61-
console.log(`Tenant: ${tenant}`);
38+
return 'info';
39+
}
6240

63-
return {
64-
env,
65-
level: getLogLevel(),
66-
hostingPlatform,
67-
tenant,
68-
};
41+
return logLevel;
6942
}
7043

7144
export function createNestLoggingModuleOptions(settings: ILoggerSettings): Params {
72-
const values: ILoggingVariables = getLoggingVariables();
73-
74-
let redactFields: string[] = sensitiveFields.map((val) => val);
75-
45+
let redactFields: string[] = sensitiveFields;
7646
redactFields.push('req.headers.authorization');
77-
7847
const baseWildCards = '*.';
7948
const baseArrayWildCards = '*[*].';
8049
for (let i = 1; i <= 6; i += 1) {
8150
redactFields = redactFields.concat(sensitiveFields.map((val) => baseWildCards.repeat(i) + val));
82-
8351
redactFields = redactFields.concat(sensitiveFields.map((val) => baseArrayWildCards.repeat(i) + val));
8452
}
8553

86-
const transport = ['local', 'test', 'debug'].includes(process.env.NODE_ENV) ? { target: 'pino-pretty' } : undefined;
87-
88-
// eslint-disable-next-line no-console
89-
console.log(loggingLevelSet);
90-
91-
// eslint-disable-next-line no-console
92-
console.log(`Selected Log Transport ${!transport ? 'None' : 'pino-pretty'}`, loggingLevelSet);
54+
const configSet = {
55+
transport: ['local', 'test', 'debug'].includes(process.env.NODE_ENV) ? { target: 'pino-pretty' } : undefined,
56+
platform: process.env.HOSTING_PLATFORM ?? 'Docker',
57+
tenant: process.env.TENANT ?? 'OS',
58+
level: getLogLevel(),
59+
levels: loggingLevelSet,
60+
};
61+
console.log('Logging Configuration:', {
62+
level: configSet.level,
63+
environment: process.env.NODE_ENV,
64+
transport: !configSet.transport ? 'None' : 'pino-pretty',
65+
platform: configSet.platform,
66+
tenant: configSet.tenant,
67+
levels: JSON.stringify(configSet.levels),
68+
});
9369

9470
return {
9571
exclude: [{ path: '*/health-check', method: RequestMethod.GET }],
72+
assignResponse: true,
9673
pinoHttp: {
97-
customLevels: loggingLevelSet,
98-
level: values.level,
74+
useOnlyCustomLevels: true,
75+
customLevels: configSet.levels,
76+
level: configSet.level,
9977
redact: {
10078
paths: redactFields,
101-
censor: customRedaction,
10279
},
10380
base: {
10481
pid: process.pid,
10582
serviceName: settings.serviceName,
10683
serviceVersion: settings.version,
107-
platform: values.hostingPlatform,
108-
tenant: values.tenant,
84+
platform: configSet.platform,
85+
tenant: configSet.tenant,
10986
},
110-
transport,
111-
autoLogging: !['test', 'local'].includes(process.env.NODE_ENV),
112-
/**
113-
* These custom props are only added to 'request completed' and 'request errored' logs.
114-
* Logs generated during request processing won't have these props by default.
115-
* To include these or any other custom props in mid-request logs,
116-
* use `PinoLogger.assign(<props>)` explicitly before logging.
117-
*/
118-
customProps: (req: any, res: any) => ({
119-
user: {
120-
userId: req?.user?._id || null,
121-
environmentId: req?.user?.environmentId || null,
122-
organizationId: req?.user?.organizationId || null,
123-
},
124-
authScheme: req?.authScheme,
125-
rateLimitPolicy: res?.rateLimitPolicy,
126-
}),
87+
transport: configSet.transport,
88+
autoLogging: !['test'].includes(process.env.NODE_ENV),
12789
},
12890
};
12991
}
13092

131-
const customRedaction = (value: any, path: string[]) => {
132-
/*
133-
* Logger.
134-
* if (obj.email && typeof obj.email === 'string') {
135-
* obj.email = '[REDACTED]';
136-
* }
137-
*
138-
* return JSON.parse(JSON.stringify(obj));
139-
*/
140-
};
141-
14293
interface ILoggerSettings {
14394
serviceName: string;
14495
version: string;

libs/application-generic/src/logging/masking.ts

+2-7
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,7 @@ const passwordFields = [
1717

1818
const phoneFields = ['homePhone', 'workPhone', 'phone'];
1919

20-
const addressFields = [
21-
'addressLine1',
22-
'addressLine2',
23-
'address',
24-
'cardAddress',
25-
];
20+
const addressFields = ['addressLine1', 'addressLine2', 'address', 'cardAddress'];
2621

2722
const httpFields = ['webhookUrl', 'avatar', 'avatar_url'];
2823

@@ -34,5 +29,5 @@ export const sensitiveFields = cardFields.concat(
3429
phoneFields,
3530
addressFields,
3631
uuidFields,
37-
httpFields,
32+
httpFields
3833
);

0 commit comments

Comments
 (0)