最稳方式是用 Symfony Profiler 存储数据而非原始日志:Profiler 默认将路由、响应码等元信息写入 var/cache/dev/profiler/(SQLite 或文件),字段完整且格式稳定;直接解析 dev.log 不可靠,因路由信息仅在 debug 级别且启用 request channel 时才可能出现,且日志格式随版本和配置浮动。

怎么从 Symfony2 日志里提取路由访问频次
直接 grep dev.log 或 prod.log 里的 GET / POST 行没用——日志里不存原始 URL,而是记录路由名(如 app_homepage)和控制器方法(如 AppBundle:Default:index),且格式随 Monolog 配置浮动。必须靠结构化解析才能批量统计。
最稳的方式是:用 Symfony Profiler 的存储数据,而非原始日志文件。Profiler 默认把每次请求的路由、响应码、耗时等元信息写进 var/cache/dev/profiler/ 下的 SQLite 或文件目录,比文本日志更可靠、字段更完整。
- 确认 profiler 已启用:检查
config/packages/dev/framework.yaml中profiler: { only_exceptions: false }(或没显式禁用) - 确保请求被采集:页面底部有 Symfony 小工具栏,点击任意请求条目后地址栏含
/_profiler/{token} - 运行命令导出最近 100 次请求的路由统计:
php bin/console profiler:export --limit=100 | grep -o 'route=[^[:space:]]*' | sort | uniq -c | sort -nr
输出形如:42 route=app_product_list、18 route=app_user_profile。注意 profiler:export 默认只导出成功请求(HTTP 2xx),加 --status=404 可单独抓错误路由。
为什么不能直接 parse dev.log 统计路由
dev.log 里路由信息藏得深:它只在 debug 级别下、且 monolog 配置了 channels: [doctrine, security, request] 时,才可能在某行末尾带 ["route" => "app_homepage"] 这样的结构。但多数默认配置不开启 request channel,导致你 grep "route" 返回空。
- 查当前生效的 channels:
php bin/console debug:config monolog,看handlers.main.channels是否含request - 若不含,临时加到
config/packages/dev/monolog.yaml:monolog: handlers: main: channels: ['%kernel.default_locale%', 'request', 'doctrine'] - 重启服务后,再触发请求,
dev.log才可能出现Matched route "app_api_v1_users"这类可 grep 的行
但即便如此,日志行格式不稳定(不同 Symfony 版本、不同 handler 类型输出不同),不如 Profiler 数据字段固定、可预测。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
如何导出带时间窗口的路由访问趋势
Profiler 默认只保留最近若干请求(由 framework.profiler.storage.dsn 决定,默认是 file:/var/cache/dev/profiler,按时间自动轮转)。要按小时/天统计,得先持久化数据:
- 改存储为数据库(推荐 SQLite):
framework.profiler.storage.dsn: 'sqlite:/var/cache/dev/profiler.db' - 用 SQL 直接查:
SELECT strftime('%Y-%m-%d %H:00', time) AS hour, route, COUNT(*) FROM profile WHERE time > datetime('now', '-7 days') GROUP BY hour, route ORDER BY hour DESC, COUNT(*) DESC; - 导出 CSV:
sqlite3 var/cache/dev/profiler.db ".mode csv" ".output routes.csv" "上述SQL"
注意:SQLite 的 time 字段是 UNIX timestamp(秒级),不是字符串,别用 LIKE 模糊匹配日期。
生产环境怎么安全地做路由统计
生产环境禁用 Profiler,dev.log 通常只设为 warning 或 error 级别,根本不会记路由匹配过程。唯一可行路径是:在 kernel.request 事件监听器里主动埋点,写入独立日志通道。
- 创建监听器,只记录路由名和时间戳:
public function onKernelRequest(RequestEvent $event): void { if (!$event->isMainRequest()) return; $route = $event->getRequest()->attributes->get('_route'); if ($route) { $this->logger->info('route_access', ['route' => $route, 'ts' => time()]); } } - 配一个专用 handler 到
monolog.yaml:handlers: route_stats: type: stream path: '%kernel.logs_dir%/routes.log' level: info - 之后用 awk + sort 统计:
awk '{print $9}' var/log/routes.log | sort | uniq -c | sort -nr(假设第 9 字段是 route 值)
关键点:这个日志必须隔离,不能混进主日志;字段要固定分隔(比如用 JSON 格式写入),否则后期解析会因空格、冒号、中括号崩掉。


















