diff --git a/backend/app/main.py b/backend/app/main.py index 540a9b7..9fef1a3 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -1,3 +1,5 @@ +import logging +import os from fastapi.responses import RedirectResponse from starlette.middleware.cors import CORSMiddleware from starlette.middleware.sessions import SessionMiddleware @@ -46,3 +48,46 @@ def health_check(): def redirect_root_to_docs(): """Redirect the route / to /docs""" return RedirectResponse(url="/docs") + + +def configure_otel(app): + # open telemetry https://github.com/ranking-agent/aragorn/blob/main/src/otel_config.py#L4 + # https://ncatstranslator.github.io/TranslatorTechnicalDocumentation/deployment-guide/monitoring/ + # https://github.com/TranslatorSRI/Jaeger-demo + if not os.environ.get('NO_JAEGER'): + logging.info("starting up jaeger telemetry") + import warnings + from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor + from opentelemetry import trace + from opentelemetry.exporter.jaeger.thrift import JaegerExporter + from opentelemetry.sdk.resources import SERVICE_NAME as telemetery_service_name_key, Resource + from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.trace.export import BatchSpanProcessor + from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor + + service_name = os.environ.get('OTEL_SERVICE_NAME', 'OPENPREDICT') + # httpx connections need to be open a little longer by the otel decorators + # but some libs display warnings of resource being unclosed. + # these supresses such warnings. + logging.captureWarnings(capture=True) + warnings.filterwarnings("ignore",category=ResourceWarning) + trace.set_tracer_provider( + TracerProvider( + resource=Resource.create({telemetery_service_name_key: service_name}) + ) + ) + jaeger_host = os.environ.get('JAEGER_HOST', 'jaeger-otel-agent.sri') + jaeger_port = int(os.environ.get('JAEGER_PORT', '6831')) + jaeger_exporter = JaegerExporter( + agent_host_name=jaeger_host, + agent_port=jaeger_port, + ) + trace.get_tracer_provider().add_span_processor( + BatchSpanProcessor(jaeger_exporter) + ) + # tracer = trace.get_tracer(__name__) + FastAPIInstrumentor.instrument_app(app, tracer_provider=trace, excluded_urls="docs,openapi.json") + HTTPXClientInstrumentor().instrument() + +# Configure open telemetry if enabled +configure_otel(app) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index f66e6e5..761c353 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -40,6 +40,11 @@ dependencies = [ # "kgx >=1.6.0", "rdflib >=6.1.1", "SPARQLWrapper >=1.8.5", + + "opentelemetry-sdk", + "opentelemetry-exporter-otlp-proto-http", + "opentelemetry-instrumentation-fastapi", + "opentelemetry-instrumentation-httpx", ] [project.optional-dependencies] @@ -121,12 +126,13 @@ itrb-test = "pytest tests/production --server https://collaboratory-api.test.tra itrb-prod = "pytest tests/production --server https://collaboratory-api.transltr.io {args}" +# OTHER TOOLS +[tool.hatch.build.targets.wheel] +packages = ["app"] + [tool.hatch.metadata] allow-direct-references = true - -# OTHER TOOLS - [tool.coverage.run] source = ["app"] branch = true diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 9b35d31..3592978 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -13,6 +13,7 @@ services: - FRONTEND_URL=http://localhost:19006 - INSTALL_DEV=true - DEV_MODE=true + - NO_JAEGER=true build: context: ./backend dockerfile: Dockerfile diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 4d0116b..48f18e7 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -11,6 +11,7 @@ services: VIRTUAL_PORT: 80 VIRTUAL_HOST: api.collaboratory.semanticscience.org LETSENCRYPT_HOST: api.collaboratory.semanticscience.org + NO_JAEGER: "true" volumes: - /data/knowledge-collaboratory/ner-models:/data/ner-models - /data/knowledge-collaboratory/nanopub-keystore:/data/nanopub-keystore diff --git a/docker-compose.yml b/docker-compose.yml index 17c35ad..79170d4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,8 @@ services: INSTALL_DEV: ${INSTALL_DEV-false} env_file: - .env + environment: + - NO_JAEGER=true volumes: - /data/knowledge-collaboratory/ner-models:/data/ner-models - /data/knowledge-collaboratory/nanopub-keystore:/data/nanopub-keystore