1. vLLM日志体系总览
日志,说白了就是系统的「黑匣子」。我做了这么多年运维,每次排查问题,第一件事就是翻日志。vLLM也不例外,它的日志体系设计得挺清晰,但如果你不了解它的「语言」,翻起来会很痛苦。
这一章,我带你把vLLM的日志体系从头捋一遍。从日志级别到格式,从输出到轮转,全给你讲透。
1.1 日志级别:从DEBUG到ERROR
vLLM的日志级别,跟Python标准库logging保持一致。一共四个级别,从低到高分别是:
| 级别 | 数值 | 什么时候出现 | 我的建议 |
|---|---|---|---|
| DEBUG | 10 | 开发调试、内部状态打印 | 生产环境别开,日志量太大 |
| INFO | 20 | 启动信息、请求统计、模型加载进度 | 日常监控用这个就够了 |
| WARNING | 30 | 配置不推荐、资源紧张、降级行为 | 需要关注,但不一定立即处理 |
| ERROR | 40 | 请求失败、OOM、模型加载失败 | 必须立刻处理 |
重要提醒:vLLM默认日志级别是INFO。我个人习惯在排查问题时临时切到DEBUG,排查完立刻切回来。否则日志文件一天能涨几个GB。
你可能会问:为什么没有FATAL或CRITICAL?嗯,vLLM的设计理念是「尽量优雅降级」。遇到严重错误时,它通常直接抛异常退出,而不是打一条FATAL日志继续跑。这一点跟很多Java框架不太一样。
1.2 日志格式解析:每一段都有含义
vLLM的日志格式长这样:
2025-03-15 14:32:18,123 INFO vllm.engine.llm_engine.py:456] Starting to load model 'meta-llama/Llama-2-7b-hf'...
拆开来看,一共五个部分:
- 时间戳:
2025-03-15 14:32:18,123,精确到毫秒。注意是本地时间,不是UTC。 - 日志级别:
INFO,固定5个字符宽度,对齐用的。 - 模块路径:
vllm.engine.llm_engine.py:456,文件名加行号。这个信息特别有用,我经常靠它定位到具体代码行。 - 分隔符:
],没什么特别含义,就是格式统一。 - 消息正文:
Starting to load model...,真正的日志内容。
小技巧:如果你用ELK或Splunk做日志聚合,建议把时间戳、级别、模块路径单独提取成字段。这样搜索起来快得多。我曾经在排查一个性能问题时,就是靠模块路径字段快速过滤出所有engine模块的日志,省了一半时间。
1.3 日志输出目标:stdout还是文件?
vLLM默认把日志打到标准输出(stdout)。这在容器化部署时很方便——docker logs直接能看到。但如果你需要持久化保存,就得配文件输出。
配置方式有两种:
- 环境变量:设置
VLLM_LOG_FILE=/var/log/vllm/server.log - 启动参数:
--log-file /var/log/vllm/server.log
我个人更推荐用环境变量。为什么?因为启动参数容易被遗忘,而环境变量可以写在Dockerfile或K8s的ConfigMap里,统一管理。
避坑指南:我曾经遇到过一个问题——同时设置了环境变量和启动参数,结果vLLM把日志打到了两个地方。排查了半天才发现是配置冲突。记住:启动参数优先级高于环境变量,但不要同时设置。
另外,vLLM的日志输出目标还有一个隐藏选项:syslog。不过这个功能目前还不太成熟,我试过一次,格式有点乱,不建议生产环境用。
1.4 日志轮转策略:别让日志撑爆磁盘
日志轮转,说白了就是「日志文件不能无限长大」。vLLM本身没有内置轮转机制,它依赖外部工具。常用的方案有两种:
方案一:Linux logrotate(推荐)
配置一个/etc/logrotate.d/vllm文件:
/var/log/vllm/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
}
解释一下关键参数:
daily:每天轮转一次rotate 7:保留最近7天的日志compress:轮转后压缩成.gzcopytruncate:这个很重要!vLLM打开文件后不会重新打开,所以不能用默认的create模式,必须用copytruncate,否则日志会丢失。
方案二:Docker日志驱动
如果你用容器部署,可以直接用Docker的日志驱动:
docker run --log-driver=json-file --log-opt max-size=100m --log-opt max-file=3 ...
这样每个日志文件最大100MB,保留3个文件。超过就自动删除最旧的。
我的经验:在K8s环境里,我一般用logrotate方案。因为Docker日志驱动在节点重启后可能丢失部分日志,而logrotate配合持久化存储更可靠。当然,如果你用EFK或Loki做日志收集,那日志轮转其实没那么重要——反正都发到远端了。
知识体系总览
下面这张图,把vLLM日志体系的四个核心维度串起来了。你可以把它当作本章的「地图」:
这张图你看懂了吗?四个维度互相独立,但又共同构成了完整的日志体系。你不需要一次性全记住,但遇到问题时,能快速定位到是哪个维度出了问题。
好了,第一章就到这里。日志体系是基础,后面几章我们会深入每个维度的实战技巧。记住:日志不是用来「看」的,是用来「查」的。掌握好它,你排查问题的速度能快一倍。
公众号:蓝海资料掘金营,微信deep3321