Skip to content

feat: API-Server - Added OTel trace id auto-instrumentation for FastAPI#82

Open
morgan-wowk wants to merge 1 commit intomasterfrom
otel-api-tracing
Open

feat: API-Server - Added OTel trace id auto-instrumentation for FastAPI#82
morgan-wowk wants to merge 1 commit intomasterfrom
otel-api-tracing

Conversation

@morgan-wowk
Copy link
Collaborator

@morgan-wowk morgan-wowk commented Feb 3, 2026

Changes:

  • Add OpenTelemetry tracing support to the API server
  • Create new otel_tracing.py module for configuring distributed tracing
  • Configure tracing in both main API server and local development server
  • Add environment variable support for OTEL_EXPORTER_OTLP_ENDPOINT to control trace export

**Changes:**

* Install OTel packages for FastAPI
* Use OTel FastAPI auto-instrumetation for trace ids on responses
@Ark-kun Ark-kun changed the title feat: Add OTel trace id auto-instrumentation for FastAPI feat: API-Server - Added OTel trace id auto-instrumentation for FastAPI Feb 6, 2026
Copy link
Contributor

@Ark-kun Ark-kun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for implementing this.

)

except Exception as e:
logger.error(f"Failed to configure OpenTelemetry tracing: {e}", exc_info=True)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can just use logger.exception. It sets exc_info=True automatically.

from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

logger = logging.getLogger(__name__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_logger (to make it private)

from fastapi import FastAPI
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
OTLPSpanExporter as GRPCSpanExporter,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious - Why are we renaming this import?

from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
OTLPSpanExporter as GRPCSpanExporter,
)
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: Let's import modules, not particular classes/functions. https://google.github.io/styleguide/pyguide.html#22-imports
Usage then becomes: module1.Class1 or module1.function1.
Ambiguous module names can be renamed.

import fastapi
#? from opentelemetry.exporter.otlp.proto.grpc import trace_exporter
from opentelemetry import trace as otel_trace
from opentelemetry.sdk import resources as otel_sdk_resources
from opentelemetry.sdk import trace as otel_sdk_trace
from opentelemetry.sdk.trace import export as otel_sdk_trace_export

TBH, I dislike the module naming conventions of opentelemetry SDK. Ambiguity like .trace vs .sdk.trace. I also kind of dislike the module names that look like verbs: trace, export and single nouns like status. These names clash with function names and local variables.

So if the result looks too ugly to you, feel free to skip.

resource = Resource(attributes={SERVICE_NAME: service_name})

# Create the OTLP exporter
otlp_exporter = GRPCSpanExporter(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is GRPCSpanExporter the only exporter that would work good for Tangle API telemetry?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can actually support multiple. Like HTTP. Good point.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change this to be configurable and support multiple exporters


try:
# Build service name with environment suffix
app_env = os.environ.get("APP_ENV", "development")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't environement usually ENV?

)

# Configure OpenTelemetry tracing
otel_tracing.setup_api_tracing(app)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for making it non-invasive.


# Instrument the FastAPI application
# This automatically creates spans for all incoming HTTP requests
FastAPIInstrumentor.instrument_app(app)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What kind of data will this capture and export?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants