setName('tools:log:search') ->setDescription('搜索数据库日志') ->addArgument('keywords', Argument::REQUIRED, '搜索关键词') ->addOption('level', 'l', Option::VALUE_OPTIONAL, '过滤日志级别 (info, warning, error)') ->addOption('limit', null, Option::VALUE_OPTIONAL, '限制显示条数', 50) ->addOption('controller', 'c', Option::VALUE_OPTIONAL, '过滤控制器名称') ->addOption('help', 'h', Option::VALUE_NONE, '显示帮助信息'); } protected function execute($input, $output) { if ($input->getOption('help')) { $this->showHelp($output); return; } $keywords = $input->getArgument('keywords'); if (empty($keywords)) { $output->error('请提供搜索关键词'); return; } $filters = $this->buildFilters($input); $limit = (int)$input->getOption('limit') ?? 50; try { $query = Db::name('debug_log'); // 搜索关键词(在 content 字段中) $query->whereLike('content', '%' . $keywords . '%'); // 应用过滤条件 if (!empty($filters['level'])) { $query->where('level', '=', $filters['level']); } if (!empty($filters['controller'])) { $query->whereLike('controller_name', '%' . $filters['controller'] . '%'); } // 获取总数 $count = $query->count(); // 获取日志记录 $logs = $query->order('create_time', 'desc') ->limit($limit) ->select() ->toArray(); // 格式化时间戳并高亮关键词 foreach ($logs as &$log) { if (!empty($log['create_time'])) { $log['create_time_formatted'] = date('Y-m-d H:i:s', $log['create_time']); } // 高亮关键词 $log['content_highlighted'] = $this->highlightKeywords($log['content'] ?? '', $keywords); } unset($log); $this->outputText($logs, $count, $keywords, $filters, $output); } catch (\Exception $e) { $output->error('搜索失败:' . $e->getMessage()); return; } } /** * 构建过滤条件 */ protected function buildFilters(Input $input): array { return [ 'level' => $input->getOption('level'), 'controller' => $input->getOption('controller') ]; } /** * 高亮关键词 */ protected function highlightKeywords(string $content, string $keywords): string { // 使用 ANSI 颜色代码高亮关键词(仅用于文本模式) return str_replace($keywords, '' . $keywords . '', $content); } /** * 文本格式输出 */ protected function outputText(array $logs, int $count, string $keywords, array $filters, Output $output): void { $output->newLine(); $output->info('=== 数据库日志搜索结果 ==='); $output->newLine(); $output->comment('搜索关键词:' . $keywords); $output->newLine(); // 显示过滤条件 $activeFilters = array_filter($filters, function($value) { return !empty($value); }); if (!empty($activeFilters)) { $output->comment('过滤条件:'); foreach ($activeFilters as $key => $value) { $output->writeln(' - ' . $key . ': ' . $value); } $output->newLine(); } if (empty($logs)) { $output->comment('没有找到包含 "' . $keywords . '" 的日志'); return; } // 显示搜索结果 $output->info('搜索结果(共 ' . $count . ' 条,显示 ' . count($logs) . ' 条):'); $output->newLine(); foreach ($logs as $log) { $levelMethod = $this->getLevelMethod($log['level'] ?? ''); $output->$levelMethod('[' . $log['level'] . '] ' . '[' . ($log['create_time_formatted'] ?? 'N/A') . '] ' . '[' . ($log['controller_name'] ?? '') . '::' . ($log['action_name'] ?? '') . ']'); // 显示内容并高亮关键词 $content = $log['content'] ?? ''; if (strlen($content) > 200) { $content = substr($content, 0, 200) . '...'; } $output->writeln(' ' . $this->highlightKeywords($content, $keywords)); $output->newLine(); } } /** * 获取日志级别对应的方法名 */ protected function getLevelMethod(string $level): string { $level = strtolower($level); $methods = [ 'error' => 'error', 'warning' => 'comment', 'info' => 'info', 'debug' => 'info' ]; return $methods[$level] ?? 'info'; } /** * 显示帮助信息 */ protected function showHelp(Output $output): void { $output->newLine(); $output->info('命令名称:'); $output->writeln(' tools:log:search - 搜索数据库日志'); $output->newLine(); $output->info('用法:'); $output->writeln(' php think tools:log:search 关键词 [选项]'); $output->newLine(); $output->info('参数:'); $output->writeln(' keywords 搜索关键词(必填)'); $output->newLine(); $output->info('选项:'); $output->writeln(' -l, --level 过滤日志级别 (info, warning, error)'); $output->writeln(' --limit 限制显示条数 (默认: 50)'); $output->writeln(' -c, --controller 过滤控制器名称'); $output->writeln(' -h, --help 显示帮助信息'); $output->newLine(); $output->info('示例:'); $output->writeln(' php think tools:log:search "用户登录失败" --level=error'); $output->writeln(' php think tools:log:search "数据库连接" --controller=Admin --limit=20'); $output->writeln(' php think tools:log:search "Exception" --level=error'); $output->newLine(); } }