104

Suivi des visites

Créez site12 en copiant site11.

  1. /cms
    1. ...
    2. site11
    3. site12

Dans ce chapitre, nous allons programmer la journalisation de toutes les requêtes vers le site, dans un fichier et dans la base de données.

Pour tester le résultat en ligne, entrez http://www.frasq.org/cms/site12 dans la barre d'adresse de votre navigateur.

Ajoutez un dossier appelé log directement à la racine du site :

  1. /cms/site12
    1. log

IMPORTANT : Assurez-vous que le processus Apache a le droit d'écrire dans le dossier :

$ chgrp www-data log
$ chmod 775 log

NOTE : Le nom du groupe du processus Apache est défini par la directive Group. Les configurations du serveur local et du serveur distant peuvent être différentes, selon votre fournisseur internet.

Définissez la variable globale $log_dir dans config.inc :

  1. global $log_dir;
  2.  
  3. $log_dir = ROOT_DIR . DIRECTORY_SEPARATOR . 'log';

Ajoutez les fichiers clientipaddress.php, validateipaddress.php et log.php dans le dossier library avec les contenus suivants :

  1. /cms/site12
    1. library
      1. clientipaddress.php
      2. validateipaddress.php
      3. log.php
  1. function client_ip_address() {
  2.     return $_SERVER['REMOTE_ADDR'];
  3. }

client_ip_address retourne la variable PHP $_SERVER['REMOTE_ADDR']. NOTE : $_SERVER['HTTP_X_FORWARDED_FOR'], dont la valeur a été ajoutée par un serveur mandataire, et $_SERVER['HTTP_CLIENT_IP'], renseignée directement par le client, ne sont pas fiables.

  1. function validate_ip_address($ipaddress) {
  2.     return preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/', $ipaddress);
  3. }

validate_ip_address retourne true si $ipaddress est une adresse IP valide, false dans le cas contraire.

  1. require_once 'clientipaddress.php';
  2. require_once 'validateipaddress.php';

Charge les fonctions client_ip_address et validate_ip_address.

  1. function write_log($logfile, $textline=false) {
  2.     global $log_dir;
  3.  
  4.     $ipaddress = client_ip_address();
  5.  
  6.     if (!validate_ip_address($ipaddress)) {
  7.         return false;
  8.     }
  9.  
  10.     $timestamp=strftime('%Y-%m-%d %H:%M:%S', time());
  11.  
  12.     $logmsg="$timestamp $ipaddress";
  13.     if ($textline) {
  14.         $logmsg .= "\t$textline";
  15.     }
  16.  
  17.     $file = isset($log_dir) ? ($log_dir . DIRECTORY_SEPARATOR . $logfile) : $logfile;
  18.  
  19.     $r = @file_put_contents($file, array($logmsg, "\n"), FILE_APPEND);
  20.  
  21.     return $r;
  22. }

write_log récupère l'adresse IP du client et la valide, formate l'empreinte du message avec la date et l'heure courantes suivie de l'adresse IP séparées par des espaces, puis ajoute $textline précédé d'une tabulation. Le message est ensuite écrit à la fin du fichier $logfile dans le répertoire désigné par la variable globale $log_dir si elle définie.

Les paramètres de journalisation des requêtes sont définis dans config.inc :

  1. global $track_db, $track_log;
  2. global $track_visitor, $track_visitor_agent;
  3.  
  4. $track_db=true;
  5. $track_log=true;
  6. $track_visitor=true;
  7. $track_visitor_agent=true;

$track_visitor à true provoque la journalisation des requêtes. $track_visitor_agent ajoute le contenu de l'en-tête User-Agent aux données enregistrées. $track_db donne le nom de la table de la BD qui contient le journal, track par défaut si $track_db est à true. $track_log donne le nom du fichier qui contient le journal, track.log dans le dossier défini par $log_dir par défaut si $track_log est à true. Si $track_db et $track_log sont à false, aucune journalisation n'est effectuée.

NOTE : Vous pouvez facilement enregistrer d'autres informations comme la langue du visiteur.

La journalisation des requêtes est gérée par la fonction dispatch dans engine.php :

  1. require_once 'track.php';

Charge la fonction track.

  1.     global $track_visitor, $track_visitor_agent;
  2.  
  3.     $req = $base_path ? substr(request_uri(), strlen($base_path)) : request_uri();
  4.  
  5.     if ($track_visitor) {
  6.         track($req, $track_visitor_agent);
  7.     }

Appelle track en lui passant la requête du client $req et l'option globale $track_agent si la variable globale $track_visitor vaut true.

Ajoutez les fichiers useragent.php, validateuseragent.php et track.php dans le dossier library avec les contenus suivants :

  1. /cms/site12
    1. library
      1. useragent.php
      2. validateagent.php
      3. track.php
  1. function user_agent() {
  2.     if (isset($_SERVER['HTTP_USER_AGENT'])) {
  3.         return $_SERVER['HTTP_USER_AGENT'];
  4.     }
  5.  
  6.     return false;
  7. }

user_agent retourne la variable PHP $_SERVER['HTTP_USER_AGENT'].

  1. function validate_user_agent($agent) {
  2.     return preg_match('/^[a-zA-Z0-9 \;\:\.\-\)\(\/\@\]\[\+\~\_\,\?\=\{\}\*\|\&\#\!]+$/', $agent);
  3. }

