Skip to content
This repository was archived by the owner on Apr 14, 2025. It is now read-only.

Commit 42d6961

Browse files
committed
First working version
0 parents  commit 42d6961

File tree

14 files changed

+637
-0
lines changed

14 files changed

+637
-0
lines changed

Cron/Monitor.php

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
<?php
2+
3+
namespace Codepeak\Cronwatch\Cron;
4+
5+
use \Codepeak\Cronwatch\Model\CronwatchRepository;
6+
use \Magento\Framework\App\Config\ScopeConfigInterface;
7+
use \Magento\Framework\ObjectManagerInterface;
8+
use \Psr\Log\LoggerInterface;
9+
10+
/**
11+
* Class Monitor
12+
*
13+
* @package Codepeak\Cronwatch\Cron
14+
* @author Robert Lord, Codepeak AB <robert@codepeak.se>
15+
*/
16+
class Monitor
17+
{
18+
/**
19+
* @var LoggerInterface
20+
*/
21+
protected $logger;
22+
23+
/**
24+
* @var ObjectManager
25+
*/
26+
protected $objectManager;
27+
28+
/**
29+
* @var ScopeConfigInterface
30+
*/
31+
protected $scopeConfig;
32+
33+
/**
34+
* Constructor
35+
*
36+
* @param LoggerInterface $logger
37+
* @param ObjectManagerInterface $objectManager
38+
* @param ScopeConfigInterface $scopeConfig
39+
*/
40+
public function __construct(
41+
LoggerInterface $logger,
42+
ObjectManagerInterface $objectManager,
43+
ScopeConfigInterface $scopeConfig
44+
) {
45+
$this->logger = $logger;
46+
$this->objectManager = $objectManager;
47+
$this->scopeConfig = $scopeConfig;
48+
}
49+
50+
/**
51+
* Execute the cron
52+
*
53+
* @return void
54+
*/
55+
public function execute()
56+
{
57+
// Make sure we're active
58+
if ($this->scopeConfig->getValue('system/cronwatch/enabled') !== '1') {
59+
return;
60+
}
61+
62+
// Build e-mail recipients
63+
$emailRecipients = [];
64+
foreach (explode(',', $this->scopeConfig->getValue('system/cronwatch/recipients')) as $recipient) {
65+
$emailRecipients[] = trim($recipient);
66+
}
67+
68+
/**
69+
* Fetch all entries in cron_schedule table
70+
*/
71+
$cronScheduleCollection = $this->objectManager->get('Magento\Cron\Model\Schedule')
72+
->getCollection()
73+
->addFieldToFilter('status', ['eq' => 'error'])
74+
->addFieldToFilter('cronwatch_id', ['null' => true]);
75+
76+
// Left join with our status table
77+
$cronScheduleCollection
78+
->getSelect()
79+
->joinLeft(
80+
['cronwatch' => $cronScheduleCollection->getTable('codepeak_cronwatch')],
81+
'main_table.schedule_id = cronwatch.cron_schedule_schedule_id',
82+
['cronwatch_id']
83+
);
84+
85+
/**
86+
* Loop each entry and build error string
87+
*/
88+
foreach ($cronScheduleCollection as $schedule) {
89+
// Remove data not needed
90+
$schedule->unsetData('cronwatch_id');
91+
92+
// Build the message
93+
$message = "Job with code '%s' marked as failed with the reason '%s'.\n\n%s";
94+
$message = sprintf(
95+
$message,
96+
$schedule->getJobCode(),
97+
$schedule->getMessages(),
98+
var_export($schedule->getData(), true)
99+
);
100+
101+
// Add entry to the logs, might be good to have information here as well
102+
$this->logger->addError($message);
103+
104+
// Setup the e-mail
105+
if (count($emailRecipients)) {
106+
try {
107+
$email = new \Zend_Mail();
108+
$email->setSubject('Cronwatch error detected: ' . $schedule->getJobCode());
109+
$email->setBodyText($message);
110+
$email->setFrom(
111+
$this->scopeConfig->getValue('trans_email/ident_general/email'),
112+
$this->scopeConfig->getValue('trans_email/ident_general/name')
113+
);
114+
$email->addTo($emailRecipients);
115+
$email->send();
116+
} catch (\Exception $e) {
117+
$this->logger->addError($e->getMessage());
118+
}
119+
}
120+
121+
// Fetch cronwatch repository
122+
$cronwatchRepository = $this->objectManager->create(CronwatchRepository::class);
123+
124+
// Create entry in our monitor table to avoid duplicates
125+
$cronwatchModel = $this->objectManager->get('Codepeak\Cronwatch\Model\Cronwatch');
126+
$cronwatchModel->setCronScheduleScheduleId($schedule->getScheduleId());
127+
128+
// Store the entity
129+
$cronwatchRepository->save($cronwatchModel);
130+
}
131+
132+
// Clean our table in case of table cron_schedule was truncated
133+
$cronwatchCollection = $this->objectManager->get('Codepeak\Cronwatch\Model\Cronwatch')
134+
->getCollection();
135+
136+
// Left join with cron_schedule table
137+
$cronwatchCollection
138+
->getSelect()
139+
->joinLeft(
140+
['cron_schedule' => $cronwatchCollection->getTable('cron_schedule')],
141+
'main_table.cron_schedule_schedule_id = cron_schedule.schedule_id',
142+
['schedule_id']
143+
);
144+
145+
// Remove entries that no longer exists in cron_schedule table, not 100% fool proof but good enough
146+
foreach ($cronwatchCollection as $cronwatch) {
147+
if (!$cronwatch->getScheduleId()) {
148+
// Fetch cronwatch repository
149+
$cronwatchRepository = $this->objectManager->create(CronwatchRepository::class);
150+
151+
// Load the model
152+
$cronwatchModel = $this->objectManager->get('Codepeak\Cronwatch\Model\Cronwatch')->load(
153+
$cronwatch->getCronwatchId()
154+
);
155+
156+
// Delete it
157+
$cronwatchRepository->delete($cronwatchModel);
158+
}
159+
}
160+
}
161+
}

