zoukankan      html  css  js  c++  java
  • 用new Image().src作LOG统计的一个注意事项 .

    用new Image().src作LOG统计的一个注意事项
    2009-08-06 17:40

    在大型网站做很多用户行为分析、产品的策划方案基本上都是通过分析用户的访问等信息而做出的,LOG信息的统计准确性会直接影响到产品的设计开发(比如搜索结果的先后排名rank值的产生等)。目前最常用的一个写LOG的方法就是用JavaScript脚本在网页里 new Image().src = "http://xxx.com/log?msg="+ msg; 这种统计方法基本上不会干扰用户的正常操作,虽然有LOG丢失的可能,但只要用得好,还是一种非常好的LOG统计回收的方案。

    但是这种LOG回收手段有一个非常隐秘的隐患,事情是这样被发现的。今年3月份百度搜索结果页面上线了Suggestion功能升级版,在LOG统计中突然发现上线后的LOG总量比上线前的少了很多(10%以上),表现出来的现象就是LOG丢失了,没有回收到服务器中来。

    工程师立即做了详细排除,从各种因素上确定LOG的大量丢失跟网页上线Suggestion有关,我们马上对Suggestion脚本进行地毯式排查,逐行分析代码,结论是这个脚本没有阻拦 new Image().src 的发包请求(至少表面上是这样的),这段脚本放在一个脚本闭包中,没有影响到全局变量/方法,也没有屏蔽干扰HTTP请求的因素。

    我们又做了一个线下试验,同样的代码环境,在线下的测试环境中用这种 new Image().src 的手段,总共向Server端发送了10000个LOG数据,也没有发生LOG丢失,试验的结果也没有发现LOG丢失的原因。

    但是在线上的环境中发生的就是有LOG数据丢失,原因不明,所以只能紧急下线这个Suggestion升级版。在这个脚本下线之后,LOG统计数据马上回归到“原正常”状态。从这个现象来看,也从另一个角度说明上线的新脚本确实对LOG统计有影响,头疼呀......

    愚者千虑,必有一得!最后方知这个问题的原因是浏览器的垃圾回收机制

    function c(q) {
        var p=window.document.location.href,sQ='',sV='';
        for(v in q){
            switch (v){
                case "title":sV=encodeURIComponent(q[v].replace(/<[^<>]+>/g,""));break;
                case "url":sV=escape(q[v]);break;
                default:sV=q[v]
            }
            sQ+=v+"="+sV+"&";
        }
        new Image().src = "http://s.baidu.com/w.gif?q=meizz&"+sQ+"path="+p+"&cid=9&t="+ new Date().getTime();
        return true;
    }

    这个 new Image() 对象没有赋给任何变量,在这个函数执行结束时,浏览器的垃圾回收机制对这种“无主”的对象是毫不客气的回收的,而正是这种回收行为导致了这个HTTP请求(异步的)没有发出,从而造成了LOG数据的丢失。那为什么上线一个脚本就会造成大量的LOG丢失呢?因为一个大脚本的运行回产生大量的“垃圾”,浏览器垃圾回收也会相应地更频繁的启动,从而造成LOG数据丢失。找到原因之后对症下药,把这个 new Image() 对象赋给一个全局有变量常期持有即可,相应的代码如下:

    var n = "log_"+ (newDate()).getTime();
    var c = window[n] =newImage();  //把new Image()赋给一个全局变量长期持有
    c.onload = (c.onerror=function(){window[n] = null;});
    c.src = "
    http://s.baidu.com/w.gif?q=meizz"+ xxxx;
    c = null;      //释放局部变量c

    在这个统计代码上线之后,百度的搜索结果页面的LOG立即多出近10%,之后再上线其它的脚本也没有再出现LOG统计量的波动。

     

    ---------------------------------------------------------------------------------------------------------------------------------

    局部变量下,测试连续发1000个log

    IE6-7 发现log丢失,某些IE内核浏览器也发现log丢失

    但在FF, chrome下未发现丢失

     

    因此 保险的做法是用一个非局部变量持有

    1. var unique = (function () {  
    2.     var time= (new Date()).getTime()+'-', i=0;  
    3.     return function () {  
    4.        return time + (i++);  
    5.     }  
    6. })();  
    7.   
    8. var imgLog = function (url) {  
    9.     var data = window['imgLogData'] || (window['imgLogData'] = {});  
    10.     var img = new Image();  
    11.     var uid = unique();  
    12.     img.onload = img.onerror = function () {//销毁一些对象   
    13.         img.onload = img.onerror = null;  
    14.         img = null;  
    15.         delete data[uid];  
    16.     }  
    17.     img.src = url + '&_uid=' + uid;  
    18. };  
        var unique = (function () {
            var time= (new Date()).getTime()+'-', i=0;
            return function () {
               return time + (i++);
            }
        })();
    
        var imgLog = function (url) {
            var data = window['imgLogData'] || (window['imgLogData'] = {});
            var img = new Image();
            var uid = unique();
            img.onload = img.onerror = function () {//销毁一些对象
                img.onload = img.onerror = null;
                img = null;
                delete data[uid];
            }
            img.src = url + '&_uid=' + uid;
        };


     转自 http://blog.csdn.net/fudesign2008/article/details/6772108

  • 相关阅读:
    CMD 下运行python的unittest测试脚本无输出
    Python2 HTMLTestRunner自动化测试报告美化
    Python3 HTMLTestRunner自动化测试报告美化
    Python+Selenium练习篇之5-利用partial link text定位元素
    Python+Selenium练习篇之6-利用class name定位元素
    Python+Selenium练习篇之3-利用tag name定位元素
    Python+Selenium练习篇之4-利用link text定位元素
    Python+Selenium练习篇之2-利用ID定位元素
    Python+Selenium练习篇之1-摘取网页上全部邮箱
    Python+Selenium基础篇之5-第一个完整的自动化测试脚本
  • 原文地址:https://www.cnblogs.com/xd502djj/p/3291064.html
Copyright © 2011-2022 走看看