Son*_*ngo 9 php logging design-patterns zend-framework
我正在使用Zend Framework构建应用程序.该应用程序需要密集记录代码中的每个操作或功能.
所以我的代码大部分时间都是这样的:
function SendMailsAction(){
$logger->log('Started sending mails.')
...
...
...Some Code...
...
...
foreach ($mails as $mail){
try{
$logger->log('Trying to send')
$mail->send()
$logger->log('Mail sent successfully.')
}catch(Exception $e){
$logger->log('Failed to send mail.')
}
}
...
...
...Some Code...
...
...
$logger->log('Finished sending mails.')
}
Run Code Online (Sandbox Code Playgroud)
有时我甚至必须登录2个表,因此大多数日志记录代码加倍,并且函数开始变得复杂和冗长.
我使用Zend框架Zend_Log进行日志记录,所以我的问题不是日志记录类本身,而是如何将日志记录代码与代码功能本身分开并保持关注点的分离.
有些人建议使用面向方面编程(AOP),但遗憾的是AOP for PHP对我的客户来说是不可接受的,所以我正在寻找面向对象的解决方案或最佳实践.
注意:
只是为了弄清楚我的问题不是如何使用Zend_Log,而是如何将日志记录添加到我的应用程序代码中.
有时我甚至必须登录2个表,因此大多数日志记录代码加倍,并且函数开始变得复杂和冗长.
它会很长.如果您的代码进行了大量的日志记录,那么它将很长,因为它必须记录,并且它记录的每个行操作都意味着代码中有一行.但是,它不应该是复杂的,因为日志记录是你可以做的最直接的事情之一.令我担心的是,你提到"有时我甚至必须登录2张桌子".在我的书,一,二,五,六十或千表,则是由一个线.每个记录器的代码不会加倍.如果你是复制粘贴一行,并$log改为$log2,你显然做错了(tm).
有些人建议使用面向方面编程(AOP),但遗憾的是AOP for PHP对我的客户来说是不可接受的,所以我正在寻找面向对象的解决方案或最佳实践.
很好,AOP.但它有缺点; 与debug_backtrace方法一样,性能受到重创.这一点,加上代码变得越来越"神奇",因为当你查看代码本身时,它会做一些不明确的事情.这会增加您调试应用程序的时间.
我的0.02美元?首先,不要重复自己:每个操作一个日志条目就足够了.使用可在运行时附加到某些类的灵活记录器.根据"严重性"或"类型" 决定是否在记录器中实际记录消息.总而言之,只需实现Observer模式:
<?php
namespace Foo;
class MailService {
public function attach( Observes $observer ) {
$this->observers[] = $observer;
}
public function notify( $message, $type = 'notice' ) {
foreach( $this->observers as $observer ) {
$observer->notify( $message, $type );
}
}
public function sendMail( ) {
$this->notify( 'Started sending mails', 'debug' );
$mails = array( );
foreach( $mails as $mail ) {
try {
$this->notify( 'Trying to send', 'debug' );
$mail->send( );
$this->notify( 'Mail sent succesfully', 'debug' );
}
catch( Exception $e ) {
$this->notify( 'Failed to send mail', 'notice' );
}
}
$this->notify( 'Finished sending mail', 'debug' );
}
}
interface Observes {
public function notify( $message, $type = 'notice' );
}
abstract class Logger implements Observes {
protected $types = array(
'debug' => 0,
'notice' => 1,
'warning' => 2,
'error' => 3
);
protected function code( $type ) {
return isset( $this->types[$type] ) ? $this->types[$type] : 0;
}
}
class FileLogger extends Logger implements Observes {
public function __construct( $filename ) {
$this->filename = $filename;
}
/**
* @todo replace the method body with a call to, say, file_put_contents.
*/
public function notify( $message, $type = 'notice' ) {
if( $this->code( $type ) > $this->code( 'notice' ) ) { // only for warning and error.
echo $message . "\n";
}
}
}
class DebugLogger extends Logger implements Observes {
public function notify( $message, $type = 'notice' ) {
if( $this->code( $type ) === $this->code( 'debug' ) ) { // only show "debug" notices.
echo $message . "\n";
}
}
}
$service = new MailService( );
$service->attach( new FileLogger( 'yourlog.txt' ) );
$service->attach( new DebugLogger( ) );
$service->sendMail( );
Run Code Online (Sandbox Code Playgroud)