我来帮你创建一个自动收集日志的脚本方案,根据不同的场景,我提供以下几种常见实现:

基础Shell脚本(Linux/Unix系统)
#!/bin/bash
# 日志收集脚本 log_collector.sh
# 配置参数
LOG_DIR="/var/log" # 日志目录
OUTPUT_DIR="/tmp/collected_logs" # 输出目录
DATE=$(date +%Y%m%d_%H%M%S)
HOSTNAME=$(hostname)
# 需要收集的日志文件列表
LOG_FILES=(
"/var/log/syslog"
"/var/log/auth.log"
"/var/log/nginx/access.log"
"/var/log/mysql/error.log"
)
# 创建输出目录
mkdir -p ${OUTPUT_DIR}/${DATE}
# 收集日志函数
collect_logs() {
echo "开始收集日志..."
for log_file in "${LOG_FILES[@]}"; do
if [ -f "$log_file" ]; then
cp "$log_file" "${OUTPUT_DIR}/${DATE}/"
echo "已收集: $log_file"
else
echo "警告: $log_file 不存在"
fi
done
}
# 压缩打包
compress_logs() {
echo "正在压缩日志..."
cd ${OUTPUT_DIR}
tar -czf "${HOSTNAME}_logs_${DATE}.tar.gz" ${DATE}/
rm -rf ${DATE}/
echo "日志已打包: ${OUTPUT_DIR}/${HOSTNAME}_logs_${DATE}.tar.gz"
}
# 主函数
main() {
collect_logs
compress_logs
}
# 执行
main
Python脚本(跨平台,功能更强大)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
日志自动收集脚本
支持:本地收集、远程收集、过滤、压缩
"""
import os
import sys
import gzip
import shutil
import logging
import argparse
from datetime import datetime
from pathlib import Path
import subprocess
import json
class LogCollector:
def __init__(self, config_file=None):
self.config = self.load_config(config_file)
self.timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
self.output_dir = Path(self.config.get('output_dir', './collected_logs'))
# 设置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
self.logger = logging.getLogger(__name__)
def load_config(self, config_file):
"""加载配置文件"""
default_config = {
'local_logs': [
'/var/log/syslog',
'/var/log/auth.log',
'/var/log/nginx/access.log'
],
'remote_servers': [],
'output_dir': './collected_logs',
'compress': True,
'max_size': 100 * 1024 * 1024 # 100MB
}
if config_file and Path(config_file).exists():
with open(config_file, 'r') as f:
loaded_config = json.load(f)
default_config.update(loaded_config)
return default_config
def collect_local_logs(self):
"""收集本地日志"""
self.logger.info("开始收集本地日志...")
collected_files = []
for log_path in self.config['local_logs']:
log_file = Path(log_path)
if log_file.exists():
try:
# 检查文件大小
if log_file.stat().st_size > self.config['max_size']:
self.logger.warning(f"{log_path} 超过大小限制,将截取最后部分")
self._tail_log(log_file)
else:
# 复制日志文件
dest = self.output_dir / f"{self.timestamp}_{log_file.name}"
shutil.copy2(log_file, dest)
collected_files.append(dest)
self.logger.info(f"已收集: {log_path}")
except Exception as e:
self.logger.error(f"收集 {log_path} 失败: {e}")
else:
self.logger.warning(f"日志文件不存在: {log_path}")
return collected_files
def _tail_log(self, log_file):
"""截取日志文件尾部"""
try:
# 使用tail命令获取最后部分
result = subprocess.run(
['tail', '-n', '10000', str(log_file)],
capture_output=True,
text=True
)
dest = self.output_dir / f"{self.timestamp}_{log_file.name}.tail"
with open(dest, 'w') as f:
f.write(result.stdout)
self.logger.info(f"已截取尾部日志: {dest}")
except Exception as e:
self.logger.error(f"截取日志失败: {e}")
def collect_remote_logs(self, server_config):
"""收集远程服务器日志(使用SSH)"""
self.logger.info(f"连接远程服务器: {server_config['host']}")
try:
# 创建临时目录
remote_temp = f"/tmp/log_collect_{self.timestamp}"
# SSH命令收集日志
ssh_cmd = f"""
mkdir -p {remote_temp}
for log in {' '.join(server_config['logs'])}; do
if [ -f "$log" ]; then
cp "$log" {remote_temp}/
fi
done
tar -czf /tmp/remote_logs_{self.timestamp}.tar.gz -C {remote_temp} .
rm -rf {remote_temp}
"""
# 执行远程命令
subprocess.run([
'ssh',
f"{server_config['user']}@{server_config['host']}",
ssh_cmd
], check=True)
# 下载压缩包
local_path = self.output_dir / f"remote_{server_config['host']}_{self.timestamp}.tar.gz"
subprocess.run([
'scp',
f"{server_config['user']}@{server_config['host']}:/tmp/remote_logs_{self.timestamp}.tar.gz",
str(local_path)
], check=True)
# 清理远程临时文件
subprocess.run([
'ssh',
f"{server_config['user']}@{server_config['host']}",
f"rm -f /tmp/remote_logs_{self.timestamp}.tar.gz"
])
self.logger.info(f"远程日志收集完成: {local_path}")
except Exception as e:
self.logger.error(f"远程收集失败: {e}")
def compress_output(self):
"""压缩输出目录"""
if not self.config.get('compress', True):
return
self.logger.info("正在压缩日志文件...")
try:
# 打包所有文件
archive_name = f"logs_{self.timestamp}.tar.gz"
archive_path = self.output_dir.parent / archive_name
# 使用tar命令
subprocess.run([
'tar', '-czf', str(archive_path),
'-C', str(self.output_dir.parent),
self.output_dir.name
], check=True)
# 删除原始目录
shutil.rmtree(self.output_dir)
self.logger.info(f"日志已压缩: {archive_path}")
return archive_path
except Exception as e:
self.logger.error(f"压缩失败: {e}")
def filter_logs(self, keyword):
"""过滤日志内容"""
self.logger.info(f"正在过滤包含 '{keyword}' 的日志...")
filtered_dir = self.output_dir / "filtered"
filtered_dir.mkdir(exist_ok=True)
for log_file in self.output_dir.glob("*"):
if log_file.is_file():
filtered_file = filtered_dir / log_file.name
try:
with open(log_file, 'r') as src, open(filtered_file, 'w') as dst:
for line in src:
if keyword in line:
dst.write(line)
self.logger.info(f"过滤完成: {log_file.name}")
except Exception as e:
self.logger.error(f"过滤 {log_file} 失败: {e}")
def create_summary(self):
"""生成收集报告"""
summary_file = self.output_dir / "collection_summary.txt"
with open(summary_file, 'w') as f:
f.write(f"日志收集报告\n")
f.write(f"时间: {datetime.now()}\n")
f.write(f"收集目录: {self.output_dir}\n\n")
f.write("收集的文件:\n")
for log_file in self.output_dir.glob("*"):
if log_file.is_file() and log_file.name != "collection_summary.txt":
size = log_file.stat().st_size
f.write(f" - {log_file.name} ({self._format_size(size)})\n")
self.logger.info(f"报告已生成: {summary_file}")
def _format_size(self, size):
"""格式化文件大小"""
for unit in ['B', 'KB', 'MB', 'GB']:
if size < 1024:
return f"{size:.2f} {unit}"
size /= 1024
return f"{size:.2f} TB"
def execute(self):
"""执行收集流程"""
try:
# 创建输出目录
self.output_dir.mkdir(parents=True, exist_ok=True)
# 收集本地日志
local_files = self.collect_local_logs()
# 收集远程日志
for server in self.config.get('remote_servers', []):
self.collect_remote_logs(server)
# 生成报告
self.create_summary()
# 压缩
result = self.compress_output()
self.logger.info("日志收集完成!")
return result
except Exception as e:
self.logger.error(f"收集过程出错: {e}")
return None
def main():
parser = argparse.ArgumentParser(description='日志自动收集工具')
parser.add_argument('-c', '--config', help='配置文件路径')
parser.add_argument('-k', '--keyword', help='过滤关键词')
parser.add_argument('--no-compress', action='store_true', help='不压缩')
args = parser.parse_args()
collector = LogCollector(args.config)
if args.no_compress:
collector.config['compress'] = False
result = collector.execute()
if args.keyword and result:
collector.filter_logs(args.keyword)
if result:
print(f"日志已保存至: {result}")
else:
print("日志收集失败")
sys.exit(1)
if __name__ == "__main__":
main()
配置文件示例 (config.json)
{
"local_logs": [
"/var/log/syslog",
"/var/log/auth.log",
"/var/log/nginx/access.log",
"/var/log/mysql/error.log",
"/var/log/apache2/access.log"
],
"remote_servers": [
{
"host": "192.168.1.100",
"user": "admin",
"logs": ["/var/log/syslog", "/var/log/nginx/access.log"]
}
],
"output_dir": "/data/collected_logs",
"compress": true,
"max_size": 104857600
}
定时执行(Crontab配置)
# 每天凌晨2点执行日志收集 0 2 * * * /usr/local/bin/log_collector.sh # 使用Python脚本,每周一执行 0 2 * * 1 /usr/bin/python3 /path/to/log_collector.py -c /path/to/config.json # 每小时收集一次(需要调整配置) 0 * * * * /usr/local/bin/log_collector.sh
日志轮转插件(可选)
# log_rotation.py - 日志轮转管理
import os
import time
from pathlib import Path
class LogRotation:
def __init__(self, log_dir, max_age_days=30):
self.log_dir = Path(log_dir)
self.max_age = max_age_days * 86400 # 转换为秒
def cleanup_old_logs(self):
"""清理过期的日志文件"""
current_time = time.time()
for log_file in self.log_dir.glob("*.tar.gz"):
file_age = current_time - log_file.stat().st_mtime
if file_age > self.max_age:
log_file.unlink()
print(f"已删除过期日志: {log_file}")
使用说明
-
安装依赖(Python版本):
pip install paramiko # 如果需要SSH连接
-
赋予执行权限:
chmod +x log_collector.sh chmod +x log_collector.py
-
运行脚本:
# Shell版本 ./log_collector.sh
Python版本
python3 log_collector.py python3 log_collector.py -c config.json # 使用配置文件 python3 log_collector.py -k "ERROR" # 过滤ERROR级别日志
4. **设置定时任务**:
```bash
crontab -e
# 添加定时任务
这个脚本方案具有以下特点:
- 支持本地和远程日志收集
- 可配置日志文件列表
- 自动压缩打包
- 日志过滤功能
- 生成收集报告
- 支持定时执行
- 错误处理和日志记录
你可以根据具体需求调整配置和功能。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播