RSS
Fouten ontvangen per e-mail

12 mei 2009

CodeIgniter, Programmeren

Fouten ontvangen per e-mail

Iedereen die al wel eens een website maakt, maakt het mee. Al is het maar een kleine website voor de lokale voetbalploeg, of een website voor het bedrijf van je pa (De Grill-Mobiel ;-) ). Op een dag loopt er iets fout op de website en moeten de mensen jouw komen opzoeken om het allemaal uit te leggen wat er juist fout ging. Meestal is de uitleg dan ‘ik klikte daar, of was het nu daar, of nee nee, daar klikte ik’ en ben je nog geen stap korter bij het oplossen van het probleem, dat misschien toch bij die eerste klik al voorkwam.

Zou het niet veel leuker zijn als je automatisch een e-mail kon ontvangen wanneer er iets fout gaat op een van je projecten. Wanneer dan de mensen naar je toe komen met hun probleem kan je trots zeggen: ‘ja, dat heb ik gisteren al opgelost, dat werkt terug zoals het hoort’. Mits een kleine extensie te schrijven voor het CodeIgniter framework is dit zo simpel als 1, 2, 3. Of zelfs nog makkelijker, want je moet helemaal niet kunnen tellen.

My_Log

Om deze extensie te kunnen schrijven, moeten we eerst op zoek naar de library die instaat voor het opvangen van alle foutmeldingen. In het CodeIgniter framework is dit de Log klasse. We maken een nieuw bestand aan in de map system/application/libraries/ en noemen dit MY_Log.php. In dit bestand zetten we het volgende:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
class MY_Log extends CI_Log
{
    var $levels = array('ERROR' => '1', 'DEBUG' => '2',  'INFO' => '3', 'ALL' => '4');
 
    function write_log($level = 'error', $msg, $php_error = FALSE)
    {
        $config =& get_config();
 
        if ($config['write_log'] === TRUE)
        {
            parent::write_log($level, $msg, $php_error);
        }
 
        $level = strtoupper($level);
 
        if ($config['email_log'] === TRUE && isset($this->levels[$level]) && $this->levels[$level] <= $config['log_threshold'])
        {
            $report = "<html><head><title>" . $config['log_email_title'] . "</title></head><body>";
            $report .= "<strong>Requested URI:</strong><br />http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "<br /><br />";
 
            if (isset($_SERVER['HTTP_REFERER'])) {
                $report .= "Referer:</strong><br />" . $_SERVER['HTTP_REFERER'] . "<br /><br />";
            }
 
            $report .= "<strong>User host:</strong><br />" . gethostbyaddr($_SERVER['REMOTE_ADDR']) . "<br /><br />";
            $report .= "<strong>Date:</strong><br />" . date('d-m-Y H:i:s') . "<br /><br />";
            $report .= "<strong>Error:</strong><br />" . $msg . "<br /><br />";
            $report .= "</body></html>";
 
            $headers  = 'MIME-Version: 1.0' . "\r\n";
            $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
            $headers .= 'From: ' . $config['log_email_from'] . "\r\n";
 
            mail($config['log_email_address'], $config['log_email_title'], $report, $headers);
        }
    }
}

Als je de broncode goed naleest zie je dat we enkele variabelen uit het config bestand van CodeIgniter uitlezen. We kunnen uiteraard niets uitlezen dat niet bestaat. Het is dan ook nodig de variabelen in kwestie aan te maken in het config bestand.

De fervente CodeIgniter gebruikers, waaronder ikzelf, willen uiteraard de Email klasse van CI gebruiken om de e-mail te versturen. Ik heb dit proberen te implementeren, maar dat is me niet gelukt. Om in een library aan het CI object te komen, moet je de get_instance() functie gebruiken. Deze functie wordt gedeclareerd nadat de Log klasse wordt geladen. Daardoor is het dus niet mogelijk op het CI object te verkrijgen in MY_Log, en is het dus ook niet mogelijk om de Email klasse te laden. Jammer, maar gelukkig doet de mail() functie van PHP het ook helemaal goed.

Het config bestand

In config.php (te vinden in system/application/config/) moeten de volgende items worden toegevoegd:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Vanaf welk niveau moeten er fouten gerapporteerd worden (deze variabele staat al in het config bestand)
$config['log_threshold'] = 1;
 
// True als je wil dat er effectief naar het logbestand geschreven wordt
$config['write_log'] = FALSE;
 
// True als je een e-mail wil ontvangen wanneer er een fout optreedt
$config['email_log'] = TRUE;
 
// Het e-mail adres naar welk de e-mail wordt verstuurd
$config['log_email_address'] = 'massimo@finalfrag.be';
 
// Het onderwerp van het e-mail bericht
$config['log_email_title'] = 'Project x foutmelding';
 
// De afzender van de e-mail
$config['log_email_from'] = 'Project x';

Het resultaat

Elke keer wanneer er nu een foutmelding op de website komt, bijvoorbeeld wanneer een PHP variabele niet kan worden gevonden of wanneer er een pagina niet werd gevonden, krijgen we een e-mail waarin meer info staat over de foutmelding. Een foutmelding ziet er als volgt uit:

1
2
3
4
5
6
7
8
9
10
11
12
REQUESTED URI:
http://www.finalfrag.be/blog/
 
USER HOST:
213.219.133.127.adsl.dyn.edpnet.net
 
DATE:
06-05-2009 19:37:29
 
ERROR:
Severity: Warning --> Cannot modify header information - headers already sent by (output started at /home/finalfrag.be/public_html/libraries/Exceptions.php:164)
/home/finalfrag.be/public_html/libraries/Smarty.php 99

Uit deze voorbeeldfoutmelding kunnen we afleiden dat er op http://www.finalfrag.be/blog/ al iets op het scherm getoond wordt voordat de sessie geladen wordt door CodeIgniter. Ook krijgen we meer informatie over de gebruiker die de foutmelding heeft veroorzaakt en wanneer.

Ik hoop dat deze blogpost je weer wat verder helpt in de mooie wereld van webontwikkeling. Vragen of opmerkingen passen zoals gewoonlijk mooi in het vakje hieronder.

Delen

Facebook Facebook     Twitter Twitter     TinyUrl: http://tinyurl.com/ctdd7l

Reageer zelf!