/
QueueLogBehavior.php
119 lines (104 loc) · 2.98 KB
/
QueueLogBehavior.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?php
/**
* @link https://craftcms.com/
* @copyright Copyright (c) Pixel & Tonic, Inc.
* @license https://craftcms.github.io/license/
*/
namespace craft\queue;
use Craft;
use craft\log\Dispatcher;
use craft\log\MonologTarget;
use Illuminate\Support\Collection;
use yii\queue\ExecEvent;
/**
* Queue Log Behavior
*
* @author Pixel & Tonic, Inc. <support@pixelandtonic.com>
* @since 3.0.0
*/
class QueueLogBehavior extends VerboseBehavior
{
/**
* @var float timestamp
*/
private float $_jobStartedAt;
/**
* @var bool Whether any jobs have executed yet
*/
private bool $_jobExecuted = false;
/**
* @inheritdoc
*/
public function events(): array
{
return [
Queue::EVENT_BEFORE_EXEC => 'beforeExec',
Queue::EVENT_AFTER_EXEC => 'afterExec',
Queue::EVENT_AFTER_ERROR => 'afterError',
];
}
/**
* @param ExecEvent $event
*/
public function beforeExec(ExecEvent $event): void
{
if (!$this->_jobExecuted) {
$this->_enableLogTarget();
}
$this->_jobStartedAt = microtime(true);
Craft::info(sprintf('%s - Started', parent::jobTitle($event)), __METHOD__);
}
/**
* @inheritdoc
*/
public function afterExec(ExecEvent $event): void
{
if (isset($this->_jobStartedAt)) {
Craft::info(sprintf('%s - Done (time: %s)', parent::jobTitle($event), $this->_formattedDuration()), __METHOD__);
} else {
Craft::info(sprintf('%s - Done', parent::jobTitle($event)), __METHOD__);
}
}
/**
* @inheritdoc
*/
public function afterError(ExecEvent $event): void
{
$message = sprintf('%s - Error', parent::jobTitle($event));
if (isset($this->_jobStartedAt)) {
$message .= sprintf(' (time: %s)', $this->_formattedDuration());
}
if ($event->error) {
$message .= sprintf(': %s', $event->error->getMessage());
}
Craft::error($message, __METHOD__);
if ($event->error) {
Craft::$app->getErrorHandler()->logException($event->error);
}
}
/**
* Enables the log target logs will get flushed to.
*/
private function _enableLogTarget(): void
{
Collection::make(Craft::$app->getLog()->targets)
->whereInstanceOf(MonologTarget::class)
->filter(fn($target, $key) => in_array($key, [
Dispatcher::TARGET_WEB,
Dispatcher::TARGET_CONSOLE,
Dispatcher::TARGET_QUEUE,
], true))
->each(function(MonologTarget $target): void {
$target->enabled = $target->getLogger()->getName() === Dispatcher::TARGET_QUEUE;
});
}
/**
* Returns the job execution time in seconds.
*
* @return string
*/
private function _formattedDuration(): string
{
return sprintf('%.3f', microtime(true) - $this->_jobStartedAt) . 's';
}
}