GoogleCloudPlatform / GoogleCloudPlatform/opentelemetry-operations-python
[HELP] Trace explorer contains a "Missing span ID xxx" entry
- Dominant language
- Python
- Stars
- 83
- Forks
- 46
- Avg merge
- 11h 40m
- Merged PRs (30d)
- 2
Description
Hi there, I have been experiementing with adding OpenTelemetry to my CloudRun application. It is a FastAPI powered application:
```py
# main.py
...
app = FastAPI()
setup_opentelemetry(app)
setup_logging()
```
```py
# setup_opentelemetry.py
import os
from fastapi import FastAPI
from opentelemetry import metrics, trace
from opentelemetry.exporter.cloud_monitoring import (
CloudMonitoringMetricsExporter,
)
from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor
from opentelemetry.instrumentation.logging import LoggingInstrumentor
from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor
from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
from opentelemetry.propagate import set_global_textmap
from opentelemetry.propagators.cloud_trace_propagator import (
CloudTraceFormatPropagator,
)
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.sdk.resources import SERVICE_INSTANCE_ID, Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
BatchSpanProcessor,
)
import galactic_api.database
def setup_opentelemetry(app: FastAPI) -> None:
# https://google-cloud-opentelemetry.readthedocs.io/en/stable/index.html
# This will use the GooglecloudResourceDetector under the covers.
resource = Resource.create(
attributes={
# Use the PID as the service.instance.id to avoid
# duplicate timeseries from different Gunicorn worker processes.
SERVICE_INSTANCE_ID: f"worker-{os.getpid()}",
}
)
# Tracing
tracer_provider = TracerProvider(resource=resource)
tracer_provider.add_span_processor(
BatchSpanProcessor(CloudTraceSpanExporter())
)
trace.set_tracer_provider(tracer_provider)
# Metrics
metrics.set_meter_provider(
MeterProvider(
metric_readers=[
PeriodicExportingMetricReader(CloudMonitoringMetricsExporter())
],
resource=resource,
)
)
# Set the X-Cloud-Trace-Context header
set_global_textmap(CloudTraceFormatPropagator())
# Instrumentors
FastAPIInstrumentor.instrument_app(app, tracer_provider=tracer_provider)
RequestsInstrumentor().instrument(tracer_provider=tracer_provider)
HTTPXClientInstrumentor().instrument()
SQLAlchemyInstrumentor().instrument(
engine=galactic_api.database.engine,
)
OpenAIInstrumentor().instrument()
# Enable OpenTelemetry Logging Instrumentation
LoggingInstrumentor().instrument()
```
The exporter is running and I can see trace data in the Trace Explorer, the problem is for each request there is always `(Missing span ID xxx)`:
Also does this output seem correct here? Why is there a span `/concepts` and a sub span `OPTIONS /concepts`
Do I need to include `set_global_textmap(CloudTraceFormatPropagator())`? Does Cloud Run auto inject a `X-Cloud-Trace-Context` header to incoming requests?
---
Contributor guide
Assessment
This issue has not been assessed yet.