Skip to content

Commit

Permalink
Merge pull request #1288 from FoalTS/log-context
Browse files Browse the repository at this point in the history
Make `addLogContext` accept a record with multiple params
  • Loading branch information
LoicPoullain authored Aug 22, 2024
2 parents e1941d1 + a249f41 commit c2c4c49
Show file tree
Hide file tree
Showing 12 changed files with 33 additions and 23 deletions.
4 changes: 4 additions & 0 deletions docs/blog/version-5.0-release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ Version 5.0 of [Foal](https://foalts.org/) is out!
- The return value of the social services `getUserInfoFromTokens` method is now typed.
## Logging
- The `Logger.addLogContext(key, value)` method now accepts a record as parameter: `Logger.addLogContext(context)`. This makes the function's signature more consistent with other logging methods (`info`, `warn`, etc.) and allows multiple keys/values to be passed at once.
## Removal of deprecated components
- The deprecated hook `@Log` has been removed. Use the `Logger` service in a custom `@Hook` instead.
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/common/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ This mecanism helps filter logs of a specific request or specific user in a logg

If needed, you call also add manually custom parameters to the logger context with this fonction:
```typescript
logger.addLogContext('myKey', 'myValue');
logger.addLogContext({ myKey: 'myValue' });
```

## Transports
Expand Down
10 changes: 6 additions & 4 deletions packages/core/src/core/logging/logger.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ describe('Logger', () => {

const logger = new Logger();
logger.initLogContext(() => {
logger.addLogContext('foo', 'bar');
logger.addLogContext({ foo: 'bar', jane: 'doe'});
logger.log('error', 'Hello world', {});
});
logger.initLogContext(() => {
logger.addLogContext('foo2', 'bar2');
logger.addLogContext({ foo2: 'bar2' });
logger.log('error', 'Hello world 2', {});
});

Expand All @@ -36,21 +36,23 @@ describe('Logger', () => {

strictEqual(loggedMessage.includes('[ERROR]'), true);
strictEqual(loggedMessage.includes('foo: "bar"'), true);
strictEqual(loggedMessage.includes('jane: "doe"'), true);
notStrictEqual(loggedMessage.includes('foo2: "bar2"'), true);

const loggedMessage2 = consoleMock.calls[1].arguments[0];

strictEqual(loggedMessage2.includes('[ERROR]'), true);
strictEqual(loggedMessage2.includes('foo2: "bar2"'), true);
notStrictEqual(loggedMessage2.includes('foo: "bar"'), true);
notStrictEqual(loggedMessage2.includes('jane: "doe"'), true);
});

it('should let given params override the context.', () => {
const consoleMock = mock.method(console, 'log', () => {}).mock;

const logger = new Logger();
logger.initLogContext(() => {
logger.addLogContext('foo', 'bar');
logger.addLogContext({ foo: 'bar' });
logger.log('error', 'Hello world', { foo: 'bar2' });
});

Expand All @@ -68,7 +70,7 @@ describe('Logger', () => {
const consoleMock = mock.method(console, 'log', () => {}).mock;

const logger = new Logger();
logger.addLogContext('foo', 'bar');
logger.addLogContext({ foo: 'bar' });

strictEqual(consoleMock.callCount(), 1);

Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/core/logging/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ export class Logger {
this.asyncLocalStorage.run({}, callback);
}

addLogContext(name: string, value: any): void {
addLogContext(context: Record<string, any>): void {
const store = this.asyncLocalStorage.getStore();
if (!store) {
this.log('warn', 'Impossible to add log context information. The logger context has not been initialized.');
return;
}
store[name] = value;
Object.assign(store, context);
}

log(
Expand Down
7 changes: 3 additions & 4 deletions packages/core/src/express/create-app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ describe('createApp', () => {
@Get('/')
@Hook((ctx, services) => {
const logger = services.get(Logger);
logger.addLogContext('foo', 'bar');
logger.addLogContext({ foo: 'bar' });
})
getA(ctx: Context) {
this.logger.info('Hello world');
Expand Down Expand Up @@ -995,9 +995,8 @@ describe('createApp', () => {

strictEqual(loggerMock.callCount(), 1);

const [key, value] = loggerMock.calls[0].arguments;
const args = loggerMock.calls[0].arguments;

strictEqual(key, 'requestId');
strictEqual(value, requestId);
deepStrictEqual(args, [{ requestId }]);
});
});
2 changes: 1 addition & 1 deletion packages/core/src/express/create-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export async function createApp(
const requestId = req.get('x-request-id') || randomUUID();

req.id = requestId;
logger.addLogContext('requestId', requestId);
logger.addLogContext({ requestId });

next();
});
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/sessions/http/use-sessions.hook.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ describe('UseSessions', () => {

strictEqual(loggerMock.callCount(), 1);

deepStrictEqual(loggerMock.calls[0].arguments, ['userId', null]);
deepStrictEqual(loggerMock.calls[0].arguments, [{ userId: null }]);
});

});
Expand All @@ -632,7 +632,7 @@ describe('UseSessions', () => {

strictEqual(loggerMock.callCount(), 1);

deepStrictEqual(loggerMock.calls[0].arguments, ['userId', userId]);
deepStrictEqual(loggerMock.calls[0].arguments, [{ userId }]);
});

context('given options.user is not defined', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/sessions/http/use-sessions.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export function UseSessions(options: UseSessionOptions = {}): HookDecorator {
/* Set ctx.user */

const logger = services.get(Logger);
logger.addLogContext('userId', session.userId);
logger.addLogContext({ userId: session.userId });

if (session.userId !== null && options.user) {
const userId = checkUserIdType(session.userId, options.userIdType);
Expand Down
2 changes: 1 addition & 1 deletion packages/jwt/src/http/jwt.hook.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
strictEqual(loggerMock.callCount(), 1);
deepStrictEqual(
loggerMock.calls[0].arguments,
['userId', 123],
[{ userId: 123 }],
);
})

Expand Down
2 changes: 1 addition & 1 deletion packages/jwt/src/http/jwt.hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export function JWT(required: boolean, options: JWTOptions, verifyOptions: Verif
const userId = checkAndConvertUserIdType(payload.sub, options.userIdType);

const logger = services.get(Logger);
logger.addLogContext('userId', userId);
logger.addLogContext({ userId });

const user = await options.user(userId as never, services);
if (!user) {
Expand Down
10 changes: 6 additions & 4 deletions packages/socket.io/src/socketio-controller.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ describe('SocketIOController', () => {
@EventName('create user')
@WebsocketHook((ctx, services) => {
const logger = services.get(Logger);
logger.addLogContext('foo', 'bar');
logger.addLogContext({ foo: 'bar' });
})
createUser(ctx: WebsocketContext, payload: any) {
this.logger.info('Hello world');
Expand Down Expand Up @@ -474,12 +474,14 @@ describe('SocketIOController', () => {
const payload = {};
await new Promise(resolve => clientSocket.emit('create user', payload, resolve));

strictEqual(loggerMock.callCount(), 2);
strictEqual(loggerMock.callCount(), 1);

const actualParameters = loggerMock.calls.map(call => call.arguments);
const expectedParameters = [
['socketId', socketId],
['messageId', messageId]
[{
socketId,
messageId,
}]
];

deepStrictEqual(actualParameters, expectedParameters);
Expand Down
7 changes: 5 additions & 2 deletions packages/socket.io/src/socketio-controller.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,11 @@ export abstract class SocketIOController implements ISocketIOController {
socket.on(route.eventName, async (payload, cb) => {
this.logger.initLogContext(async () => {
const messageId = randomUUID();
this.logger.addLogContext('socketId', socket.id);
this.logger.addLogContext('messageId', messageId);

this.logger.addLogContext({
socketId: socket.id,
messageId,
});

if (typeof payload === 'function') {
cb = payload;
Expand Down

0 comments on commit c2c4c49

Please sign in to comment.