Ubuntu JS日志中如何追踪用户行为
导读:Ubuntu 环境下追踪 JS 用户行为的落地方案 一 架构与采集要点 前端埋点与日志格式:在浏览器端封装统一的 Logger,按级别输出结构化日志(如 JSON),包含 timestamp、level、userId/page/sessi...
Ubuntu 环境下追踪 JS 用户行为的落地方案
一 架构与采集要点
- 前端埋点与日志格式:在浏览器端封装统一的 Logger,按级别输出结构化日志(如 JSON),包含 timestamp、level、userId/page/sessionId、action、element、url、ua、referrer、duration 等;对页面可见性、点击、输入、路由变化、表单提交等自动采集;页面卸载时用 navigator.sendBeacon 可靠上报,必要时做批量上报与节流;遵循 Do Not Track,避免采集敏感信息(如密码、身份证),对 IP/用户标识 做脱敏与最小化收集。
- 服务端记录与输出:Node.js 使用 winston/pino/morgan 输出结构化日志到文件或标准输出;服务端日志建议包含 requestId、userId/sessionId、ip、ua、method、url、status、duration、referer 等,便于与前端日志串联;为长期运行准备日志轮转与保留策略(如按日轮转、保留 7–14 天)。
- 传输与存储:开发/测试阶段可落盘与控制台并行;生产环境建议接入 ELK(Elasticsearch + Logstash + Kibana) 或 EFK(Elasticsearch + Fluentd + Kibana) 做集中采集、解析、检索与可视化;如运行在 systemd 下,亦可用 journald 收集服务日志并配合文件日志使用。
二 Ubuntu 端日志采集与监控
- 实时查看与检索:使用 tail -f /path/to/app.log 实时跟踪日志;用 grep ‘keyword’ 检索关键事件;用 watch -n 5 ‘grep …’ 定时巡检;对 Node/前端服务,结合 journalctl -u your-service-name -f 查看服务日志流。
- 日志轮转与维护:Node 侧用 winston-daily-rotate-file 做按日/按大小轮转;系统侧可用 logrotate 管理历史文件,避免磁盘被占满。
- 集中式收集:使用 Logstash/Fluentd/Graylog 汇聚多实例日志,统一解析与转发到 Elasticsearch,在 Kibana 建立仪表盘(如活跃用户、热门页面、转化漏斗、错误分布、会话时长)。
三 快速实现示例
- 前端埋点与上报(浏览器)
// logger.js
const Logger = {
levels: {
debug: 0, info: 1, warn: 2, error: 3 }
,
currentLevel: 1,
sessionId: sessionStorage.getItem('sessionId') || (crypto.randomUUID?.() ?? Date.now().toString()),
init() {
if (!sessionStorage.getItem('sessionId')) sessionStorage.setItem('sessionId', this.sessionId);
}
,
log(level, message, data = {
}
) {
if (this.levels[level] <
this.levels[this.currentLevel]) return;
const entry = {
timestamp: new Date().toISOString(),
level,
sessionId: this.sessionId,
page: location.pathname,
url: location.href,
referrer: document.referrer,
ua: navigator.userAgent,
action: message,
...data
}
;
// 开发环境控制台输出
if (process.env.NODE_ENV !== 'production') console[level](entry);
// 生产环境可靠上报
if (navigator.sendBeacon) {
navigator.sendBeacon('/api/log', JSON.stringify(entry));
}
else {
fetch('/api/log', {
method: 'POST', body: JSON.stringify(entry), keepalive: true }
).catch(() =>
{
}
);
}
}
,
info: (m, d) =>
this.log('info', m, d),
warn: (m, d) =>
this.log('warn', m, d),
error: (m, d) =>
this.log('error', m, d)
}
;
Logger.init();
// 自动采集示例
document.addEventListener('click', (e) =>
{
Logger.info('click', {
tagName: e.target.tagName, id: e.target.id, className: e.target.className,
text: (e.target.innerText || '').trim().slice(0, 100),
xpath: getXPath(e.target)
}
);
}
);
function getXPath(el) {
if (el.id) return `//*[@id="${
el.id}
"]`;
if (el === document.body) return '/html/body';
let ix = 0;
const sibs = el.parentNode?.childNodes || [];
for (let i = 0;
i <
sibs.length;
i++) {
const s = sibs[i];
if (s === el) return `${
getXPath(el.parentNode)}
/${
el.tagName}
[${
ix + 1}
]`;
if (s.nodeType === 1 &
&
s.tagName === el.tagName) ix++;
}
return '';
}
- 服务端记录(Node.js + Express + winston)
// server.js
const express = require('express');
const morgan = require('morgan');
const {
createLogger, format, transports }
= require('winston');
require('winston-daily-rotate-file');
const logger = createLogger({
level: 'info',
format: format.combine(format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss' }
), format.json()),
transports: [
new transports.File({
filename: 'error.log', level: 'error' }
),
new DailyRotateFile({
filename: 'app-%DATE%.log', datePattern: 'YYYY-MM-DD', zippedArchive: true,
maxSize: '20m', maxFiles: '14d'
}
),
new transports.Console({
format: format.simple() }
)
]
}
);
const app = express();
app.use(express.json({
limit: '10kb' }
));
app.use(morgan('combined', {
stream: {
write: msg =>
logger.info(msg.trim()) }
}
));
app.post('/api/log', (req, res) =>
{
// 简单校验示例:{
sessionId, action, page, ... }
if (!req.body || !req.body.sessionId || !req.body.action) {
return res.status(400).send('bad request');
}
// 服务端补充字段
const entry = {
...req.body,
ip: req.ip || req.headers['x-forwarded-for'] || '-',
ua: req.headers['user-agent'] || '-',
receivedAt: new Date().toISOString()
}
;
logger.info('frontend_log', entry);
res.status(204).end();
}
);
app.listen(3000, () =>
logger.info('server listening on :3000'));
- 运行与观测
- 启动服务后,在 Ubuntu 终端实时查看:tail -f app-*.log;或用 journalctl -u your-service-name -f 观察服务日志。
- 在 Kibana 建立索引模式(如 logstash-* 或 app-*),创建可视化:按 sessionId 统计会话数、按 action/page 统计点击与访问、按 level 统计错误、按 ip/ua 做分布与趋势。
四 分析与可视化
- 命令行快速洞察:统计访问量 Top N(示例以 Nginx 访问日志的客户端 IP 列为例)
awk '{
print $1}
' access.log | sort | uniq -c | sort -nr | head -20
- 会话与转化:以 sessionId 分组重建用户事件序列,计算页面停留时长、关键步骤转化漏斗、错误前后路径;在 Kibana 构建仪表盘展示活跃用户、热门页面、转化漏斗、错误分布、会话时长与活跃时段。
五 合规与性能建议
- 最小化与脱敏:不采集 密码/身份证/银行卡 等敏感信息;对 IP、邮箱、手机号 做脱敏或哈希;提供明显的 拒绝/关闭追踪 开关并尊重 Do Not Track。
- 可靠性与性能:页面卸载优先用 sendBeacon;高频事件做 节流/防抖 与 批量上报;避免同步阻塞;为日志设置合理 采样率 与 保留期;对日志字段建立 索引 以优化查询性能。
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: Ubuntu JS日志中如何追踪用户行为
本文地址: https://pptw.com/jishu/786245.html
