• User Attivo

    [Script] Classe per Debug e Logging

    Buona Serata,
    volevo proporvi il sistema di Logging che ho messo a punto, ed uso tuttora, per poter eseguire il debug delle mie applicazioni PHP.

    Si tratta di una semplice classe che permette di eseguire il debug di una PHP Application sul server, locale o remoto, in cui sta girando.

    Premessa
    Ho creato questa classe per soddisfare le mie esigenze, ma sicuramente potrebbe tornare utile anche ad altri, quindi la posto per tutti.

    Ciò di cui normalmente ho bisogno durante lo sviluppo di una web application si può riassumere in questi pochi punti:

    • Differenziare i log generati da PHP sul file error.log dai miei;
    • Poter creare file di log diversi per ogni componente della mia applicazione;
    • Gestire a runtime il flusso dei log per controllare gli esiti in modo organico ed ordinato;
    • Eventualmente svuotare i file di log;
    • Interrompere il debug applicativo in maniera centralizzata;

    La classe MaLogger si presta sia ad un utilizzo 'smart', ossia per tener traccia di qualche dato o risultato in modo rapido e snello, sia per eseguire un 'dump' di tutte le informazioni utili nell'intero flow della web application.

    [php]
    class MaLogger{
    private static $DEFAULT_LOG_FILE_NAME = "MaLog.log";
    const OPEN_LOG_FILE_FOR_WRITE = "a";
    const CREATE_NEW_LOG_FILE_FOR_WRITE = "w";
    public static $DEBUG_ACTIVATED = true;

    private $handle = false;
    
    /**
     * Crea un'istanza della classe.
     * 
     * @param $mode     Modalita  di creazione del file di log.
     * @param $filename Nome da attribuire al file di log.Il parametro è comprensivo di path.
     *                  Se $filename è null verrà  utilizzato $DEFAULT_LOG_FILE_NAME.
     */
    public function __construct($mode, $filename = null){
        $fileName = ($filename == null || !isset($filename)) 
                        ? MaLogger::$DEFAULT_LOG_FILE_NAME : $filename;
                        
        if($mode != MaLogger::OPEN_LOG_FILE_FOR_WRITE 
                && $mode != MaLogger::CREATE_NEW_LOG_FILE_FOR_WRITE)
            throw new Exception(
                '[MaLogger]:Modalità  di apertura file di log inesistente[' . $mode . '].'
                , $fileName);
        
            //Creo il file
            $this->handle = fopen($fileName, $mode);
            
                if($this->handle == null || !$this->handle)
                    throw new Exception('Impossibile creare o aprire il File di Log', $fileName);
    }
    
    /**
     * Scrive sul file di Log.
     *
     * @param String $text    Le informazioni da scrivere;
     * @return int        Il numero di byte scritti;
     */
    public function append($text){
        return (MaLogger::$DEBUG_ACTIVATED) ? fwrite($this->handle,$text . "\n") : 0;
    }
    
    /**
     * Chiudo il file di Log
     *
     * @return boolean    true se il file viene chiuso correttamente altrimenti false;
     */
    public function closeLogFile(){
                return fclose($this->handle);
    }
    
    /**
     * Crea un'istanza della classe MaLogger.
     *
     * @param String $mode        Modalità  di apertura del file.
     * @param String $filename    Nome opzionale del file di log.
     * @return MaLogger        Istanza di classe.
     */
    private static function initLogFile($mode,$filename=null){
        return new MaLogger($mode,$filename);
    }
    
    /**
     * Modalità  smart.
     * Crea un file di log, ci scrive le informazioni
     * e chiude la connessione.
     * 
     * @param    $text        Informazioni da tracciare. 
     * @param    $mode        Modalità  di apertura del file di log
     * @param    $filename    Nome del file di log(OPZIONALE).
     */
    public static function logThis($text,$mode,$filename=null){
        if(MaLogger::$DEBUG_ACTIVATED){
            $log = MaLogger::initLogFile($mode,$filename=null);
            $log->append($text);
            $log->closeLogFile();
        }
    }
    

    }
    [/php]Ma come si utilizza?
    Dunque,
    ora mostrerò tramite un esempio come utilizzare la classe
    per poter scrivere informazioni su un file di log.
    L'esempio ovviamente mostrarà l'utilizzo di entrambe le modalità
    sopra descritte.

    [php]
    <?php
    include './MaLogger.php';

    class MaObject{
    public $initialized = false;
    public $value = '';

    public function __construct($value = ''){
    $this->value = $value;
    $this->initialized = true;
    }
    }

    try{
    //Creo un'istanza per appendere informazioni.
    //scrivo su MaLogger:$DEFAULT_LOG_FILE_NAME
    $log = new MaLogger(MaLogger:OPEN_LOG_FILE_FOR_WRITE);
    $log->append('File di debug creato.\nInizio test.\n');

    //Utilizzo di MaLogger in modalità smart.
    //Scriverà su un nuovo file per tracciare i dati su file separati.
    $obj1 = new MaObject('Primo oggetto MaObject.');
    MaLogger::logThis('Stato di obj1: ' . $obj1->initialized
    ,MaLogger::OPEN_LOG_FILE_FOR_WRITE,'./MaObject1.log');
    $obj2 = new MaObject('Secondo oggetto MaObject.');
    MaLogger::logThis('Stato di obj2: ' . $obj2->initialized
    ,MaLogger::OPEN_LOG_FILE_FOR_WRITE,'./MaObject2.log');

    //Comunque tengo traccia di tutto il flusso dei dati
    //continuando ad utilizzare $log in modalità tradizionale
    $log->append('obj1 creato. Value = ' . $obj1->value . ';');
    $log->append('obj2 creato. Value = ' . $obj2->value . ';');
    $log->append('Esecuzione script terminata.');
    $log->closeLogFile();

    echo '<p>Hello people ;)</p>';
    }
    catch(Exception $e){
    die("Esecuzione interrotta. Si è verificata un'eccezione.nMessaggio:n$e");
    }
    ?>
    [/php]In fine, per poter disabilitare il debug in maniera centralizzata come da premessa,
    è sufficiente rendere falsa la proprietà $DEBUG_ACTIVATED.

    :ciauz: