Modelisation d'une classe Log/Erreur/Affichag

Eléphant du PHP | 254 Messages

12 mars 2006, 13:15

salut,


ca fait deja un bon petit bout de temps que j'utilise une classe "Log" qui est la mere de toutes mes autres classes : elle sert pour l'ensemble de la gestion d'erreurs ainsi que l'affichage me permettant de deboguer + facilement (log dans fichier/affichage erreur/gestionnaire d'erreur perso "error_handler()"/mail/...)


Un des principes de fonctionnement de la classe Log :
des constantes sont definis dans un fichier de config qui lui indique l'action qu'elle doit executer suivant le niveau de l'erreur rencontré (SUCCESS/NOTICE/WARNING/FATAL).
Ce niveau est generalement definit pour l'ensemble de l'appli mais peut etre adapté a chaqu'une des classes.


La question metaphysiques :
Imaginons maintenant que je prefere definir un niveau d'erreur perso qui peut etre defini pour chaque methode afin de pouvoir en laisser certaines continuer le script en cas d'erreur tandis que d'autre doivent obligatoirement le couper (pour une question de sécu par exemple) !


Qu'elles seraient vos idées pour implanter cette possibilitée sans que les methodes ou fonctions deviennent des usines a gaz :?:

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

12 mars 2006, 13:35

Tu utilises la gestion d'exception intégrée à PHP avec les constantes E_NOTICE & cie ?
Sans avoir la moindre idée de la façon dont est motorisée ta classe Log on peut difficilement avoir une idée :?

Eléphant du PHP | 254 Messages

12 mars 2006, 16:48

le probleme ou l'inconnu ne vient pas de la classe LOG !
c'est plutot comment gerer un niveau d'erreur perso pour toutes les methodes des autres classes sans avoir X vars supplémentaires a passer en arguments de chaque methodes.

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

12 mars 2006, 17:12

Donc, comme te le demande naholyr, est-ce que tu t'es penché sur la gestion des erreurs PHP 5 ?
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 254 Messages

12 mars 2006, 17:34

si tu causes des try/catch, PAS DU TOUT -> ce systeme me deplait ... ca oblige a modifier l'integralité du code !! sans oublier que le code ne devient plus portable ! donc tant que PHP5 n'occupera pas 90% des serveurs, je zappe ...

je prefere les conditions placés aux bons endroits qui appellent eventuellement un gestionnaire d'erreur perso et pour celles qui sont non previsibles une methode pour le set_error_handler() suffit .

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

12 mars 2006, 22:14

Bon je vais être plus clair alors sur ma demande ;)
Il y a 1000 façons d'implémenter un loggeur d'erreurs, donc si on ne sait pas quelle est la tienne, il est absolument impossible de deviner.

Je crois comprendre que tu "actives" ton loggeur avec set_error_handler(), et que tu déclenches manuellement si nécessaire avec trigger_error(). C'est la question que je te posais, et si c'est bien ça tu es restreint aux constantes prédéfinies par PHP : les E_* mais également les E_USER_* qui peuvent du coup résoudre partiellement ton problème.

Eléphant du PHP | 254 Messages

12 mars 2006, 23:08

voila tout le probleme, je ne voulais pas etre trop precis pour ne pas influencer vos reponses et surtout pour voir si la direction est la bonne.

comme disait l'autre zigoto (matrix :lol:) :
"il y a une difference entre connaitre le chemin et arpenter le chemin"


pour infos le set_error_handler() ne sert que pour les erreurs que je n'ai pas prevu, les autres sont gérés avec des conditions sur les retours des methodes/fonctions ...etc


voici un bout de code qui te permettra de comprendre un peu mieux comment elle fonctionne.
la methode est un classique de ce que tu trouves dans un classe MySQL et gere le changement de base de données :
        /**
        * Selection de la base de données MySQL
        *
        * @param String $stBd La base de données
        *
        * @return Boolean
        */
        public function myBd($stBd){
                @mysqli_select_db($this->rsPtMy, $stBd);
                if( @mysqli_errno($this->rsPtMy) ){
                        return $this->logHandler(
                                "class Mysql->myBd() :<br />Erreur lors de la selection de la base de données :<br />".@mysqli_error($this->rsPtMy),
                                LOG_LV_FATAL
                        );
                }

                $this->logHandler(
                        "class Mysql->myBd() :<br />Selection de la base de données :<br />".$stBd,
                        LOG_LV_NOTICE
                );
                $this->stBdMy = $stBd;
                return true;
        }

voici ce qu'il y a dans le fichier config pour gerer les erreurs des applis :
// ---------------------------------------------------------------------
// ------------------- PARTIE A NE PAS MODIFIER ----------------------
// ---------------------------------------------------------------------

error_reporting(E_ALL);
set_time_limit(6000);




/**
*  Log : Actions on error
*/
define('LOG_DISPLAY_SUCCESS', 1);
define('LOG_DISPLAY_NOTICE', 2);
define('LOG_DISPLAY_WARNING', 4);
define('LOG_DISPLAY_FATAL', 8);

