本文目录导读:

我将详细介绍在Python中使用Jaeger进行链路追踪的方法。
安装依赖
首先安装必要的包:
pip install opentelemetry-api opentelemetry-sdk opentelemetry-instrumentation pip install opentelemetry-exporter-jaeger # 或者使用OTLP exporter pip install opentelemetry-exporter-otlp
基础使用示例
1 手动创建Span
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
# 配置Jaeger exporter
jaeger_exporter = JaegerExporter(
agent_host_name="localhost",
agent_port=6831,
)
# 配置trace provider
resource = Resource.create({"service.name": "my-python-service"})
provider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(jaeger_exporter)
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer(__name__)
def business_function():
with tracer.start_as_current_span("business_operation") as span:
span.set_attribute("operation.type", "database_query")
span.add_event("query_started", {"query": "SELECT * FROM users"})
# 模拟业务逻辑
result = do_database_query()
span.add_event("query_completed")
return result
def do_database_query():
with tracer.start_as_current_span("database_query") as span:
# 模拟数据库操作
import time
time.sleep(0.1)
span.set_attribute("db.system", "postgresql")
span.set_attribute("db.statement", "SELECT * FROM users")
return {"status": "success"}
# 使用示例
if __name__ == "__main__":
result = business_function()
print(f"Result: {result}")
2 使用装饰器自动创建Span
from opentelemetry import trace
from functools import wraps
tracer = trace.get_tracer(__name__)
def trace_function(function_name=None):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
name = function_name or func.__name__
with tracer.start_as_current_span(name) as span:
# 添加函数参数作为属性(注意:不要记录敏感信息)
span.set_attribute("args.count", len(args))
span.set_attribute("kwargs.count", len(kwargs))
result = func(*args, **kwargs)
# 记录结果信息
span.set_attribute("result.type", type(result).__name__)
return result
return wrapper
return decorator
@trace_function("user_service_operation")
def process_user(user_id):
# 处理用户逻辑
with tracer.start_as_current_span("get_user_data") as span:
span.set_attribute("user.id", user_id)
# 模拟数据库查询
return {"user_id": user_id, "name": "John Doe"}
# 使用
result = process_user(12345)
完整的Web应用示例(Flask)
from flask import Flask, request, jsonify
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter
import requests
app = Flask(__name__)
# 配置Jaeger
jaeger_exporter = JaegerExporter(
agent_host_name="localhost",
agent_port=6831,
)
provider = TracerProvider()
processor = BatchSpanProcessor(jaeger_exporter)
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
# 自动instrument Flask
FlaskInstrumentor().instrument_app(app)
tracer = trace.get_tracer(__name__)
@app.route('/api/users/<user_id>')
def get_user(user_id):
with tracer.start_as_current_span("get_user_http") as span:
span.set_attribute("http.method", request.method)
span.set_attribute("http.url", request.url)
# 模拟查询用户
user_data = query_user_from_db(user_id)
# 模拟调用外部API
external_data = call_external_api()
return jsonify({
"user": user_data,
"external_data": external_data
})
def query_user_from_db(user_id):
with tracer.start_as_current_span("database_query") as span:
span.set_attribute("db.system", "mysql")
span.set_attribute("db.operation", "SELECT")
span.set_attribute("db.table", "users")
# 模拟数据库查询
import time
time.sleep(0.05)
return {
"id": user_id,
"name": "Test User",
"email": "test@example.com"
}
def call_external_api():
with tracer.start_as_current_span("external_api_call") as span:
try:
response = requests.get("https://api.example.com/data", timeout=5)
span.set_attribute("http.status_code", response.status_code)
return response.json()
except Exception as e:
span.set_attribute("error", str(e))
span.set_status(trace.Status(trace.StatusCode.ERROR))
return {"error": str(e)}
if __name__ == '__main__':
app.run(debug=True, port=5000)
高级配置
1 自定义采样器
from opentelemetry.sdk.trace.sampling import Sampler, Decision
from opentelemetry.sdk.trace import SamplingResult
class CustomSampler(Sampler):
def should_sample(self, parent_context, trace_id, name, kind, attributes, links, trace_state):
# 只采样0.5的请求
import random
if random.random() < 0.5:
return SamplingResult(Decision.RECORD_AND_SAMPLE)
return SamplingResult(Decision.DROP)
# 使用自定义采样器
provider = TracerProvider(sampler=CustomSampler())
2 上下文传播
from opentelemetry import trace, context
from opentelemetry.propagators.textmap import TextMapPropagator
# 创建trace上下文
tracer = trace.get_tracer(__name__)
# 示例:在HTTP请求中传播上下文
def make_http_request_with_tracing(url, headers=None):
if headers is None:
headers = {}
with tracer.start_as_current_span("http_request") as span:
# 注入trace上下文到headers
propagator = TextMapPropagator()
propagator.inject(headers)
# 发送HTTP请求
response = requests.get(url, headers=headers)
span.set_attribute("http.status_code", response.status_code)
return response
运行Jaeger
使用Docker运行Jaeger:
docker run -d --name jaeger \ -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \ -e COLLECTOR_OTLP_ENABLED=true \ -p 6831:6831/udp \ -p 6832:6832/udp \ -p 5778:5778 \ -p 16686:16686 \ -p 4317:4317 \ -p 4318:4318 \ -p 14250:14250 \ -p 14268:14268 \ -p 14269:14269 \ -p 9411:9411 \ jaegertracing/all-in-one:latest
常见问题解决
1 配置检查
# 检查追踪是否正常启用
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
current_span = trace.get_current_span()
print(f"Current Span: {current_span}")
# 检查tracer provider
provider = trace.get_tracer_provider()
print(f"Provider: {provider}")
2 错误处理
from opentelemetry import trace
def safe_trace_function():
with tracer.start_as_current_span("risky_operation") as span:
try:
# 可能出错的代码
result = 1 / 0
except Exception as e:
span.set_status(trace.Status(trace.StatusCode.ERROR, str(e)))
span.record_exception(e)
# 重新抛出异常或处理
raise
finally:
span.end()
最佳实践
- 合理的span粒度:每个span代表一个有意义的操作单元
- 添加有意义的属性:记录关键的业务信息
- 处理异常情况:使用
span.record_exception()记录异常 - 控制采样率:避免生产环境过高的开销
- 保护敏感数据:不要在span属性中记录密码、token等敏感信息
通过以上示例,你应该能够在Python项目中成功集成和使用Jaeger进行链路追踪了。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播