server/app/Listener/CrontabLogListener.php

93 lines
3.1 KiB
PHP

<?php
namespace App\Listener;
use Hyperf\Event\Annotation\Listener;
use Hyperf\Crontab\Event\AfterExecute;
use Hyperf\Crontab\Event\FailToExecute;
use Hyperf\Crontab\Event\BeforeExecute;
use Hyperf\Event\Contract\ListenerInterface;
use App\Model\CrontabLog as clModel;
#[Listener]
class CrontabLogListener implements ListenerInterface
{
private array $starts = [];
public function listen(): array
{
return [
BeforeExecute::class,
AfterExecute::class,
FailToExecute::class,
];
}
public function process(object $event): void
{
if ($event instanceof BeforeExecute) {
$key = $this->getKey($event);
$this->starts[$key] = microtime(true);
}
if ($event instanceof AfterExecute) {
$options = $event->crontab->getOptions();
$key = $this->getKey($event);
if (isset($this->starts[$key])) {
$start = $this->starts[$key];
// 清理开始时间 防止内存泄露
unset($this->starts[$key]);
}
if ($options['skip_log']) {
clModel::insert([
'crontab_id' => $event->crontab->getName(),
'crontab_name' => $event->crontab->getMemo(),
'callback' => $options['callback'],
'duration' => microtime(true) - ($start ?? microtime(true)),
'status' => 1,
'result' => '执行成功',
'create_time' => date("Y-m-d H:i:s")
]);
}
}
if ($event instanceof FailToExecute) {
$options = $event->crontab->getOptions();
$key = $this->getKey($event);
if (isset($this->starts[$key])) {
$start = $this->starts[$key];
// 清理开始时间 防止内存泄露
unset($this->starts[$key]);
}
if ($options['skip_log']) {
clModel::insert([
'crontab_id' => $event->crontab->getName(),
'crontab_name' => $event->crontab->getMemo(),
'callback' => $options['callback'],
'duration' => microtime(true) - ($start ?? microtime(true)),
'status' => $event->throwable ? 0 : 1,
'result' => $event->throwable?->getMessage() ?? '执行失败',
'create_time' => date("Y-m-d H:i:s")
]);
}
}
}
protected function getKey(object $event): string
{
if (property_exists($event, 'crontab') && $event->crontab) {
try {
$name = method_exists($event->crontab, 'getName')
? $event->crontab->getName()
: ($event->crontab->name ?? null);
if ($name) {
return (string) $name;
}
return spl_object_hash($event->crontab);
} catch (\Throwable $e) {
return spl_object_hash($event->crontab);
}
}
return spl_object_hash($event);
}
}