agentscope-ai / agentscope-ai/agentscope
[Bug]:trace_enabled context loss in async frameworks with uvicorn
- 主要言語
- Python
- スター
- 31.5k
- フォーク
- 3.5k
- 平均マージ
- 1日 23時間
- マージ済み PR(30日)
- 95
説明
**Describe the bug**
When using AgentScope with tracing_url configured in async frameworks like FastAPI, the trace_enabled flag stored in ContextVar may lose its value, causing the tracing
functionality to fail silently.
The issue occurs because uvicorn creates a new Context for each request, causing ContextVar values to reset to their default values. This means that even after
agentscope.init() successfully sets trace_enabled = True, the value becomes False when processing HTTP requests, resulting in tracing being disabled.
**To Reproduce**
Steps to reproduce the behavior:
1. Initialize AgentScope with tracing configured:
```python
import agentscope
agentscope.init(
project='test-project',
studio_url='http://localhost:3000',
tracing_url='http://localhost:3000/v1/traces'
)
```
2. Create a traced function:
```python
from agentscope.tracing import trace
@trace(name='test_function')
async def test_function():
print('Traced function executed')
return 'success'
```
3. Execute in FastAPI or similar async framework using `asyncio.create_task()`:
```python
import asyncio
from fastapi import FastAPI
app = FastAPI()
@app.get('/test')
async def test_endpoint():
# In FastAPI, the request handler may run in a new task
# where ContextVar context is lost
task = asyncio.create_task(test_function())
result = await task
return {'result': result}
```
4. Check AgentScope Studio or tracing backend
- Expected: Trace data should be recorded
- Actual: No trace data is recorded
**Expected behavior**
When `tracing_url` is configured during `agentscope.init()`, the tracing functionality should work consistently across all async tasks and concurrency patterns, regardless of whether the `ContextVar` context is properly inherited or not.
**Error messages**
No explicit error messages are thrown. The issue manifests silently as missing trace data in the tracing backend (AgentScope Studio or external OpenTelemetry backend).
**Environment (please complete the following information):**
- AgentScope Version: 1.0.14 (via `import agentscope; print(agentscope.__version__)`)
- Python Version: 3.11.13
- OS: macOS (Darwin 25.1.0)
- Framework: FastAPI with uvicorn
- Uvicorn Configuration: uvicorn.run("server:app", host="0.0.0.0", port=8080) (default settings, single worker)
**Additional context**
Root cause: uvicorn creates new Context for each request
Through detailed investigation, I discovered that the issue is specifically caused by uvicorn's behavior:
1. Module-level initialization sets trace_enabled = True
2. uvicorn starts and reimports the module, setting trace_enabled = True
3. lifespan runs successfully with trace_enabled = True
4. uvicorn receives a request and creates a new Context
5. ContextVar value is reset to default value False in the new Context
6. Request processing runs with trace_enabled = False
**Suggested solution:**
Add a global flag to track whether tracing has been configured, and modify `_check_tracing_enabled()` to check this flag first:
```python
# In agentscope/tracing/_trace.py
def _check_tracing_enabled() -> bool:
"""Check if tracing is enabled"""
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
# Check if a real TracerProvider is set (not the default proxy)
tracer_provider = trace.get_tracer_provider()
if isinstance(tracer_provider, TracerProvider):
# A real TracerProvider exists, which means tracing was configured
return True
# Fall back to ContextVar for runtime control
return _config.trace_enabled
```
This ensures that once tracing is configured via `init()`, it remains enabled regardless of ContextVar context propagation issues, while still allowing runtime control when tracing is not configured.
コントリビューションガイド
評価
この issue はまだ評価されていません。