GoogleCloudPlatform / GoogleCloudPlatform/opentelemetry-operations-python

[HELP] Trace explorer contains a "Missing span ID xxx" entry

Open
#453 1 comment 1 reaction 0 assignees View on GitHub
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)`:

Image

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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.