Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

trier un gros fichier de log selon les dates

1 réponse
Avatar
HelloMan
bonjour

Je dispose d'un fichier de log classique (un syslog) dont voici quelques
lignes données juste à titre d'exemple:

Jul 4 08:55:53 msi rc: Starting adiusbadsl: succeeded
Jul 4 08:55:53 msi devfsd[130]: Caught SIGHUP
Jul 4 08:55:53 msi devfsd[130]: unknown group: "video", defaulting to GID=0
Jul 4 08:55:53 msi devfsd[130]: read config file:


On a donc un champ 'mois' et un champ 'jour' en premier et deuxième position


Lors de l'analyse de logs j'ai souvent besoin de reprendre tous les logs
d'un service donné pour voir si tel ou tel événement n'a pas déjà eu lieu
par le passé.

Seulement, mes logs passent chaque semaine à la moulinette du logrotate;
j'ai donc (pour le syslog) le fichier non compressé en cours, plus les
fichiers archivés (.tar.gz)

[cm@msi cm]$ dir -l /var/log/syslog*
-rw-r----- 1 root adm 15396129 jui 4 11:42 /var/log/syslog
-rw-r----- 1 root adm 1174958 jun 30 08:16 /var/log/syslog.1.gz
-rw-r----- 1 root adm 1261194 jun 23 08:27 /var/log/syslog.2.gz
-rw-r----- 1 root adm 313027 jun 15 10:51 /var/log/syslog.3.gz
-rw-r----- 1 root adm 349995 jun 10 08:23 /var/log/syslog.4.gz
-rw-r----- 1 root adm 173740 jun 2 08:28 /var/log/syslog.5.gz

pour la reprise de tous mes logs de façon à vérifier la présence dudit
événement (par grep expression fichiergroslog), je concatène le tout dans
un gros fichier de log de la façon suivante:

[cm@msi cm]$ for i in /var/log/syslog.* ; do gunzip -c $i >> fichiergroslog
; done
[cm@msi cm]$ cat /var/log/syslog >> fichiergroslog

bien, j'ai donc tous ainsi tous les fichiers syslog concaténés dans le
fichiergroslog

mais les lignes de ce fichier ne sont pas classées par ordre chronologiques
comme je le souhaiterais (les plus anciens au début, les plus récents à la
fin) ; seulement par ordre d'apparition de la commande /var/log/syslog.*

connaitriez vous un moyen de faire ça ??

J'ai essayé avec la commande sort -M mais ça marche pas

Peut être y a t'il un moyen plus simple avec un truc du genre ls -r pour la
première phase de concaténation, mais j'arrive pas à rentrer ça en ligne de
commande

Mais je pensais surtout à quelques lignes de perl sur le fichiergroslog

merci de votre aide

1 réponse

Avatar
aglae
Je dispose d'un fichier de log classique (un syslog) dont voici quelques
lignes données juste à titre d'exemple:

Jul 4 08:55:53 msi rc: Starting adiusbadsl: succeeded
Jul 4 08:55:53 msi devfsd[130]: Caught SIGHUP
Jul 4 08:55:53 msi devfsd[130]: unknown group: "video", defaulting to
GID=0

Jul 4 08:55:53 msi devfsd[130]: read config file:


bah tu fais un split avec " " comme séparateur,

tu récupères tes champs 0,1 et 2
tu construis une clé à partir de ces champs du genre
heure (sans les ":") + jour x 1 000 000 + mois x 100 000 000

tu as donc des enregistrements (clé, ligne),
reste à coder un abr puis à ressortir le tout dans un fichier,
ou alors un hachage à trier (pb des doublons) et de la mémoire disponible,
à moins d'utiliser un fichier .dbm,
ou
http://theoryx5.uwinnipeg.ca/mod_perl/cpan-search?distinfo62
à moins que tu trouves des algos déjà coder ici
http://theoryx5.uwinnipeg.ca/mod_perl/cpan-search?requestÊt;catinfod2
http://theoryx5.uwinnipeg.ca/mod_perl/cpan-search?requestÊt;catinfo`1

prend bien garde à ne pas mettre tout ton fichier dans une liste de lignes,
tu risques de saturer ta mémoire, il te faut lire les lignes une par une

le code qui suit est une bonne base pour coder un ABR

#!/usr/bin/perl -w
# bintree - binary tree demo program
use strict;
my($root, $n);

# first generate 20 random inserts
while ($n++ < 20) { insert($root, int(rand(1000)))}

# now dump out the tree all three ways
print "Pre order: "; pre_order($root); print "n";
print "In order: "; in_order($root); print "n";
print "Post order: "; post_order($root); print "n";

# prompt until EOF
for (print "Search? "; <>; print "Search? ") {
chomp;
my $found = search($root, $_);
if ($found) { print "Found $_ at $found, $found->{VALUE}n" }
else { print "No $_ in treen" }
}

exit;

#########################################

# insert given value into proper point of
# provided tree. If no tree provided,
# use implicit pass by reference aspect of @_
# to fill one in for our caller.
sub insert {
my($tree, $value) = @_;
unless ($tree) {
$tree = {}; # allocate new node
$tree->{VALUE} = $value;
$tree->{LEFT} = undef;
$tree->{RIGHT} = undef;
$_[0] = $tree; # $_[0] is reference param!
return;
}
if ($tree->{VALUE} > $value) { insert($tree->{LEFT}, $value) }
elsif ($tree->{VALUE} < $value) { insert($tree->{RIGHT}, $value) }
else { warn "dup insert of $valuen" }
# XXX: no dups
}

# recurse on left child,
# then show current value,
# then recurse on right child.
sub in_order {
my($tree) = @_;
return unless $tree;
in_order($tree->{LEFT});
print $tree->{VALUE}, " ";
in_order($tree->{RIGHT});
}

# show current value,
# then recurse on left child,
# then recurse on right child.
sub pre_order {
my($tree) = @_;
return unless $tree;
print $tree->{VALUE}, " ";
pre_order($tree->{LEFT});
pre_order($tree->{RIGHT});
}

# recurse on left child,
# then recurse on right child,
# then show current value.
sub post_order {
my($tree) = @_;
return unless $tree;
post_order($tree->{LEFT});
post_order($tree->{RIGHT});
print $tree->{VALUE}, " ";
}

# find out whether provided value is in the tree.
# if so, return the node at which the value was found.
# cut down search time by only looking in the correct
# branch, based on current value.
sub search {
my($tree, $value) = @_;
return unless $tree;
if ($tree->{VALUE} == $value) {
return $tree;
}
search($tree->{ ($value < $tree->{VALUE}) ? "LEFT" : "RIGHT"}, $value)
}



"HelloMan" a écrit dans le message de news:
3f0553dd$0$9621$
bonjour

Je dispose d'un fichier de log classique (un syslog) dont voici quelques
lignes données juste à titre d'exemple:

Jul 4 08:55:53 msi rc: Starting adiusbadsl: succeeded
Jul 4 08:55:53 msi devfsd[130]: Caught SIGHUP
Jul 4 08:55:53 msi devfsd[130]: unknown group: "video", defaulting to
GID=0

Jul 4 08:55:53 msi devfsd[130]: read config file:


On a donc un champ 'mois' et un champ 'jour' en premier et deuxième
position



Lors de l'analyse de logs j'ai souvent besoin de reprendre tous les logs
d'un service donné pour voir si tel ou tel événement n'a pas déjà eu lieu
par le passé.

Seulement, mes logs passent chaque semaine à la moulinette du logrotate;
j'ai donc (pour le syslog) le fichier non compressé en cours, plus les
fichiers archivés (.tar.gz)

[ cm]$ dir -l /var/log/syslog*
-rw-r----- 1 root adm 15396129 jui 4 11:42 /var/log/syslog
-rw-r----- 1 root adm 1174958 jun 30 08:16
/var/log/syslog.1.gz

-rw-r----- 1 root adm 1261194 jun 23 08:27
/var/log/syslog.2.gz

-rw-r----- 1 root adm 313027 jun 15 10:51
/var/log/syslog.3.gz

-rw-r----- 1 root adm 349995 jun 10 08:23
/var/log/syslog.4.gz

-rw-r----- 1 root adm 173740 jun 2 08:28
/var/log/syslog.5.gz


pour la reprise de tous mes logs de façon à vérifier la présence dudit
événement (par grep expression fichiergroslog), je concatène le tout dans
un gros fichier de log de la façon suivante:

[ cm]$ for i in /var/log/syslog.* ; do gunzip -c $i >>
fichiergroslog

; done
[ cm]$ cat /var/log/syslog >> fichiergroslog

bien, j'ai donc tous ainsi tous les fichiers syslog concaténés dans le
fichiergroslog

mais les lignes de ce fichier ne sont pas classées par ordre
chronologiques

comme je le souhaiterais (les plus anciens au début, les plus récents à la
fin) ; seulement par ordre d'apparition de la commande /var/log/syslog.*

connaitriez vous un moyen de faire ça ??

J'ai essayé avec la commande sort -M mais ça marche pas

Peut être y a t'il un moyen plus simple avec un truc du genre ls -r pour
la

première phase de concaténation, mais j'arrive pas à rentrer ça en ligne
de

commande

Mais je pensais surtout à quelques lignes de perl sur le fichiergroslog

merci de votre aide