已閱讀5頁,還剩13頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
網(wǎng)站統(tǒng)計(jì)中的數(shù)據(jù)收集原理及實(shí)現(xiàn)_埋點(diǎn)統(tǒng)計(jì)網(wǎng)站數(shù)據(jù)統(tǒng)計(jì)分析工具是網(wǎng)站站長和運(yùn)營人員經(jīng)常使用的一種工具,比較常用的有谷歌分析、百度統(tǒng)計(jì)和騰訊分析等等。所有這些統(tǒng)計(jì)分析工具的第一步都是網(wǎng)站訪問數(shù)據(jù)的收集。目前主流的數(shù)據(jù)收集方式基本都是基于javascript的。本文將簡要分析這種數(shù)據(jù)收集的原理,并一步一步實(shí)際搭建一個(gè)實(shí)際的數(shù)據(jù)收集系統(tǒng)。數(shù)據(jù)收集原理分析簡單來說,網(wǎng)站統(tǒng)計(jì)分析工具需要收集到用戶瀏覽目標(biāo)網(wǎng)站的行為(如打開某網(wǎng)頁、點(diǎn)擊某按鈕、將商品加入購物車等)及行為附加數(shù)據(jù)(如某下單行為產(chǎn)生的訂單金額等)。早期的網(wǎng)站統(tǒng)計(jì)往往只收集一種用戶行為:頁面的打開。而后用戶在頁面中的行為均無法收集。這種收集策略能滿足基本的流量分析、來源分析、內(nèi)容分析及訪客屬性等常用分析視角,但是,隨著ajax技術(shù)的廣泛使用及電子商務(wù)網(wǎng)站對于電子商務(wù)目標(biāo)的統(tǒng)計(jì)分析的需求越來越強(qiáng)烈,這種傳統(tǒng)的收集策略已經(jīng)顯得力不能及。后來,Google在其產(chǎn)品谷歌分析中創(chuàng)新性的引入了可定制的數(shù)據(jù)收集腳本,用戶通過谷歌分析定義好的可擴(kuò)展接口,只需編寫少量的javascript代碼就可以實(shí)現(xiàn)自定義事件和自定義指標(biāo)的跟蹤和分析。目前百度統(tǒng)計(jì)、搜狗分析等產(chǎn)品均照搬了谷歌分析的模式。其實(shí)說起來兩種數(shù)據(jù)收集模式的基本原理和流程是一致的,只是后一種通過javascript收集到了更多的信息。下面看一下現(xiàn)在各種網(wǎng)站統(tǒng)計(jì)工具的數(shù)據(jù)收集基本原理。流程概覽首先通過一幅圖總體看一下數(shù)據(jù)收集的基本流程。圖1. 網(wǎng)站統(tǒng)計(jì)數(shù)據(jù)收集基本流程首先,用戶的行為會觸發(fā)瀏覽器對被統(tǒng)計(jì)頁面的一個(gè)http請求,這里姑且先認(rèn)為行為就是打開網(wǎng)頁。當(dāng)網(wǎng)頁被打開,頁面中的埋點(diǎn)javascript片段會被執(zhí)行,用過相關(guān)工具的朋友應(yīng)該知道,一般網(wǎng)站統(tǒng)計(jì)工具都會要求用戶在網(wǎng)頁中加入一小段javascript代碼,這個(gè)代碼片段一般會動態(tài)創(chuàng)建一個(gè)script標(biāo)簽,并將src指向一個(gè)單獨(dú)的js文件,此時(shí)這個(gè)單獨(dú)的js文件(圖1中綠色節(jié)點(diǎn))會被瀏覽器請求到并執(zhí)行,這個(gè)js往往就是真正的數(shù)據(jù)收集腳本。數(shù)據(jù)收集完成后,js會請求一個(gè)后端的數(shù)據(jù)收集腳本(圖1中的backend),這個(gè)腳本一般是一個(gè)偽裝成圖片的動態(tài)腳本程序,可能由php、python或其它服務(wù)端語言編寫,js會將收集到的數(shù)據(jù)通過http參數(shù)的方式傳遞給后端腳本,后端腳本解析參數(shù)并按固定格式記錄到訪問日志,同時(shí)可能會在http響應(yīng)中給客戶端種植一些用于追蹤的cookie。上面是一個(gè)數(shù)據(jù)收集的大概流程,下面以谷歌分析為例,對每一個(gè)階段進(jìn)行一個(gè)相對詳細(xì)的分析。埋點(diǎn)腳本執(zhí)行階段若要使用谷歌分析(以下簡稱GA),需要在頁面中插入一段它提供的javascript片段,這個(gè)片段往往被稱為埋點(diǎn)代碼。下面是我的博客中所放置的谷歌分析埋點(diǎn)代碼截圖:圖2. 谷歌分析埋點(diǎn)代碼其中_gaq是GA的的全局?jǐn)?shù)組,用于放置各種配置,其中每一條配置的格式為:_gaq.push(Action,param1,param2,.);Action指定配置動作,后面是相關(guān)的參數(shù)列表。GA給的默認(rèn)埋點(diǎn)代碼會給出兩條預(yù)置配置,_setAccount用于設(shè)置網(wǎng)站標(biāo)識ID,這個(gè)標(biāo)識ID是在注冊GA時(shí)分配的。_trackPageview告訴GA跟蹤一次頁面訪問。更多配置請參考:/analytics/devguides/collection/gajs/。實(shí)際上,這個(gè)_gaq是被當(dāng)做一個(gè)FIFO隊(duì)列來用的,配置代碼不必出現(xiàn)在埋點(diǎn)代碼之前,具體請參考上述鏈接的說明。就本文來說,_gaq的機(jī)制不是重點(diǎn),重點(diǎn)是后面匿名函數(shù)的代碼,這才是埋點(diǎn)代碼真正要做的。這段代碼的主要目的就是引入一個(gè)外部的js文件(ga.js),方式是通過document.createElement方法創(chuàng)建一個(gè)script并根據(jù)協(xié)議(http或https)將src指向?qū)?yīng)的ga.js,最后將這個(gè)element插入頁面的dom樹上。注意ga.async = true的意思是異步調(diào)用外部js文件,即不阻塞瀏覽器的解析,待外部js下載完成后異步執(zhí)行。這個(gè)屬性是HTML5新引入的。數(shù)據(jù)收集腳本執(zhí)行階段數(shù)據(jù)收集腳本(ga.js)被請求后會被執(zhí)行,這個(gè)腳本一般要做如下幾件事:1、通過瀏覽器內(nèi)置javascript對象收集信息,如頁面title(通過document.title)、referrer(上一跳url,通過document.referrer)、用戶顯示器分辨率(通過windows.screen)、cookie信息(通過document.cookie)等等一些信息。2、解析_gaq收集配置信息。這里面可能會包括用戶自定義的事件跟蹤、業(yè)務(wù)數(shù)據(jù)(如電子商務(wù)網(wǎng)站的商品編號等)等。3、將上面兩步收集的數(shù)據(jù)按預(yù)定義格式解析并拼接。4、請求一個(gè)后端腳本,將信息放在http request參數(shù)中攜帶給后端腳本。這里唯一的問題是步驟4,javascript請求后端腳本常用的方法是ajax,但是ajax是不能跨域請求的。這里ga.js在被統(tǒng)計(jì)網(wǎng)站的域內(nèi)執(zhí)行,而后端腳本在另外的域(GA的后端統(tǒng)計(jì)腳本是/_utm.gif),ajax行不通。一種通用的方法是js腳本創(chuàng)建一個(gè)Image對象,將Image對象的src屬性指向后端腳本并攜帶參數(shù),此時(shí)即實(shí)現(xiàn)了跨域請求后端。這也是后端腳本為什么通常偽裝成gif文件的原因。通過http抓包可以看到ga.js對_utm.gif的請求:圖3. 后端腳本請求的http包可以看到ga.js在請求_utm.gif時(shí)帶了很多信息,例如utmsr=12801024是屏幕分辨率,utmac=UA-35712773-1是_gaq中解析出的我的GA標(biāo)識ID等等。值得注意的是,_utm.gif未必只會在埋點(diǎn)代碼執(zhí)行時(shí)被請求,如果用_trackEvent配置了事件跟蹤,則在事件發(fā)生時(shí)也會請求這個(gè)腳本。由于ga.js經(jīng)過了壓縮和混淆,可讀性很差,我們就不分析了,具體后面實(shí)現(xiàn)階段我會實(shí)現(xiàn)一個(gè)功能類似的腳本。后端腳本執(zhí)行階段GA的_utm.gif是一個(gè)偽裝成gif的腳本。這種后端腳本一般要完成以下幾件事情:1、解析http請求參數(shù)的到信息。2、從服務(wù)器(WebServer)中獲取一些客戶端無法獲取的信息,如訪客ip等。3、將信息按格式寫入log。5、生成一副11的空gif圖片作為響應(yīng)內(nèi)容并將響應(yīng)頭的Content-type設(shè)為image/gif。5、在響應(yīng)頭中通過Set-cookie設(shè)置一些需要的cookie信息。之所以要設(shè)置cookie是因?yàn)槿绻櫸ㄒ辉L客,通常做法是如果在請求時(shí)發(fā)現(xiàn)客戶端沒有指定的跟蹤cookie,則根據(jù)規(guī)則生成一個(gè)全局唯一的cookie并種植給用戶,否則Set-cookie中放置獲取到的跟蹤cookie以保持同一用戶cookie不變(見圖4)。圖4. 通過cookie跟蹤唯一用戶的原理這種做法雖然不是完美的(例如用戶清掉cookie或更換瀏覽器會被認(rèn)為是兩個(gè)用戶),但是是目前被廣泛使用的手段。注意,如果沒有跨站跟蹤同一用戶的需求,可以通過js將cookie種植在被統(tǒng)計(jì)站點(diǎn)的域下(GA是這么做的),如果要全網(wǎng)統(tǒng)一定位,則通過后端腳本種植在服務(wù)端域下(我們待會的實(shí)現(xiàn)會這么做)。系統(tǒng)的設(shè)計(jì)實(shí)現(xiàn)根據(jù)上述原理,我自己搭建了一個(gè)訪問日志收集系統(tǒng)。總體來說,搭建這個(gè)系統(tǒng)要做如下的事:圖5. 訪問數(shù)據(jù)收集系統(tǒng)工作分解下面詳述每一步的實(shí)現(xiàn)。我將這個(gè)系統(tǒng)叫做MyAnalytics。確定收集的信息為了簡單起見,我不打算實(shí)現(xiàn)GA的完整數(shù)據(jù)收集模型,而是收集以下信息。埋點(diǎn)代碼埋點(diǎn)代碼我將借鑒GA的模式,但是目前不會將配置對象作為一個(gè)FIFO隊(duì)列用。一個(gè)埋點(diǎn)代碼的模板如下: var_maq=_maq|; _maq.push(_setAccount,網(wǎng)站標(biāo)識); (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)計(jì)腳本的名稱為ma.js。當(dāng)然這里有一點(diǎn)小問題,因?yàn)槲也]有https的服務(wù)器,所以如果一個(gè)https站點(diǎn)部署了代碼會有問題,不過這里我們先忽略吧。前端統(tǒng)計(jì)腳本我寫了一個(gè)不是很完善但能完成基本工作的統(tǒng)計(jì)腳本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; )();整個(gè)腳本放在匿名函數(shù)里,確保不會污染全局環(huán)境。功能在原理一節(jié)已經(jīng)說明,不再贅述。其中1.gif是后端腳本。日志格式日志采用每行一條記錄的方式,采用不可見字符A(ascii碼0x01,Linux下可通過ctrl + v ctrl + a輸入,下文均用“A”表示不可見字符0x01),具體格式如下:時(shí)間AIPA域名AURLA頁面標(biāo)題AReferrerA分辨率高A分辨率寬A顏色深度A語言A客戶端信息A用戶標(biāo)識A網(wǎng)站標(biāo)識后端腳本為了簡單和效率考慮,我打算直接使用nginx的access_log做日志收集,不過有個(gè)問題就是nginx配置本身的邏輯表達(dá)能力有限,所以我選用了OpenResty做這個(gè)事情。OpenResty是一個(gè)基于Nginx擴(kuò)展出的高性能應(yīng)用開發(fā)平臺,內(nèi)部集成了諸多有用的模塊,其中的核心是通過ngx_lua模塊集成了Lua,從而在nginx配置文件中可以通過Lua來表述業(yè)務(wù)。關(guān)于這個(gè)平臺我這里不做過多介紹,感興趣的同學(xué)可以參考其官方網(wǎng)站/,或者這里有其作者章亦春(agentzh)做的一個(gè)非常有愛的介紹OpenResty的slide:/misc/slides/ngx-openresty-ecosystem/,關(guān)于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)置變量。然后是核心的兩個(gè)location:location/1.gif #偽裝成gif文件 default_typeimage/gif; #本身關(guān)閉access_log,通過subrequest記錄log access_logoff; access_by_lua -用戶跟蹤cookie名為_utrace localuid=ngx.var.cookie_utrace ifnotuidthen -如果沒有則生成一個(gè)跟蹤cookie,算法為md5(時(shí)間戳+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; #返回一個(gè)11的空gif圖片 empty_gif; location/i-log #內(nèi)部location,不允許外部直接訪問 internal; #設(shè)置變量,注意需要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,實(shí)際應(yīng)用中最好加buffer,格式為tick access_log/path/to/logs/directory/ma.logtick; #輸出空字符串 echo; 要完全解釋這段腳本的每一個(gè)細(xì)節(jié)有點(diǎn)超出本文的范圍,而且用到了諸多第三方ngxin模塊(全都包含在OpenResty中了),重點(diǎn)的地方我都用注釋標(biāo)出來了,可以不用完全理解每一行的意義,只要大約知道這個(gè)配置完成了我們在原理一節(jié)提到的后端邏輯就可以了。日志輪轉(zhuǎn)真正的日志收集系統(tǒng)訪問日志會非常多,時(shí)間一長文件變得很大,而且日志放在一個(gè)文件不便于管理。所以通常要按時(shí)間段將日志切分,例如每天或每小時(shí)切分一個(gè)日志。我這里為了效果明顯,每一小時(shí)切分一個(gè)日志。我是通過crontab定時(shí)調(diào)用一個(gè)shell腳本實(shí)現(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這個(gè)腳本將ma.log移動到指定文件夾并重命名為ma-yyyymmddhh.log,然后向nginx發(fā)送USR1信號令其重新打開日志文件。然后再/etc/crontab里加入一行:59*root/path/to/directory/rotatelog.sh在每個(gè)小時(shí)的59分啟動這個(gè)腳本進(jìn)行日志輪轉(zhuǎn)操作。測試下面可以測試這個(gè)系統(tǒng)是否能正常運(yùn)行了。我昨天就在我的博客中埋了相關(guān)的點(diǎn),通過http抓包可以看到ma.js和1.gif已經(jīng)被正確請求:圖6. http包分析ma.js和1.gif的請求同時(shí)可以看一下1.gif的請求參數(shù):圖7. 1.gif的請求參數(shù)相關(guān)信息確實(shí)也放在了請求參數(shù)中。然后我tail打開日志文件,然后刷新一下頁面,因?yàn)闆]有設(shè)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)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025版塔吊司機(jī)與司索工安全操作雇傭協(xié)議書10篇
- 二零二四年度小程序與在線教育平臺合作開發(fā)合同3篇
- 2025房屋租賃合同以及注意事項(xiàng)
- 二零二四年度醫(yī)藥產(chǎn)品研發(fā)與臨床試驗(yàn)合同
- 鋼框架結(jié)構(gòu)施工方案
- 2025版平方家具買賣合同范本(含運(yùn)輸安裝)3篇
- 《盛明雜劇》評點(diǎn)研究
- 中小企業(yè)大數(shù)據(jù)能力、知識積累對商業(yè)模式創(chuàng)新的影響研究
- 氧化石墨烯基材料的制備及其對U(Ⅵ)吸附行為的研究
- 二零二五版木屑生物質(zhì)發(fā)電項(xiàng)目投資合同4篇
- 《色彩基礎(chǔ)》課程標(biāo)準(zhǔn)
- 人力資源 -人效評估指導(dǎo)手冊
- 大疆80分鐘在線測評題
- 2023年成都市青白江區(qū)村(社區(qū))“兩委”后備人才考試真題
- 2024中考復(fù)習(xí)必背初中英語單詞詞匯表(蘇教譯林版)
- 《現(xiàn)代根管治療術(shù)》課件
- 肩袖損傷的護(hù)理查房課件
- 2023屆北京市順義區(qū)高三二模數(shù)學(xué)試卷
- 公司差旅費(fèi)報(bào)銷單
- 2021年上海市楊浦區(qū)初三一模語文試卷及參考答案(精校word打印版)
- 八年級上冊英語完形填空、閱讀理解100題含參考答案
評論
0/150
提交評論