ubuntu

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

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

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

一 整体思路与关键指标

二 日志采集与结构化落地

// 安装: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 }));

三 快速分析命令与脚本

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
awk -F'"timestamp":"' '{ts=$2; gsub(/T.*Z/,"",ts); m[ts]++}
  END {for(t in m) print t, m[t]}' combined.log | sort
awk -F'"status":' '{s=$2; gsub(/,.*/,"",s); if(s~/^5/) err++; total++; }
  END {printf "Error rate: %.2f%%\n", err/total*100}' combined.log
# 假设日志按时间排序;按 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
// 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));

四 集中化与可视化方案

五 运维与合规要点

0
看了该问题的人还看了