diff --git a/common/telemetry.py b/common/telemetry.py index 9904ef0..6353deb 100644 --- a/common/telemetry.py +++ b/common/telemetry.py @@ -3,6 +3,8 @@ from opentelemetry.sdk.resources import SERVICE_NAME, Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter +from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor +from opentelemetry.instrumentation.redis import RedisInstrumentor def setup_telemetry(service_name: str): @@ -11,3 +13,8 @@ def setup_telemetry(service_name: str): provider = TracerProvider(resource=resource) provider.add_span_processor(processor) trace.set_tracer_provider(provider) + + # Process-wide patches on the client classes, so they also cover clients + # created at import time (gateway's _proxy_client, common.redis_client). + HTTPXClientInstrumentor().instrument() + RedisInstrumentor().instrument() diff --git a/docker-compose.yml b/docker-compose.yml index c0ee3bb..ec6db90 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -86,6 +86,8 @@ services: environment: <<: *app-env SERVICE_NAME: gateway + env_file: + - .env.observability command: uvicorn services.gateway.app:app --host 0.0.0.0 --port 8000 --reload --no-access-log ports: - "8000:8000" @@ -128,6 +130,8 @@ services: environment: <<: *app-env SERVICE_NAME: fraud + env_file: + - .env.observability command: uvicorn services.fraud.app:app --host 0.0.0.0 --port 8002 --reload --no-access-log ports: - "8002:8002" diff --git a/services/fraud/app.py b/services/fraud/app.py index 2ff72ea..4281417 100644 --- a/services/fraud/app.py +++ b/services/fraud/app.py @@ -2,19 +2,28 @@ import httpx from fastapi import FastAPI, Request from fastapi.responses import JSONResponse from pydantic import BaseModel +from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor from common.http import downstream_client from common.logging_config import configure_logging from common.redis_client import redis_client from common.settings import settings +from common.telemetry import setup_telemetry from . import chaos from .scoring import score SERVICE_NAME = "fraud" logger = configure_logging(SERVICE_NAME) +setup_telemetry(service_name=SERVICE_NAME) app = FastAPI(title=SERVICE_NAME) +FastAPIInstrumentor.instrument_app( + app, + excluded_urls="/healthz", + exclude_spans=["receive", "send"], +) + class ScoreRequest(BaseModel): account_id: str diff --git a/services/gateway/app.py b/services/gateway/app.py index 5a6e3f1..c60bb2f 100644 --- a/services/gateway/app.py +++ b/services/gateway/app.py @@ -7,18 +7,27 @@ from fastapi import FastAPI, Request from fastapi.responses import FileResponse, JSONResponse from fastapi.staticfiles import StaticFiles from pydantic import BaseModel, field_validator +from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor from common.chaos_flags import ALL_FLAGS, get_flags, set_flag, set_profile from common.logging_config import configure_logging from common.settings import settings +from common.telemetry import setup_telemetry from . import orchestrator from .orchestrator import UpstreamFailure SERVICE_NAME = "gateway" logger = configure_logging(SERVICE_NAME) +setup_telemetry(service_name=SERVICE_NAME) app = FastAPI(title=SERVICE_NAME) +FastAPIInstrumentor.instrument_app( + app, + excluded_urls="/healthz", + exclude_spans=["receive", "send"], +) + STATIC_DIR = Path(__file__).parent / "static" app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")