Node.js 实现 HTTP 访问日志

越来越咸,两个月没发文章了,刚刚换项目了,开始学一些新的知识。
近来调试 webhook 和 http callback 比较多,想要使用 Node.js 写一个接收所有 HTTP 请求,并把请求头和请求体写进log,返回 200 OK 的 service。

其实就是简单的 access.log 啦。
其实就是刚学习 Node.js 写的 demo 啦。
啊这是很简单你不要拆穿啦。

这是输出的 log 的样子,优化了可读性,时间、method、path、URL参数(Query)、请求头(Header)、请求体(Body)都详细记录了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
info: 2019-07-25 18:04:36
POST /v1.0/standard
Query:
search: keyword
Header:
cache-control: no-cache
postman-token: f4103067-4b07-447d-9fab-f09a75b6ddda
content-type: application/json
user-agent: PostmanRuntime/3.0.11-hotfix.2
accept: */*
host: localhost:4000
accept-encoding: gzip, deflate
content-length: 209
connection: keep-alive
Body:
appId: XXX
data:
userId: 123
requestId: 456
timestamp: 0

依赖配置:

| 包 | 作用 |
| - | - | - |
| body-parser | 转换form表单、json等格式的请求体 |
| express | 启http服务 |
| moment | 时间格式化 |
| winston | 打log |

package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"name": "httplog",
"version": "1.0.0",
"description": "Log all http request to the service",
"main": "app.js",
"author": "iMaeGoo",
"license": "MIT",
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1",
"moment": "^2.24.0",
"winston": "^3.2.1"
}
}
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
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
const express = require('express')
const bodyParser = require('body-parser')
const winston = require('winston')
const moment = require('moment')
const app = express()
const port = 4000
const logger = winston.createLogger({
level: 'info',
format: winston.format.simple(),
transports: [
new winston.transports.File({ filename: 'http.log' }),
new winston.transports.Console()
]
});

app.use(bodyParser.json({
type: 'application/json'
}))
app.use(bodyParser.urlencoded({
type: 'application/x-www-form-urlencoded'
}))
app.use(bodyParser.text({
type: '*/*'
}))
app.get('*', reqHandler)
app.post('*', reqHandler)
app.put('*', reqHandler)
app.delete('*', reqHandler)
app.listen(port, () => console.log(`listening & logging on port ${port}`))

function reqHandler(req, res) {
logger.info(formatReq(req))
res.send('OK')
}

function formatReq(req) {
let logStr = getStandardDateTime()
logStr += `\n\t${req.method} ${req.path}`
logStr += `\n\tQuery:`
logStr += `${toString(req.query, 2)}`
logStr += `\n\tHeader:`
logStr += `${toString(req.headers, 2)}`
if (req.method !== 'GET') {
logStr += `\n\tBody:`
if (req.body instanceof Object) {
logStr += `${toString(req.body, 2)}`
} else {
logStr += `\n\t\t${req.body}`
}
}
return logStr
}

function getStandardDateTime(date) {
return moment(date).format('YYYY-MM-DD HH:mm:ss')
}

function toString(obj, tabCount = 2) {
let str = ''
let item
for (let key in obj) {
item = obj[key]
str += '\n'
for (let i = 0; i < tabCount; i++) {
str += '\t'
}
str += `${key}:`
if (item instanceof Object) {
str += toString(item, tabCount + 1)
} else {
str += ` ${item}`
}
}
return str
}

之后安装依赖,运行:

1
2
npm install
node app.js

Spring Boot 也可以很简单实现,谁来写一下?

Node.js 实现 HTTP 访问日志

https://www.imaegoo.com/2019/http-log/

作者

iMaeGoo

发布于

2019-07-25

更新于

2019-07-25

许可协议

CC BY 4.0

评论