validate_user_agent retourne true si $agent est une désignation d'un agent valide, false dans le cas contraire.

  1. require_once 'clientipaddress.php';
  2. require_once 'validateipaddress.php';
  3. require_once 'requesturi.php';
  4. require_once 'useragent.php';
  5. require_once 'validateuseragent.php';

Charge les fonctions client_ip_address, validate_ip_address, request_uri, user_agent et validate_user_agent.

  1. function track($request_uri=false, $track_agent=false) {
  2.     global $track_log, $track_db;
  3.  
  4.     if (! ($track_log or $track_db) ) {
  5.         return true;
  6.     }
  7.  
  8.     if (!$request_uri) {
  9.         $request_uri=request_uri();
  10.     }
  11.  
  12.     if (!$request_uri) {
  13.         return false;
  14.     }
  15.  
  16.     $user_agent=$track_agent ? user_agent() : false;
  17.     if (!validate_user_agent($user_agent)) {
  18.         $user_agent=false;
  19.     }
  20.  
  21.     $r = true;

track sort immédiatement si les variables globales $track_log et $track_db sont false. Si le paramètre $request_uri n'est pas défini, track l'initialise en appelant la fonction request_uri. Si $request_uri n'est toujours pas défini, track sort. Si le paramètre $track_agent vaut true, la variable $user_agent est initialisée en appelant la fonction user_agent et validée.

  1.     if ($track_log) {
  2.         require_once 'log.php';
  3.  
  4.         $logmsg = $request_uri;
  5.         if ($user_agent) {
  6.             $logmsg .= "\t" . $user_agent;
  7.         }
  8.  
  9.         $r = write_log($track_log === true ? 'track.log' : $track_log, $logmsg);
  10.     }

Si la variable globale $track_log vaut true, track charge le code de la fonction write_log et lui demande de journaliser la requête et éventuellement l'agent dans le fichier dont le nom est défini par $track_log ou appelé track.log par défaut.

  1.     if ($track_db) {
  2.         $ip_address=client_ip_address();
  3.  
  4.         if (!validate_ip_address($ip_address)) {
  5.             return false;
  6.         }
  7.  
  8.         $sqlipaddress=db_sql_arg($ip_address, false);
  9.         $sqlrequesturi=db_sql_arg($request_uri, true);
  10.         $sqluseragent=db_sql_arg($user_agent, true, true);
  11.  
  12.         $tabtrack=db_prefix_table($track_db === true ? 'track' : $track_db);
  13.  
  14.         $sql="INSERT $tabtrack (ip_address, request_uri, user_agent) VALUES ($sqlipaddress, $sqlrequesturi, $sqluseragent)";
  15.  
  16.         $r = db_insert($sql);
  17.     }
  18.  
  19.     return $r;
  20. }

Si la variable globale $track_db vaut true, track récupère l'adresse IP du client et la valide puis prépare et exécute un ordre SQL qui enregistre les paramètres de la requête dans la table dont le nom est défini par $track_db ou appelée track par défaut.

Ajoutez la table track à la BD du site :

$ mysql -u root -p
mysql> use frasqdb2;
mysql> CREATE TABLE track (
  track_id int(10) unsigned NOT NULL AUTO_INCREMENT,
  time_stamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  ip_address varchar(15) NOT NULL,
  request_uri varchar(255) NOT NULL,
  user_agent varchar(255) DEFAULT NULL,
  PRIMARY KEY (track_id)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
mysql> quit

Vérifiez dans config.inc que les paramètres $track_log et $track_db sont à true. Entrez http://localhost/cms/site12/fr/accueil dans la barre d'adresse de votre navigateur, accédez à la page de contact, changez de langue.

Affichez le contenu du journal des connexions :

$ tail track.log

Pour obtenir le nombre total de visiteurs :

$ cut -f 1 track.log | cut -d' ' -f 3 | sort | uniq | wc -l

Pour lister les 10 pages les plus consultées :

$ cut -f 2 track.log | sort | uniq -c | sort -rn | head -10

Vérifiez la BD :

mysql> SELECT * FROM track;

Pour obtenir le nombre total de visiteurs :

mysql> SELECT COUNT(DISTINCT ip_address) from track;

Pour lister les 10 pages les plus consultées :

mysql> SELECT request_uri, COUNT(request_uri) AS count from track GROUP BY request_uri ORDER BY count DESC LIMIT 10;

IMPORTANT : La quantité de données générées peut rapidement remplir la BD et le journal. Optez pour un seul mode en mettant $track_db ou $track_log à false. Une fois une campagne d'analyse du type des clients du site (navigateurs, mobiles, robots, etc.) terminée, laissez le paramètre $track_agent à false.

Commentaires

Votre commentaire :
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip aide 2000

Entrez un maximum de 2000 caractères.
Améliorez la présentation de votre texte avec les balises de formatage suivantes :
[p]paragraphe[/p], [b]gras[/b], [i]italique[/i], [u]souligné[/u], [s]barré[/s], [quote]citation[/quote], [pre]tel quel[/pre], [br]à la ligne,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]commande[/code], [code=langage]code source en c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].