博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网站流量日志数据自定义采集
阅读量:6409 次
发布时间:2019-06-23

本文共 8883 字,大约阅读时间需要 29 分钟。

分布式集群爬虫小架构

离线hadoop分析数据整体流转图

网站流量日志数据自定义采集

网站流量日志数据自定义采集

1系统的意义

网站流量数据统计分析,可以帮助网站管理员、运营人员、推广人员等获取网站流量信息,并从流量来源、网站内容、网站访客特性等多方面提供网站分析的数据依据。从而帮助提高网站流量,提升网站用户体验,让访客更多的沉淀下来变成会员或客户,通过更少的投入获取最大化的收入。

 

2背景知识—Web 访问日志

访问日志指用户访问网站时的所有访问、浏览、点击行为数据。比如点击了哪一个链接,打开了哪一个页面,采用了哪个搜索项、总体会话时间等。而所有这些信息都可通过网站日志保存下来。通过分析这些数据,可以获知许多对网站运营至关重要的信息。采集的数据越全面,分析就能越精准。

 

日志的生成渠道分为以下两种:

一是:web 服务器软件(httpd、nginx、tomcat)自带的日志记录功能,Nginx

access.log 日志。

 

二是:自定义采集用户行为数据,通过在页面嵌入自定义的 javascript 代码来获取用户的访问行为(比如鼠标悬停的位置,点击的页面组件等),然后通过 ajax 请求到后台记录日志,这种方式所能采集的信息会更加全面。

 

在实际操作中,有以下几个方面的数据可以自定义的采集:  

系统特征:比如所采用的操作系统、浏览器、域名和访问速度等。

访问特征:包括停留时间、点击的 URL、所点击的“页面标签<a>”及标签的属性等。

来源特征:包括来访 URL,来访 IP 等。

产品特征:包括所访问的产品编号、产品类别、产品颜色、产品价格、产品利润、产品数量和特价等级等。

以电商某东为例,其自定义采集的数据日志格式如下:

GET     /log.gif?t=item.010001&m=UA-J2011-1&pin=-&uid=1679790178&sid=1679790178|12&v=je=1$sc=24-bit$sr=1600x900$ul=zh-cn$cs=GBK$dt=【云南白药套装】云南白药 牙膏 180g×3 (留兰香型)【行情 报价 价格评测】-京东$hn=item.jd.com$fl=16.0r0$os=win$br=chrome$bv=39.0.2171.95$wb=1437269412$xb=1449548587$yb=1456186252$zb=12$cb=4$usc=direct$ucp=-$umd=none$uct=-$ct=1456186505411$lt=0$tad=-$sku=1326523$cid1=1316$cid2=1384$cid3=1405$brand=20583$pinid=-&ref=&rm=1456186505411 HTTP/1.1

原理分析

首先,用户的行为会触发浏览器对被统计页面的一个 http 请求,比如打开某网页。当网页被打开,页面中的埋点 javascript 代码会被执行。

 

埋点是指:在网页中预先加入小段javascript代码,这个代码片段一般会动态创建一个script标签,并将src属性指向一个单独的js文件,此时这个单独的js文件(图中绿色节点)会被浏览器请求到并执行,这个js往往就是真正的数据收集脚本。

数据收集完成后,js会请求一个后端的数据收集脚本,这个脚本一般是一个伪装成图片的动态脚本程序,js 会将收集到的数据通过 http 参数的方式传递给后端脚本,后端脚本解析参数并按固定格式记录到访问日志。

   

3设计实现 

根据原理分析并结合Google Analytics,想搭建一个自定义日志数据采集系统,要做以下几件事: 

 

 

3.1确定收集信息

 

名称

途径

备注

访问时间

web server

Nginx $msec

IP

web server

Nginx $remote_addr

域名

javascript

document.domain

URL

javascript

document.URL

页面标题

javascript

document.title

分辨率

javascript

window.screen.height & width

颜色深度

javascript

window.screen.colorDepth

Referrer

javascript

document.referrer

浏览客户端

web server

Nginx $http_user_agent

客户端语言

javascript

navigator.language

访客标识

