• Product Introduction
  • Quick Start
    • Agent Development
    • Importing a Git Repository
    • Starting From a Template
    • Direct Upload
    • Start with AI
  • Framework Guide
    • Agent
    • Frontends
      • Vite
      • React
      • Vue
      • Hugo
      • Other Frameworks
    • Backends
    • Full-stack
      • Next.js
      • Nuxt
      • Astro
      • React Router
      • SvelteKit
      • TanStack Start
      • Vike
    • Custom 404 Page
  • Project Guide
    • Project Management
    • edgeone.json
    • Configuring Cache
    • Building Output Configuration
    • Error Codes
  • Build Guide
  • Deployment Guide
    • Overview
    • Create Deploys
    • Manage Deploys
    • Deploy Button
    • Using Github Actions
    • Using Gitlab CI/CD
    • Using CNB Plugin
    • Using IDE PlugIn
    • Using CodeBuddy IDE
  • Domain Management
    • Overview
    • Custom Domain
    • HTTPS Configuration
      • Overview
      • Apply for Free Certificate
      • Using Managed SSL Certificate
    • Configure DNS CNAME Record
  • Observability
    • Overview
    • Metric Analysis
    • Log Analysis
  • Functions
    • Overview
    • Edge Functions
    • Cloud Functions
      • Overview
      • Node.js
      • Python
      • Go
  • Agents
    • Overview
    • Quick Start
    • Conversation Storage
    • Observability
    • Sandbox Tool
      • Overview
      • Using the Agent Framework
      • Sandbox Atomic API
      • Network Search Tool
    • Agent Authentication
  • Models
    • Overview
    • Models and Vendors
      • Overview
      • Using Vendor Keys
        • OpenAI
        • Anthropic
        • Google AI Studio
        • DeepSeek
        • MiniMax
        • Hunyuan
        • Zhipu
        • MoonShot AI
    • FAQs
  • Storage
    • Overview
    • KV
    • Blob
  • Middleware
  • AI Tools
    • MCP
    • Skills
    • Plugin
  • Copilot
    • Overview
    • Quick Start
  • API Token
  • EdgeOne CLI
  • Message Notification
  • Integration Guide
    • AI
      • Dialogue Large Models Integration
      • Large Models for Images Integration
    • Database
      • Supabase Integration
      • Pages KV Integration
    • Ecommerce
      • Shopify Integration
      • WooCommerce Integration
    • Payment
      • Stripe Integration
      • Integrating Paddle
    • CMS
      • WordPress Integration
      • Contentful Integration
      • Sanity Integration
      • Payload Integration
    • Authentication
      • Supabase Integration
      • Clerk Integration
  • Best Practices
    • AI Dialogue Deployment: Deploy Project with One Sentence Using Skill
    • Using General Large Model to Quickly Build AI Application
    • Use the DeepSeek model to quickly build a conversational AI site
    • Building an Ecommerce Platform with Shopify
    • Building a SaaS Site Using Supabase and Stripe
    • Building a Company Brand Site Quickly
    • How to Quickly Build a Blog Site
  • Migration Guides
    • Migrating from Vercel to EdgeOne Pages
    • Migrating from Cloudflare Pages to EdgeOne Pages
    • Migrating from Netlify to EdgeOne Pages
  • Troubleshooting
  • FAQs
  • Limits
  • Pricing
  • Contact Us
  • Release Notes

Observability

The platform automatically collects full-link traces of calls from the Agent framework, model invocations, and tools by default with zero code intrusion. For business-defined metrics, manually report them using context.tracer.

Agent Framework Auto-Collection Support Matrix

The underlying mechanism is based on OpenInference instrumentation and is injected before user code loads. Calls from mainstream LLM SDKs and Agent frameworks automatically generate spans. These spans share the same traceId and are naturally nested with manual spans from context.tracer.
Framework
Python
Node
Claude Agent SDK
OpenAI Agents SDK
DeepAgents
LangGraph
CrewAI
-

Collection Scope

Category
Content
Model Invocation
Model name, input/output, token usage, and so on
Agent Framework Link
Agent decision-making, node transition, sub-agent delegation
Tool Invocation
Tool name, parameters, return value, time consumption

Observability Data

The platform provides two panels: the Console and Local Debugging. Both panels share the same trace data contract, meaning their UI layout, field definitions, and filtering dimensions are identical. The only difference lies in the data source: the local panel only accesses data from the current dev process, while the console aggregates data from all online requests.

Observability Dashboard in the Console

Go to the console, select your Agent project, and switch to the Agent tab. Then, view the data on the Metrics and Traces subpages.
Metrics Data
You can view core metrics aggregated by time window, including number of Agent invocations, number of model invocations, model invocation error rate, average model invocation latency, total Token consumption, and average tokens/model invocation.

Traces Data
Each task execution corresponds to a trace tree, which can be used to precisely reconstruct a request:
Link Structure: Starting from the root request span, spans automatically generated by the Agent framework are attached, making the hierarchical nesting relationships immediately clear.
LLM Invocation Details: When you expand each LLM span, you can view the prompt, completion, model name, token usage, and latency.
Tool Invocation Details: You can expand a Tool span to view its input parameters, return value, and latency, which helps troubleshoot whether the tool was invoked correctly.
Error Stack: For spans marked as ERROR, the exception name and message are displayed directly, eliminating the need to search through logs.
Filtering and Search: You can filter by run_id / conversation_id to locate the trace of a specific session or execution.


