[php5] classe de log

Soyez le premier à donner votre avis sur cette source.

Vue 4 858 fois - Téléchargée 387 fois

Description

Ceci est une classe de log.
La classe en elle-même se trouve dans le répertoire class/class.oLogger.php

Les 2 fichiers log.consult.php et log.detail.php sont là pour un exemple d'utilisation.
Je les ai extirpé de ma propre interface...donc c'est du bidouillage pour que ça tourne en local lol :-) A vous de bidouiller la css fournie.
Mais vous avez déjà une bonne base quand même, un bon exemple d'utilisation des logs créés.

Les logs sont déjà créés évidemment.

Pour créer les logs, personnellement, je les ai mis dans ma classe DB, dans la méthode effectuant une requête (oDB::query). Je ne logge pas les SELECT, mais ça, c'est un choix :-)
Donc, je lance mon log ainsi :

if (true === $log && substr (strtoupper (trim ($this->s_db_sql)), 0, 6) !== 'SELECT') {
$ologger = new oLogger;
$destId = (isset ($_SESSION['dest_id']))?$_SESSION['dest_id']:0;
$ologger -> init ($this -> s_db_sql, $destId);
}

C'est tout! C'est ce petit bout de code qui a généré les quelques logs que je montre ici.

Source / Exemple :


