線上主機每天產生數百 MB 的 IIS Log,為避免 Log 檔吃光磁碟空間,我們多會安排排程執行壓縮及清理作業,每天將前一天的 Log 壓成 ZIP 檔,再依「原始 Log 檔保留 N 天,壓縮 Log 保存 M 天,超過 M 天移至後線儲存空間」的原則刪除或搬移檔案。
今天發現某台機器的 Log 清理排程每天準時兩點執行,但 IIS Log 壓縮檔全是空包彈,大小只有 22 Bytes,裡面空空如也。
![](http://www.darkthread.net/Photos/4533-3cd4-o.gif)
起初以為是 Log 檔過大壓縮失敗,但經驗中用 7Zip 壓過數 GB 的大檔,加上現場實測用相同的 Batch Script 壓縮前一日的 Log 檔並沒有問題。DIR 檢查 IIS Log 所在目錄,看到所有檔案的更新時間是早上八點,頓時開悟。
改測試壓縮今天的 Log (原本的設計是 5/4 02:00 壓縮 5/3 的 Log),成功重現凌晨排程遇到的狀況,今天的 Log 檔 IIS 仍在使用中,會傳回 The process cannot access the file because it is being used by another process 存取錯誤。而遇此錯誤 7Zip 仍會產生不包含任何內容的空白 ZIP 檔,這就是一堆 22 Bytes ZIP 檔的由來。
![](http://www.darkthread.net/Photos/4534-489b-o.gif)
原因是 IIS Log 的日期算法預設以 UTC 時間為準,對映到台北時區 u_ex180503.log 的記錄範圍是台北時間 5/3 08:00 - 5/4 08:00,故 5/4 02:00 u_ex180503.log 仍在使用中,要等到 5/4 08:00 IIS 改寫入 u_ex180504.log 後才能拿來壓縮。
要解決此一問題,做法有二:
- 將排程延到 08:00 後執行,但這違背「維護作業應儘可能排在離峰」原則
- IIS 有個選項「使用本地時間為檔案命名 / Use local time for file naming and rollover」
勾選後 IIS 會改在台北時間午夜 12 點切換檔案,例如: 台北時間 5/4 00:00:00 起改寫入 u_ex180504.log。但須注意 Log 裡記錄的時間仍會採 UTC 時間,故 5/4 00:00:00 寫入記錄的時間會記為 5/3 16:00:00。
評估後,決定改用本地時間切檔解決,收工。