怎么用脚本监控文本文件增长

wen 实用脚本 1

本文目录导读:

怎么用脚本监控文本文件增长

  1. Python 脚本监控
  2. Bash Shell 脚本
  3. Node.js 脚本
  4. Go 语言版本
  5. 实用技巧
  6. 使用建议

Python 脚本监控

基础版(实时监控新增内容)

#!/usr/bin/env python3
import time
import os
def monitor_file(filepath, callback=None):
    """监控文件新增内容"""
    # 获取文件初始大小
    file_size = os.path.getsize(filepath)
    print(f"开始监控 {filepath},当前大小: {file_size} 字节")
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            # 跳到文件末尾
            f.seek(file_size)
            while True:
                # 读取新增内容
                line = f.readline()
                if line:
                    if callback:
                        callback(line)
                    else:
                        print(line, end='')
                else:
                    # 检查文件是否被截断(变小)
                    current_size = os.path.getsize(filepath)
                    if current_size < file_size:
                        print(f"\n文件被截断,重置位置...")
                        f.seek(0)
                        file_size = current_size
                    time.sleep(0.1)
    except FileNotFoundError:
        print(f"文件 {filepath} 不存在")
    except KeyboardInterrupt:
        print("\n监控停止")
# 自定义回调函数
def process_line(line):
    if 'ERROR' in line:
        print(f"[错误] {time.ctime()}: {line}", end='')
if __name__ == "__main__":
    monitor_file("/path/to/your/file.log", process_line)

高级版(带统计功能)

