setName('tools:log:stats') ->setDescription('统计数据库日志') ->addOption('by-level', null, Option::VALUE_NONE, '按日志级别统计') ->addOption('by-controller', null, Option::VALUE_NONE, '按控制器统计') ->addOption('by-time', null, Option::VALUE_NONE, '按时间统计') ->addOption('time-group', null, Option::VALUE_OPTIONAL, '时间分组 (hour|day|week|month)', 'day') ->addOption('help', 'h', Option::VALUE_NONE, '显示帮助信息'); } protected function execute($input, $output) { if ($input->getOption('help')) { $this->showHelp($output); return; } $byLevel = $input->getOption('by-level'); $byController = $input->getOption('by-controller'); $byTime = $input->getOption('by-time'); $timeGroup = $input->getOption('time-group') ?? 'day'; // 如果没有指定任何统计类型,默认显示所有统计 if (!$byLevel && !$byController && !$byTime) { $byLevel = $byController = $byTime = true; } try { $stats = [ 'by_level' => [], 'by_controller' => [], 'by_time' => [] ]; // 按日志级别统计 if ($byLevel) { $stats['by_level'] = $this->statsByLevel(); } // 按控制器统计 if ($byController) { $stats['by_controller'] = $this->statsByController(); } // 按时间统计 if ($byTime) { $stats['by_time'] = $this->statsByTime($timeGroup); } // 总数 $stats['total'] = Db::name('debug_log')->count(); $this->outputText($stats, $byLevel, $byController, $byTime, $output); } catch (\Exception $e) { $output->error('统计失败:' . $e->getMessage()); return; } } /** * 按日志级别统计 */ protected function statsByLevel(): array { $results = Db::name('debug_log') ->field('level, COUNT(*) as count') ->group('level') ->select() ->toArray(); $stats = []; foreach ($results as $row) { $stats[$row['level']] = (int)$row['count']; } return $stats; } /** * 按控制器统计 */ protected function statsByController(): array { $results = Db::name('debug_log') ->field('controller_name, COUNT(*) as count') ->where('controller_name', '<>', '') ->group('controller_name') ->order('count', 'desc') ->limit(20) ->select() ->toArray(); $stats = []; foreach ($results as $row) { $stats[$row['controller_name']] = (int)$row['count']; } return $stats; } /** * 按时间统计 */ protected function statsByTime(string $group): array { $query = Db::name('debug_log'); // 根据分组类型格式化时间 switch ($group) { case 'hour': $dateFormat = '%Y-%m-%d %H:00'; $phpFormat = 'Y-m-d H:00'; break; case 'week': $dateFormat = '%Y-%u'; // 年-周数 $phpFormat = 'Y-W'; // 年-周数 break; case 'month': $dateFormat = '%Y-%m'; $phpFormat = 'Y-m'; break; case 'day': default: $dateFormat = '%Y-%m-%d'; $phpFormat = 'Y-m-d'; break; } // 使用 MySQL DATE_FORMAT 函数 $results = $query->field('FROM_UNIXTIME(create_time, \'' . $dateFormat . '\') as time_period, COUNT(*) as count') ->where('create_time', '>', 0) ->group('time_period') ->order('time_period', 'desc') ->limit(30) ->select() ->toArray(); $stats = []; foreach ($results as $row) { $stats[$row['time_period']] = (int)$row['count']; } return $stats; } /** * 文本格式输出 */ protected function outputText(array $stats, bool $byLevel, bool $byController, bool $byTime, Output $output): void { $output->newLine(); $output->info('=== 数据库日志统计 ==='); $output->newLine(); // 总数 $output->info('总日志数:' . ($stats['total'] ?? 0)); $output->newLine(); // 按级别统计 if ($byLevel) { $output->comment('按日志级别统计:'); if (empty($stats['by_level'])) { $output->writeln(' 无数据'); } else { foreach ($stats['by_level'] as $level => $count) { $output->writeln(' ' . $level . ':' . $count . ' 条'); } } $output->newLine(); } // 按控制器统计 if ($byController) { $output->comment('按控制器统计(Top 20):'); if (empty($stats['by_controller'])) { $output->writeln(' 无数据'); } else { foreach ($stats['by_controller'] as $controller => $count) { $output->writeln(' ' . $controller . ':' . $count . ' 条'); } } $output->newLine(); } // 按时间统计 if ($byTime) { $output->comment('按时间统计(最近 30 个时段):'); if (empty($stats['by_time'])) { $output->writeln(' 无数据'); } else { foreach ($stats['by_time'] as $timePeriod => $count) { $output->writeln(' ' . $timePeriod . ':' . $count . ' 条'); } } $output->newLine(); } } /** * 获取日志级别对应的颜色 */ protected function getLevelColor(string $level): string { $level = strtolower($level); $colors = [ 'error' => 'error', 'warning' => 'comment', 'info' => 'info', 'debug' => 'info' ]; return $colors[$level] ?? 'info'; } /** * 显示帮助信息 */ protected function showHelp(Output $output): void { $output->newLine(); $output->info('命令名称:'); $output->writeln(' tools:log:stats - 统计数据库日志'); $output->newLine(); $output->info('用法:'); $output->writeln(' php think tools:log:stats [选项]'); $output->newLine(); $output->info('选项:'); $output->writeln(' --by-level 按日志级别统计'); $output->writeln(' --by-controller 按控制器统计'); $output->writeln(' --by-time 按时间统计'); $output->writeln(' --time-group 时间分组 (hour|day|week|month,默认: day)'); $output->writeln(' -h, --help 显示帮助信息'); $output->newLine(); $output->info('示例:'); $output->writeln(' php think tools:log:stats'); $output->writeln(' php think tools:log:stats --by-level'); $output->writeln(' php think tools:log:stats --by-controller --by-time'); $output->writeln(' php think tools:log:stats --by-time --time-group=hour'); $output->newLine(); } }