#feature: update log format

This commit is contained in:
2026-01-19 15:42:44 +08:00
parent 0646c8612b
commit ddd0f531fd
9 changed files with 180 additions and 170 deletions

View File

@@ -1,73 +0,0 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
class CleanScheduledTaskLogsCommand extends Command
{
protected $signature = 'logs:clean-scheduled-tasks {--days=7 : 保留最近几天的日志}';
protected $description = '清理定时任务日志文件,删除指定天数之前的日志';
public function handle(): int
{
$days = (int) $this->option('days');
$logPath = storage_path('logs/scheduled-tasks');
if (!File::exists($logPath)) {
Log::info('日志目录不存在,无需清理');
return Command::SUCCESS;
}
$cutoffDate = Carbon::now()->subDays($days);
Log::info("开始清理 {$days} 天前的定时任务日志...");
Log::info("截止日期: {$cutoffDate->format('Y-m-d')}");
$files = File::files($logPath);
$deletedCount = 0;
$totalSize = 0;
foreach ($files as $file) {
$filename = $file->getFilename();
// 匹配日志文件名格式: task-name-YYYY-MM-DD.log
if (preg_match('/-(\d{4}-\d{2}-\d{2})\.log$/', $filename, $matches)) {
$fileDate = Carbon::parse($matches[1]);
if ($fileDate->lt($cutoffDate)) {
$fileSize = $file->getSize();
$totalSize += $fileSize;
File::delete($file->getPathname());
$deletedCount++;
Log::info("已删除: {$filename} (" . $this->formatBytes($fileSize) . ")");
}
}
}
if ($deletedCount > 0) {
Log::info("清理完成!共删除 {$deletedCount} 个日志文件,释放空间: " . $this->formatBytes($totalSize));
} else {
Log::info('没有需要清理的日志文件');
}
return Command::SUCCESS;
}
private function formatBytes(int $bytes): string
{
if ($bytes >= 1073741824) {
return number_format($bytes / 1073741824, 2) . ' GB';
} elseif ($bytes >= 1048576) {
return number_format($bytes / 1048576, 2) . ' MB';
} elseif ($bytes >= 1024) {
return number_format($bytes / 1024, 2) . ' KB';
}
return $bytes . ' B';
}
}

View File

