express-winston 库的学习笔记
express-winston 为 express.js 应用程序的请求和错误记录提供中间件。 它使用“白名单”从请求和(0.2.x 中新增的)响应对象中选择属性。
要使用 express-winston,您需要将以下内容添加到您的应用程序中:
在 package.json 中:
{
"dependencies": {
"...": "...",
"winston": "^3.0.0",
"express-winston": "^4.0.4",
"...": "..."
}}
server.js:
var winston = require('winston'),
expressWinston = require('express-winston');
Request Logging
使用 expressWinston.logger(options) 创建一个中间件来记录您的 HTTP 请求。
var router = require('./my-express-router');
app.use(expressWinston.logger({
transports: [
new winston.transports.Console()
],
format: winston.format.combine(
winston.format.colorize(),
winston.format.json()
),
meta: true, // optional: control whether you want to log the meta data about the request (default to true)
msg: "HTTP {{req.method}} {{req.url}}", // optional: customize the default logging message. E.g. "{{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}"
expressFormat: true, // Use the default Express/morgan request formatting. Enabling this will override any msg if true. Will only output colors with colorize set to true
colorize: false, // Color the text and status code, using the Express/morgan color palette (text: gray, status: default green, 3XX cyan, 4XX yellow, 5XX red).
ignoreRoute: function (req, res) { return false; } // optional: allows to skip some log messages based on request and/or response
}));
app.use(router); // notice how the router goes after the logger.
参数定义:
transports: [], // list of all winston transports instances to use. format: [], // formatting desired for log output. winstonInstance: , // a winston logger instance. If this is provided the transports and formats options are ignored. level: String or function(req, res) { return String; }, // log level to use, the default is "info". Assign a function to dynamically set the level based on request and response, or a string to statically set it always at that level. statusLevels must be false for this setting to be used. msg: String or function, // customize the default logging message. E.g. "{{res.statusCode}} {{req.method}} {{res.responseTime}}ms {{req.url}}", "HTTP {{req.method}} {{req.url}}" or function(req, res) { return
${res.statusCode} - ${req.method}. Warning: while supported, returning mustache style interpolation from an options.msg function has performance and memory implications under load. expressFormat: Boolean, // Use the default Express/morgan request formatting. Enabling this will override any msg if true. Will only output colors when colorize set to true colorize: Boolean, // Color the text and status code, using the Express/morgan color palette (text: gray, status: default green, 3XX cyan, 4XX yellow, 5XX red). meta: Boolean, // control whether you want to log the meta data about the request (default to true). baseMeta: Object, // default meta data to be added to log, this will be merged with the meta data. metaField: String, // if defined, the meta data will be added in this field instead of the meta root object. Defaults to 'meta'. Set tonullto store metadata at the root of the log entry. requestField: [String] // the property of the metadata to store the request under (default 'req'). Set to null to exclude request from metadata statusLevels: Boolean or Object, // different HTTP status codes caused log messages to be logged at different levels (info/warn/error), the default is false. Use an object to control the levels various status codes are logged at. Using an object for statusLevels overrides any setting of options.level. ignoreRoute: function (req, res) { return false; }, // A function to determine if logging is skipped, defaults to returning false. Called before any later middleware. skip: function(req, res) { return false; }, // A function to determine if logging is skipped, defaults to returning false. Called after response has already been sent. requestFilter: function (req, propName) { return req[propName]; }, // A function to filter/return request values, defaults to returning all values allowed by whitelist. If the function returns undefined, the key/value will not be included in the meta. responseFilter: function (res, propName) { return res[propName]; }, // A function to filter/return response values, defaults to returning all values allowed by whitelist. If the function returns undefined, the key/value will not be included in the meta. requestWhitelist: [String], // Array of request properties to log. Overrides global requestWhitelist for this instance responseWhitelist: [String], // Array of response properties to log. Overrides global responseWhitelist for this instance bodyWhitelist: [String], // Array of body properties to log. Overrides global bodyWhitelist for this instance bodyBlacklist: [String], // Array of body properties to omit from logs. Overrides global bodyBlacklist for this instance ignoredRoutes: [String], // Array of paths to ignore/skip logging. Overrides global ignoredRoutes for this instance dynamicMeta: function(req, res) { return [Object]; } // Extract additional meta data from request or response (typically req.user data if using passport). meta must be true for this function to be activated headerBlacklist: [String], // Array of headers to omit from logs. Applied after any previous filters.
一个完整的例子:
var express = require('express');
var expressWinston = require('express-winston');
var winston = require('winston'); // for transports.Console
var app = module.exports = express();
app.use(express.bodyParser());
app.use(express.methodOverride());
// Let's make our express `Router` first.
var router = express.Router();
router.get('/error', function(req, res, next) {
// here we cause an error in the pipeline so we see express-winston in action.
return next(new Error("This is an error and it should be logged to the console"));
});
router.get('/', function(req, res, next) {
res.write('This is a normal request, it should be logged to the console too');
res.end();
});
// express-winston logger makes sense BEFORE the router
app.use(expressWinston.logger({
transports: [
new winston.transports.Console()
],
format: winston.format.combine(
winston.format.colorize(),
winston.format.json()
)
}));
// Now we can tell the app to use our routing code:
app.use(router);
// express-winston errorLogger makes sense AFTER the router.
app.use(expressWinston.errorLogger({
transports: [
new winston.transports.Console()
],
format: winston.format.combine(
winston.format.colorize(),
winston.format.json()
)
}));
// Optionally you can include your custom error handler after the logging.
app.use(express.errorLogger({
dumpExceptions: true,
showStack: true
}));
app.listen(3000, function(){
console.log("express-winston demo listening on port %d in %s mode", this.address().port, app.settings.env);
});
访问 /,能看到如下的日志:
{ "req": { "httpVersion": "1.1", "headers": { "host": "localhost:3000", "connection": "keep-alive", "accept": "/", "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11", "accept-encoding": "gzip,deflate,sdch", "accept-language": "en-US,en;q=0.8,es-419;q=0.6,es;q=0.4", "accept-charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.3", "cookie": "connect.sid=nGspCCSzH1qxwNTWYAoexI23.seE%2B6Whmcwd" }, "url": "/", "method": "GET", "originalUrl": "/", "query": {} }, "res": { "statusCode": 200 }, "responseTime" : 12, "level": "info", "message": "HTTP GET /favicon.ico" }
控制台打印的日志如下:

