Comment exploiter access.log

Messages postés
98
Date d'inscription
dimanche 23 novembre 2014
Statut
Membre
Dernière intervention
13 octobre 2019
- - Dernière réponse : p1erro
Messages postés
98
Date d'inscription
dimanche 23 novembre 2014
Statut
Membre
Dernière intervention
13 octobre 2019
- 13 oct. 2019 à 11:39
Bonjour
je souhaite exploiter le fichier /var/log/apache2/access.log

il y a les ip d'afficher dans ce fichier

je voudrais afficher sur mon site avec un classement par ip ce fichier et afficher que par exemple 5 ligne

voila ca a l'air simple mais je n'y arrive pas :(

merci
Afficher la suite 

2 réponses

Meilleure réponse
Messages postés
5243
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
12 octobre 2019
805
1
Merci
Salut p1erro ,

Voilà comment je ferai, compte tenu des informations que tu fournis et en prenant comme exemple un format Apache de logs courant :

<?php

$fichier = '192.168.2.20 - - [28/Jul/2006:10:27:10 -0300] "GET /cgi-bin/try/ HTTP/1.0" 200 3395
127.0.0.1 - - [28/Jul/2006:10:22:04 -0300] "GET / HTTP/1.0" 200 2216
127.0.0.1 - - [28/Jul/2006:10:27:32 -0300] "GET /hidden/ HTTP/1.0" 404 7218
192.168.2.90 - - [13/Sep/2006:07:01:53 -0700] "PROPFIND /svn/[xxxx]/Extranet/branches/SOW-101 HTTP/1.1" 401 587
192.168.2.90 - - [13/Sep/2006:07:01:51 -0700] "PROPFIND /svn/[xxxx]/[xxxx]/trunk HTTP/1.1" 401 587
192.168.2.35 - - [13/Sep/2006:07:00:53 -0700] "PROPFIND /svn/[xxxx]/[xxxx]/2.5 HTTP/1.1" 401 587
192.168.2.35 - - [13/Sep/2006:07:00:53 -0700] "PROPFIND /svn/[xxxx]/Extranet/branches/SOW-101 HTTP/1.1" 401 587
192.168.2.90 - - [13/Sep/2006:07:00:21 -0700] "PROPFIND /svn/[xxxx]/[xxxx]/trunk HTTP/1.1" 401 587
192.168.2.35 - - [13/Sep/2006:06:59:53 -0700] "PROPFIND /svn/[xxxx]/[xxxx]/2.5 HTTP/1.1" 401 587
192.168.2.20 - - [13/Sep/2006:06:59:50 -0700] "PROPFIND /svn/[xxxx]/[xxxx]/trunk HTTP/1.1" 401 587
192.168.2.90 - - [13/Sep/2006:06:58:52 -0700] "PROPFIND /svn/[xxxx]/[xxxx]/trunk HTTP/1.1" 401 587
192.168.2.15 - - [13/Sep/2006:06:58:52 -0700] "PROPFIND /svn/[xxxx]/Extranet/branches/SOW-101 HTTP/1.1" 401 587
';

preg_match_all("/^([0-9a-f]{1,4}\.[0-9a-f]{1,4}\.[0-9a-f]{1,4}\.[0-9a-f]{1,4})\s.*?-.*?-\s\[.*?\]\s(\".*?\").*/im", $fichier, $matches);

asort($matches[1]);

echo "<p>affichage des résultats, par adresse IP</p>\n";
echo "<pre>\n";
$st = "";
foreach($matches[1] as $i=>$value) {
    if ($st != $matches[1][$i]) {
        $st = $matches[1][$i];
        echo "\n>>>>>Adresse $st<<<<<\n";
    }
    echo " * " .$matches[2][$i] . "\n";
}
echo "</pre>\n";

?>


cela donne la sortie suivante sur ce jeu de données d'exemple :

<p>affichage des résultats, par adresse IP</p>
<pre>

>>>>>Adresse 127.0.0.1<<<<<
 * "GET / HTTP/1.0"
 * "GET /hidden/ HTTP/1.0"

>>>>>Adresse 192.168.2.15<<<<<
 * "PROPFIND /svn/[xxxx]/Extranet/branches/SOW-101 HTTP/1.1"

>>>>>Adresse 192.168.2.20<<<<<
 * "GET /cgi-bin/try/ HTTP/1.0"
 * "PROPFIND /svn/[xxxx]/[xxxx]/trunk HTTP/1.1"

>>>>>Adresse 192.168.2.35<<<<<
 * "PROPFIND /svn/[xxxx]/[xxxx]/2.5 HTTP/1.1"
 * "PROPFIND /svn/[xxxx]/Extranet/branches/SOW-101 HTTP/1.1"
 * "PROPFIND /svn/[xxxx]/[xxxx]/2.5 HTTP/1.1"

>>>>>Adresse 192.168.2.90<<<<<
 * "PROPFIND /svn/[xxxx]/Extranet/branches/SOW-101 HTTP/1.1"
 * "PROPFIND /svn/[xxxx]/[xxxx]/trunk HTTP/1.1"
 * "PROPFIND /svn/[xxxx]/[xxxx]/trunk HTTP/1.1"
 * "PROPFIND /svn/[xxxx]/[xxxx]/trunk HTTP/1.1"
</pre>


La regexp matche les adresses IP v4 comme IP v6 dans le format de logs proposé ainsi que le texte descriptif de la requête, et met le résultat dans un tableau de tableaux (vois la doc de
preg_match_all()
et fais des
print_r($matches);
pour comprendre comment c'est structuré). Ensuite
asort()
est utilisée sur le tableau imbriqué des adresses IP capturées pour les trier sans changer leur index, les données à afficher correspondant à la partie descriptive de la requête qui sont dans le tableau imbriqué séparé sont ensuite affichées par adresse IP avec une simple boucle
foreach
et l'index préservé récupéré à chaque itération de
foreach
.


Cela se fait en moins d'une dizaine de lignes grâce à la puissance des regexp compatibles Perl.

Le code est à adapter selon ton format effectif et comment tu veux afficher les données et la limitation du nombre d'entrées dans les logs que tu voudras afficher. Cela devrait être trivial à faire pour toi si tu est déjà familier de Php comme tu sembles l'être :-)

On peut aussi vérifier la valeur retournée par
preg_match_all()
, décider quoi faire si rien n'est matché, etc.


Dal

Dire « Merci » 1

Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CommentCaMarche

CCM 62631 internautes nous ont dit merci ce mois-ci

p1erro
Messages postés
98
Date d'inscription
dimanche 23 novembre 2014
Statut
Membre
Dernière intervention
13 octobre 2019
5 -
<?php

$fichier = file_get_contents ("/var/log/apache2/access.log");


preg_match_all('/^([0-9a-f]{1,4}\.[0-9a-f]{1,4}\.[0-9a-f]{1,4}\.[0-9a-f]{1,4})\s.*?-\s.*?(".*").*/im', $fichier, $matches);

asort($matches[1]);

echo "<p>affichage des résultats, par adresse IP</p>\n";
echo "<pre>\n";
$st = "";
$countlines = 0;
$countip = 0;
foreach($matches[1] as $i=>$value) {
    if ($st != $matches[1][$i]) {
        $st = $matches[1][$i];
        echo "\n>>>>>Adresse n°$countip : $st<<<<<\n";
        $countlines = 0;
        $countip = 0;

    }
    $countlines++;
 $countip++;

    if ($countlines > 2)

        continue;

if ($countip == 3)

break;
 else
        echo " * " .$matches[2][$i] . "\n";
}
echo "</pre>\n";
?>







le probleme c'est que il y a des numeros du genre 322 et tout

[Dal]
Messages postés
5243
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
12 octobre 2019
805 -
Relis bien le 3ème bullet-point de mon message.
p1erro
Messages postés
98
Date d'inscription
dimanche 23 novembre 2014
Statut
Membre
Dernière intervention
13 octobre 2019
5 > [Dal]
Messages postés
5243
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
12 octobre 2019
-
bon ... j'ai fais encore autrement
<?php


$fichier = file_get_contents('access.log');



preg_match_all('/^([0-9a-f]{1,4}\.[0-9a-f]{1,4}\.[0-9a-f]{1,4}\.[0-9a-f]{1,4})\s.*?-\s.*?(".*").*/im', $fichier, $matches);

asort($matches[1]);
echo "<p>affichage des résultats, par adresse IP</p>\n";
echo "<pre>\n";
$st = "";
$count = 0;
$countip = 0;
foreach($matches[1] as $i=>$value) {
    if ($st != $matches[1][$i]) {
        $st = $matches[1][$i];
        echo "\n>>>>>Adresse n°$countip : $st<<<<<\n";
        $count = 0;
        $countip = 0;
    }
    $count++;
    $countip++;
    if ($count > 2)
        continue;
    else
        echo " * " .$matches[2][$i] . "\n";
}
echo "</pre>\n";
?>




et ca ne fonctionne toujours pas l'affichage des numeros n'est pas logique pas du tout
p1erro
Messages postés
98
Date d'inscription
dimanche 23 novembre 2014
Statut
Membre
Dernière intervention
13 octobre 2019
5 -
bullet point j'ai du mal a te comprendre je suis navré est-ce "dans la boucle foreach, le premier if est la partie du code qui affiche une nouvelle IP (cf. le echo), c'est donc dans cette partie que tu peux incrémenter le compteur $countip pour savoir combien d'IP tu affiches" ???
bon je n'y arrive pas :( peux tu m'aider stp ? merci :)
Commenter la réponse de [Dal]
Messages postés
5243
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
12 octobre 2019
805
0
Merci
Salut p1erro ,