<?php
/**

  • class oLogger
  • @author : johan <barbier_johan@hotmail.com>
  • @version : 2006-04-20
  • /
class oLogger { /**
  • const sLogDir
  • path to the logs
  • /
const sLogDir ='logs'; /**
  • private array aLogs
  • array to store each log line
  • /
private $aLogs = array ( 'PAGE' => '', 'DATE' => '', 'QUERY' => '', 'TYPE' => '' ); /**
  • private array aLevels
  • array to store the query types
  • /
private $aLevels = array ( 0 => 'UNKNOWN', 1 => 'SELECT', 2 => 'UPDATE', 3 => 'INSERT', 4 => 'DELETE' ); /**
  • public array aDir
  • array to store all the log folders and log files
  • /
public $aDir = array (); /**
  • private object oXml
  • a simple_xml object
  • /
private $oXml = null; /**
  • public function __construct
  • the constructor
  • initailizes the simple_xml object if needed
  • @param (string) file : the xml log file from which will be set the simple_xml object property
  • /
public function __construct ($file = '') { if (!empty ($file)) { $this -> oXml = simplexml_load_file(self::sLogDir.'/'.$file); } } /**
  • public function init
  • initializes the logger
  • gets the sql query, the user id, current date, filename, query type, and builds the aLogs array with all of that
  • @param (string) sSql : the sql query we want to log
  • @param (int) destId : the user id (depends on your system)
  • /
public function init ($sSql, $destId) { $page = $_SERVER['PHP_SELF']; $this -> checkDir ($destId); $date = date ('H:i:s'); $file = date ('Ymd').'.xml'; $sSql = trim (preg_replace ('@(\s)+@', ' ', $sSql)); $aSql = explode (' ', $sSql); if (false === ($level = array_search ($aSql[0], $this -> aLevels))) { $level = 0; } $this -> aLogs = array ( 'PAGE' => $page, 'DATE' => $date, 'QUERY' => $sSql, 'TYPE' => $this -> aLevels[$level] ); $this -> logIt ($file, $destId); } /**
  • private function checkDir
  • used to check if a log folder exists for a given user id. If not, creates it.
  • @param (int) id : the user id
  • /
private function checkDir ($id) { if (!file_exists (self::sLogDir.'/'.$id)) { mkdir (self::sLogDir.'/'.$id); } } /**
  • private function logIt
  • build the xml from the aLogs array, and saves it into the given file
  • if the given file already exists, it appends the new xml to the existing one
  • @param (string) file : the filename in which the xml log will be written
  • @param (int) destId : the user id (depends on your system)
  • /
private function logIt ($file, $destId) { if (file_exists (self::sLogDir.'/'.$destId.'/'.$file)) { $docXml = DOMDocument::load (self::sLogDir.'/'.$destId.'/'.$file); $root = $docXml -> documentElement; } else { $docXml = new DOMDocument('1.0', 'iso-8859-1'); $root = $docXml -> createElement ('logs'); $root = $docXml -> appendChild ($root); } $log = $docXml -> createElement ('log'); $log = $root -> appendChild ($log); foreach ($this -> aLogs as $clef => $val) { $xmlClef = $docXml -> createElement ($clef); $xmlClef = $log -> appendChild ($xmlClef); $xmlVal = $docXml -> createTextNode ($val); $xmlVal = $xmlClef -> appendChild ($xmlVal); } $docXml -> save (self::sLogDir.'/'.$destId.'/'.$file); $this -> aLogs = array (); } /**
  • public function getaDir
  • builds the aDir array, in which are stored all the log folders and log files
  • @param (bool) ordID : if set to true, orders the array by users id ASC
  • /
public function getaDir ($ordID = false) { $aDestLogs = scandir (self::sLogDir); $aDestLogs = array_splice ($aDestLogs, 2); if (true === $ordID) { sort ($aDestLogs, SORT_NUMERIC); } if (!empty ($aDestLogs)) { foreach ($aDestLogs as $v) { $aFiles = scandir (self::sLogDir.'/'.$v); $aFiles = array_splice ($aFiles, 2); $this -> aDir[$v] = $aFiles; } } else { $this -> aDir = array (); } } /**
  • public function getList
  • builds an array from the oXml simple_xml object with all the values it contains in the $type xml element (the available types are the aLogs array keys)
  • used for the logs UI : with this method, I can display only the UPDATE, or the INSERT, or only a given page on the logged website...
  • @param (string) type : the type on wihch we want to filter. Must be a valid aLogs key.
  • /
public function getList ($type) { if (!array_key_exists ($type, $this -> aLogs)) { trigger_error ('Type '.$type.' non reconnu', E_USER_ERROR); } $oTypes = $this -> oXml -> xpath ('log/'.$type); $aType = array_unique ($oTypes); return $aType; } /**
  • public function getDetail
  • transforms the xml in a log file to html. Could unfortunately not use the XSLTProcessor, because my server did not implement it :-(
  • the html can, be changed, of course. The javascript is a javascript function used to get a filter, if needed.
  • @param (bool) ord : if set to true, we reverse the xml; as the xml is logged chronologically, we will reverse the dates.
  • @param (string) type : if not empty, we filter on that type.
  • @param (string) page : if not empty, we filter on that page.
  • /
public function getDetail ($ord = false, $type = '', $page = '') { $sXml = ''; $oLignes = $this -> oXml -> xpath ('log'); if (true === $ord) { $oLignes = array_reverse ($oLignes); } $iCpt = 0; foreach ($oLignes as $log) { if (!empty ($type) && $log -> TYPE != $type) { continue; } if (!empty ($page) && $log -> PAGE != $page) { continue; } $sColor = ($iCpt%2) ? 'ct1' : 'ct2'; $sXml .= <<<HTML <tr> <td class="$sColor">{$log -> DATE}</td> <td class="$sColor"><a href="javascript:filtrePage('{$log -> PAGE}');">{$log -> PAGE}</a></td> <td class="$sColor"><a href="javascript:filtreType('{$log -> TYPE}');">{$log -> TYPE}</a></td> <td class="$sColor">{$log -> QUERY}</td> </tr> HTML; $iCpt ++; } return $sXml; } } ?>

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
Hello,

désolé, je n'avais jamais vu ce message...je réponds avec un peu de retard lol... ;-)
En bonne POO, il ne faut pas mélanger le html et la classe. Donc non. D'un autre côté, PHP génère du html...alors...c'est un peu chacun qui voit midi à sa porte, au fond.
PHP5 offre de base une méthode magique retournant l'objet sous forme de chaîne...on peut en déduire que les dév de php ne sont pas contre ce mélange (__toString).
Messages postés
144
Date d'inscription
vendredi 18 avril 2003
Statut
Membre
Dernière intervention
4 janvier 2010

Re

En fait ma question précédente n'est pas une question de possibilité mais d'opportunité...

Est-il plus opportun (utile ? logique ?) de mettre un méthode dans une classe retournant le html ou juste une fonction hors de la classe.

Florian
Messages postés
144
Date d'inscription
vendredi 18 avril 2003
Statut
Membre
Dernière intervention
4 janvier 2010

Salut

Je rebondit sur le commentaire de FhX et fait par la même une petite digression.

Je suis en train de développer des classes pour un projet perso et me posais justement la question concernant les fonctions retournant du (x)html... peut-on le faire dans une classe ou doit-on créer une fonction externe ?

Désolé pour ce petit écart...

Florian
Messages postés
10839
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
23
FhX => je suis d'accord avec toi, j'aurais dû séparer. De même pour la mise en forme...mais là je suis moyennement d'accord lol. Disons que j'aurais dû faire une classe séparée, mais cela ne me dérange pas de faire une classe qui crée une mise en forme.
Au passage, le xml n'est PAS de la mise en forme...le xsl, oui... :-)
Si je ne l'ai pas fait, c'est parce que j'ai extirpé cette classe de mon projet au taf, et qu'on a bcp de classes déjà. Je ne voulais pas créer des classes supplémentaires avec uniquement une méthode (LogToHtml par exemple), pour que ce soit plus simple à utiliser au final, par mes collègues.
Par contre, une classe LogToXml, LogToFile...là je suis moins d'accord. Ca fragment bien trop, pour pas grand chose, à mon sens. La seule "sortie" que j'aurais effectivement dû faire, c'est LogToHtml. J'ai hésité, à vrai dire. Et on n'est pas obligé d'utiliser cette dernière méthode. J'ai bien fialli la virer, et mettre en forme uniquement dans log.detail.php (bref, dans une page php classique).

CouCou => par simple soucis de clarté. Quand on lit, on sait directement à quel libellé fait référence tel index numérique.
Messages postés
12303
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
41
private $aLevels = array (
0 => 'UNKNOWN',
1 => 'SELECT',
2 => 'UPDATE',
3 => 'INSERT',
4 => 'DELETE'
);


pourquoi ne pas mettre :

private $aLevels = array (
'UNKNOWN',
'SELECT',
'UPDATE',
'INSERT',
'DELETE'
);

?

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.