From 420fe5efe4cbd90a3819fe605062477e7a26071c Mon Sep 17 00:00:00 2001 From: tangou Date: Tue, 2 Sep 2025 16:29:29 +0800 Subject: [PATCH 1/4] fix(tracing): fix distributed tracing requirments attributes --- .../src/app.py | 26 ++++++++++++++++++- .../src/requirements.txt | 4 ++- .../src/run.sh | 7 ----- veadk/integrations/ve_faas/ve_faas.py | 2 ++ .../common_attributes_extractors.py | 5 ++++ veadk/tracing/telemetry/telemetry.py | 1 + 6 files changed, 36 insertions(+), 9 deletions(-) diff --git a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py index 8176c59f..8ff37cca 100644 --- a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +++ b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py @@ -36,6 +36,9 @@ from veadk.tracing.telemetry.opentelemetry_tracer import OpentelemetryTracer from veadk.types import AgentRunConfig from veadk.utils.logger import get_logger +from volcengine.base.Request import Request +from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator +from opentelemetry import context logger = get_logger(__name__) @@ -117,6 +120,8 @@ async def agent_card() -> dict: agent_card = await agent_card_builder.build() return agent_card.model_dump() +async def get_cozeloop_space_id() -> dict: + return {"space_id": os.getenv("OBSERVABILITY_OPENTELEMETRY_COZELOOP_SERVICE_NAME", default="")} load_tracer() @@ -132,7 +137,7 @@ async def agent_card() -> dict: a2a_app.post("/run_agent", operation_id="run_agent", tags=["mcp"])(run_agent_func) a2a_app.get("/agent_card", operation_id="agent_card", tags=["mcp"])(agent_card) - +a2a_app.get("/get_cozeloop_space_id", operation_id="get_cozeloop_space_id", tags=["mcp"])(get_cozeloop_space_id) # === Build mcp server === @@ -159,6 +164,25 @@ async def combined_lifespan(app: FastAPI): redoc_url=None ) +@app.middleware("http") +async def otel_context_middleware(request: Request, call_next): + carrier = { + "traceparent": request.headers.get("Traceparent"), + "tracestate": request.headers.get("Tracestate"), + } + print(carrier) + if carrier["traceparent"] is None: + return await call_next(request) + else: + ctx = TraceContextTextMapPropagator().extract(carrier=carrier) + print(ctx) + token = context.attach(ctx) + try: + response = await call_next(request) + finally: + context.detach(token) + return response + # Mount A2A routes to main app for route in a2a_app.routes: app.routes.append(route) diff --git a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt index d4b2885a..abf02522 100644 --- a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt +++ b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/requirements.txt @@ -1 +1,3 @@ -veadk-python \ No newline at end of file +veadk-python +fastapi +uvicorn[standard] \ No newline at end of file diff --git a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh index 3bfb5915..58bdcb96 100755 --- a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh +++ b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/run.sh @@ -33,13 +33,6 @@ while [[ $# -gt 0 ]]; do esac done -# in case of deployment deps not installed in user's requirements.txt -if pip list | grep -q "^fastapi \|^uvicorn "; then - echo "fastapi and uvicorn already installed" -else - python3 -m pip install uvicorn[standard] fastapi -fi - # Check if MODEL_AGENT_API_KEY is set if [ -z "$MODEL_AGENT_API_KEY" ]; then echo "MODEL_AGENT_API_KEY is not set. Please set it in your environment variables." diff --git a/veadk/integrations/ve_faas/ve_faas.py b/veadk/integrations/ve_faas/ve_faas.py index c94fe7fa..eb54a97b 100644 --- a/veadk/integrations/ve_faas/ve_faas.py +++ b/veadk/integrations/ve_faas/ve_faas.py @@ -152,6 +152,8 @@ def _create_application( "GatewayName": gateway_name, "ServiceName": service_name, "UpstreamName": upstream_name, + "EnableKeyAuth": True, + "EnableMcpSession": True, }, "TemplateId": self.template_id, }, diff --git a/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py b/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py index cb5b73f1..a38e218c 100644 --- a/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py +++ b/veadk/tracing/telemetry/attributes/extractors/common_attributes_extractors.py @@ -49,6 +49,10 @@ def common_cozeloop_report_source(**kwargs) -> str: return "veadk" +def common_cozeloop_call_type(**kwargs) -> str: + return kwargs.get("call_type") + + def llm_openinference_instrumentation_veadk(**kwargs) -> str: return VERSION @@ -68,4 +72,5 @@ def llm_openinference_instrumentation_veadk(**kwargs) -> str: "user.id": common_gen_ai_user_id, # CozeLoop / TLS required "session.id": common_gen_ai_session_id, # CozeLoop / TLS required "cozeloop.report.source": common_cozeloop_report_source, # CozeLoop required + "cozeloop.call_type": common_cozeloop_call_type, # CozeLoop required } diff --git a/veadk/tracing/telemetry/telemetry.py b/veadk/tracing/telemetry/telemetry.py index 4210061a..3ca170bf 100644 --- a/veadk/tracing/telemetry/telemetry.py +++ b/veadk/tracing/telemetry/telemetry.py @@ -227,6 +227,7 @@ def trace_call_llm( model_name=invocation_context.agent.model_name if isinstance(invocation_context.agent, Agent) else "", + call_type=span.context.trace_state.get("call_type") or "", ) llm_attributes_mapping = ATTRIBUTES.get("llm", {}) From f05002375ab2fa659943da07efacb898a847bba1 Mon Sep 17 00:00:00 2001 From: tangou Date: Wed, 3 Sep 2025 10:30:26 +0800 Subject: [PATCH 2/4] fix(tracing): fix distributed tracing requirments attributes remove unknown --- veadk/tracing/telemetry/telemetry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/veadk/tracing/telemetry/telemetry.py b/veadk/tracing/telemetry/telemetry.py index 3ca170bf..6e57d226 100644 --- a/veadk/tracing/telemetry/telemetry.py +++ b/veadk/tracing/telemetry/telemetry.py @@ -227,7 +227,7 @@ def trace_call_llm( model_name=invocation_context.agent.model_name if isinstance(invocation_context.agent, Agent) else "", - call_type=span.context.trace_state.get("call_type") or "", + call_type=span.context.trace_state.get("call_type") or "", ) llm_attributes_mapping = ATTRIBUTES.get("llm", {}) From b88b56166d0c16aedfbaf99f2b4bf7e775a073c6 Mon Sep 17 00:00:00 2001 From: tangou Date: Wed, 3 Sep 2025 10:35:34 +0800 Subject: [PATCH 3/4] fix(tracing): remove print --- .../ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py index 8ff37cca..617665ff 100644 --- a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +++ b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py @@ -170,12 +170,10 @@ async def otel_context_middleware(request: Request, call_next): "traceparent": request.headers.get("Traceparent"), "tracestate": request.headers.get("Tracestate"), } - print(carrier) if carrier["traceparent"] is None: return await call_next(request) else: ctx = TraceContextTextMapPropagator().extract(carrier=carrier) - print(ctx) token = context.attach(ctx) try: response = await call_next(request) From 46a6366ec6ee0fe678470a63f0393081ef08dc8c Mon Sep 17 00:00:00 2001 From: tangou Date: Wed, 3 Sep 2025 11:14:24 +0800 Subject: [PATCH 4/4] fix(tracing): set space_id, fix call_type --- .../template/{{cookiecutter.local_dir_name}}/src/app.py | 4 +++- veadk/tracing/telemetry/telemetry.py | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py index 617665ff..f077bcfe 100644 --- a/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py +++ b/veadk/integrations/ve_faas/template/{{cookiecutter.local_dir_name}}/src/app.py @@ -121,7 +121,7 @@ async def agent_card() -> dict: return agent_card.model_dump() async def get_cozeloop_space_id() -> dict: - return {"space_id": os.getenv("OBSERVABILITY_OPENTELEMETRY_COZELOOP_SERVICE_NAME", default="")} + return {"space_id": os.getenv("OBSERVABILITY_OPENTELEMETRY_COZELOOP_SERVICE_NAME", default="")} load_tracer() @@ -170,10 +170,12 @@ async def otel_context_middleware(request: Request, call_next): "traceparent": request.headers.get("Traceparent"), "tracestate": request.headers.get("Tracestate"), } + logger.debug(f"carrier: {carrier}") if carrier["traceparent"] is None: return await call_next(request) else: ctx = TraceContextTextMapPropagator().extract(carrier=carrier) + logger.debug(f"ctx: {ctx}") token = context.attach(ctx) try: response = await call_next(request) diff --git a/veadk/tracing/telemetry/telemetry.py b/veadk/tracing/telemetry/telemetry.py index 6e57d226..838532d0 100644 --- a/veadk/tracing/telemetry/telemetry.py +++ b/veadk/tracing/telemetry/telemetry.py @@ -227,7 +227,11 @@ def trace_call_llm( model_name=invocation_context.agent.model_name if isinstance(invocation_context.agent, Agent) else "", - call_type=span.context.trace_state.get("call_type") or "", + call_type=span.context.trace_state.get("call_type") + if hasattr(span, "context") + and hasattr(span.context, "trace_state") + and hasattr(span.context.trace_state, "get") + else "", ) llm_attributes_mapping = ATTRIBUTES.get("llm", {})