Model/Cronwatch.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace Codepeak\Cronwatch\Model;
4+
5+
use Codepeak\Cronwatch\Api\Data\CronwatchInterface;
6+
7+
/**
8+
* Class Cronwatch
9+
*
10+
* @package Codepeak\Cronwatch\Model
11+
* @author Robert Lord <robert@codepeak.se>
12+
*/
13+
class Cronwatch extends \Magento\Framework\Model\AbstractModel implements CronwatchInterface
14+
{
15+
/**
16+
* @return void
17+
*/
18+
protected function _construct()
19+
{
20+
$this->_init('Codepeak\Cronwatch\Model\ResourceModel\Cronwatch');
21+
}
22+
23+
/**
24+
* Get cronwatch_id
25+
* @return string
26+
*/
27+
public function getCronwatchId()
28+
{
29+
return $this->getData(self::CRONWATCH_ID);
30+
}
31+
32+
/**
33+
* Set cronwatch_id
34+
*
35+
* @param string $cronwatchId
36+
*
37+
* @return Codepeak\Cronwatch\Api\Data\CronwatchInterface
38+
*/
39+
public function setCronwatchId($cronwatchId)
40+
{
41+
return $this->setData(self::CRONWATCH_ID, $cronwatchId);
42+
}
43+
44+
/**
45+
* Get cron_schedule_schedule_id
46+
* @return string
47+
*/
48+
public function getCronScheduleScheduleId()
49+
{
50+
return $this->getData(self::CRON_SCHEDULE_SCHEDULE_ID);
51+
}
52+
53+
/**
54+
* Set cron_schedule_schedule_id
55+
*
56+
* @param string $cron_schedule_schedule_id
57+
*
58+
* @return Codepeak\Cronwatch\Api\Data\CronwatchInterface
59+
*/
60+
public function setCronScheduleScheduleId($cron_schedule_schedule_id)
61+
{
62+
return $this->setData(self::CRON_SCHEDULE_SCHEDULE_ID, $cron_schedule_schedule_id);
63+
}
64+
}

0 commit comments

Comments
 (0)