尽管我几乎总是告诉人们为此使用来自 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 为假)
当然,您可以只添加代码来检测该时间是否在 DST 中并自动调整,但我试图保持简单。:)
注意:如果取消注释标记为 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