apache access_log需结合java解析才能统计pv和uv:pv按有效get请求计数(过滤静态资源且状态码为2xx),uv基于cookie中的用户id(优先)或ip去重,需注意nat场景偏差及日志轮转、压缩、时区等细节。

Apache的access_log本身不直接区分PV(页面浏览量)和UV(独立访客),但结合Java程序解析日志,可以较准确地统计这两项核心指标。关键在于理解日志字段含义、合理定义PV/UV口径,并用Java高效处理日志行。
明确PV与UV的统计逻辑
PV按每次HTTP请求计数(通常过滤掉静态资源如CSS/JS/图片可更贴近“页面”概念);UV则需基于客户端标识去重,最常用的是remote_addr(IP)或cookie中的用户ID(如JSESSIONID或自定义跟踪ID)。仅用IP存在局域网NAT场景下低估UV的风险,有登录体系时优先使用业务用户ID。
解析access_log的关键字段
典型Apache Combined日志格式示例:
192.168.1.100 - - [10/Jan/2024:14:23:05 +0800] "GET /article/123 HTTP/1.1" 200 3421 "https://example.com/home" "Mozilla/5.0..." "JSESSIONID=ABC123"
Java中可用正则或Apache Commons Logging工具类提取以下字段:
- remote_addr:客户端IP(用于基础UV)
- request_line:含HTTP方法、URL、协议(用于识别页面路径及过滤资源)
- status:HTTP状态码(建议只统计2xx响应,排除失败请求)
- cookie:从请求头或日志扩展字段提取(如%{Cookie}i),用于获取JSESSIONID或uid
用Java实现轻量统计(示例逻辑)
无需引入大数据框架,用Java 8+ Stream + Map即可完成日志分析:
- 逐行读取access_log(推荐BufferedReader,避免内存溢出)
- 对每行做正则匹配,提取IP、URL、状态码、Cookie值
- PV计数:满足
method == "GET"、status.startsWith("2")、且url.endsWith(".html") || url matches "/article/\d+"等页面规则 - UV计数:将有效访问的
uid(优先)或ip存入ConcurrentHashMap或HashSet,最后取size - 支持时间窗口:解析日期字段,用LocalDateTime比对起止时间,实现按天/小时统计
注意事项与优化建议
真实场景中需注意:
- 日志轮转:处理.gz压缩日志需用GZIPInputStream;多文件需遍历目录
- 性能:单机分析大日志(>1GB)建议分批+并行Stream,或改用Logstash+ES方案
- 准确性:爬虫流量可通过User-Agent黑名单过滤(如"bot"、"spider")
- 一致性:确保时区与Apache配置一致(
LogFormat "%t"默认为服务器本地时区)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










