开源网站流量统计系统Piwik源码分析——后台处理(二)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介:   在第一篇文章中,重点介绍了脚本需要搜集的数据,而本篇主要介绍的是服务器端如何处理客户端发送过来的请求和参数。

一、设备信息检测


  通过分析User-Agent请求首部(如下图红线框出的部分),可以得到相关的设备信息。

5.jpg


 Piwik系统专门有一套代码用来分析代理信息,还独立了出来,叫做DeviceDetector。它有一个专门的demo页面,可以展示其功能,点进去后可以看到下图中的内容。


6.jpg


  它能检测出浏览器名称、浏览器的渲染引擎、浏览器的版本、设备品牌(例如HTC、Apple、HP等)、设备型号(例如iPad、Nexus 5、Galaxy S5等)、设备类别(例如desktop、smartphone、tablet等),这6类数据中的可供选择的关键字,可以参考“List of segments”或插件的“readme”。顺便说一下,Piwik还能获取到访客的定位信息,在“List of segments”中,列举出了城市、经纬度等信息,其原理暂时还没研究。

  Piwik为大部分设备信息的关键字配备了一个icon图标,所有的icon图标被放置在“plugins\Morpheus\icons”中,包括浏览器、设备、国旗、操作系统等,下图截取的是浏览器中的部分图标。


7.jpg


二、IP地址


  在Piwik系统的后台设置中,可以选择IP地址的获取方式(如下图所示)。在官方博客的一篇《Geo Locate your visitors》博文中提到,3.5版本后可以在系统中嵌入MaxMind公司提供的IP地理定位服务(GeoIP2)。


8.jpg


  下面是一张看官方的产品介绍表,从描述中可看出这是一项非常厉害的服务。不过需要注意的是,这是一项付费服务。

9.png


三、日志数据和归档数据


  在官方发布的说明文档《How Matomo (formerly Piwik) Works》中提到,在Piwik中有两种数据类型:日志数据和归档数据。日志数据(Log Data)是一种原始分析数据,从客户端发送过来的参数就是日志数据,刚刚设备检测到的信息也是日志数据,还有其它的一些日志数据的来源,暂时还没细究。由于日志数据非常巨大,因此不能直接生成最终用户可看的报告,得使用归档数据来生成报告。归档数据(Archive Data)是以日志数据为基础而构建出来的,它是一种被缓存并且可用于生成报告的聚合分析数据。

  日志数据会通过“core\Piwik\Tracker\Visit.php”中的方法保存到数据库中,其中核心的方法如下所示,注释中也强调了该方法中的内容是处理请求的主要逻辑。该方法涉及到了很多对象,以及对象的方法,错综复杂,我自己也没有研究透,只是利用PHPStorm编辑器自动索引,查找出了一些关联,具体细节还有待考证。




/**
 *  Main algorithm to handle the visit.
 *
 *  Once we have the visitor information, we have to determine if the visit is a new or a known visit.
 *
 * 1) When the last action was done more than 30min ago,
 *      or if the visitor is new, then this is a new visit.
 *
 * 2) If the last action is less than 30min ago, then the same visit is going on.
 *    Because the visit goes on, we can get the time spent during the last action.
 *
 * NB:
 *  - In the case of a new visit, then the time spent
 *    during the last action of the previous visit is unknown.
 *
 *    - In the case of a new visit but with a known visitor,
 *    we can set the 'returning visitor' flag.
 *
 * In all the cases we set a cookie to the visitor with the new information.
 */
public function handle() {
    foreach ($this->requestProcessors as $processor) {
        Common::printDebug("Executing " . get_class($processor) . "::manipulateRequest()...");
        $processor->manipulateRequest($this->request);
    }
    $this->visitProperties = new VisitProperties();
    foreach ($this->requestProcessors as $processor) {
        Common::printDebug("Executing " . get_class($processor) . "::processRequestParams()...");
        $abort = $processor->processRequestParams($this->visitProperties, $this->request);
        if ($abort) {
            Common::printDebug("-> aborting due to processRequestParams method");
            return;
        }
    }
    $isNewVisit = $this->request->getMetadata('CoreHome', 'isNewVisit');
    if (!$isNewVisit) {
        $isNewVisit = $this->triggerPredicateHookOnDimensions($this->getAllVisitDimensions() , 'shouldForceNewVisit');
        $this->request->setMetadata('CoreHome', 'isNewVisit', $isNewVisit);
    }
    foreach ($this->requestProcessors as $processor) {
        Common::printDebug("Executing " . get_class($processor) . "::afterRequestProcessed()...");
        $abort = $processor->afterRequestProcessed($this->visitProperties, $this->request);
        if ($abort) {
            Common::printDebug("-> aborting due to afterRequestProcessed method");
            return;
        }
    }
    $isNewVisit = $this->request->getMetadata('CoreHome', 'isNewVisit');
    // Known visit when:
    // ( - the visitor has the Piwik cookie with the idcookie ID used by Piwik to match the visitor
    //   OR
    //   - the visitor doesn't have the Piwik cookie but could be match using heuristics @see recognizeTheVisitor()
    // )
    // AND
    // - the last page view for this visitor was less than 30 minutes ago @see isLastActionInTheSameVisit()
    if (!$isNewVisit) {
        try {
            $this->handleExistingVisit($this->request->getMetadata('Goals', 'visitIsConverted'));
        }
        catch(VisitorNotFoundInDb $e) {
            $this->request->setMetadata('CoreHome', 'visitorNotFoundInDb', true); // TODO: perhaps we should just abort here?
        }
    }
    // New visit when:
    // - the visitor has the Piwik cookie but the last action was performed more than 30 min ago @see isLastActionInTheSameVisit()
    // - the visitor doesn't have the Piwik cookie, and couldn't be matched in @see recognizeTheVisitor()
    // - the visitor does have the Piwik cookie but the idcookie and idvisit found in the cookie didn't match to any existing visit in the DB
    if ($isNewVisit) {
        $this->handleNewVisit($this->request->getMetadata('Goals', 'visitIsConverted'));
    }
    // update the cookie with the new visit information
    $this->request->setThirdPartyCookie($this->request->getVisitorIdForThirdPartyCookie());
    foreach ($this->requestProcessors as $processor) {
        Common::printDebug("Executing " . get_class($processor) . "::recordLogs()...");
        $processor->recordLogs($this->visitProperties, $this->request);
    }
    $this->markArchivedReportsAsInvalidIfArchiveAlreadyFinished();
}


  最后了解一下Piwik的数据库设计,此处只分析与日志数据和归档数据有关的数据表。官方的说明文档曾介绍,日志数据有5张相关的数据表,我对于表的内在含义还比较模糊,因此下面所列的描述还不是很清晰。

