Моя команда и я на несколько дней погружены в глубокие размышления, чтобы найти правильное место для записи журнала уровня отладки во время разработки.
Мы используем winston
и winston-daily-rotate-file
для разделения частей процесса регистрации и nest-winston
, обертку модуля гнезда для winston logger.
Мы решили создать гибкий настраиваемый регистратор в качестве службы, расширив встроенный класс Logger.
@Injectable()
export class LoggerService extends Logger {
constructor(
@Inject('winston')
private readonly logger: winston.Logger,
) { super(); }
info(message: string, context?: string): void {
this.logger.info(message, { context });
super.log(message, context);
}
debug(message: string, context?: string): void {
// To delegate the call to the parent class, no winston used.
super.debug(message, context);
}
error(message: string, trace: string, context?: string): void {
this.logger.error(message, { context });
super.error(message, trace, context);
}
}
Как вы могли заметить из метода debug()
, запоминающее устройство ( Transports ) специально не настроено на уровне отладки. Мы хотим, чтобы они выводились через консоль только в процессе разработки.
Теперь мы можем использовать наш LoggerService из любого места в том же контексте. Например,
@Controller('users')
export class UsersController {
constructor(private readonly logger: LoggerService) {}
}
@Injectable()
export class UsersService {
constructor(private readonly logger: LoggerService) {}
// Inside a method, debug some logic.
this.logger.debug(message, UsersService.name);
}
Подход с первого взгляда выглядит хорошо, но он может стать очень запутанным, если код используется в других местах.
По этой причине мы подумали, что у нас есть место, где можно заниматься процессом отладки в одном общем месте, и предложили идею, позволяющую перехватчикам справляться с работой.
import { LoggerService } from '../../logger/logger.service';
@Injectable()
export class DebuggingInterceptor implements NestInterceptor {
constructor(private readonly logger: LoggerService) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const ctx = `${context.getClass().name} ➜ ${context.getHandler().name}()`;
return next
.handle()
.pipe(
tap((response) => {
if (process.env.NODE_ENV === 'development') {
this.logger.debug(response, ctx);
}
}),
);
}
}
Перед распечаткой журнала отладки проверка среды, находится ли она в разработке или нет, выглядит для меня немного уродливо.
Боюсь, что если подход с использованием перехватчика, описанного выше, может быть совершенно неверным?
Как я могу исправить эту проблему лучше?