最近做項目遇到一個需求,要求自行統計網站的PV、UV、IP,並顯示到後臺。於是我們可以通過nginx的日誌實現。
概念
UV:獨立訪客;以cookie爲依據,假設一臺電腦裝有3個不同的瀏覽器,分別打開同一個頁面,將會產生3個UV。
PV:訪問量;頁面每訪問或刷新一次,將會產生一個PV。
IP:獨立IP地址;以公網IP爲依據,每個獨立IP訪問該頁面,將會產生一個IP。
nginx配置
在vhost的conf文件中配置以下信息,請將此conf文件的權限設爲777,否則無法自動生成日誌文件。
#日誌格式化
log_format tongji '$remote_addr - [$time_iso8601] "$request" '
' - $status "User_Cookie:$guid" ';
server {
listen 80;
server_name xxx.com;
index index.html index.htm index.php;
root /alidata/www/tongji;
#將cookie中key爲guid,value爲字母、數字部分保存爲guid
if ( $http_cookie ~* "guid=([a-zA-Z0-9]*)"){
set $guid $1;
}
if ($time_iso8601 ~ "(\d{4}-\d{2}-\d{2})") {
set $date $1;
}
#訪問日誌引用“tongji”的格式化,並按照日期分割保存。
access_log /alidata/www/nginx_log/access_$date.log tongji;
location ~* ^(.*)$ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 8m;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
js文件
在需要統計uv的頁面引入以下js文件,生成一個當天過期的cookie。
var cookie = {
//當天剩下的毫秒數
leftTime: function() {
var curTamp = new Date().getTime();
//當日凌晨的時間戳,減去一毫秒是爲了防止後續得到的時間不會達到00:00:00的狀態
var curWeeHours = new Date(curDate.toLocaleDateString()).getTime() - 1;
var passedTamp = curTamp - curWeeHours;
var leftTamp = 24 * 60 * 60 * 1000 - passedTamp;
return leftTamp;
},
//n:鍵名,v:鍵值,exp:過期時間(ms)
setCookie: function(n, v, exp) {
var date = new Date()
date.setTime(date.getTime() + exp);
document.cookie = n + "=" + escape(v) +
((exp == null) ? "" : ";expires=" + date.toGMTString())
},
//n爲想要取到的鍵值的鍵名
getCookie: function(n) {
var reg = /\s/g;
var result = document.cookie.replace(reg, "");
var resultArr = result.split(";");
for (var i = 0; i < resultArr.length; i++) {
var nameArr = resultArr[i].split("=");
if (nameArr[0] == n) {
return nameArr[1];
}
}
}
};
//生成隨機id
var guid = function() {
function S4() {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}
return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4());
};
//如果guid不存在,則生成guid
console.log(cookie.leftTime() / 1000 / 60);
!cookie.getCookie('guid') && cookie.setCookie('guid', guid(), cookie.leftTime());
document.write(document.cookie);
日誌文件
內容如下
61.141.xxx.xxx - [2019-05-16T15:18:34+08:00] "GET /ttt.html HTTP/1.1" - 304 "User_Cookie:032284f362a63e3d375f8176aad4e0d7"
61.141.xxx.xxx - [2019-05-16T15:18:35+08:00] "GET /ttt.html HTTP/1.1" - 304 "User_Cookie:032284f362a63e3d375f8176aad4e0d7"
61.141.xxx.xxx - [2019-05-16T15:18:35+08:00] "GET /ttt.html HTTP/1.1" - 304 "User_Cookie:032284f362a63e3d375f8176aad4e0d7"
61.141.xxx.xxx - [2019-05-16T15:18:35+08:00] "GET /ttt.html HTTP/1.1" - 304 "User_Cookie:032284f362a63e3d375f8176aad4e0d7"
61.141.xxx.xxx - [2019-05-16T15:18:35+08:00] "GET /ttt.html HTTP/1.1" - 304 "User_Cookie:032284f362a63e3d375f8176aad4e0d7"
61.141.xxx.xxx - [2019-05-16T15:18:35+08:00] "GET /ttt.html HTTP/1.1" - 304 "User_Cookie:032284f362a63e3d375f8176aad4e0d7"
日誌分析
命令
//統計IP
awk '{print $1}' xxx/access.log(你的日誌文件路徑) | sort -r |uniq -c | wc -l
//統計PV
awk '{print $6}' xxx/access.log(你的日誌文件路徑) | wc -l
//統計UV
awk '{print $10}' xxx/access.log(你的日誌文件路徑) | sort -r |uniq -c |wc -l