前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用opentelemetry与jaeger实现flask应用的链路追踪

使用opentelemetry与jaeger实现flask应用的链路追踪

作者头像
杜逸先
发布2023-04-13 16:33:10
1.3K0
发布2023-04-13 16:33:10
举报

链路追踪是应用可观测性的重要组成部分,它可以帮助我们快速定位问题,提高应用的可用性和稳定性。 今天我们来看看如何使用 opentelemetry 与 jaeger 实现 flask 应用的链路追踪。

OpenTelemetry 与 Jaeger

OpenTelemetry is a collection of tools, APIs, and SDKs. Use it to instrument, generate, collect, and export telemetry data (metrics, logs, and traces) to help you analyze your software’s performance and behavior.

OpenTelemetry 是一个用于收集、生成、导出遥测数据(metrics、logs、traces)的工具集合,它可以帮助我们分析软件的性能和行为。

Jaeger 是一个开源的分布式跟踪系统,它可以收集、存储和分析应用的链路追踪数据。

Jaeger 支持 Opentelemetry 协议,可以直接从 OpenTelemetry 收集数据。

在 Flask 中集成 OpenTelemetry 与 Jaeger

部署 Jaeger

Jaeger 有多种部署方式,在开发环境下最简单的方式是使用 Jaeger 官方提供的 all-in-one 镜像。

代码语言:javascript
复制
## make sure to expose only the ports you use in your deployment scenario!
docker run -d --name jaeger \
  -e COLLECTOR_OTLP_ENABLED=true \
  -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14250:14250 \
  -p 14268:14268 \
  -p 14269:14269 \
  -p 4317:4317 \
  -p 4318:4318 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.42

访问 http://localhost:16686 查看 Jaeger 的 UI。

jaeger ui
jaeger ui

基础配置

首先安装一下相关依赖。

代码语言:javascript
复制
pip install flask opentelemetry-instrumentation-flask opentelemetry-exporter-jaeger

编辑main.py,定义一个简单的 flask 应用。

代码语言:javascript
复制
from flask import Flask
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor


def configure_trace(app: Flask):
    trace.set_tracer_provider(
        TracerProvider(resource=Resource.create({SERVICE_NAME: app.name}))
    )

    trace.get_tracer_provider().add_span_processor(
        BatchSpanProcessor(
            JaegerExporter(
                agent_host_name="localhost",
                agent_port=6831,
            )
        )
    )

    FlaskInstrumentor().instrument_app(app)


app = Flask(__name__)
configure_trace(app)


@app.get("/")
def hello():
    return "Hello, World!"

configure_trace函数中,我们配置了 opentelemetry 的 TracerProvider,它是一个全局的单例,用于创建 tracer。

然后创建了一个 JaegerExporter 并添加为 Provider 的 Processor,它会将收集到的数据发送到 Jaeger。

最后使用 FlaskInstrumentor 来为 flask 应用添加 opentelemetry 的中间件。

运行应用并访问 http://localhost:5000。

代码语言:javascript
复制
flask --app=main:app run --reload

刷新 Jaeger 的 UI,选择main服务,点击”Find Traces”,可以看到之前的访问已经被成功追踪。

search trace
search trace

点击具体的 trace 可以看到详细的链路信息,包括请求的路径、响应时间等信息。

trace info
trace info

追踪业务逻辑

我们可以使用 opentelemetry 的 API 来追踪细致的业务逻辑。

代码语言:javascript
复制
@app.get("/")
def hello():
    tracer = trace.get_tracer(__name__)
    with tracer.start_as_current_span("step-1") as span:
        span.add_event("step-1-event", {"key": "value"})
        time.sleep(0.1)
    with tracer.start_as_current_span("step-2"):
        with tracer.start_as_current_span("step-2-1"):
            time.sleep(0.05)
        with tracer.start_as_current_span("step-2-2"):
            time.sleep(0.05)
    return "Hello, World!"

通过trace.get_tracer(__name__)获取到 tracer,然后使用 with start_as_current_span(span_name)创建一个 span,可以进行具体业务逻辑的追踪。

上述代码中,我们创建了两个 span,分别是step-1step-2(拥有两个子 span),并且在step-1中添加了一个 event。

重新访问 http://localhost:5000,刷新 Jaeger 的 UI,可以看到新的 trace 已经被成功追踪,并且可以追踪到每一个 span 的开始时间、结束时间、耗时等信息。

trace span
trace span

也可以切换视图,查看 Trace 的树状结构和火焰图,从不同的角度分析链路。

trace graph
trace graph
trace flamegraph
trace flamegraph

追踪外部服务

业务流程中,我们经常会调用外部服务,比如远程 API、数据库、缓存、消息队列等,我们可以使用 opentelemetry 的 API 来追踪这些外部服务的调用。

首先需要安装对应的 opentelemetry-instrumentation 库。

代码语言:javascript
复制
pip install redis pymongo requests opentelemetry-instrumentation-redis opentelemetry-instrumentation-pymongo opentelemetry-instrumentation-requests

修改main.py,增加响应配置。

代码语言:javascript
复制
from flask import Flask
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.instrumentation.pymongo import PymongoInstrumentor
from opentelemetry.instrumentation.redis import RedisInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor


def configure_trace(app: Flask):
    trace.set_tracer_provider(
        TracerProvider(resource=Resource.create({SERVICE_NAME: app.name}))
    )

    trace.get_tracer_provider().add_span_processor(
        BatchSpanProcessor(
            JaegerExporter(
                agent_host_name="localhost",
                agent_port=6831,
            )
        )
    )

    FlaskInstrumentor().instrument_app(app)
    RequestsInstrumentor().instrument()
    PymongoInstrumentor().instrument()
    RedisInstrumentor().instrument()

增加一个新的路由。

代码语言:javascript
复制
@app.get("/external-services")
def external_services():
    requests.get("https://httpbin.org/delay/1")
    MongoClient().test.test.find_one()
    Redis().incr("key")
    return "OK"

我们在external_services函数中调用了三个外部服务,分别是一次远程请求、一次数据库查询和一次缓存操作。

访问 http://localhost:5000/external-services ,刷新 Jaeger 的 UI,可以看到对应的 trace 已经被成功追踪。

trace externel services
trace externel services

trace 信息中提供了每一个外部服务调用详细信息,包括 http 请求的路径、响应状态码、数据库查询的语句、缓存操作的 key 等。

trace externel services flamegraph
trace externel services flamegraph

调整到火焰图视图,可以清楚地看到本次请求的绝大多数时间用在了对”https://httpbin.org/delay/1"的 http 请求中(毕竟服务器延迟了一秒才返回响应内容)。

找到了性能瓶颈,也就能针对性优化代码。

代码语言:javascript
复制
@app.get("/external-services")
def external_services():
    requests.head("https://www.baidu.com")
    MongoClient().test.test.find_one()
    Redis().incr("key")
    return "OK"

重新访问 http://localhost:5000/external-services ,可以看到请求的响应时间得到了极大的优化。

trace externel services optimization
trace externel services optimization

总结

通过集成 opentelemetry 与 jaeger,我们可以很方便地在 Flask 应用中追踪业务逻辑和外部服务的调用,从而更好地分析和优化业务流程。

在下一篇文章中,我们将介绍如何在复杂系统中使用 opentelemetry 进行跨服务追踪。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-142,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • OpenTelemetry 与 Jaeger
  • 在 Flask 中集成 OpenTelemetry 与 Jaeger
    • 部署 Jaeger
      • 基础配置
        • 追踪业务逻辑
          • 追踪外部服务
          • 总结
          相关产品与服务
          数据库
          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档