#!/usr/bin/env python3
import time
import os
import sys
from collections import Counter
from datetime import datetime
class FileMonitor:
    def __init__(self, filepath):
        self.filepath = filepath
        self.initial_size = os.path.getsize(filepath)
        self.total_lines = 0
        self.keyword_counts = Counter()
        self.start_time = time.time()
    def monitor(self, keywords=None):
        """监控文件增长并统计"""
        with open(self.filepath, 'r', encoding='utf-8') as f:
            f.seek(self.initial_size)
            while True:
                line = f.readline()
                if line:
                    self.total_lines += 1
                    self.process_line(line, keywords)
                else:
                    self.display_stats()
                    time.sleep(1)
    def process_line(self, line, keywords):
        """处理每一行"""
        if keywords:
            for keyword in keywords:
                if keyword in line:
                    self.keyword_counts[keyword] += 1
    def display_stats(self):
        """显示统计信息"""
        os.system('clear')  # 或 'cls' 在Windows
        elapsed = time.time() - self.start_time
        file_size = os.path.getsize(self.filepath)
        print(f"= 文件监控报告 =")
        print(f"文件: {self.filepath}")
        print(f"运行时间: {elapsed:.1f} 秒")
        print(f"当前文件大小: {file_size} 字节")
        print(f"新增内容: {file_size - self.initial_size} 字节")
        print(f"新增行数: {self.total_lines}")
        print(f"当前时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        if self.keyword_counts:
            print("\n关键词统计:")
            for keyword, count in self.keyword_counts.most_common():
                print(f"  {keyword}: {count}次")
# 使用示例
if __name__ == "__main__":
    monitor = FileMonitor("/var/log/syslog")
    monitor.monitor(keywords=["ERROR", "WARNING", "INFO"])

Bash Shell 脚本

简单版(tail 命令)

#!/bin/bash
# 监控文件增长(类似 tail -f)
tail -f /var/log/syslog

增强版 Bash 脚本

#!/bin/bash
LOG_FILE="/path/to/your/file.log"
PATTERN="ERROR"
echo "开始监控 $LOG_FILE"
echo "搜索模式: $PATTERN"
# 使用 tail -f 并过滤
tail -f "$LOG_FILE" | while read line; do
    # 时间戳
    timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    # 检查是否匹配模式
    if echo "$line" | grep -qi "$PATTERN"; then
        echo "[$timestamp] 匹配: $line"
    else
        echo "[$timestamp] $line"
    fi
    # 可选:执行其他命令
    # echo "$line" | grep "$PATTERN" >> matched_lines.log
done

带轮转处理

#!/bin/bash
LOG_FILE="/var/log/application.log"
LAST_SIZE=0
CHECK_INTERVAL=2  # 秒
# 获取初始大小
if [ -f "$LOG_FILE" ]; then
    LAST_SIZE=$(stat -c%s "$LOG_FILE")
else
    echo "文件不存在: $LOG_FILE"
    exit 1
fi
echo "开始监控,初始大小: $LAST_SIZE 字节"
while true; do
    sleep $CHECK_INTERVAL
    # 检查文件是否存在
    if [ ! -f "$LOG_FILE" ]; then
        echo "文件被删除或轮转!"
        # 等待文件重建
        while [ ! -f "$LOG_FILE" ]; do
            sleep 1
        done
        LAST_SIZE=0
        echo "文件重新创建,继续监控..."
        continue
    fi
    CURRENT_SIZE=$(stat -c%s "$LOG_FILE")
    # 检查文件是否被截断(大小变小)
    if [ $CURRENT_SIZE -lt $LAST_SIZE ]; then
        echo "检测到日志轮转,重置位置"
        LAST_SIZE=$CURRENT_SIZE
        continue
    fi
    # 如果有新内容
    if [ $CURRENT_SIZE -gt $LAST_SIZE ]; then
        # 读取新增部分
        tail -c $((CURRENT_SIZE - LAST_SIZE)) "$LOG_FILE"
        LAST_SIZE=$CURRENT_SIZE
    fi
done

Node.js 脚本

const fs = require('fs');
const readline = require('readline');
class LogMonitor {
    constructor(filepath) {
        this.filepath = filepath;
        this.currentPosition = fs.existsSync(filepath) 
            ? fs.statSync(filepath).size 
            : 0;
        this.keywords = ['ERROR', 'WARNING'];
    }
    start() {
        console.log(`开始监控 ${this.filepath}`);
        // 每100ms检查一次
        setInterval(() => this.checkForUpdates(), 100);
    }
    checkForUpdates() {
        if (!fs.existsSync(this.filepath)) {
            console.log('文件不存在');
            return;
        }
        const stats = fs.statSync(this.filepath);
        // 检测文件截断
        if (stats.size < this.currentPosition) {
            console.log('文件被截断,重置位置');
            this.currentPosition = 0;
        }
        // 读取新增内容
        if (stats.size > this.currentPosition) {
            const stream = fs.createReadStream(this.filepath, {
                start: this.currentPosition,
                end: stats.size - 1
            });
            const rl = readline.createInterface({ input: stream });
            rl.on('line', (line) => {
                this.processLine(line);
            });
            rl.on('close', () => {
                this.currentPosition = stats.size;
            });
        }
    }
    processLine(line) {
        const timestamp = new Date().toISOString();
        // 检查关键词
        for (const keyword of this.keywords) {
            if (line.includes(keyword)) {
                console.log(`[${timestamp}] [${keyword}] ${line}`);
                return;
            }
        }
        // 或直接输出
        console.log(`[${timestamp}] ${line}`);
    }
}
// 使用
const monitor = new LogMonitor('/var/log/app.log');
monitor.start();

Go 语言版本

package main
import (
    "fmt"
    "os"
    "time"
)
func main() {
    filepath := "/var/log/app.log"
    // 获取初始大小
    fileInfo, err := os.Stat(filepath)
    if err != nil {
        fmt.Println("文件不存在")
        return
    }
    lastSize := fileInfo.Size()
    fmt.Printf("开始监控 %s, 初始大小: %d\n", filepath, lastSize)
    for {
        // 每2秒检查一次
        time.Sleep(2 * time.Second)
        fileInfo, err = os.Stat(filepath)
        if err != nil {
            fmt.Println("文件被删除")
            continue
        }
        currentSize := fileInfo.Size()
        // 检测轮转
        if currentSize < lastSize {
            fmt.Println("检测到日志轮转")
            lastSize = 0
        }
        // 读取新增内容
        if currentSize > lastSize {
            file, _ := os.Open(filepath)
            defer file.Close()
            buffer := make([]byte, currentSize-lastSize)
            file.Seek(lastSize, 0)
            file.Read(buffer)
            fmt.Printf("[%s] %s", time.Now().Format("2006-01-02 15:04:05"), buffer)
            lastSize = currentSize
        }
    }
}

实用技巧

实时显示在Web界面

# 简单的Web监控
from flask import Flask, Response
import time
app = Flask(__name__)
@app.route('/monitor')
def stream():
    def generate():
        with open("/var/log/app.log", "r") as f:
            f.seek(0, 2)  # 跳到末尾
            while True:
                line = f.readline()
                if line:
                    yield f"data: {line}\n\n"
                else:
                    time.sleep(1)
    return Response(generate(), mimetype="text/event-stream")
if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

使用建议

  1. 生产环境:使用 Python 或 Go 脚本,稳定性好
  2. 快速调试:使用 Bash + tail -f
  3. 跨平台需求:Python 是最佳选择
  4. 高并发场景:Go 语言性能最好
  5. 实时统计:添加关键词计数和统计分析

选择哪种方案取决于你的具体需求(监控频率、是否需要统计、部署环境等)。

抱歉,评论功能暂时关闭!