cookie

 Nginx $http_cookie

网站标识

javascript

自定义对象

状态码

web server

Nginx $status

发送内容量

web server

Nginx $body_bytes_sent 

3.2确定埋点代码 

埋点,是网站分析的一种常用的数据采集方法。核心就是在需要进行数据采集的关键点植入统计代码,进行数据的采集。比如以谷歌分析原型来说,需要在页面中插入一段它提供的javascript片段,这个片段往往被称为埋点代码。 

其中_maq 是全局数组,用于放置各种配置,其中每一条配置的格式为:

_maq.push(['Action', 'param1', 'param2', ...]);

 

_maq 的机制不是重点,重点是后面匿名函数的代码,这段代码的主要目的就是引入一个外部的 js 文件(ma.js),方式是通过 document.createElement 方法创建一个 script 并根据协议(http 或 https)将 src 指向对应的 ma.js,最后将这个元素插入页面的 dom 树上。

 

注意 ma.async = true 的意思是异步调用外部 js 文件,即不阻塞浏览器的解析,待外部 js 下载完成后异步执行。这个属性是 HTML5 新引入的。

 

扩展知识:js 自调用匿名函数格式: (function(){})();

第一对括号向脚本返回未命名的函数;后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。

 

自调用匿名函数的好处是,避免重名,自调用匿名函数只会在运行时执行一次,一般用于初始化。

 

3.3前端数据收集脚本 

数据收集脚本(ma.js)被请求后会被执行,一般要做如下几件事:

1、通过浏览器内置javascript对象收集信息,如页面title(通过document.title)、referrer(上一跳 url,通过 document.referrer)、用户显示器分辨率(通过 windows.screen)、cookie 信息(通过 document.cookie)等等一些信息。

 

2、解析_maq 数组,收集配置信息。这里面可能会包括用户自定义的事件跟踪、业务数据(如电子商务网站的商品编号等)等。

 

3、将上面两步收集的数据按预定义格式解析并拼接(get 请求参数)。

 

4、请求一个后端脚本,将信息放在 http request 参数中携带给后端脚本。

这里唯一的问题是步骤 4,javascript 请求后端脚本常用的方法是 ajax,但是 ajax是不能跨域请求的。一种通用的方法是 js 脚本创建一个 Image 对象,将 Image 对象的 src 属性指向后端脚本并携带参数,此时即实现了跨域请求后端。这也是后端脚本为什么通常伪装成 gif 文件的原因。

 示例代码:

