Every trace in ABV has a unique, permanent URL that points directly to the trace in the dashboard. Trace URLs provide instant access to the complete interaction timeline, including:
Full prompt and response content
Token usage and cost breakdowns
Latency metrics (first token, total duration)
Tool calls and function executions
Error messages and stack traces
Session context and user metadata
Understand Trace URL Structure
Trace URLs follow a consistent format:
https://app.abv.dev/traces/<trace-id>
app.abv.dev: ABV Dashboard (US region)
eu.app.abv.dev: EU region alternative
<trace-id>: Unique identifier for the trace (32-character hex string)
Private by default: Only team members with access to the project can view
Shareable: Can be made public for external sharing (clients, community)
Get Trace URLs Programmatically
Retrieve trace URLs directly in your code for logging, debugging, or automated workflows.Python (decorator pattern):
from abvdev import ABV, observeabv = ABV(api_key="sk-abv-...", host="https://app.abv.dev")@observe()def process_data(): # Get the URL of the current trace trace_url = abv.get_trace_url() print(f"View trace at: {trace_url}") # Or construct URL from trace ID trace_id = abv.get_current_trace_id() trace_url = abv.get_trace_url(trace_id=trace_id) return trace_urlurl = process_data()# Output: "View trace at: https://app.abv.dev/traces/a1b2c3d4..."
Python (context managers):
with abv.start_as_current_span(name="process-request") as span: # Get trace URL trace_url = abv.get_trace_url() print(f"View trace at: {trace_url}") # Add to logs logger.info(f"Processing request. Trace: {trace_url}")
JavaScript/TypeScript:
import './instrumentation'; // Must be first importimport { ABVClient } from '@abvdev/client';import { startObservation } from '@abvdev/tracing';const abv = new ABVClient();async function main() { const rootSpan = startObservation('my-trace', { input: { query: 'What is the capital of France?' } }); // Get trace URL const traceUrl = await abv.getTraceUrl(rootSpan.traceId); console.log('Trace URL:', traceUrl); rootSpan.update({ output: { content: 'The capital of France is Paris.' } }); rootSpan.end();}main();
Add Trace URLs to Logs and Monitoring
Include trace URLs in your application logs to create instant links from logs to ABV traces.Python (logging integration):
import loggingfrom abvdev import ABV, observelogging.basicConfig(level=logging.INFO)logger = logging.getLogger(__name__)abv = ABV(api_key="sk-abv-...")@observe()def process_user_request(user_id, query): trace_url = abv.get_trace_url() # Add trace URL to logs logger.info( f"Processing request for user={user_id}. " f"ABV Trace: {trace_url}" ) # Your code here result = perform_llm_call(query) if result.error: logger.error( f"LLM call failed for user={user_id}. " f"ABV Trace: {trace_url}" ) return resultprocess_user_request(user_id="user-123", query="Summarize this document")
Benefits:
Click trace URLs in logs to jump directly to ABV dashboard
Correlate application logs with LLM traces instantly
No manual searching for traces by timestamp or metadata
Share Traces with Teammates (Private)
By default, trace URLs are privateβonly team members with access to your ABV project can view them.Sharing workflow:
Get the trace URL (via SDK or dashboard)
Share the URL via Slack, email, GitHub issue, Jira ticket, etc.
Teammates click the URL and see the full trace (if they have project access)
Example: Share in Slack
import requests# Get trace URLtrace_url = abv.get_trace_url()# Post to Slackslack_webhook_url = "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"requests.post(slack_webhook_url, json={ "text": f"π¨ LLM error in production! Debug here: {trace_url}"})
Users must be logged into ABV and have project permissions
URLs work across sessions and devices (permanent links)
Make Traces Public (Optional)
For external sharing (clients, community, public demos), make traces public. Public traces are accessible to anyone with the URLβno ABV login required.Make public via UI:
Open the trace in the ABV Dashboard
Toggle βPrivateβ to βPublicβ
Share the same trace URL publicly
Make public via SDK (Python):
from abvdev import ABV, observeabv = ABV(api_key="sk-abv-...")@observe()def process_data(): # Make the current trace public abv.update_current_trace(public=True) # Get the public URL trace_url = abv.get_trace_url() print(f"Share this public trace: {trace_url}")process_data()
Make public via SDK (JavaScript/TypeScript):
import { startObservation } from '@abvdev/tracing';const rootSpan = startObservation('my-trace');// Make trace publicrootSpan.updateTrace({ public: true });rootSpan.end();
Security note: Only make traces public if they donβt contain sensitive data (PII, API keys, proprietary prompts). Use masking to redact sensitive content before sharing.
Text descriptions of bugs are vague and hard to reproduce. βThe LLM sometimes gives wrong answersβ isnβt actionable. Trace URLs provide concrete evidence.Without trace URLs:
Developer: βCan you describe the bug?β
Reporter: βThe LLM said Paris is in Germanyβ
Developer: βWhat was the input? What model? What timestamp?β
Reporter: βUh, I donβt rememberβ¦ it was yesterday around 3pmβ
Developer spends hours searching logs and trying to reproduce
Developer reproduces immediately and fixes the prompt
Best practices:
Include trace URLs in GitHub issues, Jira tickets, Linear tasks
Add trace URLs to error logs and exception handlers
Make traces public if sharing with external contributors or clients
Example: Automated bug report with trace URL
import requests@observe()def process_query(query): try: result = llm.generate(query) return result except Exception as e: # Get trace URL trace_url = abv.get_trace_url() # File GitHub issue automatically create_github_issue( title=f"LLM error: {str(e)}", body=f"Error occurred during query processing.\n\nTrace: {trace_url}\n\nStack trace:\n```\n{traceback.format_exc()}\n```" ) raise
Customer Support: Instant Context for Engineering
Support teams waste hours gathering context when users report issues. βIt didnβt workβ requires back-and-forth to extract details.Traditional support workflow:
User: βThe chatbot gave me wrong refund infoβ
Support: βCan you send a screenshot?β
User: βHereβs the screenshotβ (blurry image)
Engineering searches logs for 30 minutes to find the interaction
With trace URLs:
User: βThe chatbot gave me wrong refund infoβ
Support searches traces by user email in ABV
Support finds the trace, clicks βShare URLβ
Support sends trace URL to engineering: βThis trace shows the issueβ
Engineering clicks URL, sees full interaction in 5 seconds
Engineering identifies prompt used outdated policy docs (RAG issue)
Fix deployed within hours instead of days
Implementation:
# Store trace URLs in customer support tickets@observe()def handle_support_query(user_id, query): trace_url = abv.get_trace_url() # Add trace URL to support ticket support_ticket = create_ticket( user_id=user_id, description=query, metadata={"abv_trace_url": trace_url} ) # Process query response = generate_response(query) return response
Benefits:
Time to resolution: Days β hours
Context loss: Eliminated
Customer satisfaction: Improved (faster fixes)
Collaboration: Share Exact Context with Teammates
Debugging complex issues requires collaboration. Describing problems over Slack or email loses context. Trace URLs preserve everything.Without trace URLs (inefficient):
You: βHey, the summarization feature is failing for long documentsβ
Teammate: βWhat error?β
You: βTimeout after 30 secondsβ
Teammate: βWhat model?β
You: βGPT-4β
Teammate: βWhat was the input?β
You: βUh, let me find the logsβ¦ it was a 10-page PDFβ
Back-and-forth continues for 20 minutes
With trace URLs (instant):
You: βHey, summarization failing for long docs: [trace URL]β
Teammate clicks URL, sees:
Input: 10-page PDF (3,000 tokens)
Model: GPT-4
Timeout after 30 seconds
Cost: $0.15 (expensive!)
Teammate: βAh, we need to chunk the document or use Claude (128k context)β
Problem solved in 2 minutes
Best practices:
Share trace URLs in Slack, Microsoft Teams, or email
Add trace URLs to code review comments
Reference trace URLs in pull request descriptions
Example: Share trace in Slack automatically
@observe()def expensive_operation(data): result = process_data(data) # Get trace URL trace_url = abv.get_trace_url() trace_cost = abv.get_current_trace_cost() # Alert team if expensive if trace_cost > 1.00: # $1 threshold post_to_slack( channel="#llm-alerts", message=f"πΈ Expensive trace detected: ${trace_cost:.2f}\nDebug: {trace_url}" ) return result
Code Reviews: Reference Specific Traces in PRs
Pull request descriptions and code review comments benefit from concrete examples. Instead of saying βThis change improves latency,β link to before/after traces.Example: Pull request description with traces
## SummaryOptimized the document summarization prompt to reduce tokens and latency.## Changes- Reduced system prompt from 500 to 150 tokens- Removed redundant few-shot examples- Switched from `gpt-4` to `gpt-3.5-turbo` for simple summaries## Evidence**Before (v1.2.3):**- Trace: https://app.abv.dev/traces/abc123...- Tokens: 1,200 (input) + 300 (output)- Latency: 4.2 seconds- Cost: $0.08**After (v1.3.0):**- Trace: https://app.abv.dev/traces/def456...- Tokens: 350 (input) + 280 (output)- Latency: 1.8 seconds- Cost: $0.01**Result:** 57% latency reduction, 87% cost savings, no quality degradation.
Benefits:
Reviewers see concrete data instead of claims
Evidence-based code reviews
Easier to spot regressions or unintended side effects
Jupyter Notebooks: Interactive Trace Exploration
When running experiments in Jupyter notebooks, display trace URLs inline for interactive debugging.Example: Notebook workflow
from IPython.display import display, HTMLfrom abvdev import ABV, observeabv = ABV(api_key="sk-abv-...")@observe()def run_experiment(prompt_variant, input_text): response = llm.generate(prompt=prompt_variant, input=input_text) # Get trace URL trace_url = abv.get_trace_url() # Display clickable link in notebook display(HTML(f'<a href="{trace_url}" target="_blank">View Trace</a>')) return response# Run experimentfor variant in ["v1", "v2", "v3"]: print(f"\n=== Testing {variant} ===") result = run_experiment(variant, "Summarize this article") print(f"Output: {result}")
Output in notebook:
=== Testing v1 ===[View Trace] β Clickable linkOutput: This is a summary...=== Testing v2 ===[View Trace] β Clickable linkOutput: Another summary...
Benefits:
Click traces directly from notebook cells
Compare experiment results side-by-side in ABV Dashboard
Reproducible experiments (trace URLs never expire)
Logs and Monitoring: Correlate Events Across Systems
Application logs and monitoring dashboards (Datadog, Splunk, CloudWatch) show high-level metrics, but lack LLM-specific context. Add trace URLs to bridge the gap.Example: Structured logging with trace URLs
Use the @observe() decorator and retrieve trace URLs with abv.get_trace_url().Basic usage:
from abvdev import ABV, observeabv = ABV(api_key="sk-abv-...", host="https://app.abv.dev")@observe()def process_data(): # Get the URL of the current trace trace_url = abv.get_trace_url() print(f"View trace at: {trace_url}") # Or get URL from trace ID trace_id = abv.get_current_trace_id() trace_url_from_id = abv.get_trace_url(trace_id=trace_id) return trace_urlurl = process_data()# Output: "View trace at: https://app.abv.dev/traces/a1b2c3d4..."
Add to logs:
import logginglogging.basicConfig(level=logging.INFO)logger = logging.getLogger(__name__)@observe()def process_query(query): trace_url = abv.get_trace_url() logger.info(f"Processing query. Trace: {trace_url}") result = llm.generate(query) return result
Python: Get Trace URL in Context Managers
Use abv.start_as_current_span() and retrieve trace URLs within the context.Example:
from abvdev import ABVabv = ABV(api_key="sk-abv-...", host="https://app.abv.dev")with abv.start_as_current_span(name="process-request") as span: # Get trace URL trace_url = abv.get_trace_url() print(f"View trace at: {trace_url}") # Add to logs or monitoring logger.info(f"Trace URL: {trace_url}") # Your code here result = perform_operation()
JavaScript/TypeScript: Get Trace URL
Use the @abvdev/client package to retrieve trace URLs from trace IDs.Setup:
npm install @abvdev/tracing @abvdev/client
Example:
import './instrumentation'; // Must be first importimport { ABVClient } from '@abvdev/client';import { startObservation } from '@abvdev/tracing';const abv = new ABVClient();async function main() { const rootSpan = startObservation('my-trace', { input: { query: 'What is the capital of France?' } }); // Get trace URL const traceUrl = await abv.getTraceUrl(rootSpan.traceId); console.log('Trace URL:', traceUrl); // Add to logs console.log(`Processing query. Trace: ${traceUrl}`); rootSpan.update({ output: { content: 'The capital of France is Paris.' } }); rootSpan.end();}main();
Make Traces Public via SDK
Make traces publicly accessible (no login required) for external sharing.Python (decorator pattern):
from abvdev import ABV, observeabv = ABV(api_key="sk-abv-...")@observe()def process_data(): # Make the current trace public abv.update_current_trace(public=True) # Get the public URL trace_url = abv.get_trace_url() print(f"Share this public trace: {trace_url}")process_data()
Python (context managers):
with abv.start_as_current_span(name="process-request") as span: # Make this trace public span.update_trace(public=True) # Get the URL to share trace_url = abv.get_trace_url() print(f"Share this trace publicly: {trace_url}")
JavaScript/TypeScript:
import { startObservation } from '@abvdev/tracing';const rootSpan = startObservation('my-trace');// Make trace publicrootSpan.updateTrace({ public: true });// Get trace URLconst traceUrl = await abv.getTraceUrl(rootSpan.traceId);console.log(`Share publicly: ${traceUrl}`);rootSpan.end();
Security warning: Only make traces public if they donβt contain:
PII (emails, phone numbers, addresses)
API keys, passwords, or tokens
Proprietary prompts or system instructions
Use masking to redact sensitive content before sharing publicly.
Construct Trace URLs Manually
If you have the trace ID, you can construct the trace URL manually without calling the SDK.URL format: