Exploiter des fichiers de logs
[Durée : 40 minutes]
Si vous avez à administrer un serveur, vous aurez souvent à examiner des fichiers de logs. Au delà d'outils de stats web qu'il peut aussi être intéressant d'installer, pouvoir créer des traitements à la demande sur ces données depuis la ligne de commande est souvent bien plus pratique que de rechercher les données dans un éditeur de texte.
La NASA (National Aeronautics and Space Administration) nous offre 2 mois de fichiers de logs de son serveur web, c'est à dire que chaque fois qu'un visiteur consulte une page ou indirectement charge une image ou un autre fichier sur une page, ces accès sont enregistrés. Nous allons chercher à savoir d’où viennent les accès, et combien de requêtes ont eu lieu chaque jour.
Utilisez la commande wget pour récupérer les fichiers de logs :
wget https://ics.utc.fr/libre/api-init/logs-example/NASA_access_log_Jul95.gz
wget https://ics.utc.fr/libre/api-init/logs-example/NASA_access_log_Aug95.gz
Si la commande wget n'est pas installée, installez là en premier lieu :
sudo apt install wget
Explications sur le format du fichier :
The logs are an ASCII file with one line per request, with the following columns:
host making the request. A hostname when possible, otherwise the Internet address if the name could not be looked up.
timestamp in the format "DAY MON DD HH:MM:SS YYYY", where DAY is the day of the week, MON is the name of the month, DD is the day of the month, HH:MM:SS is the time of day using a 24-hour clock, and YYYY is the year. The timezone is -0400.
request given in quotes.
HTTP reply code.
bytes in the reply.
Question
Décompressez les 2 fichiers
Indice
Ces fichiers sont de type .gz. Lancez une recherche sur internet pour savoir comment décompresser ce type de fichier, par exemple avec les mots clés : décompresser .gz linux ou en anglais : uncompress .gz linux. Vous trouverez beaucoup de réponse, attention, certaines ne s'appliquent que aux fichiers ".tar.gz" (archives multi-fichiers) et non juste aux fichiers ".gz" (un seul fichier compressé), ce n'est pas ce dont nous avons besoin.
Solution
gunzip NASA_access_log_Aug95.gz
gunzip NASA_access_log_Jul95.gz
(gzip -d fonctionne aussi)
Question
Regroupez le contenu des 2 fichiers dans un seul fichier que vous nommerez "nasa.log", c'est à dire ajoutez les lignes du fichier du mois d'août à la suite des lignes du fichier du mois de juillet.
Solution
"cat NASA_access_log_Aug95" permet d'envoyer en sortie toutes le contenu du fichier d'août. Mais plutôt que de l'afficher, la redirection >> permet d'écrire cette sortie à la fin du fichier NASA_access_log_Jul95.log.
cat NASA_access_log_Aug95 >> NASA_access_log_Jul95
mv NASA_access_log_Jul95 nasa.log
Ensuite, vous pouvez faire le ménage :
mv NASA_access_log_Jul95 nasa.log
rm NASA_access_log_Aug95
Question
Vérifiez que vous ayez 3461612 lignes dans ce fichier. Quelle est la taille de ce fichier en Mo ?
Solution
wc -l nasa.log
ls -lh nasa.log
En résultat :
...$ wc -l nasa.log
3461612 nasa.log
...$ ls -lh nasa.log
-rw-rw-r-- 1 ics ics 356M janv. 7 11:54 nasa.log
Question
Le fichier est très gros. Quelle commande pouvez vous utiliser pour afficher son contenu sans saturer votre terminal avec toutes les données d'un coup ?
Solution
less nasa.log
Vous pouvez également utiliser d'autres outils, mais vu la taille du fichier certains éditeurs de texte peuvent avoir du mal.
Question
Nous allons nous intéresser aux requêtes qui concernent une page précise du site, la page /shuttle/countdown/ qui annonçait le temps restant avant le lancement de la prochaine fusée. En utilisant la commande grep, créez un fichier "countdown.log" qui ne contient que les lignes qui font référence à cette page. Vérifiez que vous obtenez bien 64 696 lignes.
Indice
Pour ne pas prendre d'autres pages, mettez l'adresse de la page entre guillemet, en rajoutant un espace avant et après, comme ceci : " /shuttle/countdown/ ".
Faites une recherche sur internet pour savoir rediriger la sortie d'une commande linux vers un fichier.
Solution
La commande grep prend 2 arguments.
grep ' /shuttle/countdown/ ' nasa.log > countdown.log
Question
[Question bonus] Vous venez de faire une recherche dans un fichier de 3 millions de lignes, et extrait 64 696 lignes de ce fichier. Trouvez une commande qui permette de mesurer combien le temps d'exécution d'une autre commande, et déterminer combien de temps cette opération a pris.
Indice
Cherchez sur internet "temps d'exécution d'une commande linux".
Solution
time grep ' /shuttle/countdown/ ' nasa.log > countdown.log
Qui donne en résultat sur un PC rapide :
real 0m0,143s
user 0m0,084s
sys 0m0,060s
Le premier chiffre est le plus intéressant d'un point de vu utilisateur : c'est le temps d'exécution réel entre le début et la fin de la commande.
Le 2eme est le temps de traitement "utilisateur", le temps consommé directement par le programme, dans ce cas c'est principalement le temps de l’opération de filtrage.
Le 3eme est le temps "système", le temps consommé par ce que le programme a demandé au noyau Linux, par exemple, les accès disques ou les allocations mémoires.
Question
Pour faire des stats sur les noms de domaines et adresses IP de provenance, on va éliminer les autres informations lors du traitement du fichier. Le nom de domaine (ou l'adresse IP) de provenance des visiteurs est en première position sur chaque ligne, suivi d'un caractère espace .
Dans une même ligne de commande, en partant du fichier countdown.log, combinez l'utilisation de 2 programmes :
Utilisez la commande cut traiter ce contenu et ne garder que la première colonne du fichier. Il faudra trouver les bons arguments à cette commande.
Utilisez la commande less pour afficher les résultats sans surcharger de données votre terminal
Indice
Utilisez un moteur de recherche, par exemple avec les mots clés : cut only first column shell. Aidez vous de la page man de la commande cut ("man cut")pour comprendre par vous même arguments des exemples proposés sur internet.
Ensuite, pour apprendre à combiner les deux commandes, consultez le chapitre "pipelines" du guide "LinuxCommand.org".
Solution
cut -f 1 -d ' ' countdown.log | less
On prend le premier champ (-f 1
) avec le délimiteur de champ "espace" (-d ' '
)
Question
Maintenant, on souhaite compter combien chaque nom de domaine ou adresse IP a réalisé d'accès.
Pour cela , on va partir de la commande précédente, mais avant d'afficher les résultats on va rajouter 2 opérations :
On va trier la liste, avec la commande "sort"
On va fusionner les lignes dupliquées, et compter le nombre de lignes dupliqué avec la commande "uniq" et le bon argument
Indice
Utilisez la page man de la commande uniq pour trouver l'argument qui permet de compter les lignes dupliquées (et donc le nombre d’occurrences d'une adresse).
Ensuite, combinez bien dans le bon ordre la commande de la question précédente, et les 2 nouveaux traitements ici, en enchainant plusieurs |, dans le bon ordre.
Solution
cut -f 1 -d ' ' countdown.log | sort | uniq -c | less
Les commandes sort et uniq sont très souvent utilisées ensembles.
Comme uniq ne fonctionne que sur les lignes adjacentes, si on trie les données au préalable, nous sommes sûr que toutes les lignes dupliquées sont adjacentes.
Question
À partir du résultat précédent, pouvez vous trouver les 10 adresses ou domaines qui ont fait le plus d'accès à la page countdown du site de la NASA sur la période étudiée ?
Indice
Les résultats de la commande précédente sont dans le désordre, connaissez vous une commande qui puisse remédier à cela ? Enchaînez là avec une nouvelle pipe après la commande uniq. Utilisez les bons arguments afin de vous assurer que le trie fonctionne bien.
Ensuite, enchaînez une nouvelle commande pour que seul les 10 premières lignes de la sortie soient affichées.
Solution
Vérifiez bien que vous ayez utilisé les 2 options du dernier sort, pour avoir le trie par ordre numérique, et décroissant.
cut -f 1 -d ' ' countdown.log | sort | uniq -c | sort -rn | head
En résultat :
586 piweba3y.prodigy.com
516 piweba4y.prodigy.com
434 piweba1y.prodigy.com
238 disarray.demon.co.uk
223 piweba2y.prodigy.com
214 alyssa.prodigy.com
179 news.ti.com
142 www-d1.proxy.aol.com
140 derec
137 163.206.137.21
Complément :
Si vous êtes curieux de savoir d’où provient les résultats en tête du classement, vous pouvez aller voir le site prodigy.com tel qu'il existait en 1996.
Apparemment, il s'agit d'un fournisseur d'accès de l'époque.
Celui-ci permet de vous connecter à internet en utilisant votre PC avec un processeur 486, 8Mo de mémoire vive, et un modem 14.4 Kbps (soit de l'ordre de 1000 fois moins puissant que le matériel d'aujourd'hui selon tous les critères).
Question
[Question bonus] Jour par jour, combien y'a t'il eu d'accès à la page countdown ? En regardant cette liste, arrivez vous à repérer des jours ou il n'y a eu aucun accès ?
Indice
Identifiez le format de date utilisé dans countdown.log, par exemple [01/Jul/1995:00:07:37 -0400]. Commencez par ne garder que ce qui est après le premier "[". Puis ce qui n'est qu'avant le premier ":". Vous pouvez faire cela avec cut, même s'il existe aussi d'autres outils.
Solution
Les 2 premiers "cut" permettent de n'avoir que les dates. Ensuite, on peut appliquer "uniq" car les logs sont enregistrés chronologiquement et donc déjà triés.
cut -f 2 -d '[' countdown.log | cut -f 1 -d ':' | uniq -c | less
En résultat :
2653 01/Jul/1995
2283 02/Jul/1995
3534 03/Jul/1995
2583 04/Jul/1995
3582 05/Jul/1995
3469 06/Jul/1995
2306 07/Jul/1995
570 08/Jul/1995
446 09/Jul/1995
1125 10/Jul/1995
1239 11/Jul/1995
1511 12/Jul/1995
3119 13/Jul/1995
1634 14/Jul/1995
879 15/Jul/1995
878 16/Jul/1995
1057 17/Jul/1995
874 18/Jul/1995
969 19/Jul/1995
863 20/Jul/1995
974 21/Jul/1995
561 22/Jul/1995
457 23/Jul/1995
620 24/Jul/1995
571 25/Jul/1995
559 26/Jul/1995
624 27/Jul/1995
311 28/Jul/1995
341 01/Aug/1995
604 03/Aug/1995
805 04/Aug/1995
496 05/Aug/1995
464 06/Aug/1995
833 07/Aug/1995
823 08/Aug/1995
887 09/Aug/1995
905 10/Aug/1995
894 11/Aug/1995
807 12/Aug/1995
735 13/Aug/1995
969 14/Aug/1995
868 15/Aug/1995
818 16/Aug/1995
886 17/Aug/1995
837 18/Aug/1995
520 19/Aug/1995
500 20/Aug/1995
852 21/Aug/1995
896 22/Aug/1995
888 23/Aug/1995
751 24/Aug/1995
846 25/Aug/1995
492 26/Aug/1995
483 27/Aug/1995
857 28/Aug/1995
1095 29/Aug/1995
1423 30/Aug/1995
1870 31/Aug/1995
En regardant la liste, on peut s’apercevoir qu'il n'y manque quelques dates : les 29, 30, 31 juillets et le 2 août.
Complément :
Consultez The Internet Traffic Archive (ou une page miroir si le site est indisponible) pour découvrir ce qui est à l'origine des jours d'interruption du serveur !
Les logs utilisés pour cette exercice ont été fournies par ce site.