当控制台命令出错时,如何用日志发送电子邮件?目前我已将我的应用配置为从网络界面发送电子邮件,它可以正常工作。 Swiftmailer假脱机被禁用。我的配置是:
monolog:
handlers:
main:
type: fingers_crossed
action_level: critical
handler: grouped
grouped:
type: group
members: [streamed, buffered]
streamed:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
buffered:
type: buffer
handler: swift
swift:
type: swift_mailer
from_email: info@site.com
to_email: username@site.com
subject: An Error Occurred!
level: debug
当我尝试执行抛出异常的php app/console test:exception-command -e prod
时,没有电子邮件发送。
答案 0 :(得分:1)
我遇到了同样的问题,经过几次尝试后我得到了解决方案。 问题是swiftmailer中的假脱机,它被配置为内存,所以我将其更改为文件
# app/config/config.yml
swiftmailer:
transport: %mailer_transport%
username: %mailer_user%
password: %mailer_password%
spool:
type: file
path: "%kernel.root_dir%/spool"
然后我在命令
中调用了记录器$this->logger = $this->getContainer()->get('logger');
$this->logger->critical('commands');
在命令之后我调用swiftmailer命令发送待处理的电子邮件
app/console swiftmailer:spool:send --env=prod
答案 1 :(得分:1)
它应该在您的swiftmailer配置中发送禁用假脱机的电子邮件,这应该会立即发送电子邮件而不是假脱机,并且您的命令使用记录器。
如果要使用内存假脱机,可以在命令的执行方法中刷新队列。
/**
* force emails to be sent out at the end of execute
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$container = $this->getContainer();
$logger = $container->get('logger');
$logger->critical('My Critical Error Message');
$mailer = $container->get('mailer');
$spool = $mailer->getTransport()->getSpool();
$transport = $container->get('swiftmailer.transport.real');
$spool->flushQueue($transport);
}
参考:http://symfony.com/doc/current/cookbook/console/sending_emails.html#using-memory-spooling
如果您想要记录未捕获的例外,则必须配置控制台事件以使用记录器。
http://symfony.com/doc/current/cookbook/console/logging.html#enabling-automatic-exceptions-logging
答案 2 :(得分:0)
对于Symfony< 2.3
还有另一种可能性,覆盖以下类可以帮助的Application类, 此应用程序类激活控制台的记录器并记录自动存在
//Acme/LoggingBundle/Console/Application.php
<?php
namespace Acme\LoggingBundle\Console;
use Symfony\Bundle\FrameworkBundle\Console\Application as BaseApplication;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\DependencyInjection\IntrospectableContainerInterface;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Input\ArgvInput;
class Application extends BaseApplication
{
private $originalAutoExit;
public function __construct(KernelInterface $kernel)
{
parent::__construct($kernel);
$this->originalAutoExit = true;
}
/**
* Runs the current application.
*
* @param InputInterface $input An Input instance
* @param OutputInterface $output An Output instance
*
* @return integer 0 if everything went fine, or an error code
*
* @throws \Exception When doRun returns Exception
*
* @api
*/
public function run(InputInterface $input = null, OutputInterface $output = null)
{
// make the parent method throw exceptions, so you can log it
$this->setCatchExceptions(false);
// store the autoExit value before resetting it - you'll need it later
$autoExit = $this->originalAutoExit;
$this->setAutoExit(false);
if (null === $input) {
$input = new ArgvInput();
}
if (null === $output) {
$output = new ConsoleOutput();
}
try {
$statusCode = parent::run($input, $output);
} catch (\Exception $e) {
/** @var $logger LoggerInterface */
$container = $this->getKernel()->getContainer();
$logger = null;
if($container instanceof IntrospectableContainerInterface){
$logger = $container->get('logger');
}
$message = sprintf(
'%s: %s (uncaught exception) at %s line %s while running console command `%s`',
get_class($e),
$e->getMessage(),
$e->getFile(),
$e->getLine(),
$this->getCommandName($input)
);
if($logger){
$logger->crit($message);
}
if ($output instanceof ConsoleOutputInterface) {
$this->renderException($e, $output->getErrorOutput());
} else {
$this->renderException($e, $output);
}
$statusCode = $e->getCode();
$statusCode = is_numeric($statusCode) && $statusCode ? $statusCode : 1;
}
if ($autoExit) {
if ($statusCode > 255) {
$statusCode = 255;
}
// log non-0 exit codes along with command name
if ($statusCode !== 0) {
/** @var $logger LoggerInterface */
$container = $this->getKernel()->getContainer();
$logger = null;
if($container instanceof IntrospectableContainerInterface){
$logger = $container->get('logger');
}
if($logger){
$logger->warn(sprintf('Command `%s` exited with status code %d', $this->getCommandName($input), $statusCode));
}
}
// @codeCoverageIgnoreStart
exit($statusCode);
// @codeCoverageIgnoreEnd
}
return $statusCode;
}
public function setAutoExit($bool)
{
// parent property is private, so we need to intercept it in a setter
$this->originalAutoExit = (Boolean) $bool;
parent::setAutoExit($bool);
}
}
然后在app / console中使用它
//use Symfony\Bundle\FrameworkBundle\Console\Application;
use Acme\UltimateLoggingBundle\Console\Application;
至少删除app / cache / *目录app / console cache:clear not enough