日志¶
BentoML 提供内置的日志系统,用于全面了解 BentoML 服务的运行情况。它实现了 OpenTelemetry 标准,以在整个 HTTP 调用栈中传播关键信息,用于详细的调试和分析。
本文档提供了在 BentoML 中配置日志的指南,包括管理服务器端日志以及将 BentoML 作为库使用时的自定义日志配置。
服务器日志¶
BentoML 默认启用服务器日志。服务启动后,发送到服务器的每个请求都会记录详细信息。BentoML 对日志进行结构化处理,以提供每个请求的清晰简洁概览,格式如下:
timestamp [LEVEL] [component] ClientIP:ClientPort (scheme,method,path,type,length) (status,type,length) Latency (trace,span,sampled,service.name)
由 BentoML 处理的请求的日志消息示例可能如下所示:
2024-04-13T02:03:49+0000 [INFO] [entry_service:Summarization:1] 44.xxx.xxx.104:7181 (scheme=http,method=GET,path=/docs.json,type=,length=) (status=200,type=application/json,length=5543) 1.972ms (trace=7589d361df3e8ad3f0a71acb44d150be,span=07ef3bc1685d067c,sampled=0,service.name=Summarization)
此日志条目提供了关于请求的详细信息,包括客户端 IP 和端口、请求方法、路径、负载类型和长度、响应状态、响应内容类型和长度、请求延迟以及 OpenTelemetry 标识符。
BentoML 的日志系统与 OpenTelemetry 标准完全兼容。服务器日志包含多个 OpenTelemetry 参数,这些参数有助于将日志关联回特定的请求或操作。
trace
: 标识一个 trace,它由一个或多个 span 组成,代表流经多个服务的单个请求。详情请参阅 Traces。span
: 标识 trace 中的单个 span。每个 span 代表 trace 中的一个特定操作或工作单元,例如单个 HTTP 请求。详情请参阅 Spaces。sampled
: 指示 trace 是否正在被采样,即是否应该记录 trace 数据。如果启用采样(通常用1
表示已采样,0
表示未采样),则只捕获 trace 的一个子集,这有助于管理数据量并减少性能开销。详情请参阅 Sampling。
配置日志¶
您可以在服务定义中通过使用 logging
参数在 @bentoml.service
装饰器中配置服务器日志。
import bentoml
@bentoml.service(logging={
"access": {
"enabled": True,
"request_content_length": True,
"request_content_type": True,
"response_content_length": True,
"response_content_type": True,
"skip_paths": ["/metrics", "/healthz", "/livez", "/readyz"],
"format": {
"trace_id": "032x",
"span_id": "016x"
}
}
})
class MyService:
# Service implementation
可用于控制记录哪些数据以及如何格式化的日志参数:
enabled
: 启用或禁用日志记录。request_content_length
: 记录请求体的大小。request_content_type
: 记录请求的内容类型。response_content_length
: 记录响应体的大小。response_content_type
: 记录响应的内容类型。skip_paths
: 指定应从日志记录中排除的路由路径。format
: 自定义 OpenTelemetry trace 标识符的日志格式。trace_id
: 以指定格式记录 trace 标识符,例如032x
。span_id
: 以指定格式记录 span 标识符,例如016x
。
要配置其他日志,请使用默认的 Python 日志配置。所有 BentoML 日志都记录在 bentoml
命名空间下。
库日志¶
当您将 BentoML 作为库用于 Python 应用程序时,它不会配置任何日志,不包含任何特定的处理程序、格式化程序或过滤器。这意味着如果没有额外的配置,BentoML 的日志输出将遵循 Python 根日志记录器的设置,默认情况下,根日志记录器记录 WARNING 级别及更高级别的消息(包括 ERROR 和 CRITICAL)。
要捕获 BentoML 中更详细的日志,特别是在 DEBUG
或 INFO
级别,您必须显式设置日志处理程序并将其注册到 bentoml
命名空间。以下是一个简单的示例说明如何实现这一点:
import logging
# Create a stream handler
ch = logging.StreamHandler()
# Set a format for the handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
# Get the BentoML logger
bentoml_logger = logging.getLogger("bentoml")
# Add the handler to the BentoML logger
bentoml_logger.addHandler(ch)
# Set the desired logging level (e.g., DEBUG)
bentoml_logger.setLevel(logging.DEBUG)
注意
使用 bentoml serve
启动服务时,该命令会将 service.py
fork 到一个子进程中。涉及文件操作的处理程序(例如日志轮换,RotatingFileHandler
或 TimedRotatingFileHandler
)在服务定义中不受支持。更多信息请参阅Python 日志记录 Cookbook。