diff --git a/biothings_annotator/application/cli/target.py b/biothings_annotator/application/cli/target.py index a27a4bf..4a9c8b4 100644 --- a/biothings_annotator/application/cli/target.py +++ b/biothings_annotator/application/cli/target.py @@ -19,6 +19,7 @@ from biothings_annotator.application.views import build_routes from biothings_annotator.application.middleware import build_middleware from biothings_annotator.application.exceptions import build_exception_handers +from biothings_annotator.application.telemetry import instrument_application_telemetry logging.basicConfig() logger = logging.getLogger("sanic-application") @@ -94,4 +95,5 @@ class Sanic( logger.error("Unable to add exception handler %s", exception_handler) raise gen_exc + instrument_application_telemetry(application) return application diff --git a/biothings_annotator/application/configuration/default.json b/biothings_annotator/application/configuration/default.json index 2f16644..80d9eb9 100644 --- a/biothings_annotator/application/configuration/default.json +++ b/biothings_annotator/application/configuration/default.json @@ -7,6 +7,12 @@ "REQUEST_MAX_SIZE": 100000000, "CACHE_MAX_AGE": 604800 }, + "opentelemetry": { + "OPENTELEMETRY_ENABLED": false, + "OPENTELEMETRY_SERVICE_NAME": "biothings-annotator", + "OPENTELEMETRY_JAEGER_HOST": "http://localhost", + "OPENTELEMETRY_JAEGER_PORT": 6381 + }, "extension": { "openapi": { "OAS": true, diff --git a/biothings_annotator/application/telemetry/__init__.py b/biothings_annotator/application/telemetry/__init__.py new file mode 100644 index 0000000..a7a709d --- /dev/null +++ b/biothings_annotator/application/telemetry/__init__.py @@ -0,0 +1,40 @@ +""" +Integrates opentelemetry tracing with the biothings-annotator +web service +""" + +import opentelemetry +from opentelemetry.exporter.jaeger.thrift import JaegerExporter +from opentelemetry.sdk.resources import SERVICE_NAME, Resource +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.trace.export import BatchSpanProcessor +import sanic +from tracing import instrument_app + + +def instrument_application_telemetry(application_instance: sanic.Sanic): + """ + Method integrating the opentelemetry into the annotator + web service + """ + opentelemetry_configuration = application_instance.config.get("opentelemetry", {}) + opentelemetry_enabled = opentelemetry_configuration.get("OPENTELEMETRY_ENABLED", False) + + if opentelemetry_enabled: + opentelemetry_jaeger_host = opentelemetry_configuration["OPENTELEMETRY_JAEGER_HOST"] + opentelemetry_jaeger_port = opentelemetry_configuration["OPENTELEMETRY_JAEGER_PORT"] + opentelemetry_service_name = opentelemetry_configuration["OPENTELEMETRY_SERVICE_NAME"] + + jaeger_trace_exporter = JaegerExporter( + agent_host_name=opentelemetry_jaeger_host, + agent_port=opentelemetry_jaeger_port, + udp_split_oversized_batches=True, + ) + service_resource = Resource.create({SERVICE_NAME: opentelemetry_service_name}) + + trace_provider = TracerProvider(resource=service_resource) + batch_span_processor = BatchSpanProcessor(jaeger_trace_exporter) + trace_provider.add_span_processor(batch_span_processor) + opentelemetry.trace.set_tracer_provider(trace_provider) + tracer = opentelemetry.trace.get_tracer("biothings-annotator") + instrument_app(application_instance, tracer) diff --git a/pyproject.toml b/pyproject.toml index ddf3046..71da5a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,13 @@ tests = [ "sanic-testing >= 24.6.0", "pytest-randomly" ] - +telemetry = [ + "opentelemetry-api >= 1.28.2", + "opentelemetry-sdk >= 1.28.2", + "opentelemetry-exporter-otlp >= 1.28.2", + "opentelemetry.exporter.jaeger.thrift >= 1.21.0", + "opentelemetry-instrumentation >= 0.49b2" +] [project.urls] "Homepage" = "https://github.com/biothings/biothings_annotator"