@@ -17,11 +17,11 @@ class GitMonitorCacheCommand extends Command
$cache = $monitor->refreshReleaseCache(true);
if (empty($cache)) {
Log::warning('未获取到任何 release 版本信息,请检查配置。');
Log::channel('git-monitor')->warning('未获取到任何 release 版本信息,请检查配置。');
return;
}
Log::info(sprintf(
Log::channel('git-monitor')->info(sprintf(
'已缓存 %d 个仓库的 release 分支信息。',
count($cache['repositories'] ?? [])
));

View File

@@ -25,11 +25,11 @@ class GitMonitorCheckCommand extends Command
foreach ($results as $repo => $result) {
if (isset($result['error'])) {
Log::error(sprintf('[%s] %s', $repo, $result['error']));
Log::channel('git-monitor')->error(sprintf('[%s] %s', $repo, $result['error']));
continue;
}
Log::info(sprintf(
Log::channel('git-monitor')->info(sprintf(
'[%s] 分支 %s 已对齐 %s扫描 %d 个提交。',
$repo,
$result['branch'],
@@ -38,9 +38,9 @@ class GitMonitorCheckCommand extends Command
));
if (!empty($result['issues']['develop_merges'])) {
Log::warning(sprintf(' - 检测到 %d 个 develop merge:', count($result['issues']['develop_merges'])));
Log::channel('git-monitor')->warning(sprintf(' - 检测到 %d 个 develop merge:', count($result['issues']['develop_merges'])));
foreach ($result['issues']['develop_merges'] as $commit) {
Log::warning(sprintf(
Log::channel('git-monitor')->warning(sprintf(
' • %s %s (%s)',
substr($commit['hash'], 0, 8),
$commit['subject'],
@@ -50,9 +50,9 @@ class GitMonitorCheckCommand extends Command
}
if (!empty($result['issues']['missing_functions'])) {
Log::warning(sprintf(' - 检测到 %d 个疑似缺失函数的提交:', count($result['issues']['missing_functions'])));
Log::channel('git-monitor')->warning(sprintf(' - 检测到 %d 个疑似缺失函数的提交:', count($result['issues']['missing_functions'])));
foreach ($result['issues']['missing_functions'] as $issue) {
Log::warning(sprintf(
Log::channel('git-monitor')->warning(sprintf(
' • %s %s (%s)',
substr($issue['commit']['hash'], 0, 8),
$issue['commit']['subject'],
@@ -60,7 +60,7 @@ class GitMonitorCheckCommand extends Command
));
foreach ($issue['details'] as $detail) {
$functions = implode(', ', array_slice($detail['functions'], 0, 5));
Log::warning(sprintf(' %s => %s', $detail['file'], $functions));
Log::channel('git-monitor')->warning(sprintf(' %s => %s', $detail['file'], $functions));
}
}
}

View File

@@ -14,29 +14,29 @@ class JenkinsMonitorCommand extends Command
public function handle(JenkinsMonitorService $service): void
{
Log::info('开始检查 Jenkins 构建...');
Log::channel('jenkins-monitor')->info('开始检查 Jenkins 构建...');
$results = $service->checkAllProjects();
if (isset($results['skipped'])) {
Log::warning('跳过检查: ' . ($results['reason'] ?? 'unknown'));
Log::channel('jenkins-monitor')->warning('跳过检查: ' . ($results['reason'] ?? 'unknown'));
return;
}
foreach ($results as $slug => $result) {
if (isset($result['skipped'])) {
Log::info(sprintf('[%s] 跳过: %s', $slug, $result['reason'] ?? 'unknown'));
Log::channel('jenkins-monitor')->info(sprintf('[%s] 跳过: %s', $slug, $result['reason'] ?? 'unknown'));
continue;
}
$newBuilds = $result['new_builds'] ?? [];
if (empty($newBuilds)) {
Log::info(sprintf('[%s] 无新构建', $slug));
Log::channel('jenkins-monitor')->info(sprintf('[%s] 无新构建', $slug));
} else {
Log::info(sprintf('[%s] 发现 %d 个新构建: #%s', $slug, count($newBuilds), implode(', #', $newBuilds)));
Log::channel('jenkins-monitor')->info(sprintf('[%s] 发现 %d 个新构建: #%s', $slug, count($newBuilds), implode(', #', $newBuilds)));
}
}
Log::info('检查完成');
Log::channel('jenkins-monitor')->info('检查完成');
}
}

View File

@@ -30,12 +30,12 @@ class LogAnalysisCommand extends Command
): int {
// 检查配置
if (!$slsService->isConfigured()) {
Log::error('SLS 服务未配置,请检查 .env 中的 SLS_* 配置项');
Log::channel('log-analysis')->error('SLS 服务未配置,请检查 .env 中的 SLS_* 配置项');
return Command::FAILURE;
}
if (!$aiService->isConfigured()) {
Log::error('AI 服务未配置,请在页面上配置 AI 提供商或设置 .env 中的 AI_* 配置项');
Log::channel('log-analysis')->error('AI 服务未配置,请在页面上配置 AI 提供商或设置 .env 中的 AI_* 配置项');
return Command::FAILURE;
}
@@ -44,7 +44,7 @@ class LogAnalysisCommand extends Command
$to = $this->parseTime($this->option('to') ?? 'now');
if ($from >= $to) {
Log::error('开始时间必须早于结束时间');
Log::channel('log-analysis')->error('开始时间必须早于结束时间');
return Command::FAILURE;
}
@@ -56,11 +56,10 @@ class LogAnalysisCommand extends Command
$query = $this->option('query');
Log::info("开始分析日志...");
Log::info(" 时间范围: {$from->format('Y-m-d H:i:s')} ~ {$to->format('Y-m-d H:i:s')}");
Log::info(" 查询语句: " . ($query ?: '*'));
Log::info(" 分析模式: {$mode->label()}");
$this->newLine();
Log::channel('log-analysis')->info("开始分析日志...");
Log::channel('log-analysis')->info(" 时间范围: {$from->format('Y-m-d H:i:s')} ~ {$to->format('Y-m-d H:i:s')}");
Log::channel('log-analysis')->info(" 查询语句: " . ($query ?: '*'));
Log::channel('log-analysis')->info(" 分析模式: {$mode->label()}");
try {
$result = $analysisService->analyze(
@@ -75,17 +74,17 @@ class LogAnalysisCommand extends Command
if ($outputPath = $this->option('output')) {
$json = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
file_put_contents($outputPath, $json);
Log::info("报告已保存到: {$outputPath}");
Log::channel('log-analysis')->info("报告已保存到: {$outputPath}");
}
// 推送到钉钉
if ($this->option('push')) {
Log::info("正在推送到钉钉...");
Log::channel('log-analysis')->info("正在推送到钉钉...");
$pushed = $analysisService->pushToNotification($result);
if ($pushed) {
Log::info("已推送到钉钉");
Log::channel('log-analysis')->info("已推送到钉钉");
} else {
Log::warning("钉钉推送失败");
Log::channel('log-analysis')->warning("钉钉推送失败");
}
}
@@ -94,7 +93,7 @@ class LogAnalysisCommand extends Command
return Command::SUCCESS;
} catch (\Exception $e) {
Log::error("分析失败: {$e->getMessage()}");
Log::channel('log-analysis')->error("分析失败: {$e->getMessage()}");
return Command::FAILURE;
}
}
@@ -133,57 +132,45 @@ class LogAnalysisCommand extends Command
*/
private function displaySummary(array $result): void
{
$this->newLine();
$this->info('=== 分析摘要 ===');
$this->line("总日志数: {$result['metadata']['total_logs']}");
$this->line("分析应用数: {$result['metadata']['apps_analyzed']}");
$this->line("执行时间: {$result['metadata']['execution_time_ms']}ms");
$this->newLine();
Log::channel('log-analysis')->info('=== 分析摘要 ===');
Log::channel('log-analysis')->info("总日志数: {$result['metadata']['total_logs']}");
Log::channel('log-analysis')->info("分析应用数: {$result['metadata']['apps_analyzed']}");
Log::channel('log-analysis')->info("执行时间: {$result['metadata']['execution_time_ms']}ms");
if (empty($result['results'])) {
$this->warn('未找到匹配的日志');
Log::channel('log-analysis')->warning('未找到匹配的日志');
return;
}
foreach ($result['results'] as $appName => $appResult) {
$this->line("{$appName}");
Log::channel('log-analysis')->info("{$appName}");
if (isset($appResult['error'])) {
$this->error(" 分析失败: {$appResult['error']}");
Log::channel('log-analysis')->error(" 分析失败: {$appResult['error']}");
continue;
}
$impact = $appResult['impact'] ?? 'unknown';
$impactColor = match ($impact) {
'high' => 'red',
'medium' => 'yellow',
'low' => 'green',
default => 'white',
};
$this->line(" 日志数: {$appResult['log_count']}");
$this->line(" 代码上下文: " . ($appResult['has_code_context'] ? '是' : '否'));
$this->line(" 影响级别: <fg={$impactColor}>{$impact}</>");
$this->line(" 摘要: " . ($appResult['summary'] ?? 'N/A'));
Log::channel('log-analysis')->info(" 日志数: {$appResult['log_count']}");
Log::channel('log-analysis')->info(" 代码上下文: " . ($appResult['has_code_context'] ? '是' : '否'));
Log::channel('log-analysis')->info(" 影响级别: {$impact}");
Log::channel('log-analysis')->info(" 摘要: " . ($appResult['summary'] ?? 'N/A'));
$anomalies = $appResult['core_anomalies'] ?? [];
if (!empty($anomalies)) {
$this->line(" 异常数: " . count($anomalies));
Log::channel('log-analysis')->info(" 异常数: " . count($anomalies));
$table = [];
foreach (array_slice($anomalies, 0, 5) as $anomaly) {
$table[] = [
Log::channel('log-analysis')->info(sprintf(
" - [%s] %s (数量: %d) - %s",
$anomaly['type'] ?? 'N/A',
$anomaly['classification'] ?? 'N/A',
$anomaly['count'] ?? 1,
mb_substr($anomaly['possible_cause'] ?? 'N/A', 0, 40),
];
mb_substr($anomaly['possible_cause'] ?? 'N/A', 0, 40)
));
}
$this->table(['类型', '分类', '数量', '可能原因'], $table);
}
$this->newLine();
}
}
}

View File

@@ -15,15 +15,15 @@ class ScheduledTaskRefreshCommand extends Command
public function handle(ScheduledTaskService $taskService): int
{
try {
Log::info('开始刷新定时任务列表...');
Log::channel('scheduled-tasks')->info('开始刷新定时任务列表...');
$tasks = $taskService->getAllTasks();
Log::info(sprintf('成功刷新 %d 个定时任务', count($tasks)));
Log::channel('scheduled-tasks')->info(sprintf('成功刷新 %d 个定时任务', count($tasks)));
// 记录任务列表到日志
// 显示任务列表
foreach ($tasks as $task) {
Log::info(sprintf(
Log::channel('scheduled-tasks')->info(sprintf(
' - %s: %s (%s) [%s]',
$task['name'],
$task['description'],
@@ -34,7 +34,7 @@ class ScheduledTaskRefreshCommand extends Command
return Command::SUCCESS;
} catch (\Exception $e) {
Log::error("刷新失败: {$e->getMessage()}");
Log::channel('scheduled-tasks')->error("刷新失败: {$e->getMessage()}");
return Command::FAILURE;
}
}