首页 > 解决方案 > NodeJs 的高级日志记录:TypeError: X is not iterable

问题描述

我创建了这个函数来登录到一个详细级别设置为 info 的文件,每个文件最多 5 个文件和 5 MB,并且在终端中有一个完整的完整日志(详细级别调试),但不同的级别应该使用不同的颜色。

private initialize(): void {

        var winston = require('winston');
        winston.emitErrs = true;

        var logger = new winston.Logger({
            transports: [
                new winston.transports.File({
                    level: 'info',
                    filename: './logs/all-logs.log',
                    handleExceptions: true,
                    json: true,
                    maxsize: 5242880, //5MB
                    maxFiles: 5,
                    colorize: false
                }),
                new winston.transports.Console({
                    level: 'debug',
                    handleExceptions: true,
                    json: false,
                    colorize: true
                })
            ],
            exitOnError: false
        });

        module.exports = logger;
        module.exports.stream = {
            write: function(message : any, encoding : any){
                logger.info(message);
            }
        };

    }

但是启动应用程序时出现此错误。

App encountered an unhandled rejection at
Promise: [object Promise]
Reason:
        this.enableTransports is not iterable
        TypeError: this.enableTransports is not iterable
    at LoggingService.isAtLeastOneTransportLevelActive

此处使用 enableTransports

private createLoggerWithTransports(customLevels: any): void {
        // Create Logger with transports
        const configuration: Configuration = this.configService.configuration;
        this.enableTransports = LoggingService.getEnabledTransports(configuration);
        const opts = {
            levels: customLevels.levels,
            level: LogLevels.TRACE.label,
            transports: LoggingService.createEnabledTransports(this.enableTransports),
            exitOnError: false
        };
        this.logger = winston.createLogger(opts);
    }

 private static createEnabledTransports(enabledTransports: any[]): any[] {
        const transports = enabledTransports
            .map((transportConfig: any) => LoggingService.createTransportFromConfig(transportConfig));
        return transports;
    }

  private static getEnabledTransports(configuration: Configuration): any[] {
        const transports = configuration.logging.transports
            .filter((c: any) => <any>c.enabled === true);
        return transports;
    }


static createTransportFromConfig(transportConfig) {
        switch (transportConfig.transport) {
            case 'Console':
                const consoleLogRecordConverter = this.buildLogRecordConverter(transportConfig);
                const consoleOpts = {
                    level: transportConfig.minLevel,
                    handleExceptions: false,
                    format: format.combine(format.colorize({ level: true, message: false }), format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.printf((info) => `${info.timestamp} ${info.level.toUpperCase()}: ${info.message}`))
                };
                return new winston.transports.Console(consoleOpts);
            case 'File':
                const fileLogRecordConverter = this.buildLogRecordConverter(transportConfig);
                const fileOpts = {
                    level: transportConfig.minLevel,
                    filename: transportConfig.fileName,
                    dirname: transportConfig.dirName,
                    maxfiles: transportConfig.maxFiles,
                    maxsize: transportConfig.maxSize,
                    zippedarchive: transportConfig.zippedArchive,
                    tailable: true,
                    handleexceptions: false,
                    datepattern: 'DD-MM-YYYY',
                    format: format.combine(format.colorize({ level: true, message: false }), format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.printf((info) => fileLogRecordConverter.getLogMessage(info)))
                };
                return new (winston.transports.DailyRotateFile)(fileOpts);
            default: {
                throw new Error(`Logger Transport ${transportConfig.type} not supported !`);
            }
        }
    }

标签: node.jsreactjs

解决方案


在我看来,在您想要迭代的那一刻this.enableTransports,它是一个 Promise 对象,而不是数组或集合。

LoggingService.getEnabledTransports(configuration)执行(或调用另一个执行此操作的函数)异步操作也是如此。

也许LoggingService.createTransportFromConfig(transportConfig))正在做一些事情,比如检查数据库或打开文件来获取配置。

如果是这种情况,那么您可以处理承诺并确保它在重新调整之前完成。

我们能看到里面的代码LoggingService.createTransportFromConfig(transportConfig))吗?

谢谢!


推荐阅读