Prosty logger
27 Aug 2009, 16:34:25
Więc, prosty logger. Niby trywialna rzecz, ale czasem przydatna - funkcja zrzuca wyjątek; dlaczego nie dość, że musimy go obsłużyć, to jeszcze zapisać do logów? Dlaczego fakt zalogowania się użytkownika musimy zapisać, ręcznie wywołując fopen, fwrite i fclose? Tutaj wkracza moja klasa logger. Uwaga: prawdopodobnie można to było napisać ładniej, krócej, czytelniej i funkcjonalniej - ale chciałem pokazać moją wizję takiej klasy.
Zaczynamy.
Plik logger.class.php
<?php
class logger
{
private $logfolder, $extension, $eventtypes;
function __construct($logfolder, $ext)
{
$this->logfolder = $logfolder;
$this->extension = $ext;
$this->eventtypes = array();
}
Zmienne:logger::logfolder przechowuje folder, w którym znajdują się pliki logów. Może być inicjowane w konstruktorze np. identyfikatorem sesji.
logger::extension przechowuje rozszerzenie plików logów (bez kropki!).
Konstruktora nie muszę chyba objaśniać.
public function addeventtype($type, $file)
{
$this->eventtypes[$type] = $file;
}
public function deleteeventtype($type)
{
unset($this->eventtypes[$type]);
}
public function modifyeventtype($type, $newfile)
{
if (isset($this->eventtypes[$type]))
{
$this->eventtypes[$type] = $newfile;
return true;
}
return false;
}
Coś, co pozwala powiązać tekst do zapisania do logów z plikiem typ zdarzenia. Przechowywane są one w tablicy logger::eventtypes. Powyższe funkcje (chyba są jasne dosyć) służą do dodawania, modyfikacji i usuwania typów zdarzenia.
public function writelog($eventtype, $message)
{
if (!isset($this->eventtypes[$eventtype]) && $this->eventtypes[$eventtype] == '')
{
return false;
}
$file = fopen($this->logfolder."/".$this->eventtypes[$eventtype].".".$this->extension, "a");
fwrite($file, date("d M Y, H:i:s: ").$message."\r\n");
fclose($file);
}
Funkcja służąca do zapisania informacji do logów. Pierwszy argument jest identyfikatorem typu, drugi tekstem, który ma być zapisany w pliku. Jak na razie klasa pozwala użyć jednego wywołania zamiast 3, bardziej skomplikowanych. Ale to nie wszystko ;)
public function callfunction($callback, $parameter)
{
if (!is_callable($callback))
{
return null;
}
try
{
return call_user_func_array($callback, $parameter);
}
catch (LoggerException $e)
{
$this->writelog($e->type(), $e->getmsg());
throw $e;
}
}
}
(Tak, to koniec klasy).Powyższa funkcja pozwala wywołać dowolną funkcję (przekazaną w pierwszym parametrze) przez loggera. Jeżeli funkcja ta zrzuca wyjątek wyprowadzony z pokazanej kawałek dalej klasy, to logger najpierw zapisuje wyjątek do logów (dokładniej to zapisuje wiadomość wygenerowaną przez klasę wyjątku), a potem zrzuca wyjątek dalej. W ten sposób możemy normalnie obsługiwać swoje wyjątki i jednocześnie mieć je w logach.
class LoggerException extends Exception
{
protected $code, $type;
function __construct($code)
{
$this->code = $code;
}
public function type()
{
return $this->type;
}
public function getmsg()
{
return $this->formatcode();
}
}
?>Ta klasa jest na tyle prosta, że nie będę jej objaśniał; tyle tylko, że funkcja formatcode() musi być zdefiniowana w klasie potomnej. I jeszcze mały przykład działania (z wyjątkiem). Kod:<?php
include "logger.class.php";
class Except extends LoggerException
{
function __construct($code)
{
parent::__construct($code);
$this->type = 'logger';
}
protected function formatcode()
{
return $this->code;
}
}
$logger = new logger("logs", "log");
$logger->addeventtype("logger", "logger");
function s($logger, $callback, $parameter)
{
return $logger->callfunction($callback, $parameter);
}
function lolwut($lolwut)
{
echo $lolwut;
throw new Except($lolwut." test");
}
echo "<br />".s($logger, "lolwut", array("WOW!"));
?>
Link: http://www.griwes.info/classess/loggertest.php
I cały kod:
<?php
class logger
{
private $logfolder, $extension, $eventtypes;
function __construct($logfolder, $ext)
{
$this->logfolder = $logfolder;
$this->extension = $ext;
$this->eventtypes = array();
}
public function addeventtype($type, $file)
{
$this->eventtypes[$type] = $file;
}
public function deleteeventtype($type)
{
unset($this->eventtypes[$type]);
}
public function modifyeventtype($type, $newfile)
{
if (isset($this->eventtypes[$type]))
{
$this->eventtypes[$type] = $newfile;
return true;
}
return false;
}
public function writelog($eventtype, $message)
{
if (!isset($this->eventtypes[$eventtype]) && $this->eventtypes[$eventtype] == '')
{
return false;
}
$file = fopen($this->logfolder."/".$this->eventtypes[$eventtype].".".$this->extension, "a");
fwrite($file, date("d M Y, H:i:s: ").$message."\r\n");
fclose($file);
}
public function callfunction($callback, $parameter)
{
if (!is_callable($callback))
{
return null;
}
try
{
return call_user_func_array($callback, $parameter);
}
catch (LoggerException $e)
{
$this->writelog($e->type(), $e->getmsg());
throw $e;
}
}
}
class LoggerException extends Exception
{
protected $code, $type;
function __construct($code)
{
$this->code = $code;
}
public function type()
{
return $this->type;
}
public function getmsg()
{
return $this->formatcode();
}
}
?>Na koniec: wiem, że nie jest to opisane tak, że nowicjusz zrozumie, ale może po prostu użyć :P
Skomentowano 0 razy.