123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- <?php
- namespace App\Console\Commands;
- use App\Models\Sys\SysLogRecord;
- use App\Support\EmailQueue;
- use App\Support\EsModel;
- use Illuminate\Console\Command;
- class LogMonitorWarn extends Command
- {
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'LogMonitorWarn';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = '日志监控预警';
- /**
- * Create a new command instance.
- *
- * @return void
- */
- public function __construct()
- {
- parent::__construct();
- }
- /**
- * Execute the console command.
- *
- * @return int
- */
- public function handle()
- {
- $this->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} 文件<br>示例:<br>".implode("<br>", $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];
- }
- }
|