Local Debugging Panel

edgeone makes dev automatically launches the local debugging panel (default: http://localhost:8088/agent-metrics) upon startup, with zero configuration required:
Data Source: It only collects traces generated by the current dev process, does not mix them with online data, and ensures clean debugging isolation.
Feature Parity: The Metrics / Traces subpages are fully consistent with the console, including link structure, LLM details, and attribute filtering.
Near-Zero Latency: Traces become visible as soon as they are written. You can modify a piece of code, run a request, and immediately view the trace differences in the panel.

Manual Instrumentation for context.tracer

The OpenInference instrumentor can cover mainstream LLM SDKs and frameworks, but it cannot collect data in some scenarios (such as unsupported frameworks, custom business logic, and internal service calls). For these scenarios, you can manually supplement reporting using context.tracer.

API Overview

API
Purpose
tracer.span(name, fn, attrs?)
Creates a child span and executes fn, automatically managing its lifecycle and exceptions.
tracer.startSpan(name, attrs?)
Creates a span and requires manually calling end().
tracer.setAttributes(attrs)
Batch sets attributes for the currently active span.
Node / Python Naming Conventions: JavaScript uses camelCase (startSpan / setAttributes), while Python uses snake_case (start_span / set_attributes). All other aspects are consistent. Each API in the following sections includes both Node and Python examples.

span(name, fn, attrs?)

Create a span and execute fn within it. When fn throws an exception, the exception is automatically recorded. Any span generated (automatically or manually) inside fn becomes its child node.
Parameter
Parameter
Type
Required
Description
name
string
Yes
span name
fn
(span: Span) => Promise<T>
Yes
A function executed within the span context. The parameter span is used to append attributes within the block.
attrs
Record<string, string | number | boolean>
No
Initial attributes when the span is created.
Return Value
Pass through the return value of fn.
TS Example:
const intent = await context.tracer.span('classify_intent', async (span) => {
const res = await openai.chat.completions.create({ /* ... */ });
const label = res.choices[0].message.content.trim();
span.setAttributes({ 'intent.label': label });
return label;
}, { 'agent.step': 'intent' });
Python example:
async def classify(span):
res = await openai_client.chat.completions.create(...)
label = res.choices[0].message.content.strip()
span.set_attributes({"intent.label": label})
return label

intent = await ctx.tracer.span("classify_intent", classify, {"agent.step": "intent"})

startSpan(name, attrs?)

When you create a span, you must explicitly call span.end(). Other spans generated during this period are not automatically nested under it. To nest them, use span(). This approach is suitable for scenarios that cross asynchronous boundaries (for example, putting a task into a queue or ending it within a callback).
Parameter
Parameter
Type
Required
Description
name
string
Yes
span name
attrs
Record<string, string | number | boolean>
No
Initial attributes when the span is created.
Return Value
Span — A span object is returned synchronously. The caller must call span.end() in a paired manner; otherwise, the span will not be reported and will remain resident in memory.
TS Example:
const span = context.tracer.startSpan('async_pipeline', { 'pipeline.stage': 'init' });
try {
await doStep1();
await doStep2();
} finally {
span.end(); // This call is mandatory.
}
Python example:
span = ctx.tracer.start_span("async_pipeline", {"pipeline.stage": "init"})
try:
await do_step_1()
await do_step_2()
finally:
span.end()

setAttributes(attrs)

Batch set attributes for the currently active span. This can be used to add business tags to spans automatically created by the platform.
Parameter
Parameter
Type
Required
Description
attrs
Record<string, string | number | boolean>
Yes
The attribute key-value pairs to be set. Complex objects must be serialized into JSON by the caller.
TS Example:
context.tracer.setAttributes({
'user.id': context.request.body.userId,
'user.tier': 'premium',
'agent.scenario': 'customer_service',
});
// ... business logic
Python example:
context.tracer.set_attributes({
"user.id": ctx.request.body.get("userId"),
"user.tier": "premium",
"agent.scenario": "customer_service",
})
To add attributes within the span() fn or on the span returned by startSpan(), directly call span.setAttributes(...).

Use Constraints

Do not import the OpenTelemetry SDK, as it will disrupt the platform's automatic reporting and duplicate instrumentation.
The span created by startSpan must be paired with end(); otherwise, it will not be reported and will remain resident in memory.
Attribute values only support string / number / boolean. Objects / arrays must be serialized into JSON strings.
Do not use high-cardinality dynamic values for span names (such as userId and order number). Place dynamic values in attributes instead.

General Properties

The following attributes are shared by automatic + manual spans, serving as the core dimensions for filtering and aggregation in the console panel.
Required
Meaning
agent.run_id
The unique ID for a handler execution, linking all spans within this execution.
agent.conversation_id
Session ID for cross-run aggregation
agent.route_path
The route for the current request
llm.* / gen_ai.* / openinference.*
OpenInference standard LLM attributes (model, token usage, and so on)
ai-agent
You can ask me like
What types of applications can I deploy?