2009-05-10 9 views
2

Les journaux log4j que j'ai contiennent horodatages dans le format suivant:Comment convertir un horodatage log4j en millisecondes en Perl?

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

J'ai besoin de le convertir en perl à millseconds depuis l'époque, qui dans ce cas serait , en utilisant la fonction gawk suivante. Comment je fais ça en perl?

J'ai peu ou pas d'expérience en Perl, donc apprécier si quelqu'un peut poster un script entier qui fait cela

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; 
} 

Répondre

1

ont pas utilisé, mais vous pourriez vouloir vérifier Time::ParseDate.

+0

Un grand merci. Parsedate dans le module est le même que mktime dans gawk, mais je peux comprendre le reste. –

2

Bien que je dise presque toujours aux gens d'utiliser l'un des nombreux excellents modules du CPAN pour cela, la plupart d'entre eux ont un inconvénient majeur - la vitesse. Si vous analysez un grand nombre de fichiers journaux en temps réel, cela peut parfois poser un problème. Dans ces cas, rouler le vôtre peut souvent être une solution plus appropriée, mais il y a beaucoup d'embûches et de nuances qui doivent être considérées et traitées correctement. D'où la préférence pour l'utilisation d'un module connu-correct, éprouvé, fiable écrit par quelqu'un d'autre. :)

Cependant, avant même de prendre en compte mes conseils ci-dessus, j'ai regardé votre code et l'avais converti en perl dans ma tête ... donc, voici une conversion plus ou moins directe de votre code gawk en perl. J'ai essayé de l'écrire aussi simplement que possible, afin de mettre en évidence certaines des parties les plus délicates de traiter les dates et les heures en perl à la main.

# 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; 
} 

Une différence importante entre mon code et le vôtre - mon sous-routine log4jTimeStampToMillis prend deux paramètres:

  1. la chaîne d'horodatage du journal
  2. si oui ou non que l'horodatage utilise l'heure d'été (1 pour vrai, 0 pour faux)

Bien sûr, vous pourriez simplement ajouter du code pour détecter si ce ti moi tombe en DST ou pas et ajuster automatiquement, mais j'essayais de garder les choses simples. :)

REMARQUE: Si vous décommentez la ligne marquée DEBUG, veillez à ajouter "use Data :: Dumper;" avant cette ligne dans votre programme, donc ça va marcher.

Voici un exemple de la façon dont vous pouvez tester ce sous-programme:

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 
+0

J'ai déjà trouvé ma solution mais votre réponse m'apprend un peu plus perl, je suis sûr que je reviendrai à cette réponse en écrivant du code perl. +1 –

+0

Vous êtes les bienvenus! – Hercynium

+0

Je ne vais pas downvote, mais sérieusement ... cela fonctionne probablement ... jusqu'à ce qu'il ne ... Je ne peux pas commenter l'aspect de la vitesse, mais si DateTime est lent, c'est parce qu'il fait des choses utiles. – Ryley

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

quelle langue est-ce? aussi, consultez le formateur de code - sélectionnez votre code et cliquez sur le petit bouton '101010', il le fera valoir. – Ryley

2

Vous devriez profiter du grand paquet DateTime, utilisez spécifiquement 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 

Cela vous évite Vous avez du mal à déterminer vous-même l'heure d'été (bien que vous deviez passer le TZ de votre serveur à Strptime via le paramètre time_zone). Cela vous évite également de tout gérer si cela devient pertinent (et je suis sûr que ce sera le cas).

Questions connexes