之前折騰了一個 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,
}
]
}
}
}'
這樣日誌就會被存進 data/data_2025-03-15.txt 裏,每天一個文件。
👀 /read (GET)—— 查看日誌
瀏覽器訪問 http://ip地址:端口/read,就能看到當天的所有日誌。
為了陌生人看到我們愚蠢的錯誤,加了 BasicAuth 認證,默認賬號 admin,密碼 123123(當然,你該改的)。
示例
訪問:http://localhost:9999/read
返回內容:
是不是比翻 .log 文件爽多了?
🗑 /delete (DELETE)—— 刪除指定行
有時候日誌堆積了太多無關緊要的內容,或者因為問題已經解決了,想刪掉某些行,就可以用這個接口。在網頁上也可以直接刪除。
示例
curl -X DELETE "http://localhost:9999/delete?date=2025-03-15&line=2"
這樣,2025-03-15 的日誌第 2 行就會被刪掉。
代碼細節
- 按天存儲日誌,每天一個
data_YYYY-MM-DD.txt,方便管理。 - 支持併發寫入,用了
sync.RWMutex 解決併發衝突。 - 支持清理過期日誌,默認只保留 7 天,過期自動清理。
- 加了 HTTP 認證,防止亂看日誌。
- 錯誤日誌本身也會記錄錯誤(比如寫入失敗,自己再打個日誌)。
完整代碼都在倉庫裏了,就不貼了,反正邏輯就是接收 JSON -> 寫入文件 -> 讀文件 -> 提供管理接口,沒啥特別複雜的。
最後
終於,這個日誌收集的活幹完了,項目的日誌總算有個統一的歸宿。
Go 有的時候還真的挺適合做這種完全獨立的小型單功能網頁服務,這樣以後再有 bug,我不用 SSH 上去翻來翻去,而是直接打開個網頁,就能看到錯誤信息,第一時間處理掉。
不過,光有日誌收集還不夠,下一步我可能會:
- 加個 郵件通知(但我怕郵箱會爆)
- 或者……就先擺爛吧 🙃
今天就這樣,明天的 bug,就留給明天的自己吧。