syslog
ここでは、ファイルをより小さな塊に分割しようとしています。これを行うには、次のスクリプトを使用します。
#!/bin/bash
date=$(date +%Y%m%d_%H%M)
cp /path/to/sys.log /path/to/chuck/file.log
cat /dev/null > /path/to/sys.log
cp /path/to/chuck/file.log /path/to/chuck/file_"$date".log
cat /dev/null > /path/to/chuck/file.log
スクリプトは5分ごとに実行され、それをsyslog
より小さなログに分割して追加の処理に使用します。問題は、元のファイルとチャンクファイル
にいくつかの履歴がありません。syslog
この問題を解決する方法はありますか?
ここでチャンクファイルは約2GBです。syslog
成長しています。
答え1
警告する:これは小さな最大サイズとimfile
入力モジュールがあったため、バージョン8.2002では完全には機能しませんでした。一部のデータはログファイルから失われますが、ドキュメントでは通常小さなバッファサイズはサポートされていないことを警告します。
rsyslogを使用すると、ログファイルが特定のサイズを超えると回転する組み込みメカニズムが提供されます。あなたはただ チャンネル、ファイル名、最大サイズ、サイズを超えた場合に実行するスクリプト名を指定します。それから 使用 ファイル名の代わりにフィルタのチャネル名です。
たとえば、ファイル/home/me/rotatescript
が作成された50Mibytesを超えるとスクリプトを実行するには、/var/log/mylog
次の名前のチャンネルを作成しますmylogrotatechan
。
$outchannel mylogrotatechan,/var/log/mylog,52428800,/home/me/rotatescript
そして*.* /var/log/mylog
に交換
*.* :omfile:$mylogrotatechan
文書化されていないRainerScript構文を使用する最新のソース(2023年1月)には、テストスクリプトもあります。
action(type="omfile" file="/var/log/mylog" rotation.sizeLimit="52428800"
rotation.sizeLimitCommand="/home/me/rotatescript")
一般的なスクリプトは次のとおりです。
#!/bin/bash
mv /var/log/mylog /var/log/mylog.$(date +%Y%m%d.%H%M%S)
答え2
私はPerlを使用します。ファイル::尾この目的のために(私は監視する必要があるほとんどすべて、つまり連続テールログファイルに使用します)。
#!/usr/bin/perl
# File::Tail need to be installed from a distro package e.g. 'apt
# install libfile-tail-perl' on debian, ubuntu, mint etc or from
# CPAN https://metacpan.org/pod/File::Tail
# BTW, File::Tail has several useful options, run `man File::Tail`
# for details.
use File::Tail;
# These two need to be installed from a distro package e.g. 'apt
# install libtimedate-perl' on debian, ubuntu, mint etc or from
# CPAN https://metacpan.org/release/TimeDate
use Date::Parse;
use Date::Format;
# These two modules are included with perl
use File::Basename;
use Scalar::Util qw(openhandle);
use strict;
# $logfile is hard-coded here, but you can get it from the command line
# e.g. with something as simple as `my $logfile = shift` or use one of
# the command-line option processing modules like Getopt::Std or
# Getopt::Long
my $logfile = '/var/log/syslog';
# the output dir is hard-coded here to `chunk/` in the current dir.
# set it to whatever you want, or get it from the command line.
my $basename = './chunk/' . basename($logfile);
# open a handle to the log file. File::Tail will automatically
# re-open the log file if it gets rotated and re-created.
my $logref=tie(*LOG,"File::Tail", (name => $logfile, tail => -1));
my ($d, $t, $t2, $outfile, $chunk);
while(<LOG>) {
# Example of handling two different common rsyslog logfile date
# formats. Adjust the regex(es) to suit YOUR log file.
if (/^([[:alpha:]]{3} \d+ \d\d:\d\d):/i) {
# Jul 25 00:00:02 ....
$d = $1;
} elsif (/^(\d{4}[ T]\d\d:\d\d):/) {
# 2023-07-25T00:00:01.737457+10:00 ....
$d = $1;
} else {
die "Couldn't find a known date format in:\n$_";
};
$t = str2time($d);
if ($t - $t2 >= 300) {
close($chunk) if openhandle($chunk);
# Alternatively, you could run your chunk processing
# program from here:
# (this is really basic & untested but it should work...but
# there are better ways of handling child processes.)
# if (openhandle($chunk)) {
# close($chunk);
#
# $SIG{CHLD} = "IGNORE";
# fork;
# exec("myprogram", $outfile) or
# warn "Couldn't exec 'myprogram $outfile'\n";
# };
$t2 = $t;
$d = time2str("%Y%m%d_%H%M", $t);
$outfile = "${basename}_$d";
# Ignore output files that already exist, so that we can
# just re-run this script if it gets killed for some reason.
if (! -e $outfile) {
print "opening new output file $outfile\n";
open($chunk, ">", $outfile) or
die "couldn't open $outfile for write: $!\n";
}
};
print $chunk $_ if openhandle($chunk);
}
たとえば、同じ名前で保存してsplit-log-5min.pl
実行可能にしてからchmod +x split-log-5min.pl
実行します。ログファイルが終了するまで(Ctrl-Cやなどkill
)、または書き込み用に出力ファイルを開こうとしたときにエラーが発生するまで、ログファイルのデータを実行して処理し続けます。
/var/log/syslogの抜粋でこのコマンドを実行し、その結果、数分の./chunk
5分のチャンクを含むディレクトリが作成されました。
$ ls chunk/
syslog_20230725_0000 syslog_20230725_0519 syslog_20230725_1037
syslog_20230725_0007 syslog_20230725_0525 syslog_20230725_1043
syslog_20230725_0013 syslog_20230725_0531 syslog_20230725_1049
syslog_20230725_0019 syslog_20230725_0537 syslog_20230725_1055
[...many more deleted]
syslog_20230725_0455 syslog_20230725_1013 syslog_20230725_1531
syslog_20230725_0501 syslog_20230725_1019 syslog_20230725_1537
syslog_20230725_0507 syslog_20230725_1025
syslog_20230725_0513 syslog_20230725_1031
ちなみに、5分単位で処理する内容によっては、その単位を別々のファイルにコピーしなくても、このスクリプトで処理できます。たとえば、ファイルに書き込むのではなく、各行を配列に追加してから5分ごとに配列を処理して消去します。