如何在Perl中将log4j时间戳转换为毫秒?

时间:2009-05-10 16:04:23

标签: perl log4j timestamp

log4j日志我包含以下格式的时间戳:

2009-05-10 00:48:41,905

我需要使用以下gawk函数将epl中的epl转换为毫秒,在本例中为 124189673005 。我怎么在perl中做到这一点?

我对perl很少或根本没有经验,所以如果有人可以发布完成此操作的整个脚本

,那就表示赞赏
function log4jTimeStampToMillis(log4jts) {
    # log4jts is of the form 2009-03-02 20:04:13,474
    # extract milliseconds that is after the command
    split(log4jts, tsparts, ",");
    millis = tsparts[2];

    # remove - : from tsstr
    tsstr = tsparts[1];
    gsub("[-:]", " ", tsstr);
    seconds = mktime(tsstr);
    print log4jts;
    return seconds * 1000 + millis;
}

4 个答案:

答案 0 :(得分:2)

虽然我几乎总是告诉人们使用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. 日志时间戳字符串
  2. 该时间戳是否正在使用夏令时(1表示真,0表示假)
  3. 当然,您可以添加代码来检测该时间是否属于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
    

答案 1 :(得分:2)

您应该利用精彩的DateTime软件包,特别是使用DateTime::Format::Strptime

use DateTime;
use DateTime::Format::Strptime;

sub log4jTimeStampToMillis {
    my $log4jts=shift(@_);

    #see package docs for how the pattern parameter works
    my $formatter= new DateTime::Format::Strptime(pattern => '%Y-%m-%d %T,%3N');
    my $dayObj = $formatter->parse_datetime($log4jts);

    return $dayObj->epoch()*1000+$dayObj->millisecond();
}

print log4jTimeStampToMillis('2009-05-10 10:48:41,905')."\n";
#prints my local version of the TS: 1241952521905

这可以节省您自己计算DST的痛苦(尽管您必须通过time_zone参数将服务器的TZ传递给Strptime)。如果它变得相关的话,它也可以避免你处理跳跃的一切(我相信它会)。

答案 2 :(得分:1)

尚未使用它,但您可能需要查看Time::ParseDate

答案 3 :(得分:0)

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
Date time = dateFormat.parse(log4jts);
long millis = time.getTime();