温馨提示×

Ubuntu Node.js日志中如何分析用户行为

小樊
39
2025-11-14 07:46:10
栏目: 编程语言

Ubuntu 下用结构化日志分析 Node.js 用户行为

一 整体思路与关键指标

  • 采集:在 Node.js 中使用结构化日志库(如 winston、pino、morgan)输出 JSON 日志,便于后续解析与检索。
  • 存储与解析:将日志写入文件并通过 Logstash/Fluentdrsyslog/journald 集中;命令行可用 grep、awk、sed 做快速聚合。
  • 分析维度:围绕核心指标如 PV/UV、登录/注册次数、按钮点击、表单提交、页面停留时间、错误率、响应时间 等展开。
  • 可视化与告警:用 Kibana/Grafana 做图表与看板,配置阈值告警识别异常行为。
  • 运维保障:启用 logrotate 做日志轮转,避免磁盘被占满。

二 日志采集与结构化落地

  • 选型与输出:使用 winston/pino 统一输出 JSON,包含事件名、用户标识、页面/接口、时间戳、状态码、耗时、UA、IP 等必要字段。
  • 示例(winston,记录用户事件与 HTTP 请求):
// 安装:npm i winston morgan
const winston = require('winston');
const express = require('express');
const morgan = require('morgan');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

const app = express();
app.use(express.json());

// HTTP 访问日志(结构化)
app.use(morgan('combined', {
  stream: { write: msg => logger.info({ event: 'http_request', msg }) }
}));

// 业务行为日志
app.post('/login', (req, res) => {
  const { username } = req.body;
  logger.info({
    event: 'login',
    userId: req.headers['x-user-id'] || 'anonymous',
    username,
    ip: req.ip,
    ua: req.headers['user-agent'],
    status: 'success'
  });
  res.json({ ok: true });
});

app.listen(3000, () => logger.info({ event: 'server_start', port: 3000 }));
  • 日志轮转:使用 winston-daily-rotate-file 或系统 logrotate 防止单文件过大。

三 快速分析命令与脚本

  • 统计各页面的浏览次数(假设日志含 event=page_view 且 page 字段为第 3 列)
grep '"event":"page_view"' combined.log | awk '{page=$3; gsub(/"/,"",page); count[page]++}
  END {for(p in count) print p, count[p]}' | sort -nr
  • 统计登录成功次数
grep '"event":"login".*"status":"success"' combined.log | wc -l
  • 统计每分钟请求量(按 timestamp 的分钟聚合)
awk -F'"timestamp":"' '{ts=$2; gsub(/T.*Z/,"",ts); m[ts]++}
  END {for(t in m) print t, m[t]}' combined.log | sort
  • 错误率(5xx 占比,按小时)
awk -F'"status":' '{s=$2; gsub(/,.*/,"",s); if(s~/^5/) err++; total++; }
  END {printf "Error rate: %.2f%%\n", err/total*100}' combined.log
  • 停留时间估算(相邻 page_view 的时间差,按用户)
# 假设日志按时间排序;按 userId + page 分组,计算相邻时间差(秒)
awk -F'"timestamp":"' -F'"userId":"' '
  $2 ~ /T/ {t=$2; sub(/T.*Z/,"",t); gsub(/"/,"",$4); k=$4":"$6;
  if(k in last) dur[k]+=t-last[k]; else dur[k]=0; last[k]=t}
  END {for(k in dur) print k, dur[k]}' combined.log
  • Node.js 脚本聚合页面浏览(处理 JSON 行日志)
// page-views.js
const fs = require('fs');
const readline = require('readline');

const counts = {};
const rl = readline.createInterface({ input: fs.createReadStream('combined.log'), crlfDelay: Infinity });

rl.on('line', line => {
  try {
    const e = JSON.parse(line);
    if (e.event === 'page_view' && e.page) counts[e.page] = (counts[e.page] || 0) + 1;
  } catch {}
});

rl.on('close', () => console.log(counts));
  • 提示:若使用 journald/systemd 托管进程,可用 journalctl -u your-app.service -o json 导出结构化日志后再分析。

四 集中化与可视化方案

  • 方案 A(自建 ELK):Node.js 通过 Logstash TCP/HTTPwinston-logstash 发送 JSON 到 Logstash,写入 Elasticsearch,用 Kibana 建立指标与行为看板(如 PV/UV、漏斗、路径、错误率、Top 页面/接口)。
  • 方案 B(轻量替代):使用 Fluentd/Filebeat → Elasticsearch → Kibana/Grafana,或采用 Graylog/Splunk 做集中管理与告警。
  • 看板建议:
    • 流量趋势(按分钟/小时)、Top 页面与来源、设备/浏览器分布;
    • 关键转化漏斗(访问 → 登录 → 提交)、按钮点击热图;
    • 错误率与慢请求 Top N、API 成功率与延迟 P95/P99。

五 运维与合规要点

  • 日志轮转与保留:配置 logrotatewinston-daily-rotate-file,如按日轮转、压缩、保留 7–14 天,避免磁盘撑满。
  • 隐私与合规:日志中避免记录 密码、身份证号、银行卡号 等敏感信息;必要时进行脱敏或哈希处理。
  • 性能与采样:高并发场景下控制日志级别与采样率,异步写入,避免阻塞业务线程。
  • 监控与告警:对 5xx 比例、登录失败激增、关键接口错误 设置阈值告警,结合 Kibana/Alertmanager 及时响应。

0