沒(méi)想到,日志還能這么分析!
很多時(shí)候,我們觀察程序是否如期運(yùn)行,或者是否有錯(cuò)誤,最直接的方式就是看運(yùn)行日志,當(dāng)然要想從日志快速查到我們想要的信息,前提是程序打印的日志要精煉、精準(zhǔn)。
但日志涵蓋的信息遠(yuǎn)不止于此,比如對(duì)于 nginx 的 access.log 日志,我們可以根據(jù)日志信息分析用戶行為。
什么用戶行為呢?比如分析出哪個(gè)頁(yè)面訪問(wèn)次數(shù)(PV)最多,訪問(wèn)人數(shù)(UV)最多,以及哪天訪問(wèn)量最多,哪個(gè)請(qǐng)求訪問(wèn)最多等等。
這次,將用一個(gè)大概幾萬(wàn)條記錄的 nginx 日志文件作為案例,一起來(lái)看看如何分析出「用戶信息」。

別急著開(kāi)始
當(dāng)我們要分析日志的時(shí)候,先用 ls -lh 命令查看日志文件的大小,如果日志文件大小非常大,最好不要在線上環(huán)境做。
比如我下面這個(gè)日志就 6.5M,不算大,在線上環(huán)境分析問(wèn)題不大。

如果日志文件數(shù)據(jù)量太大,你直接一個(gè) cat 命令一執(zhí)行,是會(huì)影響線上環(huán)境,加重服務(wù)器的負(fù)載,嚴(yán)重的話,可能導(dǎo)致服務(wù)器無(wú)響應(yīng)。
當(dāng)發(fā)現(xiàn)日志很大的時(shí)候,我們可以使用 scp 命令將文件傳輸?shù)介e置的服務(wù)器再分析,scp 命令使用方式如下圖:

慎用 cat
大家都知道 cat 命令是用來(lái)查看文件內(nèi)容的,但是日志文件數(shù)據(jù)量有多少,它就讀多少,很顯然不適用大文件。
對(duì)于大文件,我們應(yīng)該養(yǎng)成好習(xí)慣,用 less 命令去讀文件里的內(nèi)容,因?yàn)?less 并不會(huì)加載整個(gè)文件,而是按需加載,先是輸出一小頁(yè)的內(nèi)容,當(dāng)你要往下看的時(shí)候,才會(huì)繼續(xù)加載。

可以發(fā)現(xiàn),nginx 的 access.log 日志每一行是一次用戶訪問(wèn)的記錄,從左到右分別包含如下信息:
客戶端的 IP 地址;
訪問(wèn)時(shí)間;
HTTP 請(qǐng)求的方法、路徑、協(xié)議版本、協(xié)議版本、返回的狀態(tài)碼;
User Agent,一般是客戶端使用的操作系統(tǒng)以及版本、瀏覽器及版本等;
不過(guò),有時(shí)候我們想看日志最新部分的內(nèi)容,可以使用 tail 命令,比如當(dāng)你想查看倒數(shù) 5 行的內(nèi)容,你可以使用這樣的命令:

如果你想實(shí)時(shí)看日志打印的內(nèi)容,你可以使用 tail -f 命令,這樣你看日志的時(shí)候,就會(huì)是阻塞狀態(tài),有新日志輸出的時(shí)候,就會(huì)實(shí)時(shí)顯示出來(lái)。
PV ?分析
PV 的全稱叫 Page View,用戶訪問(wèn)一個(gè)頁(yè)面就是一次 PV,比如大多數(shù)博客平臺(tái),點(diǎn)擊一次頁(yè)面,閱讀量就加 1,所以說(shuō) PV 的數(shù)量并不代表真實(shí)的用戶數(shù)量,只是個(gè)點(diǎn)擊量。
對(duì)于 nginx 的 acess.log 日志文件來(lái)說(shuō),分析 PV 還是比較容易的,既然日志里的內(nèi)容是訪問(wèn)記錄,那有多少條日志記錄就有多少 PV。
我們直接使用 wc -l 命令,就可以查看整體的 PV 了,如下圖一共有 49903 條 PV。

PV 分組
nginx 的 acess.log 日志文件有訪問(wèn)時(shí)間的信息,因此我們可以根據(jù)訪問(wèn)時(shí)間進(jìn)行分組,比如按天分組,查看每天的總 PV,這樣可以得到更加直觀的數(shù)據(jù)。
要按時(shí)間分組,首先我們先「訪問(wèn)時(shí)間」過(guò)濾出來(lái),這里可以使用 awk 命令來(lái)處理,awk 是一個(gè)處理文本的利器。
awk 命令默認(rèn)是以「空格」為分隔符,由于訪問(wèn)時(shí)間在日志里的第 4 列,因此可以使用 awk '{print $4}' access.log 命令把訪問(wèn)時(shí)間的信息過(guò)濾出來(lái),結(jié)果如下:

