Skip to content

Commit

Permalink
instrument API with open telemetry/uptrace
Browse files Browse the repository at this point in the history
  • Loading branch information
GabrielBarberini committed Jun 9, 2024
1 parent 9ac550b commit 32aca6b
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 47 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ RUN apt-get update && \

COPY ./lib /app/lib

CMD ["gunicorn", "-w 1", "--threads=2", "-k", "uvicorn.workers.UvicornWorker", "lib:app", "--log-level", "Debug", "-b", "0.0.0.0:3000", "--timeout", "120"]
CMD ["gunicorn", "-c", "lib/settings/gunicorn.py", "-w", "1", "--threads=2", "-k", "uvicorn.workers.UvicornWorker", "lib:app", "--log-level", "Debug", "-b", "0.0.0.0:3000", "--timeout", "30"]
2 changes: 1 addition & 1 deletion lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ def parse_error(error):
return f"{exc_type} exception: {exc_obj}"


from .api import app # noqa
from .api import app # noqa
2 changes: 1 addition & 1 deletion lib/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def custom_openapi():
return app.openapi_schema
openapi_schema = get_openapi(
title="RocketPy Infinity-API",
version="1.1.0 BETA",
version="1.2.0 BETA",
description=(
"<p style='font-size: 18px;'>RocketPy Infinity-API is a RESTful Open API for RocketPy, a rocket flight simulator.</p>"
"<br/>"
Expand Down
21 changes: 15 additions & 6 deletions lib/routes/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

from fastapi import APIRouter
from opentelemetry import trace

from lib.views.environment import (
EnvSummary,
Expand All @@ -24,6 +25,8 @@
},
)

tracer = trace.get_tracer(__name__)


@router.post("/")
async def create_env(env: Env) -> EnvCreated:
Expand All @@ -33,7 +36,8 @@ async def create_env(env: Env) -> EnvCreated:
## Args
``` models.Env JSON ```
"""
return await EnvController(env).create_env()
with tracer.start_as_current_span("create_env"):
return await EnvController(env).create_env()


@router.get("/{env_id}")
Expand All @@ -44,7 +48,8 @@ async def read_env(env_id: str) -> Env:
## Args
``` env_id: str ```
"""
return await EnvController.get_env_by_id(env_id)
with tracer.start_as_current_span("read_env"):
return await EnvController.get_env_by_id(env_id)


@router.put("/{env_id}")
Expand All @@ -58,7 +63,8 @@ async def update_env(env_id: str, env: Env) -> EnvUpdated:
env: models.Env JSON
```
"""
return await EnvController(env).update_env_by_id(env_id)
with tracer.start_as_current_span("update_env"):
return await EnvController(env).update_env_by_id(env_id)


@router.delete("/{env_id}")
Expand All @@ -69,7 +75,8 @@ async def delete_env(env_id: str) -> EnvDeleted:
## Args
``` env_id: Environment ID hash ```
"""
return await EnvController.delete_env_by_id(env_id)
with tracer.start_as_current_span("delete_env"):
return await EnvController.delete_env_by_id(env_id)


@router.get("/rocketpy/{env_id}")
Expand All @@ -80,7 +87,8 @@ async def read_rocketpy_env(env_id: str) -> EnvPickle:
## Args
``` env_id: str ```
"""
return await EnvController.get_rocketpy_env_as_jsonpickle(env_id)
with tracer.start_as_current_span("read_rocketpy_env"):
return await EnvController.get_rocketpy_env_as_jsonpickle(env_id)


@router.get("/{env_id}/simulate")
Expand All @@ -91,4 +99,5 @@ async def simulate_env(env_id: str) -> EnvSummary:
## Args
``` env_id: str ```
"""
return await EnvController.simulate_env(env_id)
with tracer.start_as_current_span("simulate_env"):
return await EnvController.simulate_env(env_id)
49 changes: 32 additions & 17 deletions lib/routes/flight.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

from fastapi import APIRouter
from opentelemetry import trace

from lib.views.flight import (
FlightSummary,
Expand All @@ -27,6 +28,8 @@
},
)

tracer = trace.get_tracer(__name__)


@router.post("/")
async def create_flight(
Expand All @@ -38,9 +41,10 @@ async def create_flight(
## Args
``` Flight object as JSON ```
"""
return await FlightController(
flight, rocket_option=rocket_option, motor_kind=motor_kind
).create_flight()
with tracer.start_as_current_span("create_flight"):
return await FlightController(
flight, rocket_option=rocket_option, motor_kind=motor_kind
).create_flight()


@router.get("/{flight_id}")
Expand All @@ -51,7 +55,8 @@ async def read_flight(flight_id: str) -> Flight:
## Args
``` flight_id: Flight ID hash ```
"""
return await FlightController.get_flight_by_id(flight_id)
with tracer.start_as_current_span("read_flight"):
return await FlightController.get_flight_by_id(flight_id)


@router.get("/rocketpy/{flight_id}")
Expand All @@ -62,7 +67,10 @@ async def read_rocketpy_flight(flight_id: str) -> FlightPickle:
## Args
``` flight_id: Flight ID hash. ```
"""
return await FlightController.get_rocketpy_flight_as_jsonpickle(flight_id)
with tracer.start_as_current_span("read_rocketpy_flight"):
return await FlightController.get_rocketpy_flight_as_jsonpickle(
flight_id
)


@router.put("/{flight_id}/env")
Expand All @@ -76,7 +84,10 @@ async def update_flight_env(flight_id: str, env: Env) -> FlightUpdated:
env: env object as JSON
```
"""
return await FlightController.update_env_by_flight_id(flight_id, env=env)
with tracer.start_as_current_span("update_flight_env"):
return await FlightController.update_env_by_flight_id(
flight_id, env=env
)


@router.put("/{flight_id}/rocket")
Expand All @@ -95,12 +106,13 @@ async def update_flight_rocket(
rocket: Rocket object as JSON
```
"""
return await FlightController.update_rocket_by_flight_id(
flight_id,
rocket=rocket,
rocket_option=rocket_option,
motor_kind=motor_kind,
)
with tracer.start_as_current_span("update_flight_rocket"):
return await FlightController.update_rocket_by_flight_id(
flight_id,
rocket=rocket,
rocket_option=rocket_option,
motor_kind=motor_kind,
)


@router.put("/{flight_id}")
Expand All @@ -119,9 +131,10 @@ async def update_flight(
flight: Flight object as JSON
```
"""
return await FlightController(
flight, rocket_option=rocket_option, motor_kind=motor_kind
).update_flight_by_id(flight_id)
with tracer.start_as_current_span("update_flight"):
return await FlightController(
flight, rocket_option=rocket_option, motor_kind=motor_kind
).update_flight_by_id(flight_id)


@router.delete("/{flight_id}")
Expand All @@ -132,7 +145,8 @@ async def delete_flight(flight_id: str) -> FlightDeleted:
## Args
``` flight_id: Flight ID hash ```
"""
return await FlightController.delete_flight_by_id(flight_id)
with tracer.start_as_current_span("delete_flight"):
return await FlightController.delete_flight_by_id(flight_id)


@router.get("/{flight_id}/simulate")
Expand All @@ -143,4 +157,5 @@ async def simulate_flight(flight_id: str) -> FlightSummary:
## Args
``` flight_id: Flight ID hash ```
"""
return await FlightController.simulate_flight(flight_id)
with tracer.start_as_current_span("simulate_flight"):
return await FlightController.simulate_flight(flight_id)
29 changes: 19 additions & 10 deletions lib/routes/motor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

from fastapi import APIRouter
from opentelemetry import trace

from lib.views.motor import (
MotorSummary,
Expand All @@ -24,6 +25,8 @@
},
)

tracer = trace.get_tracer(__name__)


@router.post("/")
async def create_motor(motor: Motor, motor_kind: MotorKinds) -> MotorCreated:
Expand All @@ -33,9 +36,10 @@ async def create_motor(motor: Motor, motor_kind: MotorKinds) -> MotorCreated:
## Args
``` Motor object as a JSON ```
"""
return await MotorController(
motor=motor, motor_kind=motor_kind
).create_motor()
with tracer.start_as_current_span("create_motor"):
return await MotorController(
motor=motor, motor_kind=motor_kind
).create_motor()


@router.get("/{motor_id}")
Expand All @@ -46,7 +50,8 @@ async def read_motor(motor_id: str) -> Motor:
## Args
``` motor_id: Motor ID hash ```
"""
return await MotorController.get_motor_by_id(motor_id)
with tracer.start_as_current_span("read_motor"):
return await MotorController.get_motor_by_id(motor_id)


@router.put("/{motor_id}")
Expand All @@ -62,9 +67,10 @@ async def update_motor(
motor: Motor object as JSON
```
"""
return await MotorController(
motor=motor, motor_kind=motor_kind
).update_motor_by_id(motor_id)
with tracer.start_as_current_span("update_motor"):
return await MotorController(
motor=motor, motor_kind=motor_kind
).update_motor_by_id(motor_id)


@router.delete("/{motor_id}")
Expand All @@ -75,7 +81,8 @@ async def delete_motor(motor_id: str) -> MotorDeleted:
## Args
``` motor_id: Motor ID hash ```
"""
return await MotorController.delete_motor_by_id(motor_id)
with tracer.start_as_current_span("delete_motor"):
return await MotorController.delete_motor_by_id(motor_id)


@router.get("/rocketpy/{motor_id}")
Expand All @@ -86,7 +93,8 @@ async def read_rocketpy_motor(motor_id: str) -> MotorPickle:
## Args
``` motor_id: Motor ID hash ```
"""
return await MotorController.get_rocketpy_motor_as_jsonpickle(motor_id)
with tracer.start_as_current_span("read_rocketpy_motor"):
return await MotorController.get_rocketpy_motor_as_jsonpickle(motor_id)


@router.get("/{motor_id}/simulate")
Expand All @@ -97,4 +105,5 @@ async def simulate_motor(motor_id: str) -> MotorSummary:
## Args
``` motor_id: Motor ID hash ```
"""
return await MotorController.simulate_motor(motor_id)
with tracer.start_as_current_span("simulate_motor"):
return await MotorController.simulate_motor(motor_id)
31 changes: 21 additions & 10 deletions lib/routes/rocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""

from fastapi import APIRouter
from opentelemetry import trace

from lib.views.rocket import (
RocketSummary,
Expand All @@ -25,6 +26,8 @@
},
)

tracer = trace.get_tracer(__name__)


@router.post("/")
async def create_rocket(
Expand All @@ -36,9 +39,10 @@ async def create_rocket(
## Args
``` Rocket object as a JSON ```
"""
return await RocketController(
rocket=rocket, rocket_option=rocket_option, motor_kind=motor_kind
).create_rocket()
with tracer.start_as_current_span("create_rocket"):
return await RocketController(
rocket=rocket, rocket_option=rocket_option, motor_kind=motor_kind
).create_rocket()


@router.get("/{rocket_id}")
Expand All @@ -49,7 +53,8 @@ async def read_rocket(rocket_id: str) -> Rocket:
## Args
``` rocket_id: Rocket ID hash ```
"""
return await RocketController.get_rocket_by_id(rocket_id)
with tracer.start_as_current_span("read_rocket"):
return await RocketController.get_rocket_by_id(rocket_id)


@router.put("/{rocket_id}")
Expand All @@ -68,9 +73,10 @@ async def update_rocket(
rocket: Rocket object as JSON
```
"""
return await RocketController(
rocket=rocket, rocket_option=rocket_option, motor_kind=motor_kind
).update_rocket_by_id(rocket_id)
with tracer.start_as_current_span("update_rocket"):
return await RocketController(
rocket=rocket, rocket_option=rocket_option, motor_kind=motor_kind
).update_rocket_by_id(rocket_id)


@router.delete("/{rocket_id}")
Expand All @@ -81,7 +87,8 @@ async def delete_rocket(rocket_id: str) -> RocketDeleted:
## Args
``` rocket_id: Rocket ID hash ```
"""
return await RocketController.delete_rocket_by_id(rocket_id)
with tracer.start_as_current_span("delete_rocket"):
return await RocketController.delete_rocket_by_id(rocket_id)


@router.get("/rocketpy/{rocket_id}")
Expand All @@ -92,7 +99,10 @@ async def read_rocketpy_rocket(rocket_id: str) -> RocketPickle:
## Args
``` rocket_id: Rocket ID hash ```
"""
return await RocketController.get_rocketpy_rocket_as_jsonpickle(rocket_id)
with tracer.start_as_current_span("read_rocketpy_rocket"):
return await RocketController.get_rocketpy_rocket_as_jsonpickle(
rocket_id
)


@router.get("/{rocket_id}/simulate")
Expand All @@ -103,4 +113,5 @@ async def simulate_rocket(rocket_id: str) -> RocketSummary:
## Args
``` rocket_id: Rocket ID hash ```
"""
return await RocketController.simulate_rocket(rocket_id)
with tracer.start_as_current_span("simulate_rocket"):
return await RocketController.simulate_rocket(rocket_id)
17 changes: 17 additions & 0 deletions lib/settings/gunicorn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import uptrace
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from lib.secrets import Secrets


def post_fork(server, worker): # pylint: disable=unused-argument
uptrace.configure_opentelemetry(
dsn=Secrets.get_secret("UPTRACE_DSN"),
service_name="infinity-api",
service_version="1.2.0",
deployment_environment="production",
)
from app.lib import ( # pylint: disable=import-outside-toplevel
server as fastapi_server,
)

FastAPIInstrumentor.instrument_app(fastapi_server)
Loading

0 comments on commit 32aca6b

Please sign in to comment.