stream.write is not a function when using morgan with logger
基本上,我正在尝试使用morgan和winston实现nodejs的记录器。
当我尝试使用morgan时,抛出stream.write错误不是函数。
因为我要获取文件名,所以我正在传递模块,因此从模块对象开始有一个名为filename的属性。
下面是我的代码。
// Winston.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | const appRoot = require('app-root-path'); const { createLogger, format, transports } = require('winston'); const { combine, timestamp, label, printf } = format; const path = require('path'); // Custom Format const customFormat = printf(info => { return `${new Date(info.timestamp)} || [${info.label}] || ${info.level}: ${info.message} ` }) // Return the last folder name in the path and the calling // module's filename. const getLabel = function (moduleDetails) { if (Object.keys(moduleDetails).length > 0) { let parts = moduleDetails.filename.split(path.sep) return parts.pop(); }else{ return; } } // define the custom settings for each transport (file, console) var options = (moduleDetails) => ({ file: { level:"info", timestamp: new Date(), filename: `${appRoot}/logs/app.log`, handleExceptions: true, json: true, maxsize: 5242880, maxFiles: 5, colorize: false, label: getLabel(moduleDetails) }, console: { level:"debug", handleExceptions: true, json: false, colorize: true, } }) //instantiate a new Winston Logger with the settings defined above let logger = function (moduleDetails) { return createLogger({ format: combine( label({label:getLabel(moduleDetails)}), timestamp(), customFormat ), transports: [ new transports.File(options(moduleDetails).file) ], exitOnError: false // do not exit on handled exceptions }) } // create a stream object with 'write' function that will be used by 'morgan' // logger({})["stream"] = { // write: function (message, encoding) { // // use the 'info' log level so the output will be picked up by both transports // // (file and console) // logger().info(message) // } // } // If we're not in production then log to the `console` with the format: // `${info.timestamp} || [${info.label}] || ${info.level}: ${info.message}` // like in the log file if (process.env.NODE_ENV !== 'prod') { logger({}).add(new transports.Console(options({}).console)); } module.exports = logger module.exports.stream = { write: function (message, encoding) { // use the 'info' log level so the output will be picked up by both transports // (file and console) logger().info(message) } } |
// App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var morgan = require('morgan'); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); var winston = require('./config/winston')(module); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); app.use(morgan('combined', {"stream": winston.stream})); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); app.use('/users', usersRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // add this line to include winston logging winston.error(`${err.status || 500} || ${err.message} || ${req.originalUrl} || ${req.method} || ${req.ip}` ) // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app; |
在App.js上,尝试更改
1 | app.use(morgan('combined', {"stream": winston.stream})); |
至
1 | app.use(morgan('combined', {"stream": winston.stream.write})); |
即使我不知道为什么,这似乎仍然有效。
我认为您没有正确导出模块,应该是:
1 2 | var winston = require('./config/winston'); winston.logger(module); |
代替:
1 | var winston = require('./config/winston')(module); |