上面的信息還包含了時(shí)分秒,如果只想顯示年月日的信息,可以使用 awk 的 substr 函數(shù),從第 2 個(gè)字符開(kāi)始,截取 11 個(gè)字符。

接著,我們可以使用 sort 對(duì)日期進(jìn)行排序,然后使用 uniq -c 進(jìn)行統(tǒng)計(jì),于是按天分組的 PV 就出來(lái)了。
可以看到,每天的 PV 量大概在 2000-2800:

注意,使用 uniq -c 命令前,先要進(jìn)行 sort 排序,因?yàn)?uniq 去重的原理是比較相鄰的行,然后除去第二行和該行的后續(xù)副本,因此在使用 uniq 命令之前,請(qǐng)使用 sort 命令使所有重復(fù)行相鄰。
UV 分析
UV 的全稱是 Uniq Visitor,它代表訪問(wèn)人數(shù),比如公眾號(hào)的閱讀量就是以 UV 統(tǒng)計(jì)的,不管單個(gè)用戶點(diǎn)擊了多少次,最終只算 1 次閱讀量。
access.log 日志里雖然沒(méi)有用戶的身份信息,但是我們可以用「客戶端 IP 地址」來(lái)近似統(tǒng)計(jì) UV。

該命令的輸出結(jié)果是 2589,也就說(shuō)明 UV 的量為 2589。上圖中,從左到右的命令意思如下:
awk '{print $1}' access.log,取日志的第 1 列內(nèi)容,客戶端的 IP 地址正是第 1 列;sort,對(duì)信息排序;uniq,去除重復(fù)的記錄;wc -l,查看記錄條數(shù);
UV 分組
假設(shè)我們按天來(lái)分組分析每天的 UV 數(shù)量,這種情況就稍微比較復(fù)雜,需要比較多的命令來(lái)實(shí)現(xiàn)。
既然要按天統(tǒng)計(jì) UV,那就得把「日期 + IP地址」過(guò)濾出來(lái),并去重,命令如下:

具體分析如下:
第一次
ack是將第 4 列的日期和第 1 列的客戶端 IP 地址過(guò)濾出來(lái),并用空格拼接起來(lái);然后
sort對(duì)第一次 ack 輸出的內(nèi)容進(jìn)行排序;接著用
uniq去除重復(fù)的記錄,也就說(shuō)日期 +IP 相同的行就只保留一個(gè);
上面只是把 UV 的數(shù)據(jù)列了出來(lái),但是并沒(méi)有統(tǒng)計(jì)出次數(shù)。
如果需要對(duì)當(dāng)天的 UV 統(tǒng)計(jì),在上面的命令再拼接 awk '{uv[$1]++;next}END{for (ip in uv) print ip, uv[ip]}' 命令就可以了,結(jié)果如下圖:

awk 本身是「逐行」進(jìn)行處理的,當(dāng)執(zhí)行完一行后,我們可以用 next 關(guān)鍵字來(lái)告訴 awk 跳轉(zhuǎn)到下一行,把下一行作為輸入。
對(duì)每一行輸入,awk 會(huì)根據(jù)第 1 列的字符串(也就是日期)進(jìn)行累加,這樣相同日期的 ip 地址,就會(huì)累加起來(lái),作為當(dāng)天的 uv 數(shù)量。
之后的 END 關(guān)鍵字代表一個(gè)觸發(fā)器,就是當(dāng)前面的輸入全部完成后,才會(huì)執(zhí)行 END {} 中的語(yǔ)句,END 的語(yǔ)句是通過(guò) foreach 遍歷 uv 中所有的 key,打印出按天分組的 uv 數(shù)量。
終端分析
nginx 的 access.log 日志最末尾關(guān)于 User Agent 的信息,主要是客戶端訪問(wèn)服務(wù)器使用的工具,可能是手機(jī)、瀏覽器等。
因此,我們可以利用這一信息來(lái)分析有哪些終端訪問(wèn)了服務(wù)器。
User Agent 的信息在日志里的第 12 列,因此我們先使用 awk 過(guò)濾出第 12 列的內(nèi)容后,進(jìn)行 sort 排序,再用 uniq -c 去重并統(tǒng)計(jì),最后再使用 sort -rn(r 表示逆向排序, n 表示按數(shù)值排序) 對(duì)統(tǒng)計(jì)的結(jié)果排序,結(jié)果如下圖:

分析 TOP3 的請(qǐng)求
access.log 日志中,第 7 列是客戶端請(qǐng)求的路徑,先使用 awk 過(guò)濾出第 7 列的內(nèi)容后,進(jìn)行 sort 排序,再用 uniq -c 去重并統(tǒng)計(jì),然后再使用 sort -rn 對(duì)統(tǒng)計(jì)的結(jié)果排序,最后使用 head -n 3 分析 TOP3 的請(qǐng)求,結(jié)果如下圖:

