




已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
網(wǎng)站統(tǒng)計中的數(shù)據(jù)收集原理及實現(xiàn)_埋點統(tǒng)計網(wǎng)站數(shù)據(jù)統(tǒng)計分析工具是網(wǎng)站站長和運營人員經(jīng)常使用的一種工具,比較常用的有谷歌分析、百度統(tǒng)計和騰訊分析等等。所有這些統(tǒng)計分析工具的第一步都是網(wǎng)站訪問數(shù)據(jù)的收集。目前主流的數(shù)據(jù)收集方式基本都是基于javascript的。本文將簡要分析這種數(shù)據(jù)收集的原理,并一步一步實際搭建一個實際的數(shù)據(jù)收集系統(tǒng)。數(shù)據(jù)收集原理分析簡單來說,網(wǎng)站統(tǒng)計分析工具需要收集到用戶瀏覽目標網(wǎng)站的行為(如打開某網(wǎng)頁、點擊某按鈕、將商品加入購物車等)及行為附加數(shù)據(jù)(如某下單行為產(chǎn)生的訂單金額等)。早期的網(wǎng)站統(tǒng)計往往只收集一種用戶行為:頁面的打開。而后用戶在頁面中的行為均無法收集。這種收集策略能滿足基本的流量分析、來源分析、內(nèi)容分析及訪客屬性等常用分析視角,但是,隨著ajax技術的廣泛使用及電子商務網(wǎng)站對于電子商務目標的統(tǒng)計分析的需求越來越強烈,這種傳統(tǒng)的收集策略已經(jīng)顯得力不能及。后來,Google在其產(chǎn)品谷歌分析中創(chuàng)新性的引入了可定制的數(shù)據(jù)收集腳本,用戶通過谷歌分析定義好的可擴展接口,只需編寫少量的javascript代碼就可以實現(xiàn)自定義事件和自定義指標的跟蹤和分析。目前百度統(tǒng)計、搜狗分析等產(chǎn)品均照搬了谷歌分析的模式。其實說起來兩種數(shù)據(jù)收集模式的基本原理和流程是一致的,只是后一種通過javascript收集到了更多的信息。下面看一下現(xiàn)在各種網(wǎng)站統(tǒng)計工具的數(shù)據(jù)收集基本原理。流程概覽首先通過一幅圖總體看一下數(shù)據(jù)收集的基本流程。圖1. 網(wǎng)站統(tǒng)計數(shù)據(jù)收集基本流程首先,用戶的行為會觸發(fā)瀏覽器對被統(tǒng)計頁面的一個http請求,這里姑且先認為行為就是打開網(wǎng)頁。當網(wǎng)頁被打開,頁面中的埋點javascript片段會被執(zhí)行,用過相關工具的朋友應該知道,一般網(wǎng)站統(tǒng)計工具都會要求用戶在網(wǎng)頁中加入一小段javascript代碼,這個代碼片段一般會動態(tài)創(chuàng)建一個script標簽,并將src指向一個單獨的js文件,此時這個單獨的js文件(圖1中綠色節(jié)點)會被瀏覽器請求到并執(zhí)行,這個js往往就是真正的數(shù)據(jù)收集腳本。數(shù)據(jù)收集完成后,js會請求一個后端的數(shù)據(jù)收集腳本(圖1中的backend),這個腳本一般是一個偽裝成圖片的動態(tài)腳本程序,可能由php、python或其它服務端語言編寫,js會將收集到的數(shù)據(jù)通過http參數(shù)的方式傳遞給后端腳本,后端腳本解析參數(shù)并按固定格式記錄到訪問日志,同時可能會在http響應中給客戶端種植一些用于追蹤的cookie。上面是一個數(shù)據(jù)收集的大概流程,下面以谷歌分析為例,對每一個階段進行一個相對詳細的分析。埋點腳本執(zhí)行階段若要使用谷歌分析(以下簡稱GA),需要在頁面中插入一段它提供的javascript片段,這個片段往往被稱為埋點代碼。下面是我的博客中所放置的谷歌分析埋點代碼截圖:圖2. 谷歌分析埋點代碼其中_gaq是GA的的全局數(shù)組,用于放置各種配置,其中每一條配置的格式為:_gaq.push(Action,param1,param2,.);Action指定配置動作,后面是相關的參數(shù)列表。GA給的默認埋點代碼會給出兩條預置配置,_setAccount用于設置網(wǎng)站標識ID,這個標識ID是在注冊GA時分配的。_trackPageview告訴GA跟蹤一次頁面訪問。更多配置請參考:/analytics/devguides/collection/gajs/。實際上,這個_gaq是被當做一個FIFO隊列來用的,配置代碼不必出現(xiàn)在埋點代碼之前,具體請參考上述鏈接的說明。就本文來說,_gaq的機制不是重點,重點是后面匿名函數(shù)的代碼,這才是埋點代碼真正要做的。這段代碼的主要目的就是引入一個外部的js文件(ga.js),方式是通過document.createElement方法創(chuàng)建一個script并根據(jù)協(xié)議(http或https)將src指向?qū)膅a.js,最后將這個element插入頁面的dom樹上。注意ga.async = true的意思是異步調(diào)用外部js文件,即不阻塞瀏覽器的解析,待外部js下載完成后異步執(zhí)行。這個屬性是HTML5新引入的。數(shù)據(jù)收集腳本執(zhí)行階段數(shù)據(jù)收集腳本(ga.js)被請求后會被執(zhí)行,這個腳本一般要做如下幾件事:1、通過瀏覽器內(nèi)置javascript對象收集信息,如頁面title(通過document.title)、referrer(上一跳url,通過document.referrer)、用戶顯示器分辨率(通過windows.screen)、cookie信息(通過document.cookie)等等一些信息。2、解析_gaq收集配置信息。這里面可能會包括用戶自定義的事件跟蹤、業(yè)務數(shù)據(jù)(如電子商務網(wǎng)站的商品編號等)等。3、將上面兩步收集的數(shù)據(jù)按預定義格式解析并拼接。4、請求一個后端腳本,將信息放在http request參數(shù)中攜帶給后端腳本。這里唯一的問題是步驟4,javascript請求后端腳本常用的方法是ajax,但是ajax是不能跨域請求的。這里ga.js在被統(tǒng)計網(wǎng)站的域內(nèi)執(zhí)行,而后端腳本在另外的域(GA的后端統(tǒng)計腳本是/_utm.gif),ajax行不通。一種通用的方法是js腳本創(chuàng)建一個Image對象,將Image對象的src屬性指向后端腳本并攜帶參數(shù),此時即實現(xiàn)了跨域請求后端。這也是后端腳本為什么通常偽裝成gif文件的原因。通過http抓包可以看到ga.js對_utm.gif的請求:圖3. 后端腳本請求的http包可以看到ga.js在請求_utm.gif時帶了很多信息,例如utmsr=12801024是屏幕分辨率,utmac=UA-35712773-1是_gaq中解析出的我的GA標識ID等等。值得注意的是,_utm.gif未必只會在埋點代碼執(zhí)行時被請求,如果用_trackEvent配置了事件跟蹤,則在事件發(fā)生時也會請求這個腳本。由于ga.js經(jīng)過了壓縮和混淆,可讀性很差,我們就不分析了,具體后面實現(xiàn)階段我會實現(xiàn)一個功能類似的腳本。后端腳本執(zhí)行階段GA的_utm.gif是一個偽裝成gif的腳本。這種后端腳本一般要完成以下幾件事情:1、解析http請求參數(shù)的到信息。2、從服務器(WebServer)中獲取一些客戶端無法獲取的信息,如訪客ip等。3、將信息按格式寫入log。5、生成一副11的空gif圖片作為響應內(nèi)容并將響應頭的Content-type設為image/gif。5、在響應頭中通過Set-cookie設置一些需要的cookie信息。之所以要設置cookie是因為如果要跟蹤唯一訪客,通常做法是如果在請求時發(fā)現(xiàn)客戶端沒有指定的跟蹤cookie,則根據(jù)規(guī)則生成一個全局唯一的cookie并種植給用戶,否則Set-cookie中放置獲取到的跟蹤cookie以保持同一用戶cookie不變(見圖4)。圖4. 通過cookie跟蹤唯一用戶的原理這種做法雖然不是完美的(例如用戶清掉cookie或更換瀏覽器會被認為是兩個用戶),但是是目前被廣泛使用的手段。注意,如果沒有跨站跟蹤同一用戶的需求,可以通過js將cookie種植在被統(tǒng)計站點的域下(GA是這么做的),如果要全網(wǎng)統(tǒng)一定位,則通過后端腳本種植在服務端域下(我們待會的實現(xiàn)會這么做)。系統(tǒng)的設計實現(xiàn)根據(jù)上述原理,我自己搭建了一個訪問日志收集系統(tǒng)。總體來說,搭建這個系統(tǒng)要做如下的事:圖5. 訪問數(shù)據(jù)收集系統(tǒng)工作分解下面詳述每一步的實現(xiàn)。我將這個系統(tǒng)叫做MyAnalytics。確定收集的信息為了簡單起見,我不打算實現(xiàn)GA的完整數(shù)據(jù)收集模型,而是收集以下信息。埋點代碼埋點代碼我將借鑒GA的模式,但是目前不會將配置對象作為一個FIFO隊列用。一個埋點代碼的模板如下: var_maq=_maq|; _maq.push(_setAccount,網(wǎng)站標識); (function() varma=document.createElement(script);ma.type=text/javascript;ma.async=true; ma.src=(https:=tocol?https:/analytics:http:/analytics)+./ma.js; vars=document.getElementsByTagName(script)0;s.parentNode.insertBefore(ma,s); )(); 這里我啟用了二級域名,統(tǒng)計腳本的名稱為ma.js。當然這里有一點小問題,因為我并沒有https的服務器,所以如果一個https站點部署了代碼會有問題,不過這里我們先忽略吧。前端統(tǒng)計腳本我寫了一個不是很完善但能完成基本工作的統(tǒng)計腳本ma.js:(function() varparams=; /Document對象數(shù)據(jù) if(document) params.domain=document.domain|; params.url=document.URL|; params.title=document.title|; params.referrer=document.referrer|; /Window對象數(shù)據(jù) if(window&window.screen) params.sh=window.screen.height|0; params.sw=window.screen.width|0; params.cd=window.screen.colorDepth|0; /navigator對象數(shù)據(jù) if(navigator) params.lang=navigator.language|; /解析_maq配置 if(_maq) for(variin_maq) switch(_maqi0) case_setAccount: params.account=_maqi1; break; default: break; /拼接參數(shù)串 varargs=; for(variinparams) if(args!=) args+=&; args+=i+=+encodeURIComponent(paramsi); /通過Image對象請求后端腳本 varimg=newImage(1,1); img.src=/1.gif?+args; )();整個腳本放在匿名函數(shù)里,確保不會污染全局環(huán)境。功能在原理一節(jié)已經(jīng)說明,不再贅述。其中1.gif是后端腳本。日志格式日志采用每行一條記錄的方式,采用不可見字符A(ascii碼0x01,Linux下可通過ctrl + v ctrl + a輸入,下文均用“A”表示不可見字符0x01),具體格式如下:時間AIPA域名AURLA頁面標題AReferrerA分辨率高A分辨率寬A顏色深度A語言A客戶端信息A用戶標識A網(wǎng)站標識后端腳本為了簡單和效率考慮,我打算直接使用nginx的access_log做日志收集,不過有個問題就是nginx配置本身的邏輯表達能力有限,所以我選用了OpenResty做這個事情。OpenResty是一個基于Nginx擴展出的高性能應用開發(fā)平臺,內(nèi)部集成了諸多有用的模塊,其中的核心是通過ngx_lua模塊集成了Lua,從而在nginx配置文件中可以通過Lua來表述業(yè)務。關于這個平臺我這里不做過多介紹,感興趣的同學可以參考其官方網(wǎng)站/,或者這里有其作者章亦春(agentzh)做的一個非常有愛的介紹OpenResty的slide:/misc/slides/ngx-openresty-ecosystem/,關于ngx_lua可以參考:/chaoslawful/lua-nginx-module。首先,需要在nginx的配置文件中定義日志格式:log_formattick$msecA$remote_addrA$u_domainA$u_urlA$u_titleA$u_referrerA$u_shA$u_swA$u_cdA$u_langA$http_user_agentA$u_utraceA$u_account;注意這里以u_開頭的是我們待會會自己定義的變量,其它的是nginx內(nèi)置變量。然后是核心的兩個location:location/1.gif #偽裝成gif文件 default_typeimage/gif; #本身關閉access_log,通過subrequest記錄log access_logoff; access_by_lua -用戶跟蹤cookie名為_utrace localuid=ngx.var.cookie_utrace ifnotuidthen -如果沒有則生成一個跟蹤cookie,算法為md5(時間戳+IP+客戶端信息) uid=ngx.md5(ngx.now().ngx.var.remote_addr.ngx.var.http_user_agent) end ngx.headerSet-Cookie=_utrace=.uid.;path=/ ifngx.var.arg_domainthen -通過subrequest到/i-log記錄日志,將參數(shù)和用戶跟蹤cookie帶過去 ngx.location.capture(/i-log?.ngx.var.args.&utrace=.uid) end ; #此請求不緩存 add_headerExpiresFri,01Jan198000:00:00GMT; add_headerPragmano-cache; add_headerCache-Controlno-cache,max-age=0,must-revalidate; #返回一個11的空gif圖片 empty_gif; location/i-log #內(nèi)部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_subrequeston; #記錄日志到ma.log,實際應用中最好加buffer,格式為tick access_log/path/to/logs/directory/ma.logtick; #輸出空字符串 echo; 要完全解釋這段腳本的每一個細節(jié)有點超出本文的范圍,而且用到了諸多第三方ngxin模塊(全都包含在OpenResty中了),重點的地方我都用注釋標出來了,可以不用完全理解每一行的意義,只要大約知道這個配置完成了我們在原理一節(jié)提到的后端邏輯就可以了。日志輪轉(zhuǎn)真正的日志收集系統(tǒng)訪問日志會非常多,時間一長文件變得很大,而且日志放在一個文件不便于管理。所以通常要按時間段將日志切分,例如每天或每小時切分一個日志。我這里為了效果明顯,每一小時切分一個日志。我是通過crontab定時調(diào)用一個shell腳本實現(xiàn)的,shell腳本如下:_prefix=/path/to/nginxtime=date+%Y%m%d%Hmv$_prefix/logs/ma.log$_prefix/logs/ma/ma-$time.logkill-USR1cat$_prefix/logs/nginx.pid這個腳本將ma.log移動到指定文件夾并重命名為ma-yyyymmddhh.log,然后向nginx發(fā)送USR1信號令其重新打開日志文件。然后再/etc/crontab里加入一行:59*root/path/to/directory/rotatelog.sh在每個小時的59分啟動這個腳本進行日志輪轉(zhuǎn)操作。測試下面可以測試這個系統(tǒng)是否能正常運行了。我昨天就在我的博客中埋了相關的點,通過http抓包可以看到ma.js和1.gif已經(jīng)被正確請求:圖6. http包分析ma.js和1.gif的請求同時可以看一下1.gif的請求參數(shù):圖7. 1.gif的請求參數(shù)相關信息確實也放在了請求參數(shù)中。然后我tail打開日志文件,然后刷新一下頁面,因為沒有設access log buffer, 我立即得到了一條新日志:1351060731.360AAA/ACodingLabsAA1024A1280A24Azh-CNAMozilla/5.0(Macintosh;IntelMacOSX10_8_2)AppleWebKit/5
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中國低壓就地補償柜市場調(diào)查研究報告
- 2025年中國不銹鋼攪拌釜市場調(diào)查研究報告
- 2025年中國X光檢測儀器市場調(diào)查研究報告
- 2025年中國IC存儲編程器市場調(diào)查研究報告
- 2025年噪聲、振動、磁輻射、放射線監(jiān)測儀項目合作計劃書
- 《財務分析與應用》課件
- 2025年人行道養(yǎng)護車項目合作計劃書
- 陜西成人考試試題及答案
- 《卓越銷售技巧》課件
- 2025年農(nóng)業(yè)用地流轉(zhuǎn)管理合同
- 實驗06 探究凸透鏡成像的規(guī)律-中考物理實驗之真題匯編(解析版)
- 電商客服崗轉(zhuǎn)正述職報告
- 標準實施情況報告
- 農(nóng)業(yè)安全問題
- 導管護理相關知識
- 上海2025年上海交通大學醫(yī)學院招聘72人筆試歷年參考題庫附帶答案詳解
- DB37-T 5061-2024 住宅小區(qū)供配電設施建設標準
- GB/T 45135-2024鈦合金板材超塑成形和擴散連接件通用技術規(guī)范
- (2025)時事政治題庫(含參考答案)
- 【含聽力9英一?!亢戏适惺裆絽^(qū)2024年中考一模英語
- 保利拍賣行合同模板
評論
0/150
提交評論