模擬Google Analytics

看到Google Analytics那麼強大,我們是不是也心動想編寫一個自己的分析工具,心動不如手動,開始吧。

1.首先編寫analytics.js,也就是每個頁面中異步下載的那個js文件:

// 這裏使用匿名代碼塊,文件一經加載就會執行,而且使文件內部代碼外部無法調用
// 這裏隱藏掉了搜索部分,加入購物車部分代碼;代碼相似,讀者可以模仿添加 
(function(document)
{	
	var functions = 
	{
		send : function()
		{
			// 這裏是簡化的代碼,請求參數會比較少,當然你可以隨意加入需要的請求數據
			var account_id = arguments[0];
			var page_url = window.location.href;
			var request_time = parseInt(new Date().getTime() / 1000);
			// 模擬Google Analytics向服務器發送一個請求,請求一個1x1的圖片,這裏使用gif格式也是爲了最小化,節省帶寬
			send_img = document.createElement("img");
			send_img.src = encodeURI("http://localhost:8080/my_analytics/images/analytics.gif?" + "uid=" + uuid() + "&type=page_view&page_url=" + page_url + "&account_id=" + account_id);
			document.getElementsByTagName("body")[0].appendChild(send_img);
		},
		ecommerce : function()
		{
			var goods_list = arguments[0]; 
			// 使用瀏覽器內置的arguments獲取傳入的參數
			for(var i = 0; i < goods_list.length; i++)
			{
				var goods_name = goods_list[i]['goods_name'];
				var goods_id = goods_list[i]['goods_id'];
				var add_time = goods_list[i]['add_time'];
				var address = goods_list[i]['address'];

				send_img = document.createElement("img");
				send_img.src = encodeURI("http://localhost:8080/my_analytics/images/analytics.gif?" + "uid=" + uuid() + "&type=ecommerce&goods_id=" + goods_id + "&goods_name=" + goods_name + "&address=" + address + "&purchase_time=" + add_time);
				document.getElementsByTagName("body")[0].appendChild(send_img);
			}
		}
	};


	setInterval(
		function()
		{
		  	for(var i = 0; i < my_ga.ops.length; i++)
		        {
			     // 動態調用方法,並且傳入參數
			      functions[my_ga.ops[i][0]](my_ga.ops[i][1]); 
			
			    // 執行之後去除該命令
			     my_ga.ops.splice(i, 1); 
			 }
		},20); 
	// 這裏設置每隔20毫秒執行一次,js文件加載後,用戶如果有操作會立馬執行

	// 生成uuid,目的是爲了防止瀏覽器緩存圖片造成不發送請求的情況		
	function uuid()
	{
		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); return v.toString(16);});
	}

	// 獲取存儲在用戶瀏覽器的cookie,分析工具肯定會在用戶本地存儲追蹤cookie
	function get_cookie(cookie_name)
	{
		var c_value = document.cookie;var c_start = c_value.indexOf(" " + cookie_name + "="); 		if (c_start == -1) 
			c_start = c_value.indexOf(cookie_name + "=");
		if (c_start == -1) 
			c_value = null;
		else 
		{ 
			c_start = c_value.indexOf("=", c_start) + 1;
			var c_end = c_value.indexOf(";", c_start);if (c_end == -1)c_end = c_value.length;c_value = unescape(c_value.substring(c_start,c_end)); }c_value = c_value == null ? "" : c_value;return c_value;
		}
	}
)(document);

2. 頁面使用如下代碼來加載上js文件:
<!-- Analytics Code -->
<script>
			(function(i,s,o,g,r,a,m)
			{
				i['AnalyticsObject']=r;	

				i[r] = i[r] || function()
				{
					(i[r].ops = i[r].ops || []).push(arguments);
				}
				
				a = s.createElement(o);
				a.type = "text/javascript";
				m = s.getElementsByTagName(o)[0];
				a.async=true; // 1 asynchronous
				a.src=g;
				m.parentNode.insertBefore(a,m);
			})(window, document, 'script', 'http://localhost:8080/my_analytics/scripts/analytics.js', 'my_ga');
			
			// 這裏發送一次頁面瀏覽,將用戶賬號傳入方法,當然用戶可能未登錄,可以同時取用戶賬號以及存儲在用戶瀏覽器的追蹤cookie以標示用戶(此略去)
		 	var account_id = "{$user_id}";
			my_ga('send', account_id);
</script>


ecommerce部分應該添加在purchase ok頁面(即 Thank You 頁面)可如下:

<script type="text/javascript">


	var account_id = "{$user_id}";				
	var goods_list = new Array();	


	  // 這裏使用的是php語法,循環出訂單中的商品
	 <!-- {foreach from=$order_goods_list item=goods} -->
	 	var goods = new Array();
		goods['goods_name'] = encodeURI("{$goods.goods_name}");
		goods['goods_id'] = "{$goods.goods_id}";
		goods['goods_number'] = "{$goods.goods_number}";
		goods['add_time'] = "{$order.add_time}";
		goods['address'] = encodeURI("{$order.address}");
		goods_list.push(goods);
	 <!-- {/foreach} -->


		 my_ga('ecommerce', goods_list);
</script>


3. 服務器端處理:
我這裏使用的是tomcat作爲服務器的java web app。基本原理是:使用tomcat的日誌記錄功能將用戶請求分類存儲,然後定時讀取日誌,將用戶行爲記錄進數據庫。
配置tomcat日誌記錄如下:



<Context path="/my_analytics" docBase="D:\Programs\MyEclipse\workspace\my_analytics\WebRoot">


<!-- 記錄頁面瀏覽 -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
	rotatable="true"	directory="E:/my_analytics_logs/"
	prefix="page_view_" 	suffix=".txt"
	fileDateFormat="yyyyMMddHHmm"	pattern="%{parameters}r"
	buffered="false" 	resolveHosts="false" 	conditionIf="page_view"
	/>




<!-- 記錄添加購物車 -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
	rotatable="true"	directory="E:/my_analytics_logs/"
	prefix="cart_" 	suffix=".txt"
	fileDateFormat="yyyyMMddHHmm"	pattern="%{parameters}r"
	buffered="false" 	resolveHosts="false" 	conditionIf="cart"
	/>




<!-- 記錄購買記錄 -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
	rotatable="true"	directory="E:/my_analytics_logs/"
	prefix="ecommerce_" 	suffix=".txt"
	fileDateFormat="yyyyMMddHHmm"	pattern="%{parameters}r"
	buffered="false" 	resolveHosts="false" 	conditionIf="ecommerce"
	/>




<!-- 記錄搜索記錄 -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
	rotatable="true"	directory="E:/my_analytics_logs/"
	prefix="search_" 	suffix=".txt"
	fileDateFormat="yyyyMMddHHmm"	pattern="%{parameters}r"
	buffered="false" 	resolveHosts="false" 	conditionIf="search"
	/>


</Context>


對於AccessLogValve的使用,可以查閱幫助文檔。
至此,分析框架已經搭建完成,儘管項目不大,但是進行過程中同樣遇到了很多棘手的問題,一點點的摸索解決。沒有提到之處,請大家自己動手完成,基本思路原理已經很明確了。



Good Bye, Readers! Have A Nice Weekend.....



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章