用 Node.js 复盘 Nuxt 3 个人站:把 Nginx 日志洗成内容热度榜
访问日志不只是排错工具。我把来源、路径和访问频次聚合后,找出值得改标题、补内链、上推荐位的文章。

作者
ZHOUYI
个人站跑了一段时间后,我发现只看 PV 很容易自我感动:首页刷新、接口请求、爬虫访问都会把数字抬上去。真正有用的是知道哪些文章有人从搜索进来,哪些页面只被路过一次。于是我决定把 Nginx access log 洗一遍,做成内容热度榜,用来指导标题、内链和推荐位优化。
热度榜不是简单 PV 榜
我把日志拆成三个维度:路径、来源、频次。路径要归一化到文章详情,去掉查询参数和埋点后缀;来源要区分搜索、站内跳转和直接访问;频次则看同一访客或同一天内的重复访问。这样能区分“标题党”和“真正有需求的内容”。同时先过滤静态资源、接口、健康检查,避免噪音淹没结论。
Node.js 逐行读日志,别把大文件读进内存
access.log 会越来越大,所以我用 Node.js 内置的 readline 逐行处理。这里假设日志是常见 combined 格式,请求行里包含方法、路径和协议。不同服务器配置字段可能不同,上线前最好先 tail 几行确认真实格式,以官方文档为准。
const fs = require('fs');
const readline = require('readline');
const rl = readline.createInterface({ input: fs.createReadStream('access.log') });
const stat = new Map();
rl.on('line', (line) => {
const parts = line.split(' ');
const path = parts[6] || '';
const status = parts[8] || '';
if (!path.startsWith('/articles/') || status !== '200') return;
const clean = path.split('?')[0];
stat.set(clean, (stat.get(clean) || 0) + 1);
});
rl.on('close', () => console.log([...stat.entries()].sort((a, b) => b[1] - a[1]).slice(0, 20)));把结果落到 MongoDB 和 Redis
脚本跑完后,我会把每天的热度结果写入 MongoDB,字段包括日期、路径、访问数、搜索来源数。首页推荐位不直接查日志,而是读 Redis 里的榜单缓存。这样既能按周回看趋势,也不会因为流量增加反复扫日志。若后续要做小程序端推荐,也可以复用同一份聚合数据。
- 先过滤 /api、/_nuxt、favicon 和机器人特征,减少误判
- 把同一路径的 query 参数合并,避免 A/B 或埋点参数拆散统计
- 按天聚合后再看周趋势,单日异常先标记,不要急着改内容
复盘后我做了几件小事:给高访问但低停留的文章补目录和内链,把搜索词明显的标题改得更完整,把转化好的文章放进相关推荐。变化不会立竿见影,但至少知道该优化哪里。对独立开发者来说,日志不只是排错材料,它也是低成本的内容运营罗盘。