1. 程式人生 > >頁面埋點&nginx日誌採集

頁面埋點&nginx日誌採集

頁面埋點&nginx日誌採集

採集頁面(web容器:httpd/nginx負載均衡 + apache server)<===> 日誌採集伺服器(nginx伺服器)

  1. 通過某個頁面跳轉到我們的頁面;
  2. 我們頁面一渲染完成載入埋點的js,執行業務邏輯採集資訊;
  3. 採集頁面完成之後,訪問log.gif,把引數拼接在args傳送給採集伺服器;
  4. 採集伺服器返回一個1*1空的圖片,斷開連線。

採集頁面埋點(在頁面body最後埋js)

<script type="text/javascript">
    var _maq = _maq || [];
    _maq.push(['_setAccount'
, 'zx5352']); (function() { var ma = document.createElement('script'); ma.type = 'text/javascript'; ma.async = true; ma.src = 'http://xxxxxx/ma.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ma, s); })();
</script
>

採集伺服器js

(function () {
    var params = {};
    //Document物件資料
    if(document) {
        params.domain = document.domain || ''; 
        params.url = document.URL || ''; 
        params.title = document.title || ''; 
        params.referrer = document.referrer || ''; 
    }   
    //Window物件資料
if(window && window.screen) { params.sh = window.screen.height || 0; params.sw = window.screen.width || 0; params.cd = window.screen.colorDepth || 0; } //navigator物件資料 if(navigator) { params.lang = navigator.language || ''; } //解析_maq配置 if(_maq) { for(var i in _maq) { switch(_maq[i][0]) { case '_setAccount': params.account = _maq[i][1]; break; default: break; } } } //拼接引數串 var args = ''; for(var i in params) { if(args != '') { args += '&'; } args += i + '=' + encodeURIComponent(params[i]); } //通過Image物件請求後端指令碼 var img = new Image(1, 1); img.src = 'http://xxxxxx/log.gif?' + args; })();

採集伺服器nginx配置

worker_processes  2;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format tick "$msec^A$remote_addr^A$u_domain^A$u_url^A$u_title^A$u_referrer^A$u_sh^A$u_sw^A$u_cd^A$u_lang^A$http_user_agent^A$u_utrace^A$u_account";

    access_log  logs/access.log  tick;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;
        location /1.gif {
            #偽裝成gif檔案
            default_type image/gif;    
            #本身關閉access_log,通過subrequest記錄log
            access_log off;

            access_by_lua "
                -- 使用者跟蹤cookie名為__utrace
                local uid = ngx.var.cookie___utrace        
                if not uid then
                    -- 如果沒有則生成一個跟蹤cookie,演算法為md5(時間戳+IP+客戶端資訊)
                    uid = ngx.md5(ngx.now() .. ngx.var.remote_addr .. ngx.var.http_user_agent)
                end 
                ngx.header['Set-Cookie'] = {'__utrace=' .. uid .. '; path=/'}
                if ngx.var.arg_domain then
                -- 通過subrequest到/i-log記錄日誌,將引數和使用者跟蹤cookie帶過去
                    ngx.location.capture('/i-log?' .. ngx.var.args .. '&utrace=' .. uid)
                end 
            ";  

            #此請求不快取
            add_header Expires "Fri, 01 Jan 1980 00:00:00 GMT";
            add_header Pragma "no-cache";
            add_header Cache-Control "no-cache, max-age=0, must-revalidate";

            #返回一個1×1的空gif圖片
            empty_gif;
        }   

        location /i-log {
            #內部location,不允許外部直接訪問
            internal;

            #設定變數,注意需要unescape
            set_unescape_uri $u_domain $arg_domain;
            set_unescape_uri $u_url $arg_url;
            set_unescape_uri $u_title $arg_title;
            set_unescape_uri $u_referrer $arg_referrer;
            set_unescape_uri $u_sh $arg_sh;
            set_unescape_uri $u_sw $arg_sw;
            set_unescape_uri $u_cd $arg_cd;
            set_unescape_uri $u_lang $arg_lang;
            set_unescape_uri $u_utrace $arg_utrace;
            set_unescape_uri $u_account $arg_account;

            #開啟日誌
            log_subrequest on;
            #記錄日誌到ma.log,實際應用中最好加buffer,格式為tick
            access_log /var/nginx_logs/ma.log tick;

            #輸出空字串
            echo '';
        }
    }
}