由于不想安装日志分析软件,所以我就想自己弄个 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 放到指标。
另外我这个方法有没有什么问题呢?或者大家有没有什么建议?
请大家指出、建议,集思广益,也算是丰富网络资料,方便以后需要的小站长参考。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.