define('LOG_WRITE_SUCCESS', 16);
define('LOG_WRITE_NOTICE', 32);
define('LOG_WRITE_WARNING', 64);
define('LOG_WRITE_FATAL', 128);

define('LOG_HALT_ON_FATAL', 256);

/**
*  Log : formating data
*/
define('LOG_DISPLAY_TEXT', 0);
define('LOG_DISPLAY_HTML', 1);
define('LOG_DISPLAY_FLASH', 2);
define('LOG_DISPLAY_XML', 3);

/**
*  Log : levels for log to file/display (Level for Log::logHandler())
*/
define('LOG_LV_SUCCESS', 1);
define('LOG_LV_NOTICE', 2);
define('LOG_LV_WARNING', 4);
define('LOG_LV_FATAL', 8);

$GLOBALS['tbLog'] = array(
	LOG_LV_SUCCESS => array('type'=>'SUCCESS', 'color'=>'green'),     // 0
	LOG_LV_NOTICE => array('type'=>'NOTICE', 'color'=>'steelblue'),   // 1
	LOG_LV_WARNING => array('type'=>'WARNING', 'color'=>'#FF9900'), // 2
	LOG_LV_FATAL => array('type'=>'FATAL', 'color'=>'red')             // 3
);




// ---------------------------------------------------------------------
// ------------ CONFIGURATION DE LA GESTION DES ERREURS -----------
// ---------------------------------------------------------------------

/*
* Level for handle the error
*
* LOG_DISPLAY_SUCCESS = Display SUCCESS to screen
* LOG_DISPLAY_NOTICE = Display NOTICE to screen
* LOG_DISPLAY_WARNING = Display WARNING to screen
* LOG_DISPLAY_FATAL = Display FATAL Error to screen
*
* LOG_WRITE_SUCCESS = Write SUCCESS to log file
* LOG_WRITE_NOTICE = Write NOTICE to log file
* LOG_WRITE_WARNING = Write WARNING to log file
* LOG_WRITE_FATAL = Write FATAL Error to log file
*
* LOG_HALT_ON_FATAL = Halt script on FATAL Error
*
* Combine differents choices
*/
define('LOG_ERROR_LEVEL',
	LOG_DISPLAY_SUCCESS +
	//LOG_DISPLAY_NOTICE +
	//LOG_DISPLAY_WARNING +
	LOG_DISPLAY_FATAL +
	LOG_WRITE_SUCCESS +
	//LOG_WRITE_NOTICE +
	//LOG_WRITE_WARNING +
	LOG_WRITE_FATAL +
	LOG_HALT_ON_FATAL
);

/**
* Format for displaying Log
*
* LOG_DISPLAY_TEXT = return text Log
* LOG_DISPLAY_HTML = return text Log embed in HTML
* LOG_DISPLAY_FLASH = return text Log URL-encoded (for Flash player)
* LOG_DISPLAY_XML = return text Log with XML TAG
*
* One choice
*/
define('LOG_FORMAT_TO_DISPLAY', LOG_DISPLAY_HTML);

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

12 mars 2006, 23:17

Okay je crois avoir compris le problème ^^

Si j'étais toi je modifierais la méthode logHandler() afin qu'elle renvoi un booléen : true = continuer, false = stopper.
Ainsi ton appel $this->logHandler("mon message", LOG_LV_*)
deviendrait if (!$this->logHandler("mon message", LOG_LV_*) return;
Et dans ta méthode logHandler() tu n'as qu'à tester la valeur de ton LOG_LV_* pour savoir si tu renvoies false (stopper l'exécution de la fonction en cours), ou true (continuer).

Exemple :
class Loggable {
  var $stopLevels = array();
  function log($message, $level) {
    echo $message;
    return !in_array($stopLevels, $level);
  }
}

class MaClasse extends Loggable {
  function MaClasse () {
    $this->stopLevels = array(LOG_LV_FATAL);
  }
  function fonctionQuiContinue() {
    echo "debut";
    if (!$this->log("message", LOG_LV_WARNING)) return;
    echo "fin";
  }
  function fonctionQuiNeContinuePas() {
    echo "debut";
    if (!$this->log("message", LOG_LV_FATAL)) return;
    echo "fin";
  }
}

Eléphant du PHP | 254 Messages

13 mars 2006, 00:06

dans le 1er script :
return $this->logHandler( ..... 
la methode renvoit deja un booleen, TRUE pour un SUCCESS et FALSE sinon

--------------------
pour en revenir a ma "question metaphysique" :
le but serait de pouvoir configurer hors de la classe LOG ou du fichier de config, et donc sans etre obligé de retoucher le code trop en profondeur comme rajouter X variables en arguments a chaque fonction afin de personnaliser chaque action de ces methodes en cas d'erreur.

Administrateur PHPfrance
Administrateur PHPfrance | 3131 Messages

13 mars 2006, 00:09

Je comprends vraiment pas ce que tu veux dire désolé :?

Eléphant du PHP | 254 Messages

13 mars 2006, 00:24

c'est pas grave, merci les gars, je crois que je vais faire un autre sujet avec comme titre :
comment feriez vous une classe LOG :D