之前折腾了一个 PHP 日志系统,终于能让项目的错误信息乖乖地记录到日志里了。但问题又来了:日志是存了,可我怎么知道它什么时候爆炸了?
有些错误轻微到无关紧要,有些错误严重到能把整个系统送走,但如果我要知道这些错误,我得 SSH 进服务器,然后手动去翻日志,效率低得要死。而且,多个服务器运行着同样的代码,有的报错,有的没事,我根本不知道到底哪里出了问题。
于是,为了在 bug 出现的时候第一时间收到消息,而不是等老板过来吼我,我写了一个 Go 小脚本,它专门用来:
- 接收远程日志(让 PHP 直接把 bug 抛过来)
- 存储日志信息(按天存储,避免日志混乱)
- 提供查看和管理接口(可以用浏览器访问日志)
- 支持删除指定行日志(万一哪条日志看着不爽,删!)
这样,我就能一眼看到错误日志,而不是等到 bug 发酵成灾难级事故。
先把已经实现好的仓库地址贴出来:点击前往GitHub
这个 Go 脚本干了些什么?
它其实就是一个简单的 HTTP 服务器,提供了几个 API:
📥 /write
(POST)—— 发送日志
任何项目出错了,可以 POST
一条日志过来,它会存入文件,每条一行,格式是 JSON。
示例:
curl -X POST http://localhost:9999/write -d '{
"time": "2025-03-15 12:00:00",
"level": "ERROR",
"message": "数据库连接失败",
"context": {
"project": "my-app",
"ip": "192.168.1.10",
"method": "GET",
"full_url": "https://example.com/api",
"trace": {
"message": "SQLSTATE[HY000] General error",
"file": "/var/www/html/index.php",
"line": 42,
"trace": [
{
"file": "/var/www/html/index.php",
"line": 42,
},
{
"file": "/var/www/html/index.php",
"line": 42,
}
]
}
}
}'
AI 代码解读
这样日志就会被存进 data/data_2025-03-15.txt
里,每天一个文件。
👀 /read
(GET)—— 查看日志
浏览器访问 http://ip地址:端口/read
,就能看到当天的所有日志。
为了陌生人看到我们愚蠢的错误,加了 BasicAuth 认证,默认账号 admin
,密码 123123
(当然,你该改的)。
示例
访问:http://localhost:9999/read
AI 代码解读
返回内容:
是不是比翻 .log
文件爽多了?
🗑 /delete
(DELETE)—— 删除指定行
有时候日志堆积了太多无关紧要的内容,或者因为问题已经解决了,想删掉某些行,就可以用这个接口。在网页上也可以直接删除。
示例
curl -X DELETE "http://localhost:9999/delete?date=2025-03-15&line=2"
AI 代码解读
这样,2025-03-15 的日志第 2 行就会被删掉。
代码细节
- 按天存储日志,每天一个
data_YYYY-MM-DD.txt
,方便管理。 - 支持并发写入,用了
sync.RWMutex
解决并发冲突。 - 支持清理过期日志,默认只保留 7 天,过期自动清理。
- 加了 HTTP 认证,防止乱看日志。
- 错误日志本身也会记录错误(比如写入失败,自己再打个日志)。
完整代码都在仓库里了,就不贴了,反正逻辑就是接收 JSON -> 写入文件 -> 读文件 -> 提供管理接口,没啥特别复杂的。
最后
终于,这个日志收集的活干完了,项目的日志总算有个统一的归宿。
Go 有的时候还真的挺适合做这种完全独立的小型单功能网页服务,这样以后再有 bug,我不用 SSH 上去翻来翻去,而是直接打开个网页,就能看到错误信息,第一时间处理掉。
不过,光有日志收集还不够,下一步我可能会:
- 加个 邮件通知(但我怕邮箱会爆)
- 或者……就先摆烂吧 🙃
今天就这样,明天的 bug,就留给明天的自己吧。