(1)log_visit:每次访问都会生成一条访问者记录,表中的字段可参考“Visits”。

(2)log_action:网站上的访问和操作类型(例如特定URL、网页标题),可分析出访问者感兴趣的页面,表中的字段可参考“Action Types”。

(3)log_link_visit_action:访问者在浏览期间执行的操作,表中的字段可参考“Visit Actions”。

(4)log_conversion:访问期间发生的转化(与目标相符的操作),表中的字段可参考“Conversions”。

(5)log_conversion_item:与电子商务相关的信息,表中的字段可参考“Ecommerce items”。

  归档数据的表有两种前缀,分别是“archive_numeric_”和“archive_blob_”,表的字段可参考“Archive data”。通过对字段的观察可知,两种最大的不同就是value字段的数据类型。archive_numeric_* 表中的value能储存数值(数据类型是Double),而archive_blob_* 表中的value能储存出数字以外的其他任何数据(数据类型是Blob)。

  两种表都是动态生成的,因此前缀的后面都用“*”表示。生成规则可按年、月、周、天或自定义日期范围,不设置的话,默认是按月计算,例如archive_numeric_2018_09、archive_blob_2018_09。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
SQL 前端开发 JavaScript
|
15天前
|
开发框架 移动开发 前端开发
为什么说用PageAdmin 网站模版创建官网有优势?
随着网站模版广泛使用,除了一些用户使用网站模版来搭建网站,更有一些建站公司使用网站模版为他人搭建网站,在众多的网站模版厂商,为什么说PageAdmin 网站模版创建官网有一定的优势?
|
1月前
|
数据可视化 前端开发
DIY官网可视化微擎后台 生成后台源码
DIY官网可视化微擎后台 生成后台源码
33 0
|
4月前
|
开发框架 前端开发 JavaScript
若依怎样看开发文档,域名搜这个就行ruoyi.vip,建链接点击在线文档,有前端手册和后端手册,若依文档里有项目扩展,项目扩展有大量的开源的软件
若依怎样看开发文档,域名搜这个就行ruoyi.vip,建链接点击在线文档,有前端手册和后端手册,若依文档里有项目扩展,项目扩展有大量的开源的软件
|
6月前
|
Go
区域代理分红商城系统开发指南教程/步骤功能/方案逻辑/源码项目
The development of regional proxy dividend distribution mall system involves multiple aspects such as proxy dividend function and electronic mall system development. The following is an overview of the steps for developing a regional agent dividend distribution mall system
|
小程序 JavaScript 数据可视化
一分钟搭建小程序管理后台,借助云开发CMS搭建可视化的数据管理网页平台
一分钟搭建小程序管理后台,借助云开发CMS搭建可视化的数据管理网页平台
847 0
|
内存技术
简单系统后台页面开发分享【2020网页综合笔记01】
简单系统后台页面开发分享【2020网页综合笔记01】
112 0
简单系统后台页面开发分享【2020网页综合笔记01】
|
JSON 前端开发 JavaScript
开源网站流量统计系统Piwik源码分析——参数统计(一)
 Piwik现已改名为Matomo,这是一套国外著名的开源网站统计系统,类似于百度统计、Google Analytics等系统。最大的区别就是可以看到其中的源码,这正合我意。因为我一直对统计的系统很好奇,很想知道里面的运行原理是怎么样的,碰巧了解到有这么一个系统,因此马上尝试了一下。国内关于该系统的相关资料比较匮乏,大多是分享怎么安装的,并没有找到有关源码分析的文章。下面先对其做个初步的分析,后面会越来越详细,本人目前的职位是前端,因此会先分析脚本代码,而后再分析后台代码。
开源网站流量统计系统Piwik源码分析——参数统计(一)
|
PHP 开发者
MyCms 自媒体 CMS 系统 v2.7,支持自定义页面
MyCms 是一款基于Laravel开发的开源免费的自媒体博客CMS系统,助力开发者知识技能变现。
142 0
MyCms 自媒体 CMS 系统 v2.7,支持自定义页面