Laravel 5 发送错误到电子邮件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33163893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel 5 Send Errors to Email
提问by West55
I am trying to figure out how I can send errors to my email in Laravel 5. I haven't had much luck finding any good resources.
我想弄清楚如何在 Laravel 5 中向我的电子邮件发送错误。我没有找到任何好的资源。
There used to be good packages like: https://github.com/TheMonkeys/laravel-error-emailerThat did this for you in Laravel 4.
曾经有一些不错的软件包,例如:https: //github.com/TheMonkeys/laravel-error-emailer在 Laravel 4 中为您做了这些。
They have yet to release a Laravel5 update because of the way they changed error handling... which I am also not to familiar with.
他们还没有发布 Laravel5 更新,因为他们改变了错误处理的方式……我也不熟悉。
I have a few Laravel 5 applications which I need to monitor but I need a more efficient way of doing it besides checking error logs on storage.
我有一些需要监控的 Laravel 5 应用程序,但除了检查存储上的错误日志之外,我还需要一种更有效的方法。
Any help would be greatly appreciated. I know there are others out there seeking this information as well.
任何帮助将不胜感激。我知道还有其他人也在寻求这些信息。
回答by Subash
You can do this by catching all the errors in the App\Exceptions\Handler::report()
. So in you App/Exceptions/Handler.php
add a report
function if its not already there.
您可以通过捕获App\Exceptions\Handler::report()
. 所以在你App/Exceptions/Handler.php
添加一个report
函数,如果它不存在的话。
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $e
* @return void
*/
public function report(\Exception $e)
{
if ($e instanceof \Exception) {
// emails.exception is the template of your email
// it will have access to the $error that we are passing below
Mail::send('emails.exception', ['error' => $e->getMessage()], function ($m) {
$m->to('your email', 'your name')->subject('your email subject');
});
}
return parent::report($e);
}
If you need more info, refer to laravel documentation form mailerand errors.
回答by West55
EDIT: I found a 3rd party log system built for Laravel
编辑:我发现了一个为 Laravel 构建的 3rd 方日志系统
www.understand.io
www.understand.io
Very nice solution, doesn't email me, but this works for what I need.
非常好的解决方案,不会给我发电子邮件,但这适用于我的需要。
I played around with this and went through the Laravel core files and came up with something similar to what you see on an error page.
我玩弄了这个并浏览了 Laravel 核心文件,并提出了类似于您在错误页面上看到的内容。
You just need to create a view file that echos out $content for the email
您只需要创建一个视图文件来回显电子邮件的 $content
public function report(\Exception $e)
{
if ($e instanceof \Exception) {
$debugSetting = Config::get('app.debug');
Config::set('app.debug', true);
if (ExceptionHandler::isHttpException($e)) {
$content = ExceptionHandler::toIlluminateResponse(ExceptionHandler::renderHttpException($e), $e);
} else {
$content = ExceptionHandler::toIlluminateResponse(ExceptionHandler::convertExceptionToResponse($e), $e);
}
Config::set('app.debug', $debugSetting);
$data['content'] = (!isset($content->original)) ? $e->getMessage() : $content->original;
Mail::queue('errors.emails.error', $data, function ($m) {
$m->to('[email protected]', 'Server Message')->subject('Error');
});
}
return parent::report($e);
}
回答by hogan
The other answers seem quite right. We have done this a while ago and found one big issue with this: If the mail command fails, it can result in a infinite loop of throwing an error and trying to send the according email which will result in a failure again... This will fill up the log quite quickly and kill your server.
其他答案似乎很正确。我们不久前已经这样做了,并发现了一个大问题:如果邮件命令失败,可能会导致无限循环,抛出错误并尝试发送相应的电子邮件,这将再次导致失败......这将很快填满日志并杀死您的服务器。
Bear this in mind and don't send an email in that case.
请记住这一点,在这种情况下不要发送电子邮件。
Side Note: I decided to put this in the answer because it is relevant to all answers and should not get hidden in one comment.
旁注:我决定将其放在答案中,因为它与所有答案相关,不应隐藏在一个评论中。
回答by Jerodev
You can use the Exception Handlerfor this. Place your mail code in the report function and it will email you the error every time one occurs.
您可以为此使用异常处理程序。将您的邮件代码放在报告功能中,它会在每次发生错误时通过电子邮件发送给您。
回答by StevePorter
Theres a package here https://github.com/designmynight/laravel-log-mailerthat adds a mail driver to Laravel 5.6's LogManager which should do exactly what you are after.
这里有一个包https://github.com/designmynight/laravel-log-mailer,它向 Laravel 5.6 的 LogManager 添加了一个邮件驱动程序,它应该完全符合你的要求。
There are configuration settings in the config/logging.php file and you can create different mail channels for logging information to different recipients. The email template is also customisable.
config/logging.php 文件中有一些配置设置,您可以创建不同的邮件通道来将信息记录到不同的收件人。电子邮件模板也是可定制的。
回答by Francisco Corrales Morales
Here is the solution for Laravel 5.3
这是 Laravel 5.3 的解决方案
#file: /app/Exceptions/Handler.php
public function report(Exception $e)
{
if($this->shouldReport($e)){
\Mail::send(
['html' => 'error.emails.exception'],
['content' => $data['content']],
function ($m) {
$m->from(['[email protected]']);
$m->to(['[email protected]']);
$m->subject('Crash Report');
}
);
}
parent::report($e);
}
- You need to create the exception.blade.php file in /resources/views/emails
- I advise you to use this content, to make the email look the same as Laravel's error page.
- 您需要在 /resources/views/emails 中创建 exception.blade.php 文件
- 我建议你使用这个 content,让邮件看起来和 Laravel 的错误页面一样。
回答by markharp1
I expanded on West55's answer, to include some request info in the email. Useful to know, especially when you want to try and duplicate the error yourself. It's wrapped in a try/catch just to make sure we don't throw another exception while getting request info.
我扩展了 West55 的回答,在电子邮件中包含了一些请求信息。了解这一点很有用,尤其是当您想自己尝试复制错误时。它包含在 try/catch 中只是为了确保我们在获取请求信息时不会抛出另一个异常。
public function report(Exception $e)
{
if ($e instanceof Exception){
$debugSetting = \Config::get('app.debug');
// email err if debug off (in prod env)
if (!$debugSetting){
\Config::set('app.debug', true);
if (ExceptionHandler::isHttpException($e)) {
$content = ExceptionHandler::toIlluminateResponse(ExceptionHandler::renderHttpException($e), $e);
} else {
$content = ExceptionHandler::toIlluminateResponse(ExceptionHandler::convertExceptionToResponse($e), $e);
}
\Config::set('app.debug', $debugSetting);
$lc2 = (isset($content->original)) ? $content->original : $e->getMessage();
// add request info to err msg
$lc1= '';
try{
$request= request();
$lc1=
"<div>" .
"-- Request --<br>" .
"<br>Method: " . $request->getMethod() .
"<br>Uri: " . $request->getUri() .
"<br>Ip: " . $request->getClientIp() .
"<br>Referer: " . $request->server('HTTP_REFERER') .
"<br>Is secure: " . $request->isSecure() .
"<br>Is ajax: " . $request->ajax() .
"<br>User agent: " . $request->server('HTTP_USER_AGENT') .
"<br>Content:<br>" . nl2br(htmlentities($request->getContent())) .
"</div>";
}catch (Exception $e2){}
if (strpos($lc2, '</body>') !== false){
$lc2= str_replace('</body>', $lc1 . '</body>', $lc2);
}else{
$lc2.= $lc1;
}
$la2['content']= $lc2; //put into array for blade
$ln1= Mail::send('emails.exception2', $la2, function($m){
$m->to('[email protected]')
->subject('Fatal Error');
});
}
}
parent::report($e);
}
回答by MingalevME
/config/logging.php
/config/logging.php
// ...
'monitoring-mail' => [
'driver' => 'custom',
'via' => App\Logging\Mail::class,
'level' => env('LOG_MONITORING_MAIL_LEVEL', 'error'),
'to' => env('LOG_MONITORING_TO'),
'from' => env('LOG_MONITORING_FROM'),
],
// ...
/app/Logging/Mail.php
/app/Logging/Mail.php
<?php
namespace App\Logging;
use App\Helpers\Log\MailHandler;
use Monolog\Logger;
class Mail
{
public function __invoke(array $config)
{
$handler = new MailHandler($config['to'], $config['level'], $config['bubble'] ?? true, $config);
return new Logger('mail', [$handler]);
}
}
/app/Helpers/Log/MailHandler.php
/app/Helpers/Log/MailHandler.php
<?php
namespace App\Helpers\Log;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Mail;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
class MailHandler extends AbstractProcessingHandler
{
/** @var string */
protected $to;
/** @var array */
protected $config;
public function __construct(string $to, $level = Logger::DEBUG, bool $bubble = true, ?array $config = null)
{
parent::__construct($level, $bubble);
if (empty($to)) {
throw new \InvalidArgumentException('"To" cannot be empty');
}
$this->to = $to;
$this->config = (array) $config;
}
protected function write(array $record): void
{
$body = $record['formatted'] ?? $record['message'] ?? '<empty>';
Mail::raw($body, function (Message $message) use ($record) {
$subject = ($record['level_name'] ?? 'ERROR') . ': ' . ($record['message'] ?? '<empty>');
$message->to($this->to);
$message->subject($subject);
if (!empty($this->config['from'])) {
$message->from($this->config['from']);
}
});
}
}