插件窝 干货文章 如何用JS统计Linux日志数据

如何用JS统计Linux日志数据

const 使用 日志 ERROR 808    来源:    2025-05-07

使用JavaScript统计Linux日志数据

要在JavaScript中统计Linux日志数据,有几种主要方法可以实现。以下是几种常见方案:

1. 使用Node.js直接读取日志文件

const fs = require('fs');
const readline = require('readline');

async function analyzeLogFile(filePath) {
  const fileStream = fs.createReadStream(filePath);
  const rl = readline.createInterface({
    input: fileStream,
    crlfDelay: Infinity
  });

  const stats = {
    errorCount: 0,
    warningCount: 0,
    infoCount: 0,
    ipAddresses: new Map(),
    httpStatusCodes: new Map()
  };

  for await (const line of rl) {
    // 统计错误级别
    if (line.includes('ERROR')) stats.errorCount++;
    if (line.includes('WARNING')) stats.warningCount++;
    if (line.includes('INFO')) stats.infoCount++;

    // 提取IP地址统计
    const ipMatch = line.match(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/);
    if (ipMatch) {
      const ip = ipMatch[0];
      stats.ipAddresses.set(ip, (stats.ipAddresses.get(ip) || 0) + 1);
    }

    // 提取HTTP状态码
    const httpStatusMatch = line.match(/\s(\d{3})\s/);
    if (httpStatusMatch) {
      const status = httpStatusMatch[1];
      stats.httpStatusCodes.set(status, (stats.httpStatusCodes.get(status) || 0) + 1);
    }
  }

  return stats;
}

// 使用示例
analyzeLogFile('/var/log/nginx/access.log')
  .then(stats => console.log(stats))
  .catch(err => console.error(err));

2. 使用日志分析工具结合Node.js

方案1: 使用grep预处理日志

const { exec } = require('child_process');

// 使用grep预处理日志
exec('grep "ERROR" /var/log/syslog | wc -l', (error, stdout, stderr) => {
  if (error) {
    console.error(`exec error: ${error}`);
    return;
  }
  console.log(`Number of ERROR entries: ${stdout}`);
});

方案2: 使用awk预处理数据

const { exec } = require('child_process');

exec('awk \'{print $1}\' /var/log/nginx/access.log | sort | uniq -c | sort -nr', 
  (error, stdout, stderr) => {
    if (error) {
      console.error(`exec error: ${error}`);
      return;
    }
    console.log('Top IP addresses:');
    console.log(stdout);
});

3. 使用专门的日志分析库

使用winston分析日志

const winston = require('winston');
const { ElasticsearchTransport } = require('winston-elasticsearch');

// 配置日志传输到Elasticsearch
const esTransport = new ElasticsearchTransport({
  level: 'info',
  clientOpts: { node: 'http://localhost:9200' }
});

const logger = winston.createLogger({
  transports: [esTransport]
});

// 然后可以使用Elasticsearch的聚合查询进行统计分析

4. 浏览器端分析(需先传输日志数据)

如果需要在浏览器中分析,可以先使用Node.js处理后端日志数据,然后通过API提供给前端:

// 后端API端点
const express = require('express');
const app = express();
const logStats = require('./logAnalyzer'); // 假设这是你的分析模块

app.get('/api/log-stats', async (req, res) => {
  try {
    const stats = await logStats.getStats();
    res.json(stats);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.listen(3000, () => console.log('Server running on port 3000'));
// 前端使用fetch获取数据
fetch('/api/log-stats')
  .then(response => response.json())
  .then(data => {
    // 使用Chart.js等库可视化数据
    console.log('Log statistics:', data);
    renderCharts(data);
  });

5. 实时日志监控

使用Node.js的tail命令实现实时监控:

const { spawn } = require('child_process');
const tail = spawn('tail', ['-f', '/var/log/syslog']);

tail.stdout.on('data', (data) => {
  const lines = data.toString().split('\n');
  lines.forEach(line => {
    if (line) console.log('New log entry:', line);
    // 这里可以添加实时分析逻辑
  });
});

tail.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});

tail.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

注意事项

  1. 文件权限:确保Node.js进程有权限读取日志文件
  2. 日志轮转:处理日志轮转(如logrotate)的情况
  3. 大文件处理:对于大日志文件,使用流式处理避免内存问题
  4. 性能考虑:对于高频日志,考虑使用更高效的语言如Go或Rust处理

以上方法可以根据你的具体需求和环境选择最适合的方案。