From b153b7ac1843636bd52137509de2d6bbaae6fd2f Mon Sep 17 00:00:00 2001 From: Wu Clan Date: Tue, 30 Dec 2025 12:16:59 +0800 Subject: [PATCH] Add observability instrument for httpx request (#980) --- backend/utils/otel.py | 2 ++ .../backend/grafana/dashboards/fba_server.json | 6 +++--- pyproject.toml | 1 + requirements.txt | 7 +++++++ uv.lock | 18 ++++++++++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/backend/utils/otel.py b/backend/utils/otel.py index f1e821d4..88840fb1 100644 --- a/backend/utils/otel.py +++ b/backend/utils/otel.py @@ -4,6 +4,7 @@ from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor +from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor from opentelemetry.instrumentation.logging import LoggingInstrumentor from opentelemetry.instrumentation.redis import RedisInstrumentor from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor @@ -97,4 +98,5 @@ def init_otel(app: FastAPI) -> None: LoggingInstrumentor().instrument(set_logging_format=True) SQLAlchemyInstrumentor().instrument(engine=async_engine.sync_engine) RedisInstrumentor.instrument_client(redis_client) # type: ignore + HTTPXClientInstrumentor().instrument() FastAPIInstrumentor.instrument_app(app) diff --git a/deploy/backend/grafana/dashboards/fba_server.json b/deploy/backend/grafana/dashboards/fba_server.json index 02ef1f75..8bed4ead 100644 --- a/deploy/backend/grafana/dashboards/fba_server.json +++ b/deploy/backend/grafana/dashboards/fba_server.json @@ -1735,7 +1735,7 @@ "uid": "loki" }, "editorMode": "code", - "expr": "(rate({service_name=\"fba_server\"} |= \"$trace_id\" [1m]))", + "expr": "(rate({service_name=\"$app_name\"} |= \"$trace_id\" [1m]))", "legendFormat": "{{level}}", "refId": "A" } @@ -1779,7 +1779,7 @@ "uid": "loki" }, "editorMode": "code", - "expr": "{service_name=\"fba_server\"} | json | line_format \"{{.body}}\" |= \"$trace_id\"", + "expr": "{service_name=\"$app_name\"} | json | line_format \"{{.body}}\" |= \"$trace_id\"", "refId": "A" } ], @@ -1822,7 +1822,7 @@ "uid": "loki" }, "editorMode": "code", - "expr": "{service_name=\"fba_server\"} | json | level=~\"ERROR|CRITICAL\" | line_format \"{{.body}}\" |= \"$trace_id\"", + "expr": "{service_name=\"$app_name\"} | json | level=~\"ERROR|CRITICAL\" | line_format \"{{.body}}\" |= \"$trace_id\"", "refId": "A" } ], diff --git a/pyproject.toml b/pyproject.toml index b52ba5f9..a8b8ad6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ dependencies = [ "msgspec>=0.20.0", "opentelemetry-exporter-otlp-proto-grpc>=1.39.1", "opentelemetry-instrumentation-fastapi>=0.60b1", + "opentelemetry-instrumentation-httpx>=0.60b1", "opentelemetry-instrumentation-logging>=0.60b1", "opentelemetry-instrumentation-redis>=0.60b1", "opentelemetry-instrumentation-sqlalchemy>=0.60b1", diff --git a/requirements.txt b/requirements.txt index cd40e451..3bec099f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -167,6 +167,7 @@ opentelemetry-api==1.39.1 # opentelemetry-instrumentation # opentelemetry-instrumentation-asgi # opentelemetry-instrumentation-fastapi + # opentelemetry-instrumentation-httpx # opentelemetry-instrumentation-logging # opentelemetry-instrumentation-redis # opentelemetry-instrumentation-sqlalchemy @@ -180,6 +181,7 @@ opentelemetry-instrumentation==0.60b1 # via # opentelemetry-instrumentation-asgi # opentelemetry-instrumentation-fastapi + # opentelemetry-instrumentation-httpx # opentelemetry-instrumentation-logging # opentelemetry-instrumentation-redis # opentelemetry-instrumentation-sqlalchemy @@ -187,6 +189,8 @@ opentelemetry-instrumentation-asgi==0.60b1 # via opentelemetry-instrumentation-fastapi opentelemetry-instrumentation-fastapi==0.60b1 # via fastapi-best-architecture +opentelemetry-instrumentation-httpx==0.60b1 + # via fastapi-best-architecture opentelemetry-instrumentation-logging==0.60b1 # via fastapi-best-architecture opentelemetry-instrumentation-redis==0.60b1 @@ -206,6 +210,7 @@ opentelemetry-semantic-conventions==0.60b1 # opentelemetry-instrumentation # opentelemetry-instrumentation-asgi # opentelemetry-instrumentation-fastapi + # opentelemetry-instrumentation-httpx # opentelemetry-instrumentation-redis # opentelemetry-instrumentation-sqlalchemy # opentelemetry-sdk @@ -213,6 +218,7 @@ opentelemetry-util-http==0.60b1 # via # opentelemetry-instrumentation-asgi # opentelemetry-instrumentation-fastapi + # opentelemetry-instrumentation-httpx packaging==25.0 # via # kombu @@ -410,6 +416,7 @@ win32-setctime==1.2.0 ; sys_platform == 'win32' wrapt==1.17.3 # via # opentelemetry-instrumentation + # opentelemetry-instrumentation-httpx # opentelemetry-instrumentation-redis # opentelemetry-instrumentation-sqlalchemy wsproto==1.3.2 diff --git a/uv.lock b/uv.lock index 4536fbb5..adff42bb 100644 --- a/uv.lock +++ b/uv.lock @@ -708,6 +708,7 @@ dependencies = [ { name = "msgspec" }, { name = "opentelemetry-exporter-otlp-proto-grpc" }, { name = "opentelemetry-instrumentation-fastapi" }, + { name = "opentelemetry-instrumentation-httpx" }, { name = "opentelemetry-instrumentation-logging" }, { name = "opentelemetry-instrumentation-redis" }, { name = "opentelemetry-instrumentation-sqlalchemy" }, @@ -769,6 +770,7 @@ requires-dist = [ { name = "msgspec", specifier = ">=0.20.0" }, { name = "opentelemetry-exporter-otlp-proto-grpc", specifier = ">=1.39.1" }, { name = "opentelemetry-instrumentation-fastapi", specifier = ">=0.60b1" }, + { name = "opentelemetry-instrumentation-httpx", specifier = ">=0.60b1" }, { name = "opentelemetry-instrumentation-logging", specifier = ">=0.60b1" }, { name = "opentelemetry-instrumentation-redis", specifier = ">=0.60b1" }, { name = "opentelemetry-instrumentation-sqlalchemy", specifier = ">=0.60b1" }, @@ -1799,6 +1801,22 @@ wheels = [ { url = "https://mirrors.aliyun.com/pypi/packages/7d/cc/6e808328ba54662e50babdcab21138eae4250bc0fddf67d55526a615a2ca/opentelemetry_instrumentation_fastapi-0.60b1-py3-none-any.whl", hash = "sha256:af94b7a239ad1085fc3a820ecf069f67f579d7faf4c085aaa7bd9b64eafc8eaf" }, ] +[[package]] +name = "opentelemetry-instrumentation-httpx" +version = "0.60b1" +source = { registry = "https://mirrors.aliyun.com/pypi/simple" } +dependencies = [ + { name = "opentelemetry-api" }, + { name = "opentelemetry-instrumentation" }, + { name = "opentelemetry-semantic-conventions" }, + { name = "opentelemetry-util-http" }, + { name = "wrapt" }, +] +sdist = { url = "https://mirrors.aliyun.com/pypi/packages/86/08/11208bcfcab4fc2023252c3f322aa397fd9ad948355fea60f5fc98648603/opentelemetry_instrumentation_httpx-0.60b1.tar.gz", hash = "sha256:a506ebaf28c60112cbe70ad4f0338f8603f148938cb7b6794ce1051cd2b270ae" } +wheels = [ + { url = "https://mirrors.aliyun.com/pypi/packages/43/59/b98e84eebf745ffc75397eaad4763795bff8a30cbf2373a50ed4e70646c5/opentelemetry_instrumentation_httpx-0.60b1-py3-none-any.whl", hash = "sha256:f37636dd742ad2af83d896ba69601ed28da51fa4e25d1ab62fde89ce413e275b" }, +] + [[package]] name = "opentelemetry-instrumentation-logging" version = "0.60b1"