opentelemetry python版本跨服务调用示例
opentelemetry跨服务调用的时候,需要引用opentelemetry-instrumentation-requests,然后在用request跨服务请求。(注意,如果是异步要用aiohttp-client) 服务端我是用的jaeger,直接通过all-in-one的docker部署的,代码如下:
docker run -d --name jaeger \
-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 9411:9411 \
jaegertracing/all-in-one:1.32
启动好jaeger之后,访问页面为:http://localhost:16686
python需要启动两个服务来展示跨服务调用。我用的框架是fastapi,所以需要安装opentelemetry-instrumentation-fastapi 由服务2调用服务1 服务1:
import fastapi
from opentelemetry import trace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from fastapi import Body
from pybase.lib.tracer.jaeger_ import register_to_jaeger
from pydantic import BaseModel
app = fastapi.FastAPI()
class UserInfo(BaseModel):
name: str
tracer = trace.get_tracer(__name__)
@app.post("/server")
async def server(userinfo: str = Body(...), name: str = Body(..., )):
return {"message": f"hello {userinfo},{name}"}
FastAPIInstrumentor.instrument_app(app)
if __name__ == '__main__':
register_to_jaeger("fastapi-jaeger-server", "localhost")
import uvicorn
uvicorn.run(app,port=8001)
服务2
import fastapi
import requests
from opentelemetry import trace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from fastapi import Body
from opentelemetry.instrumentation.requests import RequestsInstrumentor
RequestsInstrumentor().instrument()
from pybase.lib.tracer.jaeger_ import register_to_jaeger
from pydantic import BaseModel
app = fastapi.FastAPI()
class UserInfo(BaseModel):
name: str
tracer = trace.get_tracer(__name__)
@app.post("/foobar")
async def foobar(userinfo: str = Body(...), name: str = Body(..., )):
with tracer.start_as_current_span("foo"):
with tracer.start_as_current_span("bar"):
with tracer.start_as_current_span("baz"):
print("Hello world from OpenTelemetry Python!")
return {"message": f"hello {userinfo},{name}"}
@app.post("/foobar2")
async def foobar2(userinfo: str = Body(...), name: str = Body(..., )):
return {"message": f"hello {userinfo},{name}"}
@app.post("/client")
def client(userinfo: str = Body(...), name: str = Body(..., )):
res=requests.post("http://127.0.0.1:8001/server",json={
"userinfo":userinfo,"name":name
})
return res.json()
FastAPIInstrumentor.instrument_app(app)
if __name__ == '__main__':
register_to_jaeger("fastapi-jaeger", "localhost")
import uvicorn
uvicorn.run(app)
依赖到的一个函数register_to_jaeger:
from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
def register_to_jaeger(service_name: str, jaeger_host: str, jaeger_port: int = 6831):
"""
注册服务到jaeger,这样就可以发送tracer相关信息到jaeger服务器
Args:
service_name: 注册的服务明
jaeger_host: jaeger地址
jaeger_port:
Returns: TracerProvider
"""
provider = TracerProvider(
resource=Resource.create({SERVICE_NAME: service_name})
)
trace.set_tracer_provider(
provider
)
jaeger_exporter = JaegerExporter(
agent_host_name=jaeger_host,
agent_port=jaeger_port,
)
span_processor = BatchSpanProcessor(jaeger_exporter)
trace.get_tracer_provider().add_span_processor(span_processor)
然后执行:
curl -X 'POST' \
'http://127.0.0.1:8000/client' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"userinfo": "string",
"name": "string"
}'
就可以得到如下效果: 如有问题,欢迎指正。
|