use ByteSpin\ConsoleCommandSchedulerBundle\Entity\Scheduler;
use ByteSpin\ConsoleCommandSchedulerBundle\Entity\SchedulerLog;
use ByteSpin\ConsoleCommandSchedulerBundle\Controller\Admin\SchedulerCrudController;
use ByteSpin\ConsoleCommandSchedulerBundle\Controller\Admin\SchedulerLogCrudController;
(...)
yield MenuItem::subMenu('Symfony Scheduler', 'fa-duotone fa-folder-gear')->setSubItems([
MenuItem::linkToCrud('Scheduled Tasks', 'fa-light fa-clock', Scheduler::class)->setController(SchedulerCrudController::class),
MenuItem::linkToCrud('Logs', 'fa-duotone fa-clock-rotate-left', SchedulerLog::class)->setController(SchedulerLogCrudController::class),
]);
(...)
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\Mailer\MailerInterface;
use ByteSpin\ConsoleCommandSchedulerBundle\Event\ScheduledConsoleCommandGenericEvent;
readonly class MyEventSubscriber implements EventSubscriberInterface
{
public function __construct(
private MailerInterface $mailer,
) {
}
public static function getSubscribedEvents(): array
{
return [
'bytespin.failure.scheduled.console.command' => [
['notifyInCaseOfFailure'],
],
];
}
public function notifyInCaseOfFailure(GenericEvent $event): void
{
/** @var ScheduledConsoleCommandGenericEvent $consoleCommand */
$consoleCommand = $event->getSubject();
$message = 'The following scheduled console command failed:' . PHP_EOL .
'- Command: ' . $consoleCommand->command . ' ' . implode(' ', $consoleCommand->commandArguments) . PHP_EOL .
'- Scheduled at: ' . $consoleCommand->start->format('Y-m-d H:i:s') . PHP_EOL .
'- Failed at: ' . $consoleCommand->end->format('Y-m-d H:i:s') . PHP_EOL .
'- Duration: ' . $consoleCommand->duration . PHP_EOL .
'- Return code was: ' . $consoleCommand->returnCode . PHP_EOL .
'- Please see log file ' . $consoleCommand->logFile;
try {
$notification = new Email();
$notification
->from('[email protected]')
->subject('Scheduled Console Command Failure!')
->to('[email protected]')
->text($message);
$this->mailer->send($notification);
} catch (TransportExceptionInterface $e) {
throw new Exception('Error while sending notification. Error was: ' . $e->getMessage());
}
}
}
(...)
use ByteSpin\ConsoleCommandSchedulerBundle\Converter\DurationConverter;
use ByteSpin\ConsoleCommandSchedulerBundle\Event\ScheduledConsoleCommandOutputEvent;
use ByteSpin\ConsoleCommandSchedulerBundle\Job\JobIdOptionTrait;
use ByteSpin\ConsoleCommandSchedulerBundle\Model\CommandType;
(...)
class YourCommandScheduledByTheBundle extends Command
{
// this is mandatory to get the job id that when executed by the bundle
use JobIdOptionTrait;
public function __construct(
private readonly DurationConverter $durationConverter, // convert duration in human-readable format
private readonly EventDispatcherInterface $eventDispatcher,
(...)
) {
parent::__construct();
}
protected function configure(): void
{
(...)
// configure option provided by ByteSpin\ConsoleCommandSchedulerBundle\Job\JobIdOptionTrait
$this->configureJobIdOption();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
// get ByteSpin scheduled job id
$jobId = $input->getOption('job-id');
$start = time();
$returnCode = $this->yourClass->yourMethod($yourParameter, ...);
$end = time();
$duration = $end - $start;
// build the output event to be caught in notification email
$outputEvent = new ScheduledConsoleCommandOutputEvent(
commandId: $jobId,
commandType: CommandType::CHILD, // (can be of CommandType::MASTER if you want to insert the main command in your details)
dateTime: (new DateTime())->setTimestamp($start),
command: $this->getName(),
commandArguments: $commandArguments, // you can format them using $input->getOptions())
duration: $this->durationConverter->convert($duration),
returnCode: $returnCode // 0 is SUCCESS, any other values are FAILURE
commandOutput: 'You can catch here and format Exceptions or any output you need in notification email'
)
;
$this->eventDispatcher->dispatch($outputEvent);
}