Le serveur Apache "écoute" les requêtes HTTP qui lui sont émises ; chacune est enregistrée dans un fichier de log, "access.log" :
Différentes informations sont ainsi reccueillies : l'ip du demandeur, le jour et l'heure ainsi que la ressource demandée.
Ce fichier est difficilement exploitable ; aussi on envisage de placer ces informations dans une base de donnée MySql afin que l'administrateur (ou une application spécifique) puisse l'exploiter en l'interrogeant (quels sont les jours et heures les plus encombrés?, quels sont les ip les plus demandeuses?, etc...). Ceci permettra aussi de supprimer les lignes du fichiers de log puisqu'elles auront été enregistrées dans une base de données.
L'objectif de la future application est donc de construire les scripts SQL qui vont alimenter la base de données à partir du fichier de log.
Acteur : l'administrateur
Scénario nominal
1. L'administrateur indique une date (début)
2. Le système retourne un fichier de scripts sql (insert into...)qui
va permettre d'alimenter la base de données à partir des lignes
du fichier log concernées (les dates au moins égale à
la date fournie)
Scénario alternatif
1.1 L'administrateur ne fournit pas une date valide
1.2 Le système en informe l'administrateur, retour à 1
Travail à faire
Créer un répertoire pour votre application
php, dans votre espace personnel
Télécharger le fichier log et placez-le
dans ce répertoire
Copier le fichier de commande DOS ExecPhp.bat dans ce répertoire
La base de donnée MySql ("BdLogApache") ne contiendra qu'une seule table : "requetes", avec 4 champs :
- id : l'identifiant id (auto-incrémenté)
- jour : la date (type datetime)
- ip : l'ip (type char(15))
- requete : la requête (type char(100))
Travail à faire
Créer la base de données avec l'administrateur de MySql
L'application comportera plusieurs fonctions ; elles seront regroupées dans un fichier spécifique : fonctions.inc.php. Le programme appelant sera dans un autre fichier gestionLog.php.
1) Fonctions d'extraction des informations d'une ligne du fichier log
Il s'agit, à partir d'une ligne lue, de capturer l'ip, la date et la ressource.
1.a Récupérer l'adresse IP
Nom
|
Rôle
|
Arguments
|
Valeur de retour
|
getIP | extrait, à partir d'une chaîne de caractère, la chaîne correspondant à l'adresse IP | la chaîne lue | l'adresse IP |
La fonction sera à écrire dans le fichier fonctions.inc.ph et son appel dans le fichier gestionLog.php.
On doit obtenir sur la console :
Remarque : la variable $uneLigne a été valorisée par une chaîne extraite du fichier de log ; attention il faut encadrer la chaîne par des apostrophes (simple cote).
Travail à faire
Avec Notepad++, écrire la fonction getIP et la tester comme indiqué.
Aide : il faudra utiliser la fonction split de php
1.b Récupérer la requête émise
Nom
|
Rôle
|
Arguments
|
Valeur de retour
|
getLaRequete | extrait, à partir d'une chaîne de caractère, l'expression de la requête émise | la chaîne lue | la requête |
On doit obtenir sur la console :
Travail à faire
Ecrire la fonction getLaRequete et la tester comme indiqué.
Aide : il faudra utiliser la fonction strstr de php
1.c Récupérer la date
Nom
|
Rôle
|
Arguments
|
Valeur de retour
|
getLaDate | extrait, à partir d'une chaîne de caractère, la date en format numérique | la chaîne lue | la date |
C'est un peu plus complexe et nécessite plus de 3 lignes de code :-)
On doit obtenir :
Travail à faire
Ecrire la fonction getLadate et la tester comme indiqué
Aide : on peut utiliser les fonctions split, substr et str_replace de php.
2) Fonctions de récupération des lignes du fichier log
2.a Récupération de toutes les lignes
Chaque ligne du fichier log sera placée dans un tableau.
Il faut écrire une fonction
Nom
|
Rôle
|
Arguments
|
Valeur de retour
|
getLesLignes | place dans un tableau chaque ligne du fichier log | le fichier | le tableau des lignes |
On doit obtenir sur la console
Travail à faire
Ecrire la fonction getLesLignes. La tester comme indiqué
Aide : l'utilisation de la fonction file de PHP facilitera grandement les choses
2.b Récupération des lignes filtrées sur une date
Le cas d'utilisation précise que seules les requêtes affectuées à partir d'une date seront conservées. Il faut donc extraire du tableau les seules lignes conformes.
Nom
|
Rôle
|
Arguments
|
Valeur de retour
|
getLesLignesValides | place dans un tableau chaque ligne du fichier log correspondant à un critère (date supérieure ou égale) | le tableau et une date de type chaîne | le tableau des lignes filtrée |
On doit obtenir sur la console :
Travail à faire
Ecrire et tester la fonction getLesLignesValides comme indiqué
Aide : utiliser la fonction substr_count qui permettra
de comparer deux chaînes de caractères ; on peut utiliser la
fonction unset qui supprime une ligne d'un tableau.
unset($tab[10]) supprime la ligne 10 du tableau $tab ; par contre les indices
ne sont pas reconstruits (on passera de l'indice 9 à l'indice 11).
Dans la copie d'écran plus haut c'est pourquoi on affiche l'indice
6000, alors que le tableau contient en fait beaucoup moins de valeurs.
3) Fonction de construction des ordres d'insertion dans la base de données
Il s'agit ici de générer dans un fichier les ordres sql insert into
Une fonction creeSql génèrera dans un tableau les commandes insert into.
Remarque : dans la "vraie vie professionelle" ces utilisations de tableaux intermédiaires ne sont pas très performants ;-) ; on pouvait souvent s'en passer. Mais on est à l'école...
Nom
|
Rôle
|
Arguments
|
Valeur de retour
|
creeSql | construit et retourne les ordres SQL dans un tableau avec autant de ligne que d'ordre insert into | le tableau | le tableau de lignes sql |
On doit obtenir sur la console :
Travail à faire
Ecrire et tester la fonction creeSql comme indiqué
Aide : il faudra utiliser une fonction de conversion de date pour insérer dans MySql des dates au format américain ; voici son code :
function dateFrancaisVersAnglais($madate)
{
@list ($date,$heure,$minute,$seconde)=explode(':',$madate);
@list($jour,$mois,$annee)=explode('/',$date);
return $annee."/".$mois."/".$jour.":".$heure.":".$minute.":".$seconde;
}
Pour parcourir le tableau, il est fortement conseillé de parcourir le tableau avec l'instruction foreach
Dernière étape. Création du fichier sql
Le fichier de script sql va être créé grace à une fonction qui va utiliser les différentes fonctions déjà écrites :
Nom
|
Rôle
|
Arguments
|
Valeur de retour
|
creeFichierSql | Crée et remplit un fichier avec des scrits sql de création de lignes. |
1. le fichier log 2. le fichier créé 3. la date de filtre |
aucune |
L'appel de la fonction se fera ainsi :
Dans le fichier 'create.sql' se trouveront tous les ordres insert into pour les lignes filtrées par la date passée en paramètre
On vous fournit quelques lignes
function creeFichierSql($nomFichierLog,$nomFichierSql ,$uneDate)
{
...
$idFichier = fopen($nomFichierSql,'w'); //
ouverture du fichier à écrire
for($i=0;$i<count($lignesSql);$i++) //
$lignesSql : tableau des ordres sql valides
{
$uneLigne
= $lignesSql[$i];
fwrite($idFichier,$uneLigne); //
écriture d'une ligne
}
fclose($idFichier); //
fermeture du fichier
}
Travail
à faire
Terminer comme indiqué. Tester. Proposer
une petite interface web qui permet à l'administrateur de sélectionner
la date et construit le fichier sql.
Ouvrir l'administrateur de MySql et exécuter le script. Vérifier
que les lignes ont bien éré insérées dans la base.
On désire enfin faire une interface permettant de mener une requête sur la base. Il s'agit, pour un jour donné, d'afficher les statistiques d'accès, par IP.
Aide : on vous fournit le code sql pour une date :
SELECT ip, count( * ) AS nbAccess
FROM requetes
WHERE date( jour ) = '2006-05-25'
GROUP BY ip
Remarque : la fonctionMySql date extrait la seule partie date (année, mois, jour) et ne tient pas compte de l'heure.
La date fournie sera bien sûr une variable ;-)
Il faudra retourner dans un même formulaire les statistiques.
On vous donne deux fonctions d'accès à la base de données
(à mettre dans le fichier de fonctions.
function connect()
{
$hote="localhost";
$login="root";
$mdp="";
return mysql_connect($hote, $login, $mdp);
}
function selectBase($connexion)
{
$bd="bdlogapache";
$ok=mysql_select_db($bd, $connexion);
return $ok;
}
On vous fournit aussi leurs utilisations (on est trop gentils
en ce moment ;-)) :
$connexion=connect();
if (!$connexion)
{
echo" Echec de la connexion au serveur
MySql";
exit();
}
if (!selectBase($connexion))
{
echo "La base de données bdlogapache
est inexistante ou non accessible";
exit();
}
Enfin pour gérer à nouveau les dates prise en charge dans les requêtes MySql :
function dateFrancaisVersAnglaisMySql($madate)
{
@list($jour,$mois,$annee)=explode('/',$madate);
return $annee."-".$mois."-".$jour;
}
maintenant c'est à vous...