Avec une regexp et preg_match_all(), tu dois pouvoir matcher les adresses IP et obtenir un array Php.

Ensuite, tu peux utiliser la fonction standard array_count_values() qui renvoie en sortie un tableau associatif avec le décompte des occurrences des éléments du tableau fourni en entrée.

Dal
p1erro
Messages postés
98
Date d'inscription
dimanche 23 novembre 2014
Statut
Membre
Dernière intervention
13 octobre 2019
5 -
merci, alors je n'ai pas tout compris et j'ai mon idee de faire


$ip = $_SERVER['REMOTE_ADDR'];
$fichier = "/var/log/apache2/access.log";
$trucAChercher = "$ip";
$data = file_get_contents($fichier);

if ( preg_match('/.*'.preg_quote($trucAChercher).'.*/im', $data, $output_array) )
{
echo $output_array[0];

}


mais ca ne va pas du tout car vu que remote addr est affiche que pour celui qui visionne la page ca ne me plait pas moi je veux que tout le monde puisse voir pour chaque ip dans access.log du genre :


je veux que ce qu'il y a en vert mais le meme principe celui de voir le conntrack des autre hors avec ma methode on peut voir que son propre log ;(

merci d'avance
p1erro
Messages postés
98
Date d'inscription
dimanche 23 novembre 2014
Statut
Membre
Dernière intervention
13 octobre 2019
5 -
en fait pour mieux structurer ma question : je veux triller le fichier access.log la toutes les ip sont mélangées moi je veux genre un echo de plusieurs ligne d'une ip apres re echo de l'ip suivante dans le fichier avec plusieurs ligne ainsi de suite mais ce qui comptes c'est regrouper les lignes qui contiennent la meme ip et je veux que ca se fasse en sortie pas de machin .bash qui trie si possible ;(
[Dal]
Messages postés
5243
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
12 octobre 2019
805 -
Dans ton code, tu ne cherches que
$_SERVER['REMOTE_ADDR']
et, de plus, tu ne le cherches qu'une seule fois puisque tu utilises
preg_match()
avec une seule IP et non
preg_match_all()
avec une regexp adaptée matchant le type d'informations que tu veux trouver, comme je te le suggérais.


Aussi, contrairement à ce que j'avais initialement compris de ta question tu ne veux pas juste afficher des IP et le nombre de fois qu'elles apparaissent dans tes logs, mais un extrait des lignes du fichier par IP sous une certaine forme.

Le mieux est que tu postes un exemple de lignes brutes (avec des IP confidentialisées) issues de ton fichier access.log (dont le format peut varier d'une installation à une autre) et que tu postes aussi le résultat que tu attends. Poste cela sous forme texte sur le forum (et avec les balises de code, si possible) et non d'images.

On y verra plus clair pour t'aider, si on peut.
[Dal]
Messages postés
5243
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
12 octobre 2019
805 -
Précise aussi tu dois gérer les adresses IP v6 et IP v4, ou seulement IP v4 selon les caractéristiques de ton serveur, car la façon de les matcher va évidemment être différente.
Commenter la réponse de [Dal]