[PHP] Debugage des applications

Debugage des applications [PHP] - PHP - Programmation

Marsh Posté le 28-02-2006 à 10:53:47    

Bonjour à tous,
 
Mon site prend de l'essort et au fil des modifications, il s'etoffe et devient de plus en plus complexe.
Malgrés les phases de tests, il arrive que malheureusement un bug se glisse sur mes pages.
 
J'ai decouvert recemment la splendide fonction php : set_error_handler
Ainsi à chaque Warning et/ou Notice ma fonction d'erreur personnailsée m'envoie un mail et je peux ainsi corriger dans la foulée.
 
Voila en gros ma fonction :
 

Code :
  1. function myErrorHandler($errorLvl, $message, $file, $lineNum, $context=array()) {
  2. global $CONF;
  3. switch ($errorLvl) { //Niveau de l'erreur
  4.  case E_WARNING:     $errorType = 'E_WARNING';      break;
  5.  case E_NOTICE:      $errorType = 'E_NOTICE';       break;
  6.  case E_USER_ERROR:  $errorType = 'E_USER_ERROR';   break;
  7.  case E_USER_WARNING:$errorType = 'E_USER_WARNING'; break;
  8.  default:            $errorType = 'Erreur inconnue';break
  9. }
  10. if($CONF['show_errors']){
  11.  //affiche l'erreur
  12.  print("<div class='error'>".$errorType.": ".$message." in ".$file." line ".$lineNum."</div>" );
  13. }else{
  14.  //envoie un mail
  15.  $out  = "Bonjour,\n\nUne erreur de type ".$errorType." est survenue dans le script :\n".$file." à la ligne ".$lineNum."\n\n";
  16.  $out .= $message."\n\n";
  17.  $out .= print_r($context,TRUE);
  18.  $out .= "Cordialement\n\nmyErrorHandler pour fluminis";
  19.  if(email(
  20.   "you@yoursite.com",
  21.   $CONF['admin_mail'],
  22.   "Erreur reporting : ".$errorType.": ".$file." (".$lineNum." )",
  23.   $out
  24.   )){
  25.   print_error("Une erreur est survenue, d&eacute;sol&eacute; pour la g&egrave;ne occasionn&eacute;e." );
  26.  }else{
  27.   print_error("Une erreur est survenue, d&eacute;sol&eacute; pour la g&egrave;ne occasionn&eacute;e. Veuillez contacter les administrateur du site pour qu'ils corrigent cette erreur au plus vite" );
  28.  }
  29. }
  30. }
  31. //activation de mon gestionnaire d'erreur personnalisé
  32. set_error_handler("myErrorHandler" );


 
$CONF['show_errors'] me permet d'afficher l'erreur sur mon serveur de test, sur le serveur de prod, il est à false.
$CONF['admin_mail'] contient l'email de la personne a prevenir
la fonction 'email' remplace la fonction 'mail' de php chez mon hebergeur
 
J'aimerai savoir comment vous faites sur vos sites web pour gerer et tracker ces bugs qui peuvent survenir.
Et comment je pourrai amméliorer ma fonction de traitement d'erreur.


Message édité par fluminis le 28-02-2006 à 10:56:33

---------------
http://poemes.iceteapeche.com - http://www.simuland.net
Reply

Marsh Posté le 28-02-2006 à 10:53:47   

Reply

Marsh Posté le 28-02-2006 à 11:11:31    

perso j'ai aucun moyen de traquer les bugs en phase de prod :x
 
Je connaissais pas non plus ce que tu as montré, merci de l'info, et ça m'a l'air pas mal fait ton truc

Reply

Marsh Posté le 28-02-2006 à 11:25:54    

pas bête...mais plutôt qu'envoyer un mail avec le contenu de l'erreur j'aurais plutôt écrit l'erreur dans un log et envoyé un mail juste pour prévenir d'aller lire le log...au moins si l'envoi de mail échoue tu perds pas d'info...;)


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 28-02-2006 à 11:29:26    

pfiou c'est énorme cette fonction set_error_handler, merci de ce post !

Reply

Marsh Posté le 28-02-2006 à 11:31:52    

pas idiot, je pense rarement au log,
enfin si j'y pense mais comme ecrire dans un fichier log ne me previent pas, je ne vais pas voir le log et c'est comme si je ne n'etais pas au courant de l'erreur. Conjointement à un envois de mail pourquoi pas...
 
Par contre, en l'etat, la fonction n'est pas tip top pour les erreurs SQL.
Il va falloir que je rajoute un test ou deux pour recupérer l'erreur mysql.
 
Je viens de voir la fonction debug_backtrace egalement qui semble très prometteuse...


Message édité par fluminis le 28-02-2006 à 11:40:31

---------------
http://poemes.iceteapeche.com - http://www.simuland.net
Reply

Marsh Posté le 28-02-2006 à 11:36:55    

Pour le log (fichier, e-mail ou autre), y'a error_log() ;)

Reply

