Skip to content
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

feat(open-telemetry-nest): added log context for nest #8

Merged
merged 1 commit into from
Mar 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { LogLevel } from '@nestjs/common';
import { Logger } from 'winston';
import { GlobalProviders } from '@zonneplan/open-telemetry-node';
import { SeverityNumber } from '@opentelemetry/api-logs';
import { LogAttributes, SeverityNumber } from '@opentelemetry/api-logs';
import { LoggerService } from '../services/logger.service';
import { context } from '@opentelemetry/api';

Expand Down Expand Up @@ -58,12 +58,10 @@ export class NestWinstonLoggerAdapter extends LoggerService {
}

public override log(message: any, ...optionalParams: any[]) {
this.logger.info(message, ...optionalParams);
this.emitLog(SeverityNumber.INFO, message, ...optionalParams);
}

public override error(message: any, ...optionalParams: any[]) {
this.logger.error(message, ...optionalParams);
this.emitLog(SeverityNumber.ERROR, message, ...optionalParams);
}

Expand All @@ -73,7 +71,6 @@ export class NestWinstonLoggerAdapter extends LoggerService {
}

public override debug(message: any, ...optionalParams: any[]) {
this.logger.debug(message, ...optionalParams);
this.emitLog(SeverityNumber.DEBUG, message, ...optionalParams);
}

Expand All @@ -83,7 +80,6 @@ export class NestWinstonLoggerAdapter extends LoggerService {
}

public override fatal(message: any, ...optionalParams: any[]) {
this.logger.log('fatal', message, ...optionalParams);
this.emitLog(SeverityNumber.FATAL, message, ...optionalParams);
}

Expand All @@ -102,16 +98,15 @@ export class NestWinstonLoggerAdapter extends LoggerService {
public override setLogLevels(_: LogLevel[]): any {
// ignored
}

private emitLog(
severityNumber: SeverityNumber,
body: any,
...optionalParams: any[]
): void {
const attributes =
optionalParams[0] && typeof optionalParams[0] === 'object'
? optionalParams[0]
: {};
const { context: contextName, attributes } = this.getContextAndAttributes(
optionalParams
);

let severityText =
this.severityNumberToSeverityTextMap[severityNumber] ??
Expand All @@ -126,6 +121,13 @@ export class NestWinstonLoggerAdapter extends LoggerService {
return;
}

if (contextName) {
this.setContext(contextName);
}

const winstonLogLevel = this.toWinstonLogLevel(nestLogLevel);
this.logger[winstonLogLevel](body, attributes);

if (!GlobalProviders.logProvider) {
console.error('OpenTelemetry log provider not initialized');
return;
Expand All @@ -139,4 +141,44 @@ export class NestWinstonLoggerAdapter extends LoggerService {
context: context.active()
});
}

/**
* Takes the first index to decide what the context or attributes are
* - if the first index is an object, it is assumed to be the attributes
* - if the first index is a string, it is assumed to be the context (see the NestJS implementation)
* @note we currently only support one parameter
* @see https://github.com/nestjs/nest/blob/master/packages/common/services/console-logger.service.ts#L295
* @private
*/
private getContextAndAttributes(params: unknown[]): {
context: string | undefined;
attributes: LogAttributes;
} {
const param = params[0];
if (!param) {
return { context: undefined, attributes: {} };
}

if (typeof param === 'string') {
return { context: param, attributes: {} };
}

if (typeof param === 'object') {
return { context: undefined, attributes: param as LogAttributes };
}

return { context: undefined, attributes: {} };
}

private toWinstonLogLevel(level: LogLevel) {
if (level === 'fatal') {
return 'error';
}

if (level === 'log') {
return 'info';
}

return level;
}
}
Loading