morgan
http请求日志打印中间件,通过设置不同的日志等级(combined、common、dev、short、tiny),或者传递自定义的日志解析函数,来输出对应的客户端请求日志信息,然后如果再配合这个
fs
模块的话,则可实现将日志以每天的形式写入到文件中,且一天以一个文件的方式来命名,即可做到像javaweb那种日志服务
const http = require('http');
const connect = require('connect');
const bodyParser = require('body-parser');
const morgan = require('morgan');
const app = connect();
app.use(morgan());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(bodyParser.text());
app.use(bodyParser.raw());
app.use((req, res) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.write('你提交的数据是: \n');
console.info(req.body);
res.end(JSON.stringify(req.body));
});
http.createServer(app).listen(3000);
morgan函数的使用
使用给定的格式和选项创建一个新的 morgan logger 中间件函数。格式参数可以是预定义名称的字符串(名称见下文)、格式字符串的字符串或将生成日志条目的函数。格式函数将使用三个参数 tokens、req 和 res 调用,其中 tokens 是具有所有已定义标记的对象,req 是 HTTP 请求,res 是 HTTP 响应。该函数应返回一个字符串,该字符串将作为日志行,或 undefined / null 以跳过日志记录 可以使用预定义的morgan函数,也可以通过传递格式化的字符串的方式来使用morgan函数,也可以使用自定义格式的morgan日志函数,还可以额外接收一optinos对象,通过对象的不同属性,来提供个性化的网络请求日志服务!!
预定义的morgan函数
- combined:标准的Apache日志输出格式
:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
- tiny: 简单格式输出
:method :url :status :res[content-length] - :response-time ms
- common: 标准的Apache常见日志输出格式
:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
- dev: 按响应状态着色的简洁输出,以供开发使用。 :status 标记为成功代码为绿色,服务器错误代码为红色,客户端错误代码为黄色,重定向代码为青色,信息代码为无色
:method :url :status :response-time ms - :res[content-length]
- short: 比默认值更短,还包括响应时间
:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
格式化的morgan函数
morgan(':method :url :status :res[content-length] - :response-time ms')
morgan函数中提供了一系列的预定义变量,用于供用户方便调用:
变量名 | 描述 |
---|---|
:date[format] |
format的值可以是clf(输出如:10/Oct/2000:13:55:36 +0000)、iso(输出如:2000-10-10T13:55:36.000Z)、web(输出如:Tue, 10 Oct 2000 13:55:36 GMT)三者其一,默认是web |
:http-version |
客户端请求的http版本 |
:method |
客户端请求方式 |
:referrer |
客户端请求的Referrer标头 |
:remote-addr |
客户端请求的ip地址 |
:remote-user |
用户作为请求的基本身份验证的一部分进行身份验证 |
:req[header] |
请求的给定标头。如果标题不存在,则该值将在日志中显示为“-” |
:res[header] |
响应的给定标头。如果标题不存在,则该值将在日志中显示为“-” |
:response-time[digits] |
从请求进入 morgan 到写入响应标头之间的时间,以毫秒为单位 |
:status |
响应的状态码 |
:total-time[digits] |
从请求进入 morgan 到响应完成写入连接之间的时间,以毫秒为单位 |
:url |
请求的 URL。如果存在,这将使用 req.originalUrl,否则使用 req.url |
:user-agent |
请求的 User-Agent 标头的内容 |
假如 不满足的预定义变量的供我们来使用的话,我们可以通过morgan.token('预定义变量', function(req, res))
的方式来重写这个自己的预定义变量的格式,比如有如下的示例:
morgan.token('method', (req, res) => {
return `请求方式是(${req.method})`;
});
app.use(morgan());
自定义的morgan函数
morgan(function (tokens, req, res) {
return [
tokens.method(req, res),
tokens.url(req, res),
tokens.status(req, res),
tokens.res(req, res, 'content-length'), '-',
tokens['response-time'](req, res), 'ms'
].join(' ')
})
传递额外options的morgan函数
关于options中的参数描述如下:
- immediate: 根据请求而不是响应写入日志行。这意味着即使服务器崩溃也会记录请求,但无法记录来自响应的数据(如响应代码、内容长度等)
- skip: 确定是否跳过日志记录的函数,默认为 false。这个函数将被称为 skip(req, res),如下所示:
// 只输出异常日志 morgan('combined', { skip: function (req, res) { return res.statusCode < 400 } })
- stream: 用于写入日志行的输出流,默认为 process.stdout,:confused: 是否可以考虑将其怼到一个文件可写入流中呢?