Marsh Posté le 28-02-2006 à 11:41:24    

Pour les erreurs MySQL, j'ai en fait un singleton qui gère la connexion et toutes les requetes à la base.  
Ce singleton retourne une valeur pour chaque type d'erreur (erreur de connection, erreur de requête, ...), ce qui permet d'appeler un gestionnaire d'erreur qui fait ce que tu veux derrière. Facile à intégrer à ton système donc.
Voilà, my2cents

Reply

Marsh Posté le 28-02-2006 à 11:57:45    

Perso j'ai mis en parallele de ma fonction myErrorhandler les fonctions suivantes pour l'acces à la bdd :
 

Code :
  1. //Identifiant de connection
  2. $LINK = 0;
  3. /*
  4. * Connexion à la base de données
  5. * Ouvre la connexion et met à jour la variable $LINK
  6. */
  7. function db_connect(){
  8. //get variables
  9. global $LINK,$CONF; //$host, $user, $password,$base;
  10. if($LINK == 0){
  11.  if($LINK = @mysql_connect($CONF['host'], $CONF['user'], $CONF['password'])){
  12.   //ok the connection is established
  13.   if(! @mysql_select_db($CONF['base'],$LINK)){
  14.    print_error("Une erreur est survenue lors de la connexion &agrave; la base de donn&eacute;es. Veuillez nous excuser pour la g&egrave;ne occasionn&eacute;e." );
  15.    return false;
  16.   }
  17.  }else{
  18.   print_error("Une erreur est survenue lors de la connexion &agrave; la base de donn&eacute;es. Veuillez nous excuser pour la g&egrave;ne occasionn&eacute;e." );
  19.   return false;
  20.  }
  21. }
  22. //else a mysql connection is already openned
  23. return true;
  24. }
  25. /*
  26. * Execute une query
  27. * Si besoin on peut logguer les erreurs sql ici
  28. */
  29. function db_query($sql){
  30. global $LINK,$CONF;
  31. if(db_connect()){
  32.  $result = @mysql_query($sql,$LINK);
  33.  if(!$result){
  34.   $out  = "Bonjour,\n\nUne erreur MySql est survenue\n\n";
  35.   $out .= $sql."\n\n";
  36.   $out .= "MySQL error ".mysql_errno().": ".mysql_error()."\n";
  37.   $out .= "Cordialement\n\nmyErrorHandler pour fluminis";
  38.   if(!email(
  39.    "fluminis@iceteapeche.com",
  40.    $CONF['admin_mail'],
  41.    "[Poemes d'Icetea] Erreur reporting : Mysql",
  42.    $out
  43.    ) && $CONF['show_errors']){
  44.     print_error("Une erreur est survenue, d&eacute;sol&eacute; pour la g&egrave;ne occasionn&eacute;e. Veuillez contacter les administrateur du site pour qu'ils corrigent cette erreur au plus vite" );
  45.   }
  46.  }
  47.  return $result;
  48. }else{
  49.  return 0;
  50. }
  51. }


 
Mais je pense qu'il est possible de ne pas mettre l'envois de mail une deuxieme fois ici mais de tout regrouper dans myErrorhandler...


---------------
http://poemes.iceteapeche.com - http://www.simuland.net
Reply

Marsh Posté le 28-02-2006 à 12:03:06    

