Как я могу преобразовать метку времени log4j в миллисекунды в Perl? - PullRequest
2 голосов
/ 10 мая 2009

Журналы log4j, которые я имею, содержат метки времени в следующем формате:

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

Мне нужно преобразовать его в perl в миллисекунды начиная с эпохи, которая в этом случае будет 124189673005 , используя следующую функцию gawk. Как мне сделать это в 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 ]

2 голосов
/ 24 ноября 2010

Вам следует воспользоваться преимуществом замечательного пакета 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 (хотя вам придется передавать TZ вашего сервера в Strptime через параметр time_zone). Это также избавляет вас от необходимости совершать скачки во всем, если это становится актуальным (и я уверен, что так и будет).

2 голосов
/ 11 мая 2009

Хотя я почти всегда советую людям использовать для этого один из множества превосходных модулей из 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 для ложной)

Конечно, вы могли бы просто добавить код, чтобы определить, попадает ли это время в летнее время или нет, и настроить его автоматически, но я старался сделать его простым. :)

ПРИМЕЧАНИЕ. Если вы раскомментируете строку с пометкой 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 голос
/ 10 мая 2009

Не использовал, но вы можете проверить Time :: ParseDate .

0 голосов
/ 24 ноября 2010
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS");
Date time = dateFormat.parse(log4jts);
long millis = time.getTime();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...