如何用OpenTelemetry自动检测实现Flask API的MongoDB遥测监控?
轻量实现Flask API的MongoDB查询监控(基于OpenTelemetry)
核心方案
用OpenTelemetry的自动检测(Auto Instrumentation),几乎无需改动业务代码,仅需添加几行初始化代码即可实现监控,性能开销可控(默认采样率低,自动检测的额外开销通常在个位数百分比)。
步骤1:安装依赖
安装OTEL核心包、Flask和MongoDB的自动检测插件,以及链路追踪导出器(以Jaeger为例):
pip install opentelemetry-api opentelemetry-sdk opentelemetry-instrumentation-flask opentelemetry-instrumentation-pymongo opentelemetry-exporter-jaeger-thrift
步骤2:代码实现(极小改动)
在Flask API的入口文件添加OTEL初始化逻辑,业务代码完全保留原有写法:
from flask import Flask, jsonify from pymongo import MongoClient from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.instrumentation.flask import FlaskInstrumentor from opentelemetry.instrumentation.pymongo import PymongoInstrumentor from opentelemetry.exporter.jaeger.thrift import JaegerExporter # 初始化OTEL追踪器 trace.set_tracer_provider(TracerProvider()) tracer = trace.get_tracer(__name__) # 配置Jaeger导出器(可替换为OTLP等其他导出器对接监控平台) jaeger_exporter = JaegerExporter( agent_host_name="localhost", agent_port=6831, ) trace.get_tracer_provider().add_span_processor( BatchSpanProcessor(jaeger_exporter) ) # 启动Flask和MongoDB的自动检测 app = Flask(__name__) FlaskInstrumentor().instrument_app(app) PymongoInstrumentor().instrument() # 原有MongoDB连接逻辑,无需修改 client = MongoClient("mongodb+srv://<你的Atlas连接字符串>") db = client["test_db"] collection = db["test_col"] # 原有API端点,无需修改 @app.route("/api/get-data", methods=["GET"]) def get_data(): data = list(collection.find({"category": "test"})) return jsonify({"count": len(data), "data": data}) @app.route("/api/heavy-query", methods=["GET"]) def heavy_query(): data = list(collection.find({})) return jsonify({"count": len(data), "data": data}) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)
步骤3:启动监控后端
用Docker快速启动Jaeger本地实例:
docker run -d --name jaeger \ -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ -p 5775:5775/udp \ -p 6831:6831/udp \ -p 16686:16686 \ jaegertracing/all-in-one:latest
步骤4:定位问题
启动API后访问各个端点,打开http://localhost:16686进入Jaeger UI:
- 每个API请求对应一个顶层Span,标注了端点路径(如
/api/heavy-query) - 每个MongoDB操作(find、insert等)会作为子Span关联到对应的请求Span
- 通过查看Span的调用次数、耗时,可直接定位哪个端点触发了过量的MongoDB查询
性能优化建议
- 调整采样率:生产环境可设置概率采样降低开销,比如仅采样10%的请求:
from opentelemetry.sdk.trace.sampling import TraceIdRatioBased trace.set_tracer_provider(TracerProvider(sampler=TraceIdRatioBased(0.1))) - 保留BatchSpanProcessor:批量导出Span,减少网络请求频次(示例已配置)
- 仅启用必要检测:只加载Flask和MongoDB的检测插件,避免不必要的开销
内容的提问来源于stack exchange,提问作者Lance
相关产品推荐
相关产品推荐

