通過實時日誌分析_進行訪問日誌的快速統計
簡介
很多個人站長在搭建網站時使用nginx作為伺服器,為了瞭解網站的訪問情況,一般有兩種手段:
- 使用CNZZ之類的方式,在前端頁面插入js,使用者訪問的時候觸發js,記錄訪問請求。
- 利用流計算、或離線統計分析nginx的access log,從日誌中挖掘有用資訊。
兩種方式各有優缺點:
- CNZZ使用起來比較簡單,各種指標定義清楚。但這種方式只能記錄頁面的訪問請求,像ajax之類的請求是無法記錄的,還有爬蟲資訊也不會記錄。
- 利用流計算、離線計算引擎可以支援個性化需求,但需要搭建一套環境,並且在實時性以及分析靈活性上比較難平衡。
兩種手段相互補充,才能對網站的狀況有更加深入的瞭解。
日誌服務在查詢基礎上新推出來SQL支援實時日誌分析功能,極大的降低了站長們分析access log的門檻,本文將詳細介紹如何使用日誌服務分析access log中的各種指標。
Nginx訪問日誌格式
一個典型的nginx訪問日誌配置:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $http_host '
'$status $request_length $body_bytes_sent "$http_referer" '
'"$http_user_agent " $request_time';
access_log access.log main;
欄位解釋:
- remote_addr : 客戶端地址
- remote_user : 客戶端使用者名稱
- time_local : 伺服器時間
- request : 請求內容,包括方法名,地址,和http協議
- http_host : 使用者請求是使用的http地址
- status : 返回的http 狀態碼
- request_length : 請求大小
- body_bytes_sent : 返回的大小
- http_referer : 來源頁
- http_user_agent : 客戶端名稱
- request_time : 整體請求延時
收集訪問日誌到日誌服務
分析訪問日誌
通常,對access log的訪問需求有,檢視網站的pv,uv,熱點頁面,熱點方法,錯誤請求,客戶端型別,來源頁面等等。下文將逐個介紹各個指標的計算方法。
-
PV統計不僅可以一段時間總的PV,還可以按照小的時間段,檢視每段時間的,比如每5分鐘pv
統計程式碼
*|select from_unixtime( __time__- __time__% 300) as t, count(1) as pv group by __time__- __time__% 300 order by t limit 60
統計結果
-
統計一小時內每5分鐘的UV
統計程式碼:
*|select from_unixtime( __time__- __time__% 300) as t, approx_distinct(remote_addr) as uv group by __time__- __time__% 300 order by t limit 60
-
統計一小時內總的UV
統計程式碼:
*|select approx_distinct(remote_addr)
統計結果:
-
最近一小時訪問最多的10個頁面
*|select url,count(1) as pv group by url order by pv desc limit 10
-
最近一小時各種請求方法的佔比
*| select method, count(1) as pv group by method
-
最近一小時各種http狀態碼的佔比
*| select status, count(1) as pv group by status
-
最近一小時各種瀏覽器的佔比
*| select user_agent, count(1) as pv group by user_agent
-
最近一小時referer來源於不同域名的佔比
*|select url_extract_host(http_referer) ,count(1) group by url_extract_host(http_referer)
-
最近一小時使用者訪問不同域名的佔比
*|select http_host ,count(1) group by http_host
一些高階功能
除了一些訪問指標外,站長常常還需要對一些訪問請求進行診斷,檢視一下處理請求的延時如何,有哪些比較大的延時,哪些頁面的延時比較大。
-
通過每5分鐘的平均延時和最大延時, 對延時的情況有個總體的把握
*|select from_unixtime(__time__ -__time__% 300) as time, avg(request_time) as avg_latency , max(request_time) as max_latency group by __time__ -__time__% 300 limit 60
-
知道了最大延時之後,我們需要知道最大延時對應的請求頁面是哪個,方便進一步優化頁面響應。
*|select from_unixtime(__time__ - __time__% 60) , max_by(url,request_time) group by __time__ - __time__%60
-
從總體把握,我們需要知道網站的所有請求的延時的分佈, 把延時分佈在十個桶裡邊,看每個延時區間的請求個數
*|select numeric_histogram(10,request_time)
-
除了最大的延時,我們還需要知道最大的十個延時,對應的值是多少
*|select max(request_time,10)
-
當我們知道了/0這個頁面的訪問延時最大,為了對/0頁面進行調優,接下來需要統計/0這個頁面的訪問PV,UV,各種method次數,各種status次數,各種瀏覽器次數,平均延時,最大延時
url:"/0"|select count(1) as pv, approx_distinct(remote_addr) as uv, histogram(method) as method_pv,histogram(status) as status_pv, histogram(user_agent) as user_agent_pv, avg(request_time) as avg_latency, max(request_time) as max_latency
-
同時,我們也可以限定只檢視request_time 大於1000的請求的pv,uv,以及各個url的請求次數
request_time > 1000 |select count(1) as pv, approx_distinct(remote_addr) as uv, histogram(url) as url_pv