1. 背景需求
访问日志是目前web server,proxy最常用的问题跟踪、统计分析的源头。所以尽管由于IO,产生访问日志对系统的的影响很大(据客户的实际反馈,因打开访问日志,系统性能有50%以上的损耗),但在正式的上线环境中应该尽量打开访问日志。然后,产生的日志作为源头,会被输出到ES等统一的日志平台进行分析处理,或被各式各样的日志分析工具进行分析。比如一款开源的基于c编写的日志分析工具goaccess,就可以既在命令行下使用,也提供HTML格式的报表。
其产生的报表可以有命令行的:
或 html格式的:
以上图片来源于:https://goaccess.io/
当然,NJet针对落盘影响性能这个问题也做了很多优化,比如:
- 动态配置访问日志,仅仅在某个具体的访问url,仅仅在分析故障阶段打开,并在分析定位完成后尽快关闭;
- 动态输出日志到远端,避免磁盘IO的影响。但这个优化是减少了IO,也少输出了记录,影响了用户分析自己的网站的完整性。
在分析了goaccess的代码后,我们觉得,可以把NJet和goaccess结合起来,由NJet直接把访问记录提供给goaccess,复用goaccess经历社区需求验证的分析报表。这样即提供了丰富的分析报表,又避免了IO对性能的影响。
2. 实现简介
2.1 架构设计
goaccess原使用基于堆内存的hash存储报表数据,修改为共享内存存储。NJet 的工作进程在一个HTTP请求完成后,直接产生符合goaccess要求的统计信息计入共享内存中。
同时goaccess作为一个单独的CoPilot嵌入NJet中,并对外提供数据的实时更新。
运维人员通过NJet的统一的控制面端口访问,获得实时的报表。
2.2 相关指令
Syntax: | access_log_zone name size. |
---|---|
Default: | — |
Context: | NJT_HTTP_MAIN_CONF |
- name: 共享内存的名字。
- size: 共享内存大小。
例如: access_log_zone abc 1m
;
Syntax: | access_log_zone_valid days |
---|---|
Default: | — |
Context: | NJT_HTTP_MAIN_CONF |
- days: 统计日志保存的天数。
例如: access_log_zone_valid 3
;
2.3 配置文件变更
2.3.1 数据面
njet.conf中需要 在main节新增加CoPilot配置,及加载so:
helper access_data modules/njt_helper_access_data_module.so conf/goaccess.conf;
load_module modules/njt_http_access_log_zone_module.so;
在html节增加zone相关的配置
access_log_zone log_zone 100m;
access_log_zone_valid 3;
2.3.2 控制面
在njet_ctr中新增加goaccess报表的访问路径
location /report/ {
root html;
}
location /ws {
proxy_pass http://127.0.0.1:7890;
}
2.3.3 goaccess.conf
output html/report/report.html
real-time-html true
3. 测试
在如下的测试场景中,NJet部署在机器i192.168.40.139,其监听8080,控制面端口8081
load_module modules/njt_http_sendmsg_module.so;
load_module modules/njt_ctrl_config_api_module.so;
load_module modules/njt_helper_health_check_module.so;
load_module modules/njt_http_upstream_api_module.so;
load_module modules/njt_http_location_api_module.so;
load_module modules/njt_http_dyn_server_api_module.so;
load_module modules/njt_doc_module.so;
load_module modules/njt_http_vtsd_module.so;
load_module modules/njt_http_ssl_api_module.so;
#load_module modules/njt_stream_stsd_module.so;
#load_module modules/njt_http_lua_module.so;
error_log logs/error_ctrl.log debug;
events {
worker_connections 1024;
}
http {
include mime.types;
access_log off;
server {
listen 8081;
location / {
return 200 "njet control panel\n";
}
location /api {
dyn_module_api;
}
location /doc {
doc_api;
}
location /report/ {
root html;
}
location /ws {
proxy_pass http://127.0.0.1:7890;
}
location /metrics {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
}
}
conf/goaccess.conf
output html/report/report.html
real-time-html true
测试结果:
在访问server(8080)一段时间后,可以通过控制面端口(http://192.168.40.139:8081/report/report.html)查看报表信息
其他说明
- CoPilot,控制面、数据面等概念请参考用户指南中NJet架构说明
- 感谢goaccess提供的丰富访问日志报表
- 由于不再处理日志文件,报表页面展现的某些数据是无效的,如日志分析的字节数等。
- 本功能在3.0.1起支持
- 目前统计数据尚没有持久化,重启会丢失,会在下一个版本中解决