Skip to content

fix: enable OTel Cloud Logging and Cloud Trace export#112

Open
mohammadp1001 wants to merge 9 commits into
mainfrom
fix/111-otel-cloud-logging-dependency
Open

fix: enable OTel Cloud Logging and Cloud Trace export#112
mohammadp1001 wants to merge 9 commits into
mainfrom
fix/111-otel-cloud-logging-dependency

Conversation

@mohammadp1001

@mohammadp1001 mohammadp1001 commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary

alphoryn/telemetry/otel.py:setup_otel() is called unconditionally at every CLI startup and is meant to wire up both Cloud Logging and Cloud Trace export by default. Three stacked bugs kept it from actually working end-to-end:

  1. Cloud Logging crashed on every startup with No module named 'opentelemetry.exporter.cloud_logging'. PR fix: add OTel GCP exporter packages to enable Cloud Trace export #110 added opentelemetry-exporter-gcp-trace and opentelemetry-exporter-gcp-monitoring to pyproject.toml but missed opentelemetry-exporter-gcp-logging, the package that actually provides that module.
  2. Trace spans were never created. setup_otel() only passed enable_cloud_logging=True to get_gcp_exporters()enable_cloud_tracing defaults to False, so the span exporter/processor was never constructed at all.
  3. Span export 400'd once created. telemetry.googleapis.com rejects any span batch whose OTel Resource lacks a gcp.project_id attribute. ADK's resource detector only reads it from the standard OTEL_RESOURCE_ATTRIBUTES env var, so setup_otel() now resolves the project ID via google.auth.default() and sets that env var before providers are built. This also required adding opentelemetry-exporter-otlp-proto-http as a dependency (the actual span exporter ADK uses), pinned to match google-adk's opentelemetry-api/opentelemetry-sdk version constraints.

Verification

Ran a real alphoryn run session end-to-end (run-8/session-0001, tickers SPY/QQQ) against the alphoryn GCP project:

  • setup_otel() completes with no warning (previously crashed every time)
  • ✅ Custom structured telemetry events (SESSION_STARTTOOL_CALLSIGNAL_SNAPSHOT_BUILTAGENT_DECISIONSESSION_END) confirmed landing in Cloud Logging under logName="projects/alphoryn/logs/alphoryn"
  • ✅ OTel-instrumented GenAI content logs (gen_ai.system.message, gen_ai.user.message, gen_ai.choice) confirmed landing in Cloud Logging, timestamps matching the run exactly
  • ✅ Cloud Trace spans confirmed via trace_v1.ListTraces() — a 22-span trace for the run appeared (invocationinvoke_agent alphoryn_main_agentcall_llmgenerate_content gemini-2.5-proexecute_tool ...), matching the run's actual tool-call sequence

Also discovered and documented (not fixed here, out of scope): python -m alphoryn.cli.main run ... silently no-ops on this dev machine (exit 0, no output, no DB record) — the python -c "from alphoryn.cli.main import app; ...; app()" invocation style is confirmed working and is what was used for verification above.

Test plan

  • pip install "opentelemetry-exporter-gcp-logging>=1.12.0a0" "opentelemetry-exporter-otlp-proto-http>=1.36.0" then setup_otel() completes without warning
  • Ran alphoryn run for one session; confirmed SESSION_START...SESSION_END event chain in Cloud Logging
  • Confirmed OTel GenAI logs (gen_ai.*) present in Cloud Logging with matching timestamps
  • Confirmed real spans present in Cloud Trace via trace_v1.ListTraces() for the same run

Closes #111

setup_otel() calls get_gcp_exporters(enable_cloud_logging=True)
unconditionally at every CLI startup, but pyproject.toml only had the
trace and monitoring GCP exporters (added in #110) — not the logging
one, so every startup crashed with "No module named
'opentelemetry.exporter.cloud_logging'" and traces were silently never
exported.

Verified end-to-end against a real alphoryn run: setup_otel() now
completes cleanly, and OTel GenAI content logs (gen_ai.system.message,
gen_ai.user.message, gen_ai.choice) land in Cloud Logging with
timestamps matching the run. Cloud Trace spans did not appear after
polling for ~2 minutes post-run; documented as a likely separate,
unrelated gap in TELEMETRY_ACCESS.md rather than blocking this fix,
since the crash this closes is specifically in the logging exporter
path.

Closes #111
Three stacked gaps kept spans from ever reaching Cloud Trace:
- enable_cloud_tracing was never passed to get_gcp_exporters(), so no
  span exporter was constructed
- the OTLP span exporter needs opentelemetry-exporter-otlp-proto-http,
  which wasn't a declared dependency
- telemetry.googleapis.com rejects span batches whose OTel Resource is
  missing gcp.project_id; ADK's default resource detector only reads
  it from OTEL_RESOURCE_ATTRIBUTES, so it's now set from
  google.auth.default() before providers are created

Verified end-to-end: a real alphoryn run (run-8/session-0001) now
produces a 22-span trace visible via trace_v1.ListTraces.
Cloud Trace span export is now verified working end-to-end (see
otel.py fix), so the doc's "unconfirmed"/follow-up language is
replaced with the actual verification results.
@mohammadp1001 mohammadp1001 changed the title fix: add missing opentelemetry-exporter-gcp-logging dependency fix: enable OTel Cloud Logging and Cloud Trace export Jul 10, 2026
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.

OTel Cloud Logging export fails silently: missing opentelemetry-exporter-gcp-logging dependency

1 participant