info(date('H:i') . ' 开始执行');
$this->start();
$this->info(date('H:i') . ' 结束执行');
return 0;
}
public function start()
{
list($D, $H, $I) = explode('-', date('d-H-i'));
# 监测
if ((($H % 1) == 0) && ($I == 0)) {
// $this->check("-1 hour");
}
# 清除上个月索引
// if ($D == 1 && $H == 1 && $I == 0) {
// $this->lastMonIdxClear();
// }
# 清除sql记录
if ($H == 1 && $I == 0) {
$this->sqlClear();
}
}
public function check($timeRag)
{
$emails = env('EXCEPTION_REPORT_EMAIL');
if (empty($emails)) return true;
// list($total, $examples, $exFileCnt) = self::esQuery($timeRag);
list($total, $examples, $exFileCnt) = self::sqlQuery($timeRag);
if (!empty($examples)) {
# 发送邮件
EmailQueue::rPush("日志监控预警", $timeRag."监测:总共 {$total} 错误,包含 {$exFileCnt} 文件
示例:
".implode("
", $examples), explode(',', $emails));
}
}
public function lastMonIdxClear()
{
$index = 'kwaiad-log-'.date('Y.m', strtotime("-1 month"));
if (EsModel::existsIdx($index)) EsModel::deleteIdx($index);
}
protected function esQuery($timeRag)
{
$_source = ["level", "msg", "exFile"];
$filter = [
[
"term" => [
"level" => "ERROR"
]
],
[
"range" => [
"fTime" => [
'gte' => date('Y-m-d H:i:s', strtotime($timeRag)),
'lte' => date('Y-m-d H:i:s')
]
]
]
];
$aggs = [
"exFileCnt" => [
"cardinality" => [
"field" => "exFile"
]
]
];
# 拼装搜索条件
$searchData = [
"index" => "kwaiad-log-".date('Y.m'),
"body" => [
"_source" => $_source,
"query" => [
"bool" => [
"filter" => $filter,
]
],
"size" => 1000,
"aggs" => $aggs
]
];
# 查询
$data = EsModel::searchDoc($searchData);
if(!isset($data['hits']['total']['value']) || $data['hits']['total']['value'] == 0) {
return true;
}
# 错误总数
$total = $data['hits']['total']['value'];
# 示例展示
$examples = [];
$hits = $data['hits']['hits'];
foreach($hits as $hit) {
$item = $hit['_source'];
$key = md5($item['exFile'].'###'.$item['msg']);
if (isset($examples[$key])) continue;
$examples[$key] = '文件:'.$item['exFile'].' 错误信息:'.$item['msg'];
}
# 文件数
$exFileCnt = $data['aggregations']['exFileCnt']['value'];
return [$total, $examples, $exFileCnt];
}
public function sqlClear()
{
SysLogRecord::query()
->where('created_at', '<', date('Y-m-d H:i:s', strtotime("-5 day")))
->delete();
}
protected function sqlQuery($timeRag)
{
$query = SysLogRecord::query()
->select(['content', 'file'])
->where('level', 'ERROR')
->whereBetween('created_at', [
date('Y-m-d H:i:s', strtotime($timeRag)),
date('Y-m-d H:i:s')
]);
$total = $query->count();
if ($total == 0) return [0, [], 0];
$list = $query->groupBy(['file', 'content'])->get();
$exFileCnt = count(array_unique($list->pluck('file')->all()));
$examples = [];
foreach ($list as $item) {
$examples[] = '文件:'.$item->file.' 错误信息:'.$item->content;
}
return [$total, $examples, $exFileCnt];
}
}