#feature: add AI log analysis & some bugfix

This commit is contained in:
2026-01-14 13:58:50 +08:00
parent e479ed02ea
commit ae6c169f5f
33 changed files with 3898 additions and 164 deletions

View File

@@ -3,6 +3,7 @@
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\EnvController;
use App\Http\Controllers\JiraController;
use App\Http\Controllers\LogAnalysisController;
use App\Http\Controllers\MessageSyncController;
use App\Http\Controllers\MessageDispatchController;
use App\Http\Controllers\SqlGeneratorController;
@@ -76,3 +77,30 @@ Route::prefix('admin')->middleware('admin.ip')->group(function () {
Route::put('/ip-user-mappings/{mapping}', [IpUserMappingController::class, 'update']);
Route::delete('/ip-user-mappings/{mapping}', [IpUserMappingController::class, 'destroy']);
});
// 日志分析 API 路由
Route::prefix('log-analysis')->group(function () {
// 日志查询(预览)
Route::post('/query', [LogAnalysisController::class, 'queryLogs']);
// AI 分析
Route::post('/analyze', [LogAnalysisController::class, 'analyze']);
// 历史报告
Route::get('/reports', [LogAnalysisController::class, 'listReports']);
Route::get('/reports/{id}', [LogAnalysisController::class, 'getReport']);
// 配置(读取不需要管理员权限)
Route::get('/config', [LogAnalysisController::class, 'getConfig']);
// 获取 logstore 列表
Route::get('/logstores', [LogAnalysisController::class, 'getLogstores']);
// 连接测试
Route::get('/test-sls', [LogAnalysisController::class, 'testSlsConnection']);
Route::get('/test-ai', [LogAnalysisController::class, 'testAiConnection']);
// 配置更新(需要管理员权限)
Route::put('/config', [LogAnalysisController::class, 'updateConfig'])
->middleware('admin.ip');
});

View File

@@ -1,8 +1,76 @@
<?php
use App\Services\ConfigService;
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schedule;
Artisan::command('inspire', function () {
$this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');
/*
|--------------------------------------------------------------------------
| Scheduled Tasks
|--------------------------------------------------------------------------
|
| 定时任务配置
| 所有定时任务统一在此文件管理
|
*/
// Git Monitor - 每 10 分钟检查 release 分支
Schedule::command('git-monitor:check')
->everyTenMinutes()
->withoutOverlapping()
->runInBackground()
->name('git-monitor-check');
// Git Monitor - 每天凌晨 2 点刷新 release 缓存
Schedule::command('git-monitor:cache')
->dailyAt('02:00')
->withoutOverlapping()
->name('git-monitor-cache');
// SLS 日志分析定时任务 - 每天凌晨 2 点执行
// 分析过去 24 小时的 ERROR 和 WARNING 日志并推送到钉钉
// 可通过数据库配置 log_analysis.settings.daily_schedule_enabled 控制是否启用
/*
Schedule::command('log-analysis:run --from="-24h" --to="now" --query="ERROR or WARNING" --push')
->dailyAt('02:00')
->withoutOverlapping()
->runInBackground()
->when(function () {
try {
$settings = app(ConfigService::class)->get('log_analysis.settings', []);
return $settings['daily_schedule_enabled'] ?? false;
} catch (\Exception $e) {
return false;
}
})
->name('daily-log-analysis')
->onFailure(function () {
Log::error('每日日志分析定时任务执行失败');
});
*/
// SLS 日志分析定时任务 - 每 4 小时执行一次
// 分析过去 6 小时的 ERROR 和 WARNING 日志并推送到钉钉
// 可通过数据库配置 log_analysis.settings.schedule_enabled 控制是否启用
Schedule::command('log-analysis:run --from="-6h" --to="now" --query="ERROR or WARNING" --push')
->everyFourHours()
->withoutOverlapping()
->runInBackground()
->when(function () {
try {
$settings = app(ConfigService::class)->get('log_analysis.settings', []);
return $settings['schedule_enabled'] ?? false;
} catch (\Exception $e) {
return false;
}
})
->name('frequent-log-analysis')
->onFailure(function () {
Log::error('SLS 日志分析定时任务执行失败');
});

View File

@@ -14,6 +14,7 @@ Route::get('/worklog', [AdminController::class, 'index'])->name('admin.worklog')
Route::get('/message-sync', [AdminController::class, 'index'])->name('admin.message-sync');
Route::get('/event-consumer-sync', [AdminController::class, 'index'])->name('admin.event-consumer-sync');
Route::get('/message-dispatch', [AdminController::class, 'index'])->name('admin.message-dispatch');
Route::get('/log-analysis', [AdminController::class, 'index'])->name('admin.log-analysis');
Route::get('/settings', [AdminController::class, 'index'])->name('admin.settings');
Route::get('/logs', [AdminController::class, 'index'])->name('admin.logs');
Route::get('/ip-mappings', [AdminController::class, 'index'])->name('admin.ip-mappings')->middleware('admin.ip');