Commande GREP ou autres pour parser des logs d'Apache.
Résolu/Fermé
pcsystemd
Messages postés
681
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
1 mars 2023
-
Modifié le 17 sept. 2021 à 16:49
mamiemando Messages postés 32298 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 mars 2023 - 23 sept. 2021 à 12:04
mamiemando Messages postés 32298 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 mars 2023 - 23 sept. 2021 à 12:04
A voir également:
- Commande GREP ou autres pour parser des logs d'Apache.
- Invite de commande - Guide
- Commande en attente d'acceptation fnac ✓ - Forum Consommation et internet
- Find grep ✓ - Forum Linux / Unix
- Apache openoffice - Télécharger - Suite bureautique
- View recovery logs - Guide
6 réponses
acefalo
Messages postés
65
Date d'inscription
vendredi 5 décembre 2014
Statut
Membre
Dernière intervention
16 août 2022
13
19 sept. 2021 à 23:23
19 sept. 2021 à 23:23
Bonjour,
Si ton access.log est classé par heure d'accès, awk devrait faire l'affaire.
$4 = 4e colonne, séparateur par défaut = 'espace', && = opérateur AND
Exemple d'une entrée de log fonctionnant avec ce script :
Tes entrées de log ont-elles cette forme? Si cela ne fonctionne pas, tu peux fournir une ligne complète de log anonymisée.
Si ton log à cette forme (exemple, débute par [17/Sep):
Tu peux utiliser awk de cette manière :
Sources :
Log Samples from Apache
https://www.ossec.net/docs/log_samples/apache/apache.html
grep an accesslog(apache) file within a specific time period
https://gist.github.com/sheeplogh/3421464
Si ton access.log est classé par heure d'accès, awk devrait faire l'affaire.
$4 = 4e colonne, séparateur par défaut = 'espace', && = opérateur AND
awk '$4 >= "[17/Sep/2021:08:13:48" && $4 <= "[17/Sep/2021:16:11:00"' access.log | wc -l
Exemple d'une entrée de log fonctionnant avec ce script :
127.0.0.1 - - [17/Sep/2021:08:13:48 -0300] "GET / HTTP/1.0" 200 2216
Tes entrées de log ont-elles cette forme? Si cela ne fonctionne pas, tu peux fournir une ligne complète de log anonymisée.
Si ton log à cette forme (exemple, débute par [17/Sep):
[17/Sep/2021:08:13:48 +0200] "GET /auto
Tu peux utiliser awk de cette manière :
awk '$1 >= "[17/Sep/2021:08:13:48" && $1 <= "[17/Sep/2021:16:11:00"' access.log | wc -l
Sources :
Log Samples from Apache
https://www.ossec.net/docs/log_samples/apache/apache.html
grep an accesslog(apache) file within a specific time period
https://gist.github.com/sheeplogh/3421464
mamiemando
Messages postés
32298
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
23 mars 2023
7 575
Modifié le 20 sept. 2021 à 10:47
Modifié le 20 sept. 2021 à 10:47
Bonjour,
Voici comment tu pourrais faire en
Sauve ça dans un fichier (disons
En gros, on cherche les lignes qui contiennent un timestamp (donc, qui ont un truc entre crochets) avec l'expression régulière
Pour chaque ligne du log, si la date extraite est comprise entre les deux autres dates passées en paramètres du programme, on écrit la ligne (sinon on l'ignore).
Pour lancer le programme, lance dans ton terminal :
Bonne chance
Voici comment tu pourrais faire en
python3:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import datetime, re, sys RE_APACHE = re.compile(".*\[(.*)\].*") if len(sys.argv) != 4: print(f"usage: {sys.argv[0]} input_log date_min date_max", sys.stderr) sys.exit(1) def parse_date(date): return datetime.datetime.strptime(date, "%d/%b/%Y:%H:%M:%S %z") filename = sys.argv[1] date_min = parse_date(sys.argv[2]) date_max = parse_date(sys.argv[3]) assert date_min <= date_max with open(filename) as f: for line in f: m = RE_APACHE.match(line) if not m: continue date = parse_date(m.group(1)) if date_min <= date <= date_max: print(line.strip())
Sauve ça dans un fichier (disons
toto.py)
En gros, on cherche les lignes qui contiennent un timestamp (donc, qui ont un truc entre crochets) avec l'expression régulière
RE_APACHE. Note que l'expression régulière permet de s'affranchir de la position du timestamp dans la ligne, on fait uniquement l'hypothèse qu'il est entre crochet.
Pour chaque ligne du log, si la date extraite est comprise entre les deux autres dates passées en paramètres du programme, on écrit la ligne (sinon on l'ignore).
Pour lancer le programme, lance dans ton terminal :
python3 toto.py apache.log "20/Sep/2021:07:57:00 +0000" "20/Sep/2021:07:58:00 +0000"
Bonne chance
dubcek
Messages postés
18589
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
21 mars 2023
5 584
20 sept. 2021 à 11:17
20 sept. 2021 à 11:17
hello
on convertit les dates en secondes
on convertit la chaine pour être compatible avec date -d ...
JJ/Mmm/AAAA:HH:MM:SS devient JJ-Mmm-AAAA HH:MM:SS
on convertit les dates en secondes
on convertit la chaine pour être compatible avec date -d ...
JJ/Mmm/AAAA:HH:MM:SS devient JJ-Mmm-AAAA HH:MM:SS
d1="17/Sep/2021:08:13:48"; t1=${d1////-}; t1=${t1/:/ }; t1=$(date -d "$t1" +%s)
d2="17/Sep/2021:16:11:01"; t2=${d2////-}; t2=${t2/:/ }; t2=$(date -d "$t2" +%s)
awk -F "[][]|[ ]" -v t1=$t1 -v t2=$t2 '{x=$2; gsub("/", "-", x); sub(":", " ", x); "date -d \"" x "\" +%s" | getline t}; t >= t1 && t <=t2 {print $0}' access.log
dubcek
Messages postés
18589
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
21 mars 2023
5 584
Modifié le 22 sept. 2021 à 15:57
Modifié le 22 sept. 2021 à 15:57
vérifier qu'il ne manque pas de "
ou essayer avec gawk
awk -F "[][]|[ ]" -v t1=$t1 -v t2=$t2 '{x=$2; gsub("/", "-", x); sub(":", " ", x); "date -d \"" x "\" +%s" | getline t}; t >= t1 && t <=t2 {print $0}' access.log
ou essayer avec gawk
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
pcsystemd
Messages postés
681
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
1 mars 2023
21
22 sept. 2021 à 14:45
22 sept. 2021 à 14:45
Merci a tous pour votre temps et vos solutions.
@mamiemando
Je n'ai pas la version 3 de Python du coup je vais voir si cela fonctionne avec ma version 2.7.9!
@dubcek
J'ai l'erreur suivante :
@mamiemando
Je n'ai pas la version 3 de Python du coup je vais voir si cela fonctionne avec ma version 2.7.9!
@dubcek
J'ai l'erreur suivante :
d1="21/Sep/2021:13:13:48"; t1=${d1////-}; t1=${t1/:/ }; t1=$(date -d "$t1" +%s)
d2="21/Sep/2021:14:01:01"; t2=${d2////-}; t2=${t2/:/ }; t2=$(date -d "$t2" +%s)
awk -F "[][]|[ ]" -v t1=$t1 -v t2=$t2 '{x=$2; gsub("/", "-", x); sub(":", " ", x); "date -d \"" x "\" +%s" | getline t}; t >= t1 && t <=t2 {print $0}' access.log
/bin/sh: 1: Syntax error: Unterminated quoted string
mamiemando
Messages postés
32298
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
23 mars 2023
7 575
23 sept. 2021 à 12:04
23 sept. 2021 à 12:04
En python 2 il faudrait faire quelques adaptations et python2 c'est un peu vieille école, donc je ne saurais que trop te conseiller d'installer un interpréteur python3 (e.g.
Pour migrer le script en python2 il faudrait faire quelques adaptations mineures :
Bonne chance
sudo apt install python3).
Pour migrer le script en python2 il faudrait faire quelques adaptations mineures :
-
print(msg)
devientprint msg
ou il faut importer la fonctionprint
depuisfrom __future__
; - même remarque pour
with
- le test de la forme
L <= x <= U
doit être réécrit en une clause d'opérations binaires (iciL <= x
andx <= U
)
Bonne chance
pcsystemd
Messages postés
681
Date d'inscription
dimanche 27 novembre 2005
Statut
Membre
Dernière intervention
1 mars 2023
21
22 sept. 2021 à 17:40
22 sept. 2021 à 17:40
Ok merci. Je vais tester.
20 sept. 2021 à 09:58
L'idée d'utiliser est bonne, mais la solution proposée ne marchera pas en l'état.
En effet, considérera les dates comme des chaînes qu'il comparera selon l'ordre lexicographique (donc, caractère par caractère, conformément au code ASCII de chaque caractère). Si cela se passerait bien pour les valeurs numériques, ça ne sera malheureusement pas le cas avec les mois (typiquement Jan arrive avant Dec et Dec arrive Sep).
Il faut donc pour chaque ligne convertir le mois sous forme numérique avant de réaliser la comparaison, ce qui peut se faire un ou avec un langage comme .
Bonne chance
20 sept. 2021 à 17:25
J'y avait pensé que cela ne fonctionnerait pas avec les chevauchements de mois, j'aurais dû le spécifier. Dans ma tête je faisais une distinction entre plage horaire (qui se situait dans la même journée ou à tout le moins dans un intervalle assez rapproché dans le temps) et période (peu importe la journée ou le mois). Entre le 31 août et le 1er septembre, c'est assez rapproché dans le temps et mon script ne fonctionnera pas dans ce cas là et avec tous les chevauchements de mois.
Pour les cas simples où nous voulons seulement les accès dans la même journée (je pense que cela fonctionne aussi pour le mois au complet), penses-tu que mon script à d'autres problèmes ? J'aime ta solution et celle de dubcek. Votre maîtrise de et de vous permet plus d'expressivité.
21 sept. 2021 à 15:36
En effet.
Pour les cas simples où nous voulons seulement les accès dans la même journée (je pense que cela fonctionne aussi pour le mois au complet),
Tout à fait, et c'est ce problème que dubcek et moi résolvons avec nos deux propositions.
Oui :
La solution de dubcek et la mienne ne font pas d'hypothèse sur le formatage des dates ou la durée du log. La solution de dubcek a l'avantage d'être concise et de ne nécessiter qu' .
La mienne à l'inconvénient de nécessiter d'avoir Python3 sur la machine. Elle apporte en contrepartie quelques avantages,
Bonne chance