看到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.....