(function () {     var params = {};     //Document对象数据     if(document) {         params.domain = document.domain || '';              params.url = document.URL || '';              params.title = document.title || '';          params.referrer = document.referrer || '';      }    //Window对象数据 if(window && window.screen) {     params.sh = window.screen.height || 0;             params.sw = window.screen.width || 0;     params.cd = window.screen.colorDepth || 0; }    //navigator对象数据if(navigator) {         params.lang = navigator.language || '';  }        //解析_maq配置     if(_maq) {     for(var i in _maq) {         switch(_maq[i][0]) {                             case '_setAccount':                       params.account = _maq[i][1];                       break;                             default:                                   break;             }            }        }    //拼接参数串 var args = '';      for(var i in params) {             if(args != '') {             args += '&';         }            args += i + '=' + encodeURIComponent(params[i]); }       //通过Image对象请求后端脚本 var img = new Image(1, 1);  img.src = 'http://xxx.xxxxx.xxxxx/log.gif?' + args; })();

 

整个脚本放在匿名函数里,确保不会污染全局环境。其中log.gif是后端脚本。

3.4后端脚本 

首先,需要在 nginx 的配置文件中定义日志格式: 

log_format tick  "$msec||$remote_addr||$status||$body_bytes_sent||$u_domain||$u_url| |$u_title||$u_referrer||$u_sh||$u_sw||$u_cd||$u_lang||$http_user_agent||$u_account";

注意这里以 u_开头的是我们待会会自己定义的变量,其它的是 nginx 内置变

量。然后是核心的两个 location:

location / log.gif {     #伪装成gif文件     default_type image/gif;         #本身关闭access_log,通过subrequest记录log         access_log off;        access_by_lua "         -- 用户跟踪cookie名为__utrace         local uid = ngx.var.cookie___utrace                         if not uid then             -- 如果没有则生成一个跟踪cookie,算法为 md5(时间戳+IP+客户端信息)                         uid = ngx.md5(ngx.now() .. ngx.var.remote_addr .. ngx.var.http_user_agent)        end                  ngx.header['Set-Cookie'] = {'__utrace=' .. uid .. '; path=/'}         if ngx.var.arg_domain         then             -- 通过subrequest子请求到/i-log记录日志,将参数和用户跟踪cookie带过去                         ngx.location.capture('/i-log?' .. ngx.var.args .. '&utrace=' .. uid)         end      ";          #此请求资源本地不缓存     add_header Expires "Fri, 01 Jan 1980 00:00:00 GMT";         add_header Pragma "no-cache";     add_header Cache-Control "no-cache, max-age=0, mustrevalidate";     #返回一个1×1的空gif图片     empty_gif; }       location /i-log {     #内部location,不允许外部直接访问         internal;        #设置变量,注意需要unescape,来自ngx_set_misc模块     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_account $arg_account;     #打开日志      log_subrequest on;     #记录日志到ma.log 格式为tick     access_log /path/to/logs/directory/ma.log tick;        #输出空字符串     echo ''; }

要完全掌握这段脚本的每一个细节还是比较吃力的,用到了诸多第三方 ngxin 模块(全都包含在 OpenResty 中了),重点都用注释标出来,可以不用完全理解每一行的意义,只要大约知道这个配置完成了我们提到的后端逻辑就可以了。

   

3.5日志格式 

日志格式主要考虑日志分隔符,一般会有以下几种选择:固定数量的字符、制表符分隔符、空格分隔符、其他一个或多个字符、特定的开始和结束文本。

3.6日志切分 

日志收集系统访问日志时间一长文件变得很大,而且日志放在一个文件不便于管理。通常要按时间段将日志切分,例如每天或每小时切分一个日志。通过

crontab定时调用一个shell脚本实现,如下: 

_prefix="/path/to/nginx" time=`date +%Y%m%d%H` mv ${_prefix}/logs/ma.log ${_prefix}/logs/ma/ma-${time}.log kill -USR1 `cat ${_prefix}/logs/nginx.pid

这个脚本将 ma.log 移动到指定文件夹并重命名为 ma-{yyyymmddhh}.log,

然后向nginx发送USR1信号令其重新打开日志文件。

 

USR1通常被用来告知应用程序重载配置文件, 向服务器发送一个USR1信号将导致以下步骤的发生:停止接受新的连接,等待当前连接停止,重新载入配置文件,重新打开日志文件,重启服务器,从而实现相对平滑的不关机的更改。

 

然后在/etc/crontab 里加入一行:

59  *  *  *  * root/path/to/directory/rotatelog.sh

在每个小时的 59 分启动这个脚本进行日志轮转操作。

   

4系统环境部署 

Nginx服务器安装在node1中。首先服务器中安装依赖 

yum -y install gcc perl pcre-devel openssl openssl-devel

上传LuaJIT-2.0.4.tar.gz并安装LuaJIT 

tar -zxvf LuaJIT-2.0.4.tar.gz -C /usr/local/src/cd /usr/local/src/LuaJIT-2.0.4/ make && make install PREFIX=/usr/local/luajit

设置LuaJIT环境变量 

vi /etc/profileexport LUAJIT_LIB=/usr/local/luajit/libexport LUAJIT_INC=/usr/local/luajit/include/luajit-2.0source   /etc/profile

创建modules文件夹,保存nginx依赖的模块

mkdir -p /usr/local/nginx/modules

上传nginx依赖的模块 

set-misc-nginx-module-0.29.tar.gzlua-nginx-module-0.10.0.tar.gzngx_devel_kit-0.2.19.tar.gzecho-nginx-module-0.58.tar.gz

将依赖的模块直接解压到modules目录 

tar -zxvf lua-nginx-module-0.10.0.tar.gz -C /usr/local/nginx/modules/tar -zxvf set-misc-nginx-module-0.29.tar.gz -C /usr/local/nginx/modules/tar -zxvf ngx_devel_kit-0.2.19.tar.gz -C /usr/local/nginx/modules/tar -zxvf echo-nginx-module-0.58.tar.gz -C /usr/local/nginx/modules/

上传openresty-1.9.7.3.tar.gz并且安装

tar -zxvf openresty-1.9.7.3.tar.gz -C /usr/local/src/cd /usr/local/src/openresty-1.9.7.3/./configure --prefix=/usr/local/openresty --with-luajit && make && make install

上传nginx压缩包并且安装nginx 

tar -zxvf nginx-1.8.1.tar.gz -C /usr/local/src/

编译nginx并支持其他模块 

cd /usr/local/src/nginx-1.8.1/./configure --prefix=/usr/local/nginx \  --with-ld-opt="-Wl,-rpath,/usr/local/luajit/lib" \  --add-module=/usr/local/nginx/modules/ngx_devel_kit-0.2.19 \ --add-module=/usr/local/nginx/modules/lua-nginx-module-0.10.0 \ --add-module=/usr/local/nginx/modules/set-misc-nginx-module-0.29 \ --add-module=/usr/local/nginx/modules/echo-nginx-module-0.58 make -j2make install

node2中安装httpd服务(apache服务器)

yum -y install httpd

备注:如果对linux相关操作不熟,请严格按照上述步骤搭建环境,切记心细,心细,再心细

5、自定义采集数据实现 

 

创建页面index.html,添加埋点代码,放入httpd默认目录/var/www/html下。  

 

在默认目录nginx/html下添加一个数据采集脚本ma.js。

 

修改nginx的配置文件,添加自定义相关业务逻辑。

 

启动nginx (以下命令在nginx的安装目录中执行)

sbin/nginx -c conf/nginx.conf

通过游览器访问nginx

观察自定义日志采集文件是否有对应的内容输出

tail  -F  logs/user_defined.log

此时还可以观察nginx默认的输出日志文件 

tail  -F  logs/access.log

停止nginx: 

sbin/nginx –s stop

 

转载于:https://www.cnblogs.com/daiwei1981/p/9644659.html

你可能感兴趣的文章
rocketmq 消息指定_RocketMQ入坑系列(一)角色介绍及基本使用
查看>>
redis zset转set 反序列化失败_掌握好Redis的数据类型,面试心里有底了
查看>>
p图软件pⅰc_娱乐圈最塑料的夫妻,P图永远只P自己,太精彩了吧!
查看>>
jenkins 手动执行_Jenkins 入门
查看>>
怎么判断冠词用a还是an_葡语干货 | 葡萄牙语冠词用法整理大全
查看>>
js传参不是数字_JS的Reflect学习和应用
查看>>
三个不等_数学一轮复习05,从函数观点看方程与不等式,记住口诀与联系
查看>>
卡尺测量的最小范围_汽车维修工具-测量用具
查看>>
网优5g前景_5G网络优化师前景怎么样?
查看>>
竞态条件的赋值_[译] part25: golang Mutex互斥锁
查看>>
delmatch oracle_完美完全卸载(清除)oracle数据库的方式(方法)
查看>>
pyqt 滚动条 美化_Pyqt5 关于流式布局和滚动条的综合使用示例代码
查看>>
51单机片 编译hex_单片机爬坑记-05-编译环境(完)
查看>>
java 正则表达式 img_Java正则表达式获得html字符串里的<img src=""/> 中的url列表
查看>>
java 文件crc校验_一个获取文件crc32校验码的简洁的java类 | 学步园
查看>>
java flatmapfunction_Java8 Stream flatmap中间操作用法解析
查看>>
java rmi spring 4.0_Java Spring RMI一些尝试
查看>>
JAVA怎么连接华为的HDFS系统_JAVA-API操作HDFS文件系统(HDFS核心类FileSystem的使用)...
查看>>
java牛客网四则运算_数据库刷题—牛客网(51-61)
查看>>
Java get set6_JDK6的新特性(转)
查看>>