feat(langchain): multi-agent travel planner with Gunicorn + Azure App Service deployment#347
Open
adityamehra wants to merge 2 commits into
Open
feat(langchain): multi-agent travel planner with Gunicorn + Azure App Service deployment#347adityamehra wants to merge 2 commits into
adityamehra wants to merge 2 commits into
Conversation
… + Azure deployment Adds a new example demonstrating a five-agent LangGraph travel planner (coordinator → flight → hotel → activity → synthesizer) served by Gunicorn + UvicornWorker with full OpenTelemetry observability. Key design decisions: - Programmatic OTel initialization via initialize() at module import time, running post-fork in each Gunicorn worker to ensure PeriodicExportingMetricReader starts in the correct process (fixes silent metric drop on Linux with --preload). - sys.modules sentinel + TracerProvider type check allow both the CLI wrapper (opentelemetry-instrument) and programmatic approaches to coexist without double-initialization. - Agent names carry a _gc suffix to distinguish the Gunicorn deployment from other runtimes in Splunk APM Agent view. - Azure App Service deployment via startup.sh + Oryx build (SCM_DO_BUILD_DURING_DEPLOYMENT=true). - Splunk OTel Collector in Azure Container Instance (pinned to 0.123.0) with otlphttp/splunk exporter replacing the deprecated sapm exporter. - resourcedetection processor uses override: false so app-supplied deployment.environment is never overwritten by the collector. Verified: traces (gen_ai.agent.invoke, gen_ai.client.chat) and metrics (gen_ai.client.token.usage, gen_ai.client.operation.duration) are visible in Splunk Observability Cloud from both local Gunicorn and Azure App Service. Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
Author
Screenshots
trace and metrichttps://app.us1.signalfx.com/#/apm/traces/2da2e67dcccd7a996b199945f4fa46af |
…corn example Co-authored-by: Cursor <cursoragent@cursor.com>
keith-decker
approved these changes
Jun 12, 2026
keith-decker
left a comment
Contributor
There was a problem hiding this comment.
SPLUNK_ACCESS_TOKEN and SPLUNK_HEC_TOKEN are passed as normal ACI env vars; they should use secure env vars.
But that shouldn't block the demo.
I'm approving, but we might want to consider pinning the langchain and langgraph dependencies. We can either catch when the demo breaks on updates without that, or keep the demo working through updates.
shuningc
reviewed
Jun 12, 2026
|
|
||
| final_state: Optional[PlannerState] = None | ||
| try: | ||
| for step in compiled.stream(initial_state, config): |
Contributor
There was a problem hiding this comment.
This is a synchronous blocking iterator, not async.
Probably compiled.astream() (async version) is better
shuningc
reviewed
Jun 12, 2026
| _, node_state = next(iter(step.items())) | ||
| final_state = node_state | ||
| except Exception as exc: | ||
| raise HTTPException(status_code=500, detail=str(exc)) from exc |
Contributor
There was a problem hiding this comment.
The details might contain endpoints or secrets which are exposed here
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
examples/multi_agent_travel_planner/gunicorn/— a five-agent LangGraph travel itinerary pipeline (coordinator → flight → hotel → activity → synthesizer) served by Gunicorn + UvicornWorker with full OpenTelemetry observability.Files added
app.py_gcsuffix agent namesstartup.sh--preload)requirements.txtsplunk-otel-instrumentation-langchain==0.1.14from PyPI.env.exampleREADME.mdcollector/otel-collector-config.yamlcollector/deploy-aci.shcollector/README.mdKey design decisions
Fork-safe OTel initialization (
app.py)The standard
opentelemetry-instrument gunicornpattern fails silently for metrics on Linux when--preloadis used: thePeriodicExportingMetricReaderbackground thread is created in the master process and does not survivefork(). This example uses programmatic initialization (initialize()called at module import time) so each Gunicorn worker initializes the full OTel SDK — including a fresh metric reader thread — after the fork:The
sys.modulessentinel prevents double-init on reimport; theTracerProvidertype check lets the CLI wrapper (opentelemetry-instrument) and programmatic approaches coexist.For more details please refer the OTel troubleshooting guide
Collector:
sapm→otlphttp/splunksplunk-otel-collector:latest(≥ v0.147.0 / collector v1.12.0) removed thesapmexporter. The config usesotlphttp/splunkfor traces instead and the collector image is pinned to0.123.0for stability.resourcedetectionprocessor:override: falseEnsures
deployment.environmentset by the app viaOTEL_RESOURCE_ATTRIBUTESis never overwritten by the collector's resource detection.Telemetry emitted
gen_ai.agent.invoke(one per LangGraph node) +gen_ai.client.chat(one per LLM call)gen_ai.client.token.usage,gen_ai.client.operation.durationgen_ai.agent.name,deployment.environment,service.name,gen_ai.request.modelTest plan
flight_summary,hotel_summary,activities_summary,final_itineraryservice.namegen_ai.client.token.usagemetric appears in Splunk APM Agent view per agentMade with Cursor