Hi Guys, I think you stumble upon the article after a very long search of
How to integrate AWS Xray with application written with FASTAPI python?
So you are not alone I have searched for a very long time and this is what I found which works for me, there are something which I don't understand it's just there😅.
First, let's take a quick look at what AWS X-Ray is. AWS X-Ray is a distributed tracing system that allows you to visualize the entire lifecycle of a request across all of your microservices. With X-Ray, you can quickly identify performance bottlenecks, troubleshoot errors, and understand the dependencies between your services.
If You wanna read more about aws xray here the link
Let's Start.
First you need to know where you are going to deploy the application EC2, EBS, or EKS. I have deployed it on EKS so I'll use that over here, but all of them will work with little bit of changes.
Installation of ADOT Collector
For those who are wondering what's this? AWS Distro for OpenTelemetry, and for those who were thinking that they can get away without installing it you were wrong as I am🥲, I thought it too but can't so here the link you can follow to install it for EKS.
After you have decided and installed the collector with your prefer way of installing (I prefer Daemonset) remember the service name we have to mention it in application.
Integration
There are some python packages that you need to install
opentelemetry-distro==0.36b0
opentelemetry-exporter-otlp==1.15.0
opentelemetry-exporter-otlp-proto-grpc==1.15.0
opentelemetry-exporter-otlp-proto-http==1.15.0
opentelemetry-instrumentation==0.36b0
opentelemetry-instrumentation-asgi==0.36b0
opentelemetry-instrumentation-aws-lambda==0.36b0
opentelemetry-instrumentation-boto3sqs==0.36b0
opentelemetry-instrumentation-botocore==0.36b0
opentelemetry-instrumentation-dbapi==0.36b0
opentelemetry-instrumentation-fastapi==0.36b0
opentelemetry-instrumentation-grpc==0.36b0
opentelemetry-instrumentation-logging==0.36b0
opentelemetry-instrumentation-pymongo==0.36b0
opentelemetry-instrumentation-requests==0.36b0
opentelemetry-instrumentation-sqlalchemy==0.36b0
opentelemetry-instrumentation-sqlite3==0.36b0
opentelemetry-instrumentation-starlette==0.36b0
opentelemetry-instrumentation-urllib==0.36b0
opentelemetry-instrumentation-urllib3==0.36b0
opentelemetry-instrumentation-wsgi==0.36b0
opentelemetry-propagator-aws-xray==1.0.1
opentelemetry-proto==1.15.0
opentelemetry-sdk==1.15.0
opentelemetry-sdk-extension-aws==2.0.1
opentelemetry-semantic-conventions==0.36b0
opentelemetry-util-http==0.36b0
I know it's never ending list trust me, but without these my application wasn't even starting so I don't know about these but it works I hope it works for you too.
Main Code
# OpenTelemetry Configuration
# Basic packages for your application
# Add imports for OTel components into the application
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
# Import the AWS X-Ray for OTel Python IDs Generator into the application.
from opentelemetry.sdk.extension.aws.trace import AwsXRayIdGenerator
# Sends generated traces in the OTLP format to an ADOT Collector running on port 4317
otlp_exporter = OTLPSpanExporter(endpoint="http://xray-collector-collector.amazon-cloudwatch:4317")
# Processes traces in batches as opposed to immediately one after the other
span_processor = BatchSpanProcessor(otlp_exporter)
# Configures the Global Tracer Provider
trace.set_tracer_provider(TracerProvider(active_span_processor=span_processor, id_generator=AwsXRayIdGenerator()))
# Using the AWS resource Detectors
import opentelemetry.trace as trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.extension.aws.resource.ec2 import (
AwsEc2ResourceDetector,
)
from opentelemetry.sdk.resources import get_aggregated_resources
trace.set_tracer_provider(
TracerProvider(
resource=get_aggregated_resources(
[
AwsEc2ResourceDetector(),
]
),
)
)
app = FastAPI()
@app.get("/test")
def test():
return {"message": "Hello This is testing"}
You might be thinking why I copy pasted the whole code, it's coz when I was searching I couldn't make any sense of the code so I thought why not just pour it all.
Make sure you set your own endpoint url in the otlp_exporter
otherwise it won't send any traces.
Dockerfile
# Pull base image
FROM python:3.8
# Set enviroment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PYTHONPATH=/code
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
# Added OpenTelemetry Collector attributes
ENV OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST=".*"
ENV OTEL_RESOURCE_ATTRIBUTES='service.name=aws-xray-test'
# Set work directory
WORKDIR /code
# Install dependencies
COPY requirements.txt /code/
RUN pip install -r requirements.txt --no-cache-dir
# Copy project
COPY . /code/
ENTRYPOINT ["opentelemetry-instrument","/opt/venv/bin/python", "-m", "uvicorn", "main:app"]
CMD ["--reload", "--host", "0.0.0.0", "--port", "8000"]
NOTE: see the Entrypoint and the ENV make sure you set them
And My Wonderful reader if you made it till here than I hope your Integration is successful
Conclusion
In conclusion, integrating AWS X-Ray with your FastAPI application is a simple and effective way to gain visibility into the performance and behavior of your application. With X-Ray, you can quickly identify performance bottlenecks, troubleshoot errors, and understand the dependencies between your services. So why not give it a try today?
Plus If you face any issue with above steps plz reach out to me
here's my linkedin
Top comments (0)