Skip to content

Commit e2449d0

Browse files
committed
fix(logger): prevent overwriting service keys
1 parent 7293cc1 commit e2449d0

File tree

3 files changed

+80
-15
lines changed

3 files changed

+80
-15
lines changed

packages/logger/src/Logger.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ class Logger extends Utility implements LoggerInterface {
221221
* @param attributes - The attributes to add to all log items.
222222
*/
223223
public appendKeys(attributes: LogAttributes): void {
224-
this.#appendAnyKeys(attributes, 'temp');
224+
this.#appendKeys(attributes, 'temp');
225225
}
226226

227227
/**
@@ -230,7 +230,7 @@ class Logger extends Utility implements LoggerInterface {
230230
* @param attributes - The attributes to add to all log items.
231231
*/
232232
public appendPersistentKeys(attributes: LogAttributes): void {
233-
this.#appendAnyKeys(attributes, 'persistent');
233+
this.#appendKeys(attributes, 'persistent');
234234
}
235235

236236
/**
@@ -287,13 +287,6 @@ class Logger extends Utility implements LoggerInterface {
287287
* @param extraInput - The extra input to log.
288288
*/
289289
public debug(input: LogItemMessage, ...extraInput: LogItemExtraInput): void {
290-
for (const extra of extraInput) {
291-
if (!(extra instanceof Error) && !(typeof extra === 'string')) {
292-
for (const key of Object.keys(extra)) {
293-
this.#checkReservedKeyAndWarn(key);
294-
}
295-
}
296-
}
297290
this.processLogItem(LogLevelThreshold.DEBUG, input, extraInput);
298291
}
299292

@@ -673,10 +666,10 @@ class Logger extends Utility implements LoggerInterface {
673666
* @param attributes - The attributes to add to the log item.
674667
* @param type - The type of the attributes to add.
675668
*/
676-
#appendAnyKeys(attributes: LogAttributes, type: 'temp' | 'persistent'): void {
669+
#appendKeys(attributes: LogAttributes, type: 'temp' | 'persistent'): void {
677670
for (const attributeKey of Object.keys(attributes)) {
678671
if (this.#checkReservedKeyAndWarn(attributeKey) === false) {
679-
this.#keys.set(attributeKey, 'temp');
672+
this.#keys.set(attributeKey, type);
680673
}
681674
}
682675
if (type === 'temp') {
@@ -732,6 +725,11 @@ class Logger extends Utility implements LoggerInterface {
732725
} else {
733726
const { message: inputMessage, ...rest } = input;
734727
message = inputMessage;
728+
for (const key of Object.keys(rest)) {
729+
if (this.#checkReservedKeyAndWarn(key)) {
730+
delete rest[key];
731+
}
732+
}
735733
otherInput = rest;
736734
}
737735

@@ -758,6 +756,13 @@ class Logger extends Utility implements LoggerInterface {
758756
merge(additionalAttributes, otherInput);
759757
// then we merge the extra input attributes (if any)
760758
for (const item of extraInput) {
759+
if (!(item instanceof Error) && !(typeof item === 'string')) {
760+
for (const key of Object.keys(item)) {
761+
if (this.#checkReservedKeyAndWarn(key)) {
762+
delete item[key];
763+
}
764+
}
765+
}
761766
const attributes: LogAttributes =
762767
item instanceof Error
763768
? { error: item }
@@ -1123,7 +1128,7 @@ class Logger extends Utility implements LoggerInterface {
11231128
private setPowertoolsLogData(
11241129
serviceName?: ConstructorOptions['serviceName'],
11251130
environment?: ConstructorOptions['environment'],
1126-
persistentKeys: ConstructorOptions['persistentKeys'] = {}
1131+
persistentKeys?: ConstructorOptions['persistentKeys']
11271132
): void {
11281133
this.addToPowertoolsLogData({
11291134
awsRegion: this.getEnvVarsService().getAwsRegion(),
@@ -1137,7 +1142,7 @@ class Logger extends Utility implements LoggerInterface {
11371142
this.getEnvVarsService().getServiceName() ||
11381143
this.getDefaultServiceName(),
11391144
});
1140-
this.appendPersistentKeys(persistentKeys);
1145+
persistentKeys && this.appendPersistentKeys(persistentKeys);
11411146
}
11421147
}
11431148

packages/logger/src/formatter/LogItem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class LogItem {
3232
* @param attributes - The attributes to add to the log item.
3333
*/
3434
public addAttributes(attributes: LogAttributes): this {
35-
merge(attributes, this.attributes);
35+
merge(this.attributes, attributes);
3636

3737
return this;
3838
}

packages/logger/tests/unit/repro.test.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ it('does not overwrite via constructor keys', () => {
8888
);
8989
});
9090

91-
it('does not overwrite via extra keys', () => {
91+
it('does not overwrite via extra keys debug', () => {
9292
const debugSpy = vi.spyOn(console, 'debug');
9393
const warnSpy = vi.spyOn(console, 'warn');
9494
const logger = new Logger({
@@ -117,3 +117,63 @@ it('does not overwrite via extra keys', () => {
117117
})
118118
);
119119
});
120+
121+
it('does not overwrite via main', () => {
122+
const debugSpy = vi.spyOn(console, 'debug');
123+
const warnSpy = vi.spyOn(console, 'warn');
124+
const logger = new Logger({
125+
logLevel: 'DEBUG',
126+
});
127+
128+
logger.debug({
129+
level: 'Hello, World!',
130+
timestamp: 'foo',
131+
message: 'bar',
132+
});
133+
134+
const log = JSON.parse(debugSpy.mock.calls[0][0]);
135+
expect(log).toStrictEqual(
136+
expect.objectContaining({
137+
level: 'DEBUG',
138+
timestamp: expect.not.stringMatching('foo'),
139+
message: 'bar',
140+
})
141+
);
142+
expect(warnSpy).toHaveBeenCalledTimes(2);
143+
const warn = JSON.parse(warnSpy.mock.calls[0][0]);
144+
expect(warn).toStrictEqual(
145+
expect.objectContaining({
146+
message: 'The key "level" is a reserved key and will be dropped.',
147+
})
148+
);
149+
});
150+
151+
it('does not overwrite via extra keys info', () => {
152+
const logSpy = vi.spyOn(console, 'info');
153+
const warnSpy = vi.spyOn(console, 'warn');
154+
const logger = new Logger({
155+
logLevel: 'DEBUG',
156+
});
157+
158+
logger.info('stuff', {
159+
level: 'Hello, World!',
160+
timestamp: 'foo',
161+
message: 'bar',
162+
});
163+
164+
const log = JSON.parse(logSpy.mock.calls[0][0]);
165+
expect(log).toStrictEqual(
166+
expect.objectContaining({
167+
level: 'INFO',
168+
timestamp: expect.not.stringMatching('foo'),
169+
message: 'stuff',
170+
})
171+
);
172+
expect(warnSpy).toHaveBeenCalledTimes(3);
173+
const warn = JSON.parse(warnSpy.mock.calls[0][0]);
174+
expect(warn).toStrictEqual(
175+
expect.objectContaining({
176+
message: 'The key "level" is a reserved key and will be dropped.',
177+
})
178+
);
179+
});

0 commit comments

Comments
 (0)