ou une fonction a part qui fait l'envoie de mail, que tu appelles dans ton gestionnaire d'erreur PHP et MySQL. Bête et méchant quoi (ouais c'est mon jour de messages super constructifs je sais)

Reply

Marsh Posté le 28-02-2006 à 15:06:08    

D'autres idées pour la gestion et le deguscage des bugs sur un site web ?


---------------
http://poemes.iceteapeche.com - http://www.simuland.net
Reply

Marsh Posté le 28-02-2006 à 15:06:08   

Reply

Marsh Posté le 28-02-2006 à 15:20:54    

Djebel1 a écrit :

ou une fonction a part qui fait l'envoie de mail, que tu appelles dans ton gestionnaire d'erreur PHP et MySQL. Bête et méchant quoi (ouais c'est mon jour de messages super constructifs je sais)


Je me demande ce qui se passerait si cette fonction provoque une erreur. :lol:
C'est un coup à avoir une belle boucle sans fin.

Reply

Marsh Posté le 28-02-2006 à 15:21:08    

coder bien du premier coup? [:petrus dei]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 28-02-2006 à 15:48:53    

Même bien codé, si le programme d'envoie de mail plante, t'as pas droit à uen belle alerte?

Reply

Marsh Posté le 28-02-2006 à 15:49:27    

euh, c'était une connerie, hein.[:petrus75]


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 28-02-2006 à 15:50:01    

dans l'un des articles gratuits de nexen.net, j'avais vu un outil pour débugger du php, mais ça supposait avoir mis des instructions par-ci par-là dans ses scripts pour que l'outil fonctionne. Ca reposait sur debug_backtrace(), il me semble...

Reply

Marsh Posté le 28-02-2006 à 16:01:47    

En surfant sur nexen, j'ai trouvé une classe de debugage téléchargeable ici : http://phpdebug.sourceforge.net  
 
Par contre j'ai pas testé.
il semble que ça utilise la librairie PEAR. J'en entends beaucoup parler mais je ne sais pas dutout ce que c'est. Est-ce qu'il faut l'installer (la librairie pear) ou elle est disponible par defaut dans php ?


---------------
http://poemes.iceteapeche.com - http://www.simuland.net
Reply

Marsh Posté le 28-02-2006 à 17:52:49    

fluminis a écrit :

En surfant sur nexen, j'ai trouvé une classe de debugage téléchargeable ici : http://phpdebug.sourceforge.net  
 
Par contre j'ai pas testé.
il semble que ça utilise la librairie PEAR. J'en entends beaucoup parler mais je ne sais pas dutout ce que c'est. Est-ce qu'il faut l'installer (la librairie pear) ou elle est disponible par defaut dans php ?


 
Je ne sais pas s'il s'agit de la même librairie dont je parlais précédemment.
Pear est un ensemble de packages php réalisant des fonctions dont on a souvent besoin dans un projet de site web ; ça évite de réinventer la roue à chaque fois.
Certains package de Pear sont filés avec easyphp (DB, par ex, qui est une couche d'abstraction de SGBD). C'est bien pratique :)

Reply

Marsh Posté le 01-03-2006 à 09:31:53    

Toujours dans mes recherches de gestion d'erreur, je viens de trouver cette page :
http://frederic.bouchery.free.fr/? [...] es-Erreurs
 
Il se sert de la fonction debug_backtrace pour recupérer le nom de la fonction qui a générée l'erreur, et d'un tableau associatif pour appeller la fonction de gestion d'erreur correspondante.
 
C'est une idée à creuser, peut etre qu'avec ca on pourrait savoir plus facilement qu'il y a eu une erreur mysql et ainsi afficher/envoyer un mail avec l'erreur mysql...


---------------
http://poemes.iceteapeche.com - http://www.simuland.net
Reply

Marsh Posté le 08-03-2006 à 09:58:39    

Bien...
Finalement envoyer un mail à chaque erreur ne semble pas une bonne idée :
j'ai eu une erreur Notice dans une boucle...
La page etait assez visitée. Bilan un tentaine de passage dans la boucle par page vue : j'ai recu un nombre incalculable de mails !
De même sur un site perso free, ça a explosé mon quota de mail :(
La technique est encore à paufiner.
 
Le log proposé plus haut, pourquoi pas mais si je continue à envoyé en parallele un mail pour me signaler qu'il y a une erreur, je vais revenir au meme probleme.
Des idées pour améliorer ca ?


---------------
http://poemes.iceteapeche.com - http://www.simuland.net
Reply

Marsh Posté le 08-03-2006 à 11:04:01    

Mes idées persos vite fait :

  • stocker toutes les erreurs dans un tableau et ne générer un mail que si l'erreur n'a pas déjà été répertorié. Mais s'il y a des erreurs en chaine, t'auras quand même droit à pleins de mails.
  • sotcker toutes les erreurs dans un tableau et ne générer le mail que tout à la fin du script si le tableau est vide. Probléme possible : une erreur fatale et le script s'arrêtera avant d'arriver à la vérification du nombre d'erreur et l'envoie de mail.
  • stocker toutes les erreurs dans un tableau avec un status "erreur envoyé par mail? oui/non" et envoyer le mail dés qu'on tombe sur une erreur qui n'est ni une alerte (E_USER_WARNING) ni une "note" (E_USER_NOTICE) ou quand le script se termine (s'il reste des alertes non envoyé)


Je pense que c'est la derniére solution qui envéra le moins de mail en perdant le minimum d'infos.

Reply

Marsh Posté le 08-03-2006 à 11:18:07    

Ton idée de tableau est interessante.
Je vais regarder ca.
Ce qui est dommage, c'est que je vais devoir rajouter quelquechose à la fin de mes scripts. Là, une seule ligne en haut de mes scripts (include("debug.php" ); ) suffisait...


Message édité par fluminis le 08-03-2006 à 11:18:20

---------------
http://poemes.iceteapeche.com - http://www.simuland.net
Reply

Marsh Posté le 08-03-2006 à 11:22:22    

Je sais plus si c'est toujours faisable en php5, mais avec php3 et 4, (a moins que ca soit géré par apache, je sais plus) il était possible de faire appeler un fichier php à la fin de l'exécution de chaque script php (une sorte d'include pas visible) et il était même possible de faire ça avant l'exécution de chaque script php.
 
Mais je n'ai jamais été fan de cette façon de faire et je ne me souviens plus du tout comment c'est faisable.
 
Personellement, j'ai un script qui apelle tous les autre en fonction de ce qui est demandé comme ça, j'ai qu'un seul fichier à modifier pour ce genre de chôse.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed