Manual Tracing
Add custom tracing to your functions
Manual Tracing
Using the @observe Decorator
Add custom tracing to any function:
import palantyra
@palantyra.observe(name="Process Document")
def process_document(doc_text):
# Add custom attributes
palantyra.set_span_attributes({
"document_length": len(doc_text),
"document_type": "pdf"
})
# Your LLM calls here
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": doc_text}]
)
return response
# Function is automatically traced
result = process_document("Long document text...")
Context Manager Approach
import palantyra
def analyze_data(data):
with palantyra.start_as_current_span(
name="Data Analysis",
metadata={"data_size": len(data)}
):
# Add attributes during execution
palantyra.set_span_attributes({
"step": "preprocessing"
})
processed = preprocess(data)
palantyra.set_span_attributes({
"step": "analysis"
})
result = analyze(processed)
# Set output
palantyra.set_span_output(result)
return result
Decorator Options
@palantyra.observe(
name="Custom Name", # Override function name
session_id="session_123", # Track sessions
user_id="user_456", # Track users
metadata={"version": "v2"}, # Custom metadata
tags=["production", "api"], # Categorize traces
ignore_input=False, # Don't log inputs
ignore_output=False, # Don't log outputs
ignore_inputs=["password"] # Specific args to ignore
)
def my_function(text, password):
# Your code here
pass
Nested Spans
Create hierarchical traces:
@palantyra.observe(name="Parent Operation")
def parent_operation():
# This creates a parent span
with palantyra.start_as_current_span(name="Child Operation 1"):
# Child span 1
result1 = do_something()
with palantyra.start_as_current_span(name="Child Operation 2"):
# Child span 2
result2 = do_something_else()
return result1, result2