1. 程式人生 > 實用技巧 >nginx 的訪問日誌切割

nginx 的訪問日誌切割

1. 高階用法–使用 nginx 本身來實現

當 nginx 在容器裡,把 nginx 日誌掛載出來的時候,我們發現就不適合再使用 kill -USR1 的方式去分割日誌
這時候當然就需要從 nginx 本身配置去解決這個問題了,我們都知道訪問日誌裡面都有一個時間相關的欄位,如果我們把這個時間撈出來,這個問題就解決了
我們來看按天生成訪問日誌

  1. if($time_iso8601~"^(\d{4})-(\d{2})-(\d{2})"){
  2. set$year $1;
  3. set$month $2;
  4. set$day $3;
  5. }
  6. access_log/var/log/nginx/${year}_${month}_${day}_access.log json;

檢視日誌生成的結果

看到日誌已經按照我們的需求切割出來了,這個的日誌切割可以達到秒級,用法都是一樣的,去正則匹配到時間戳就好了。nginx 內建的變數有很多,列如 ${server_name} 這些變數都是可以用來命名日誌
當然如果我們需要壓縮,就寫個對應的定時任務去做壓縮就好了,

if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") {
            set $year $1;
            set $month $2;
            set $day $3;
        }
        access_log  logs
/django.${year}_${month}_${day}_access.log main;

2. 使用 shell 指令碼實現

首先來看我的訪問日誌是沒有做任何切割的

接下來,很簡單,shell 指令碼來了

  1. #/bin/bash
  2. # author jiangexing
  3. set-e #指令碼執行,遇到錯就退出,不再往下執行
  4. sleep 1# 配合定時任務,0 點過一秒再開始切割任務
  5. yesterday=$(date -d 'yesterday'+%Y-%m-%d)#取得伺服器當前時間
  6. ng_logs_dir='/var/log/nginx'#nginx 日誌檔案目錄
  7. if[-
    d $ng_logs_dir ];then#判斷日誌目錄是否存在
  8. cd $ng_logs_dir
  9. mv access.log access_${yesterday}.log #通過 mv 命令將日誌移動到分割後的日誌,error 日誌我一般不做切割
  10. kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)#傳送 kill -USR1 訊號給 Nginx 的主程序號,讓 Nginx 重新生成一個新的日誌檔案
  11. sleep 1
  12. tar -czf access_${yesterday}.log.tar.gz access_${yesterday}.log #把舊的日誌打成壓縮包
  13. rm -f access_${yesterday}.log #已有壓縮包,刪除壓縮前的日誌
  14. else
  15. echo "日誌目錄不存在,請檢查"
  16. exit0
  17. fi

S
我們可以先來手動執行一下指令碼看一下效果

這已經達到了我們想要的效果了,點個贊

當然還有最重要的一步,那就是要做好定時任務
  1. 00***/usr/local/nginx/scripts/split.sh

3. 使用 logrotate 來實現

這種切割的方法,一開始我是不知道的,因為我之前的 nginx 都是使用原始碼安裝的,在一次偶然的情況下,使用了 yum 安裝的方式安裝了 nginx,然後發現 nginx 的日誌自動切割和壓縮了,這就讓我要去一探究竟了
後來發現,這個切割功能是由 logrotate 來實現的,接下來我們一起來看看看

3.1 檢視系統是否已經安裝了 logrotate


如上圖紅框框中,如果 base 前面有個@符號,就表示這個軟體已經安裝,當然這個只是眾多檢查方法之一
如果沒有安裝就安裝一下

  1. yum install logrotate -y

安裝完成後,自動在/etc/cron.daily/下生成個 logrotate 可執行的指令碼檔案,此指令碼每天都會執行一次

3.2 配置 logrotate

接下來我們就來配置 nginx 切割的配置檔案,我的 nginx 日誌路徑在/var/log/nginx
我們在 /etc/logrotate.d/ 目錄下新建一個 nginx 的檔案

  1. vim nginx
  2. #########以下為檔案配置內容##############
  3. /var/log/nginx/*log # 這裡也可以寫明對具體哪幾個檔案進行切割
  4. {
  5. su root root
  6. daily
  7. dateext
  8. missingok
  9. rotate 7
  10. notifempty
  11. compress
  12. create 644 www www
  13. sharedscripts
  14. postrotate
  15. [ -f /usr/local/nginx/logs/nginx.pid ] && kill -USR1 `cat /usr/local/nginx/logs/nginx.pid`
  16. endscript
  17. }

我們也可以先手 手動執行一下切割試試看看效果

  1. logrotate -f /etc/logrotate.d/nginx

看一下執行之後的結果是不是我們想要的

沒錯,這就是我們想要的 ,這種方式和第一種還是比較像的。

3.3logrotate 配置項詳解

logrotate 的預設配置檔案是 /etc/logrotate.conf。主要引數:

daily–>指定轉儲週期為每天

weekly–>指定轉儲週期為每週

monthly–>指定轉儲週期為每月

dateext–>在檔案末尾添加當前日期

compress–>通過 gzip 壓縮轉儲以後的日誌

nocompress–>不需要壓縮時,用這個引數

copytruncate–>先把日誌內容複製到舊日誌檔案後才清除日誌檔案內容,可以保證日誌記錄的連續性

nocopytruncate–>備份日誌檔案但是不截斷

create mode owner group–>轉儲檔案,使用指定的檔案模式建立新的日誌檔案

nocreate–>不建立新的日誌檔案

delaycompress 和 compress –>一起使用時,轉儲的日誌檔案到下一次轉儲時才壓縮

nodelaycompress–>覆蓋 delaycompress 選項,轉儲同時壓縮。

errors address–>專儲時的錯誤資訊傳送到指定的 Email 地址

ifempty–>即使是空檔案也轉儲,這個是 logrotate 的預設選項。

notifempty–>如果是空檔案的話,不轉儲

mail address–>把轉儲的日誌檔案傳送到指定的 E-mail 地址

nomail–>轉儲時不傳送日誌檔案

olddir directory–>轉儲後的日誌檔案放入指定的目錄,必須和當前日誌檔案在同一個檔案系統

noolddir–>轉儲後的日誌檔案和當前日誌檔案放在同一個目錄下

rotate count–>指定日誌檔案刪除之前轉儲的次數,0 指沒有備份,5 指保留 5 個備份

tabootext [+] list 讓 logrotate –> 不轉儲指定副檔名的檔案,預設的副檔名是:.rpm-orig, .rpmsave, v, 和 ~

size–> size 當日志文件到達指定的大小時才轉儲,Size 可以指定 bytes (預設)以及 KB (sizek)或者 MB (sizem).

prerotate/endscript –>在轉儲以前需要執行的命令可以放入這個對,這兩個關鍵字必須單獨成行

postrotate/endscript –>在轉儲以後需要執行的命令可以放入這個對,這兩個關鍵字必須單獨成行