构建分布式文本到图像AI系统及数据科学系统的监控与日志管理
1. 分布式文本到图像AI系统构建
我们在MinIO服务器上会得到一个很长的URL,在浏览器中打开该URL,就能看到系统刚刚生成的图像。现在我们拥有了一个功能完备的系统,用户可以进行以下操作:
- 请求根据自己的提示和参数生成图像
- 获取请求进度信息
- 从可靠存储中获取生成的图像
该系统架构可部署在多台机器的云环境中。通常,我们可以使用一个标准、廉价的服务器来提供API服务,再使用一个配备专用GPU和大量RAM的昂贵服务器来运行工作进程。由于进程间的通信由消息代理、数据库和对象存储这些核心元素处理,因此代码无需更改即可处理这种部署。
2. 数据科学系统的监控与日志管理
在构建数据科学应用时,确保系统正确运行并及时发现问题至关重要。我们将介绍如何设置合适的日志记录工具,以及如何实时监控软件的性能和健康状况。
2.1 技术要求
- 需要一个Python虚拟环境。
- 要运行Dramatiq工作进程,需要在本地计算机上运行Redis服务器,最简单的方法是将其作为Docker容器运行。若从未使用过Docker,可阅读官方文档中的入门教程(https://docs.docker.com/get-started/),之后使用以下命令运行Redis服务器:
$ docker run -d --name worker-redis -p 6379:6379 redis
所有代码示例可在GitHub仓库(https://github.com/PacktPublishing/Building-Data-Science-Applications-with-FastAPI-Second-Edition/tree/main/chapter15)中找到。
2.2 使用Loguru配置和使用日志记录工具
在软件开发中,日志是控制系统行为最简单但最强大的方法。以Uvicorn运行FastAPI应用时,控制台输出的日志能告诉我们服务器启动和处理请求的情况,还能帮助我们发现问题。
日志级别
:日志级别用于分类日志的重要性,常见的日志级别如下表所示:
| 日志级别 | 说明 |
| ---- | ---- |
| DEBUG | 提供程序具体执行信息,有助于调试代码 |
| INFO | 记录程序正常运行的基本信息 |
| WARNING | 表示可能存在问题,但不影响程序正常运行 |
| ERROR | 表示程序出现严重问题,可能需要采取行动 |
我们可以配置日志记录器输出的最低日志级别。在本地开发时,可将级别设置为DEBUG以获取所有信息;在生产环境中,可将级别设置为INFO或WARNING以仅获取最重要的消息。
使用Loguru添加日志
:使用Python标准库中的logging模块添加日志很简单,但配置复杂。Python开发者通常使用封装了logging模块的库,如Loguru。以下是使用步骤:
1. 安装Loguru:
(venv) $ pip install loguru
- 在Python shell中测试:
>>> from loguru import logger
>>> logger.debug("This is my log!")
2023-02-21 08:44:00.168 | DEBUG | __main__:<module>:1 - This is my log!
- 在完整脚本中使用:
# chapter15_logs_01.py
from loguru import logger
def is_even(n) -> bool:
logger.debug("Check if {n} is even", n=n)
if not isinstance(n, int):
logger.error("{n} is not an integer", n=n)
raise TypeError()
return n % 2 == 0
if __name__ == "__main__":
is_even(2)
is_even("hello")
运行该脚本,日志会正确添加到输出中,并且Loguru能精确告诉我们日志调用在代码中的位置。
理解和配置sink :默认情况下,Loguru的日志会添加到控制台输出。Loguru引入了sink的概念,用于定义日志记录器如何处理日志行。我们不仅可以将日志输出到控制台,还可以保存到文件、数据库,甚至发送到Web服务。每个sink都可以关联一个日志级别,这样我们可以根据日志的性质或重要性将其路由到不同的位置。以下是配置示例:
# chapter15_logs_02.py
import sys
from loguru import logger
logger.remove()
logger.add(sys.stdout, level="WARNING")
logger.add("file.log", level="DEBUG", rotation="1 day")
在上述代码中,
remove
方法用于移除之前定义的sink,
add
方法用于定义新的sink。运行该示例后,控制台只会输出WARNING及以上级别的日志,而文件会记录所有级别的日志。
流程图如下:
graph LR
A[日志记录] --> B[控制台输出]
A --> C[文件存储]
B -->|WARNING及以上级别| D[显示日志]
C -->|所有级别| E[保存日志]
结构化日志和添加上下文 :为了更好地理解日志内容,我们可以采用结构化日志的方法。Loguru通过上下文支持这种方法,示例如下:
# chapter15_logs_03.py
from loguru import logger
def is_even(n) -> bool:
logger_context = logger.bind(n=n)
logger_context.debug("Check if even")
if not isinstance(n, int):
logger_context.error("Not an integer")
raise TypeError()
return n % 2 == 0
默认情况下,Loguru不会将上下文信息添加到格式化的日志行中,我们需要进行自定义:
# chapter15_logs_04.py
import sys
from loguru import logger
logger.add(
sys.stdout,
level="DEBUG",
format="<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
"<level>{level: <8}</level> | "
"<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
"<level>{message}</level>"
" - {extra}",
)
运行该示例后,日志行将包含额外的上下文信息。
日志作为JSON对象
:另一种结构化日志的方法是将日志数据序列化为JSON对象。在配置sink时设置
serialize=True
即可启用此功能。如果计划使用Logstash或Datadog等日志摄取服务,这种方法很有用,因为它们可以解析JSON数据并进行查询。
3. 配置Prometheus指标并在Grafana中监控
在数据科学系统的运维中,除了日志记录,对系统性能指标的监控同样关键。Prometheus是一个开源的系统监控和警报工具包,它可以收集和存储时间序列数据,而Grafana则是一个可视化工具,能将Prometheus收集的数据以直观的图表形式展示出来。
3.1 配置Prometheus
要使用Prometheus监控系统,首先需要对其进行配置。以下是一个简单的配置步骤:
1.
安装Prometheus
:可以从Prometheus的官方网站下载适合你操作系统的版本,并进行安装。
2.
创建配置文件
:创建一个
prometheus.yml
文件,用于定义监控目标和规则。示例配置如下:
global:
scrape_interval: 15s # 每15秒收集一次数据
scrape_configs:
- job_name: 'your_app'
static_configs:
- targets: ['localhost:8000'] # 替换为你的应用地址和端口
- 启动Prometheus :使用以下命令启动Prometheus,并指定配置文件:
./prometheus --config.file=prometheus.yml
3.2 在应用中暴露指标
在你的FastAPI应用中,需要使用
prometheus_client
库来暴露指标。以下是一个示例代码:
from fastapi import FastAPI
from prometheus_client import start_http_server, Counter
app = FastAPI()
# 创建一个计数器指标
REQUEST_COUNTER = Counter('app_requests_total', 'Total number of requests')
@app.get("/")
def read_root():
# 每次请求时增加计数器
REQUEST_COUNTER.inc()
return {"Hello": "World"}
if __name__ == "__main__":
# 启动Prometheus指标服务器
start_http_server(8001)
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
在上述代码中,我们创建了一个计数器指标
app_requests_total
,并在每次请求时增加该计数器的值。同时,启动了一个HTTP服务器,用于暴露Prometheus指标。
3.3 在Grafana中配置数据源和仪表盘
- 安装和启动Grafana :从Grafana的官方网站下载适合你操作系统的版本,并启动Grafana服务。
-
配置数据源
:登录Grafana,在左侧菜单中选择“Configuration” -> “Data Sources”,然后添加一个Prometheus数据源,填写Prometheus的地址(如
http://localhost:9090)。 -
创建仪表盘
:在Grafana中,选择“Create” -> “Dashboard”,然后添加一个新的面板。在面板配置中,选择Prometheus数据源,并编写查询语句来展示指标数据。例如,查询
app_requests_total指标:
app_requests_total
通过以上步骤,你就可以在Grafana中直观地监控应用的性能指标了。
表格:配置Prometheus和Grafana的步骤总结
| 步骤 | 操作内容 |
| ---- | ---- |
| 1 | 安装Prometheus并创建配置文件 |
| 2 | 在应用中使用
prometheus_client
库暴露指标 |
| 3 | 安装和启动Grafana |
| 4 | 在Grafana中配置Prometheus数据源 |
| 5 | 创建仪表盘并添加面板展示指标数据 |
4. 配置Sentry用于错误报告
Sentry是一个开源的错误跟踪和性能监控平台,它可以帮助我们快速定位和解决应用中的错误。
4.1 安装Sentry SDK
在你的FastAPI应用中,需要安装Sentry的Python SDK。使用以下命令进行安装:
pip install sentry-sdk
4.2 初始化Sentry
在应用代码中初始化Sentry,并配置DSN(Data Source Name)。示例代码如下:
import sentry_sdk
from fastapi import FastAPI
sentry_sdk.init(
dsn="your_dsn_here", # 替换为你的Sentry DSN
traces_sample_rate=1.0,
)
app = FastAPI()
@app.get("/")
def read_root():
try:
# 模拟一个错误
result = 1 / 0
return {"result": result}
except ZeroDivisionError as e:
raise e
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
在上述代码中,我们初始化了Sentry SDK,并在应用中模拟了一个除零错误。当错误发生时,Sentry会自动捕获并发送错误报告到Sentry平台。
4.3 查看错误报告
登录Sentry平台,在项目的控制台中可以查看详细的错误报告,包括错误堆栈跟踪、环境信息等。通过这些信息,我们可以快速定位和解决应用中的问题。
流程图如下:
graph LR
A[应用运行] --> B[发生错误]
B --> C[Sentry SDK捕获错误]
C --> D[发送错误报告到Sentry平台]
D --> E[在Sentry控制台查看报告]
通过以上对日志记录、性能指标监控和错误报告的配置,我们可以构建一个健壮、可维护的数据科学系统,及时发现和解决系统中出现的问题,确保系统的稳定运行。
超级会员免费看

被折叠的 条评论
为什么被折叠?



