Opentelemetry Python version cross service invocation example
When calling opentelemetry across services, you need to import opentelemetry-instrumentation-requests, and then use request to cross service requests. (note that aiohttp-client should be used if it is asynchronous)
I use Jaeger on the server, which is deployed directly through the docker of all-in-one. The code is as follows:
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
After starting Jaeger, visit the following page: http://localhost:16686
Python needs to start two services to demonstrate cross service invocation. The framework I use is fastapi, so I need to install opentelemetry-instrumentation-fastapi
call service 1 by service 2
Service 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)
Service 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)
A function that depends on 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):
"""
Register the service to jaeger so that tracer-related information can be sent to the jaeger server
Args:
service_name: the registered service name
jaeger_host: jaeger address
jaeger_port:
Returns: TracerProvider
"""
provider = TracerProvider(
resource=Resource.create({SERVICE_NAME: service_name})
)
trace.set_tracer_provider(
provider
)
# create a JaegerExporter
jaeger_exporter = JaegerExporter(
agent_host_name=jaeger_host,
agent_port=jaeger_port,
)
# Create a BatchSpanProcessor and add the exporter to it
span_processor = BatchSpanProcessor(jaeger_exporter)
# add to the tracer
trace.get_tracer_provider().add_span_processor(span_processor)
Then execute:
curl -X 'POST' \
'http://127.0.0.1:8000/client' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"userinfo": "string",
"name": "string"
}'
You can get the following results:
if you have any questions, please correct them.