Хотя я почти всегда советую людям использовать для этого один из множества превосходных модулей из CPAN, у большинства из них есть один существенный недостаток - скорость. Если вы анализируете большое количество файлов журнала в режиме реального времени, это иногда может быть проблемой. В таких случаях более подходящим решением может стать использование собственного, но есть много подводных камней и нюансов, которые необходимо учитывать и правильно обрабатывать. Отсюда предпочтение использования известного-правильного, проверенного, надежного модуля, написанного кем-то другим. :)
Однако, прежде чем я даже обдумал свой совет выше, я посмотрел на ваш код и преобразовал его в perl в моей голове ... поэтому, вот более-менее прямое преобразование вашего gawk-кода в perl. Я попытался написать это настолько просто, насколько это возможно, чтобы выделить некоторые из более тонких частей работы с датами и временем в perl вручную.
# import the mktime function from the (standard) POSIX module
use POSIX qw( mktime );
sub log4jTimeStampToMillis {
my ($log4jts, $dst) = @_;
# extract the millisecond field
my ($tsstr, $millis) = split( ',', $log4jts );
# extract values to pass to mktime()
my @mktime_args = reverse split( '[-: ]', $tsstr );
# munge values for posix compatibility (ugh)
$mktime_args[3] -= 1;
$mktime_args[4] -= 1;
$mktime_args[5] -= 1900;
# print Dumper \@mktime_args; ## DEBUG
# convert, make sure to account for daylight savings
my $seconds = mktime( @mktime_args, 0, 0, $dst );
# return that time as milliseconds since the epoch
return $seconds * 1000 + $millis;
}
Одно важное различие между моим и вашим кодом - моя подпрограмма log4jTimeStampToMillis принимает два параметра:
- строка метки времени журнала
- независимо от того, использует ли эта временная метка летнее время (1 для истины, 0 для ложной)
Конечно, вы могли бы просто добавить код, чтобы определить, попадает ли это время в летнее время или нет, и настроить его автоматически, но я старался сделать его простым. :)
ПРИМЕЧАНИЕ. Если вы раскомментируете строку с пометкой DEBUG, обязательно добавьте «use Data :: Dumper;» до этой строки в вашей программе, чтобы она работала.
Вот пример того, как вы можете протестировать эту подпрограмму:
my $milliseconds = log4jTimeStampToMillis( "2009-05-10 00:48:41,905", 1 );
my $seconds = int( $milliseconds / 1000 );
my $local = scalar localtime( $seconds );
print "ms: $milliseconds\n"; # ms: 1241844521905
print "sec: $seconds\n"; # sec: 1241844521
print "local: $local\n"; # local: Sat May 9 00:48:41 2009