服务器问答

把 Nginx access_log 接入 Google Analytics 的方法和几个问题
0
2021-05-19 21:16:04
idczone

由于不想安装日志分析软件,所以我就想自己弄个 access_log 分析,经过一段时间折腾,发现要做个与第三方统计平台相当的分析系统的工作量还是挺大的。然后我就放弃自建了,计划把数据接入统计平台。

说到统计平台,百度统计在功能上足以满足我,而且实时性高,但百度统计没有 HTTP API 给提交自定义数据,遂放弃。后选择 Google Analytics,虽实时性不如百度,但有 Measurement Protocol 接口,功能更丰富。

我服务器软件是 Nginx + ngx_lua ,找了一下,目前网上还没有比较靠谱的接入教程,都是通过 post_action 或者 mirror 实现数据提交,缺点较多,比如受 location 段影响 ,比如不能获取到 ngx_lua 处理后的 headers 等。

所以我研究并用了个新方法,这里分享给各小站长作为参考。

我的方法

1、通过 lua_shared_dict 设置一个内存空间。

2、在 Nginx http 加一段 log_by_lua 代码,内容是把 Analytics 需要的字段包装好和一个时间戳通过 ngx.shared.DICT.rpush 存到内存数组最后。

3、在 Nginx http 加一段 init_worker_by_lua 代码,内容是通过 ngx.timer.every 创建一个每秒执行一次的定时任务,回调函数内容是通过 ngx.shared.DICT.lpop 在内存数组里取出最前面的数据,循环取出 20 条,每条都通过时间戳计算出距离当前秒数,作为 qt 参数附加到提交内容里,然后通过 resty.http 提交 Analytics 接口。

特点

数据字段是在 log_by_lua 阶段生成的,不受 location 匹配的影响,不需要动具体的 server 配置。而且几乎可以取到所有数据用来提交,比如可能被 lua filter 改变的 http status,request_time,bytes_sent 等。注:非 HTTP GET 请求也有 log 阶段,所以处理代码需要判断 ngx.var.request_uri 是否 nil 和 ngx.var.request_method 是否 GET。

提交数据先通过 lua_shared_dict 存到内存再异步读出来提交,可以实现一次提交多条,比每一个请求都提交一次的做法节省资源。注:定期提交造成的时间差通过 qt 参数修正,Analytics 允许最大 4 个小时的修正。

数据生成时把 ngx.var.host 用作 dh 域名参数,把 ngx.var.sent_http_content_type、ngx.var.status 等用作 cd 维度参数,可以在 Analytics 依据这些内容创建不同数据视图,比如特定域名、特定文件类型、特定服务器、特定 HTTP 状态的数据视图,如果不过滤那就是所有服务器所有请求的总数据视图。

我的问题

Analytics 数据量限制说标准帐号每天发送会话限制 20 万,超过了延迟处理或不处理,但一个会话可以有多个匹美国服务器配。浏览器的 analytics.js 怎么计算会话我知道,一个浏览器打开就是一个会话,期间用户导致发送的每一条命中数据就是匹配。

那么通过 Measurement Protocol 发送数据该怎么计算会话呢?是按数据里的客户端 cid,用户 uid,IP 替换 uip ?抑或就是请求接口的本地 IP 地址?

像 http_status、content_type、bytes_sent 这三个大家会放到维度还是指标呢?我目前的选择是前两个放到维度,bytes_sent 放到指标。

另外我这个方法有没有什么问题呢?或者大家有没有什么建议?

请大家指出、建议,集思广益,也算是丰富网络资料,方便以后需要的小站长参考。


发现要做个与第三方统计平台相当的分析系统的工作量还是挺大的???
Matomo 开源统计程序欢迎你。PHP Yes !

这我倒没想到。。。一开始想着有几条统计 SQL 够了,最近受灾影响需要比较多维度的统计发现不够用,然后试着写,感觉工作量太大了,然后就开始找统计平台,没想过找现成的开源程序。。。
现在 Google Analytics 够用了,以后需要自建的时候就试试你推荐的。PHP Yes !我之前的数据入库和查询也是 PHP 写的。

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服