Xinference 日志系统全指南:级别配置、轮转策略、环境变量与目录结构
【免费下载链接】inferenceSwap GPT for any LLM by changing a single line of code. Xinference lets you run open-source, speech, and multimodal models on cloud, on-prem, or your laptop — all through one unified, production-ready inference API.项目地址: https://gitcode.com/GitHub_Trending/in/inference
Xinference 提供了完整的日志体系,覆盖xinference-local、xinference-supervisor、xinference-worker以及独立 Token Router 服务,支持命令行与文件双重输出、按大小/按天自动轮转、text/json 两种格式以及细粒度的下载进度日志控制。本文以 logging.rst 为骨架,结合仓库源码(constants.py、deploy/utils.py、router/logging_config.py)深入讲解日志级别、轮转参数、环境变量、日志目录结构及生产环境下的 Token Router 日志落地实践,读完即可独立完成本地与分布式部署的日志排障与运维配置。
日志级别配置
Xinference 通过命令行参数--log-level控制日志级别,所有部署入口(local、supervisor、worker)均支持该选项。
命令行使用
以本地集群为例,使用DEBUG级别启动:
xinference-local --log-level debug从 cmdline.py 的 Click 定义可以看到,--log-level的默认值是INFO,可用的级别按输出量从多到少排列为:
DEBUG > INFO > WARNING > ERROR > CRITICAL源码中同时把该级别透传给TRANSFORMERS_VERBOSITY(见 cmdline.py 的set_envs("TRANSFORMERS_VERBOSITY", log_level.lower())),因此设置的日志级别会同时约束 Xinference 自身与 Transformers 库的日志输出。
级别的作用范围
设置日志级别后,对命令行(stderr 控制台输出)与日志文件同时生效,两者使用统一的级别配置。这一行为由 deploy/utils.py 中的get_config_dict保证:无论console_handler、stream_handler还是file_handler,都采用同一个log_level;同时xinference、uvicorn、transformers、vllm等 logger 也统一应用该级别。
日志文件与轮转策略
Xinference 支持日志文件的自动轮转(log rotation),默认配置为:
- maxBytes:单个日志文件达到100MB时触发轮转;
- backupCount:最多保留30个备份文件。
轮转行为由 core/log.py 中统一的create_rotating_handler工厂实现,该函数支持三种轮转模式(rotation参数):
| 模式 | 实现类 | 触发条件 | 备份控制参数 |
|---|---|---|---|
daily | TimedRotatingFileHandler(标准库) | 每天午夜(when="midnight") | backupCount=retention_days |
daily+size | SafeTimedAndSizeRotatingFileHandler | 每天午夜 + 达到max_bytes | 按天保留retention_days,按文件数量封顶backup_count |
size | SafeRotatingFileHandler | 仅按大小(maxBytes) | backupCount=retention_days |
值得注意的是,constants.py 中XINFERENCE_LOG_ROTATION的默认值实际是daily+size,即默认同时按天和按大小进行轮转;而在get_config_dict中,轮转策略、maxBytes、backupCount、retention_days都会通过 dictConfig 传递给对应的 handler(见 deploy/utils.py)。
多进程安全设计
生产环境 Supervisor 与 Worker 可能并发写同一日志文件,deploy/utils.py 中的SafeRotatingFileHandler为此做了专门加固:
- 使用
fcntl文件锁序列化doRollover,避免多进程同时轮转导致文件错乱; shouldRollover入口检查 inode,若其他进程已完成轮转则重新打开流;- 大小判断基于
os.fstat().st_size而非stream.tell(),反映文件真实大小; - 自动创建父目录,避免 xoscar 子池进程通过共享内存重建日志配置时因目录缺失抛
FileNotFoundError。
环境变量:全面控制日志行为
Xinference 提供一组环境变量精细控制日志行为,定义于 constants.py:
| 环境变量 | 默认值 | 说明 |
|---|---|---|
XINFERENCE_LOG_CONSOLE | true | 是否输出到控制台。设为false时仅写文件,此时 stdout/stderr 被重定向到 logger,tqdm 进度条被采样记录 |
XINFERENCE_LOG_FORMAT | text | 日志格式,可选text或json |
XINFERENCE_LOG_DOWNLOAD_PROGRESS | sampled | 仅当XINFERENCE_LOG_CONSOLE=false时生效,控制下载进度条的记录粒度 |
XINFERENCE_LOG_ROTATION | daily+size | 轮转模式:daily、daily+size或size |
XINFERENCE_LOG_RETENTION_DAYS | 30 | 按天轮转时保留的天数 |
XINFERENCE_LOG_MAX_BYTES | 104857600(100MB) | 按大小轮转的单文件上限 |
XINFERENCE_LOG_BACKUP_COUNT | 300 | 备份文件数量上限(daily+size模式) |
XINFERENCE_LOG_DIR | <XINFERENCE_HOME>/logs | 日志根目录,见 constants.py |
XINFERENCE_LOG_POLLING_ACCESS | false | 是否记录 Web UI 轮询/progress、/replicas和指标抓取的 access 日志 |
下载进度日志的三种模式
XINFERENCE_LOG_DOWNLOAD_PROGRESS只在关闭控制台输出时才有意义,合法值及行为(源码注释见 constants.py):
sampled(默认):每个分片在25/50/75/100%处记录一次,退出时记录终态;full:记录 tqdm 的每一帧进度;off:不记录进度帧,只保留开始/出错行。
若传入非法值,启动时会向 stderr 打印 WARNING 并回退到sampled(见 constants.py)。该机制由redirect_streams_to_logger上下文管理器与StreamToLogger实现(见 deploy/utils.py),它在模型加载期间把 stdout/stderr 重定向到xinference.stdout/xinference.stderrlogger,从而把 tqdm 进度条写入日志文件。
实际使用示例
# 关闭控制台输出,下载进度按采样点(25/50/75/100%)记录 XINFERENCE_LOG_CONSOLE=false XINFERENCE_LOG_DOWNLOAD_PROGRESS=sampled xinference-local # 关闭控制台输出,记录下载进度的每一帧 XINFERENCE_LOG_CONSOLE=false XINFERENCE_LOG_DOWNLOAD_PROGRESS=full xinference-local # 关闭控制台输出,不记录任何下载进度日志 XINFERENCE_LOG_CONSOLE=false XINFERENCE_LOG_DOWNLOAD_PROGRESS=off xinference-local需要说明的是,deploy/utils.py 的install_stream_redirect函数注释明确警告:不要在进程启动时调用全局流重定向,否则会破坏 xoscar 子池的创建;因此 Xinference 采用redirect_streams_to_logger上下文管理器做作用域内的临时重定向。
text 与 json 两种格式
XINFERENCE_LOG_FORMAT=json时,deploy/utils.py 会选择JsonFileFormatter,否则使用TextFileFormatter。text 格式的单行日志(见AddressFormatter.format,deploy/utils.py)包含:
时间戳(UTC, 毫秒精度) 级别 logger名 pid:进程号 role:角色 address:地址 node:主机名 消息内容 [key=value...]结构化字段(如角色、地址等)以key=value形式追加在行尾,异常堆栈单独换行输出。json 格式则把上述字段组织为结构化 JSON,便于对接 ELK 等日志采集系统。
日志目录结构
所有日志默认存储在<XINFERENCE_HOME>/logs目录下,<XINFERENCE_HOME>可通过环境变量配置(参见 using_xinference.rst)。每次启动 Xinference 集群时,会在日志目录下创建一个以**集群启动时间(毫秒时间戳)**命名的子目录,避免多次启动的日志互相覆盖。
本地部署(单文件合并)
本地部署时,Supervisor 与 Worker 的日志合并写入同一个文件:
<XINFERENCE_HOME>/logs └── local_1699503558105 └── xinference.log其中1699503558105为集群创建时刻的毫秒时间戳。因此多次本地启动集群时,可以依据该时间戳定位到对应批次的日志(XINFERENCE_DEFAULT_LOG_FILE_NAME为xinference.log,见 constants.py)。
分布式部署(按角色分目录)
分布式部署时,Supervisor 与每个 Worker 在日志目录下各自创建子目录,子目录名以角色名 + 该角色启动时间的毫秒时间戳命名:
<XINFERENCE_HOME>/logs └── supervisor_1699503558908 └── xinference.log worker_1699503559105 └── xinference.log这种按角色隔离的目录设计,让运维人员可以按节点、按角色快速检索日志。注意日志目录本身是全局配置的:XINFERENCE_LOG_DIR默认os.path.join(XINFERENCE_HOME, "logs")(见 constants.py),审计日志audit.log也写入同一目录(见 api/oauth2/advanced/audit.py)。
Token Router 日志:生产落地实践
独立的xinference-router服务复用与 Supervisor/Worker 相同的文件格式器与轮转 handler(由 router/logging_config.py 的configure_router_logging调用get_config_dict与get_log_file("router")完成),因此具备一致的 text/json 格式与轮转能力。
systemd 部署示例
文档给出了一份适合生产 systemd 部署的非敏感配置,写入/etc/xinference/router.env:
XINFERENCE_TOKEN_ROUTER_LOG_LEVEL=INFO XINFERENCE_TOKEN_ROUTER_ACCESS_LOG=false XINFERENCE_LOG_FORMAT=json XINFERENCE_LOG_CONSOLE=false XINFERENCE_LOG_DIR=/data/inference/logs/router XINFERENCE_LOG_ROTATION=daily+size XINFERENCE_LOG_RETENTION_DAYS=30 XINFERENCE_LOG_MAX_BYTES=104857600 XINFERENCE_LOG_BACKUP_COUNT=300应用这些设置后,Router 的应用日志写入/data/inference/logs/router/xinference.log。要点:
- 该目录必须存在且对 Router 服务账号可写;
- 轮转由 Xinference 自身管理,不要再对同一文件叠加系统
logrotate/copytruncate规则,以免双重轮转导致文件错乱; XINFERENCE_TOKEN_ROUTER_LOG_LEVEL的合法取值与 Python logging 级别一致(CRITICAL/ERROR/WARNING/INFO/DEBUG/NOTSET),非法值会被 logging_config.py 的normalize_log_level规整回INFO;XINFERENCE_TOKEN_ROUTER_ACCESS_LOG默认false(见 logging_config.py)。
Router 日志内容与安全边界
Router 会输出结构化的生命周期、配置、路由决策、完成、拒绝以及后端错误事件。路由事件在可用时会同时记录请求的虚拟模型名与选中的物理后端模型 UID,便于在 Token Router 场景下追踪每个请求实际打到哪个后端。
出于安全考虑,以下内容绝不会出现在 Router 日志中:
- 请求体、prompt/消息内容、响应体;
Authorization头、API Key、控制面 token。
URL 也会经过sanitize_log_url(见 logging_config.py)剥除凭据、查询参数与 fragment 后再记录。结构化字段采用白名单机制:只有_ROUTER_LOG_FIELDS中的字段才会被写入(见router_log_extra,logging_config.py),从机制上杜绝敏感字段泄漏。
Uvicorn 访问日志与 journal 兜底
Uvicorn access 日志默认关闭,因为它会重复记录高流量的请求信息;仅当需要 access 日志诊断时才设置XINFERENCE_TOKEN_ROUTER_ACCESS_LOG=true。Uvicorn error 日志保持开启,并复用同一套 Xinference 日志配置。
在 systemd 部署中,应保持 journal 输出开启,作为进程生命周期消息与应用日志初始化前发生的启动失败信息的兜底通道——这一阶段应用日志系统尚未就绪,只能依赖 journald 留存排障线索。
小结
| 关注点 | 推荐做法 |
|---|---|
| 日常排障 | xinference-local --log-level debug或在启动命令前设置XINFERENCE_LOG_CONSOLE=false只写文件 |
| 长时间运行 | 依赖默认的daily+size轮转(100MB 上限 + 30 天保留),或按需调XINFERENCE_LOG_MAX_BYTES/XINFERENCE_LOG_RETENTION_DAYS |
| 日志采集 | 设置XINFERENCE_LOG_FORMAT=json对接 ELK 等系统 |
| 下载模型排障 | XINFERENCE_LOG_CONSOLE=false+XINFERENCE_LOG_DOWNLOAD_PROGRESS=full记录每一帧进度 |
| Router 生产部署 | 使用router.env模板,目录预创建且仅由 Xinference 轮转,避免叠加 logrotate |
Xinference 的日志体系把"控制台输出、文件轮转、进度条捕获、结构化格式、安全脱敏"整合为一套统一配置,既适合单机本地调试,也足以支撑分布式集群与独立 Token Router 的生产运维需求。如需进一步了解日志与审计的联动(如audit.log与审计中心),可继续阅读 audit_security.rst 与 logging.rst 相关章节。
【免费下载链接】inferenceSwap GPT for any LLM by changing a single line of code. Xinference lets you run open-source, speech, and multimodal models on cloud, on-prem, or your laptop — all through one unified, production-ready inference API.项目地址: https://gitcode.com/GitHub_Trending/in/inference
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考