Nginx使用logrotate實(shí)現(xiàn)日志輪轉(zhuǎn)與保留策略!
使用 Nginx 作為 Web 服務(wù)器或反向代理時(shí),訪問日志(access.log)和錯(cuò)誤日志(error.log)是非常重要的調(diào)試和分析工具。但隨著運(yùn)行時(shí)間的增加,access.log 文件會變得越來越大,不僅占用磁盤空間,也會影響日志的查詢效率。本文將介紹如何通過日志輪轉(zhuǎn)來實(shí)現(xiàn) Nginx 的日志按天切割,并設(shè)置日志的保留時(shí)間,以優(yōu)化日志管理。
一、問題背景
默認(rèn)情況下,Nginx 將所有訪問記錄寫入一個(gè)日志文件中(如 /var/log/nginx/access.log)。隨著時(shí)間推移:
- 文件體積過大:日志文件可能達(dá)到GB甚至TB級別,打開和查詢效率極低
- 磁盤空間占用:未經(jīng)壓縮的日志文件會快速消耗磁盤空間
- 管理困難:單文件難以進(jìn)行歷史分析、歸檔和自動化處理
- 故障排查低效:在海量日志中定位問題如同大海撈針
為了解決這個(gè)問題,我們需要對日志進(jìn)行定期切割,并保留一定時(shí)間的歷史日志。
二、宿主機(jī)安裝方案:使用logrotate實(shí)現(xiàn)日志輪轉(zhuǎn)
Linux 系統(tǒng)中廣泛使用的日志輪轉(zhuǎn)工具是 logrotate,它支持按天、按大小自動切割日志,并可設(shè)置保留份數(shù)。
步驟1:確認(rèn)是否安裝了 logrotate
大多數(shù) Linux 發(fā)行版默認(rèn)已安裝。你可以執(zhí)行以下命令檢查:
which logrotate
如果未安裝,可以使用包管理器安裝:
# Ubuntu / Debian sudo apt update && sudo apt install logrotate # CentOS / RHEL sudo yum install logrotate
步驟2:創(chuàng)建或修改 logrotate 配置文件
logrotate的配置文件一般位于/etc/logrotate.d下面,我們可以新建一個(gè)nginx的配置文件來管理日志,注意改為自己的nginx日志目錄。
sudo bash -c 'cat > /etc/logrotate.d/nginx << EOF
/var/log/nginx/*.log
{
daily
missingok
rotate 30
compress
delaycompress
notifempty
sharedscripts
postrotate
[ -f /run/nginx.pid ] && kill -USR1 \$(cat /run/nginx.pid)
endscript
}
EOF'參數(shù)說明:
| 參數(shù) | 說明 |
|---|---|
| daily | 每天輪換一次 |
| missingok | 如果日志文件不存在,不報(bào)錯(cuò) |
| rotate 30 | 保留最近 30 天的日志 |
| compress | 壓縮舊日志文件(生成 .gz 文件) |
| delaycompress | 推遲壓縮到下一輪,避免剛輪換就壓縮 |
| notifempty | 如果日志為空,不進(jìn)行輪換 |
| sharedscripts | 所有日志共用 postrotate 腳本 |
| postrotate ... endscript | 切割完成后向Nginx主進(jìn)程發(fā)送USR1信號使其重新打開日志文件 |
步驟3:測試 logrotate 配置
為了避免配置錯(cuò)誤導(dǎo)致服務(wù)異常,測試配置,其中 -d 表示 debug 模式,只輸出日志不會真正執(zhí)行操作:
sudo logrotate -d /etc/logrotate.d/nginx
如果你想強(qiáng)制執(zhí)行一次日志輪換,可以去掉 -d:
sudo logrotate -f /etc/logrotate.d/nginx
三、Docker環(huán)境方案:容器化Nginx日志輪轉(zhuǎn)
如果我們使用了docker安裝的 Nginx,上面這段腳本可能 不會生效,原因如下:
- /run/nginx.pid 這個(gè)文件在容器中可能存在,也可能不存在;
- 即使存在,你在宿主機(jī)上運(yùn)行 kill -USR1 是無效的,因?yàn)槟繕?biāo)進(jìn)程在容器內(nèi)部;
- 所以你不能直接在宿主機(jī)上使用 kill 向容器內(nèi)的進(jìn)程發(fā)送信號。
正確做法(Docker 環(huán)境下)
你可以改用 docker exec 命令向容器內(nèi)發(fā)送信號。
postrotate
docker exec <nginx_container_name> kill -USR1 1
endscript但是上面的腳本可能會執(zhí)行失?。?nbsp;exec: "kill": executable file not found in $PATH,雖然docker exec your_container kill -USR1 1這是標(biāo)準(zhǔn)的向容器發(fā)送信號的方式,但容器內(nèi)可能是一個(gè)極簡鏡像(比如基于 alpine 或 scratch),它不包含 kill 命令。
正確解決方案:改用 sh -c 直接發(fā)送信號
你可以通過在容器內(nèi)運(yùn)行一個(gè) shell 命令來發(fā)送信號,而不是依賴 kill 命令本身。例如:
docker exec your_container sh -c 'kill -USR1 1'
修改后的完整的宿主機(jī)logrotate配置,注意修改日志路徑:
sudo bash -c 'cat > /etc/logrotate.d/nginx << EOF
/opt/nginx/logs/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
sharedscripts
postrotate
docker exec nginx sh -c "kill -USR1 1"
endscript
}
EOF'四、日志輪轉(zhuǎn)效果驗(yàn)證
執(zhí)行完日志輪換后,你可以在日志目錄看到類似下面的文件:
/var/log/nginx/ ├── access.log # 當(dāng)前活動日志 ├── access.log.1 # 昨日日志(未壓縮) ├── access.log.2.gz # 前日日志(已壓縮) ├── error.log ├── error.log.1 └── error.log.2.gz
壓縮效果對比:
- 原始日志:2.4GB
- 壓縮后:720MB(節(jié)省70%空間)
- 30天保留策略可節(jié)省數(shù)十GB磁盤空間
五、高級配置技巧
自定義日志路徑
如果你希望將日志按項(xiàng)目或域名分類存儲,可以在 Nginx 配置中指定不同的日志路徑:
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example.com-access.log;
error_log /var/log/nginx/example.com-error.log;
}
server {
listen 80;
server_name api.example.com;
access_log /var/log/nginx/api-access.log;
error_log /var/log/nginx/api-error.log;
}按日期命名的日志文件
/var/log/nginx/*.log {
daily
dateext # 使用日期后綴
dateformat -%Y%m%d # 日期格式
rotate 90
...
}生成文件名示例:access.log-20240623.gz
日志分析與監(jiān)控集成
postrotate
# 發(fā)送通知到監(jiān)控系統(tǒng)
curl -X POST https://monitor.example.com/logrotate -d 'server=web01'
# 觸發(fā)日志分析任務(wù)
/opt/scripts/log-analysis.sh &
endscript
六、常見問題
日志切割后,Nginx 是否需要重啟?
不需要。只需發(fā)送 USR1 信號給 Nginx 進(jìn)程,使其重新打開日志文件即可。
kill -USR1 $(cat /run/nginx.pid)
報(bào)錯(cuò)unknown user 'www-data'
/etc/logrotate.d/nginx 配置文件使用了一個(gè)系統(tǒng)中 不存在的用戶:www-data,通常是這一行引起的錯(cuò)誤:
create 0640 www-data adm
- create 表示在日志輪換后自動創(chuàng)建新的日志文件。
- www-data 是通常用于 Nginx 進(jìn)程運(yùn)行的用戶,在 Ubuntu/Debian 系統(tǒng)上存在。
解決方法:
將 www-data 替換為你的系統(tǒng)中存在的用戶和組,比如 nginx(常見于 CentOS/RHEL):
create 0640 nginx adm
或者如果你不確定用哪個(gè)用戶,可以先注釋掉這一行,讓系統(tǒng)使用默認(rèn)權(quán)限創(chuàng)建日志文件:
# create 0640 www-data adm
postrotate腳本的作用
postrotate
[ -f /run/nginx.pid ] && kill -USR1 \$(cat /run/nginx.pid)
endscript
postrotate ... endscript:是一個(gè)腳本塊,在 logrotate 完成日志切割之后自動運(yùn)行。通常用于通知服務(wù)重新加載配置或重新打開日志文件。[ -f /run/nginx.pid ]:如果 /run/nginx.pid 文件存在,就繼續(xù)執(zhí)行后面的命令kill -USR1 $(cat /run/nginx.pid):獲取 Nginx 主進(jìn)程的 PID(進(jìn)程號),向 Nginx 發(fā)送一個(gè) USR1 信號
Nginx 收到 USR1 信號后的行為是:重新打開日志文件(包括 access.log 和 error.log)。這樣做的目的是為了讓 Nginx 開始寫入新的日志文件(比如切割后的 access.log),而不是繼續(xù)寫入舊的被重命名的日志文件(如 access.log.1)。
總結(jié)
通過logrotate實(shí)現(xiàn)Nginx日志輪轉(zhuǎn):
宿主機(jī)方案:標(biāo)準(zhǔn)配置+USR1信號通知
Docker方案:docker exec穿透容器執(zhí)行命令
核心價(jià)值:
- 節(jié)省70%磁盤空間
- 保留30天歷史日志便于審計(jì)
- 避免單文件過大導(dǎo)致的性能問題
最佳實(shí)踐:生產(chǎn)環(huán)境建議啟用dateext按日期歸檔,并集成日志分析系統(tǒng)實(shí)時(shí)監(jiān)控異常。
到此這篇關(guān)于Nginx使用logrotate實(shí)現(xiàn)日志輪轉(zhuǎn)與保留策略!的文章就介紹到這了,更多相關(guān)Nginx logrotate日志輪轉(zhuǎn)與保留內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Ubuntu?22.04.1?LTS?編譯安裝?nginx-1.22.1的配置過程
Ubuntu安裝Nginx有兩種方式,一種是通過命令的方式,這種方式安裝的Nginx版本低,之前漏掃掃出來Nginx版本低,需要升級所以現(xiàn)在用編譯的方式安裝版本高點(diǎn)的,本文介紹Ubuntu22.04.1?LTS編譯安裝nginx1.22.1的配置過程,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧2024-01-01
實(shí)例詳解SpringBoot+nginx實(shí)現(xiàn)資源上傳功能
這篇文章主要介紹了SpringBoot+nginx實(shí)現(xiàn)資源上傳功能,由于小編最近在使用nginx放置靜態(tài)資源問題,遇到很多干貨,特此分享到腳本之家平臺,供大家參考,需要的朋友可以參考下2019-10-10

