最佳实践:在 Laravel 5 应用中添加电子邮件错误日志记录的位置

Best Practice: Where to Add Email Error Logging in a Laravel 5 App

我的 AppServiceprovider::boot 方法中有以下代码,它确保每当记录任何带有警告或更高严重级别的内容时我都会收到一封电子邮件。

$message = \Swift_Message::newInstance( 'An Error has Occurred in XXX' )
    ->setTo( env('ERROR_EMAIL_TO') )
    ->setFrom( env('ERROR_EMAIL_FROM') )
    ->setReplyTo( env('ERROR_EMAIL_REPLY_TO') )
    ->setContentType( 'text/html' );
$swiftMailer = \Mail::getSwiftMailer();
$handler = new SwiftMailerHandler( $swiftMailer, $message, Logger::WARNING );
$handler->setFormatter( new HtmlFormatter() );
\Log::getMonolog()->pushHandler( $handler );

但是虽然这行得通,但我还是忍不住觉得它放错了地方。

您会在哪里将此代码添加到 Laravel 网络应用程序?

使用中间件怎么样?我已经编写了一些中间件来记录所有请求,以及过去 API 的响应,这些 API 可以轻松地发送电子邮件以通知用户错误(这几乎是我设置它的用例)。

在您的中间件 class 中使用 terminate() 方法将允许您在向用户发送响应后执行逻辑 - 因此您的电子邮件不应减慢体验对于最终用户。

namespace App\Http\Middleware;
use Closure;

class LogRequestAndResponseMiddleware
{
/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    return $next($request);
}

public function terminate($request, $response)
{
    // Send out an e-mail to you here
}

我认为这也可以让您有一个重构代码的好时机,这将有助于将逻辑移出中间件并进入其自己的责任范围。

在这种情况下,我想我目前想通过电子邮件接收通知,但我可能在未来的某个时候想通过 Websocket 发送事件。

因此,我将使用合约来总结逻辑并相应地实现它:

interface ErrorNotificationContract
{
    public function inform($user, $message)
}

class EmailErrorNotification implements ErrorNotificationContract
{
    protected $mail;

    public function __construct(Mail $mail)
    {
        $this->mail = $mail;
    }

    public function inform($user, $message)
    {
         // Your send e-mail logic.
    }
}

然后您可以使用服务提供商进行注册。副作用是您可以获得以下额外好处:

  • EmailErrorNotification 中的依赖注入(更好的可测试性)
  • 更好的解耦代码
  • 可以很容易更改的实现 - 只需创建一个新的 class 来实现 ErrorNotificationContract

在你的中间件中你可以这样做:

public function terminate($request, $response)
{
    // ...

    $errorNotifier->inform('youremail@domain.com', 'something bad happened');
}