我的日志文件中有以下示例日志格式
[01/18/2024 23:59:58 job100305.mydomain.com dbmy.db18.import 3823039] {"PREFIX":"ZaoBzgriEBMAIglWABgEZg","LEVEL":"info","MESSAGE":"received\n"}
[01/18/2024 23:59:58 job100129.mydomain.com db.db5.my-route 2423585] {"ELAPSED":"0.036","PREFIX":"ZaoBzgriFH4AJIMBAALvAw","LEVEL":"info","MESSAGE":"finished in 0.036\n","ROUTINGKEY":"mydomain11016.Interface.DistributeManager.InboundDistributor.RemotePutMessageBatch"}
...
所以我有这个日志文件名,例如
mylog-2024-01-19_00001
mylog-2024-01-19_00002
mylog-2024-01-19_00003
....
mylog-2024-01-19_00023
同一文件夹中一天中每小时一个。 这些文件是巨大的文件(例如:每个约 4TB)。所以我很难从这些文件中读取内容。
所以我需要编写一个shell脚本,它应该利用并行命令来解析文件的内容。 我可以从当前机器访问以下机器。
dev1.mydomain.com
dev2.mydomain.com
....
dev10.mydomain.com
我在所有这些机器上都启用了 ssh keygen 交换。这意味着我可以在没有密码的情况下通过 ssh 连接到这些机器。 我的主目录中有 sshlogin 文件,其中包含上述所有域,并配置了应运行多少线程
4/ dev1.mydomain.com
4/ dev2.mydomain.com
...
4/ dev3.mydomain.com
现在我需要一个 shell 脚本,它应该异步触发并行命令来 grep 给定的文本,
我已经尝试过这个脚本。但不确定我做错了什么,它没有产生任何结果。
#!/bin/bash
log_directory="/path/to/log/files" directory
start_date="2024-01-19"
end_date="2024-01-19"
output_file="parsed_logs.txt"
for log_file in $(ls $log_directory/mylog-$start_date*); do
date_part=$(echo $log_file | grep -oP '\d{4}-\d{2}-\d{2}')
if [[ "$date_part" >= "$start_date" && "$date_part" <= "$end_date" ]]; then
dev_server=$(grep "$date_part" ~/sshlogins | awk '{print $2}')
parallel --sshloginfile ~/sshlogins -S $dev_server -j4 "grep 'your_search_pattern' {} >> $output_file" ::: $log_file
fi
done
echo "Parsing completed. Results are stored in $output_file."
您尝试做的事情的一个方面尚不清楚:本地计算机上有什么,远程服务器上有什么?我怀疑这与您的问题有关。
从你的问题来看,听起来一切都在远程服务器上。我不太熟悉使用并行的“通过 ssh 分发”功能,但我相信您的代码尝试在本地运行
parallel
并根据本地计算机上的日志文件夹结构设置并行调用,然后分发已经设置/解决了要在远程服务器上运行的 grep
命令。
为此,您需要本地计算机上远程服务器上日志文件夹目录的“骨架副本”(即与远程服务器具有相同结构和文件名的目录,但所有日志文件都是空的)而不是每个都填充了荒谬的 4 TB 数据)。如果没有这个,您将不会得到任何输出,因为您将循环遍历本地计算机上不存在的目录。
替代解决方案是:
a)运行整个循环,检查日志文件夹目录并在日期范围内循环,并在日志文件夹目录实际存在的远程计算机(例如,通过 ssh)上运行并行命令,或者
b) 通过使用 ssh 查询远程服务器上的日志文件夹目录来设置并行调用。这看起来就像用
ls /path/to/log/dir
替换 ssh user@server 'ls /path/to/log/dir'
。