use anyhow::Result;
use std::env;
use vecstore::telemetry::{init_telemetry, init_telemetry_json, record_event, traced_sync};
use vecstore::{HybridQuery, Metadata, Query, VecStore};
fn main() -> Result<()> {
let use_json = env::args().any(|arg| arg == "--json");
if use_json {
println!("🔍 Initializing JSON tracing for production...");
init_telemetry_json()?;
} else {
println!("🔍 Initializing console tracing...");
init_telemetry()?;
}
println!("\n=== VecStore Distributed Tracing Demo ===\n");
demo_basic_tracing()?;
demo_hybrid_search_tracing()?;
demo_custom_spans()?;
demo_performance_monitoring()?;
println!("\n✅ All tracing demos complete!");
println!("\n💡 Tips:");
println!(" - Set RUST_LOG=vecstore=trace for detailed traces");
println!(" - Use --json flag for structured logging");
println!(" - Integrate with OpenTelemetry for production observability");
Ok(())
}
fn demo_basic_tracing() -> Result<()> {
println!("📊 Demo 1: Basic Operations with Automatic Tracing");
println!(" All query() and upsert() calls automatically create spans\n");
let mut store = VecStore::open("tracing_demo.db")?;
tracing::info!("Starting data ingestion phase");
for i in 0..10 {
let vector = vec![i as f32 * 0.1, (i + 1) as f32 * 0.1, (i + 2) as f32 * 0.1];
let mut fields = std::collections::HashMap::new();
fields.insert("index".to_string(), serde_json::json!(i));
fields.insert("category".to_string(), serde_json::json!("demo"));
let metadata = Metadata { fields };
store.upsert(format!("doc{}", i), vector, metadata)?;
}
record_event("data_ingestion_complete");
tracing::info!("Starting query phase");
let query = Query::new(vec![0.5, 0.6, 0.7]).with_limit(5);
let results = store.query(query)?;
println!(" Found {} results (traced automatically)", results.len());
record_event("query_complete");
Ok(())
}
fn demo_hybrid_search_tracing() -> Result<()> {
println!("\n📊 Demo 2: Hybrid Search Tracing");
println!(" Hybrid queries show vector + keyword weighting in traces\n");
let mut store = VecStore::open("tracing_demo.db")?;
let docs = vec![
(
"doc1",
vec![0.9, 0.8, 0.7],
"machine learning and artificial intelligence",
),
("doc2", vec![0.8, 0.9, 0.6], "deep learning neural networks"),
("doc3", vec![0.7, 0.7, 0.8], "natural language processing"),
];
for (id, vector, text) in docs {
let mut fields = std::collections::HashMap::new();
fields.insert("text".to_string(), serde_json::json!(text));
let metadata = Metadata { fields };
store.upsert(id.to_string(), vector, metadata)?;
store.index_text(id, text)?;
}
let query = HybridQuery {
vector: vec![0.1, 0.2, 0.3],
keywords: "machine learning".to_string(),
k: 3,
filter: None,
alpha: 0.7, };
tracing::info!("Executing hybrid query");
let results = store.hybrid_query(query)?;
println!(" Found {} hybrid results", results.len());
println!(" Check traces to see vector/keyword weighting (alpha=0.7)");
Ok(())
}
fn demo_custom_spans() -> Result<()> {
println!("\n📊 Demo 3: Custom Span Creation");
println!(" Use traced_sync() for custom business logic\n");
let result = traced_sync("data_preprocessing", || {
tracing::info!("Processing batch of documents");
let documents = vec![
"Document about AI",
"Document about ML",
"Document about NLP",
];
for (i, doc) in documents.iter().enumerate() {
tracing::debug!(doc_index = i, doc_length = doc.len(), "Processing document");
}
record_event("preprocessing_complete");
Ok::<_, anyhow::Error>(documents.len())
})?;
println!(" Processed {} documents in custom span", result);
Ok(())
}
fn demo_performance_monitoring() -> Result<()> {
println!("\n📊 Demo 4: Performance Monitoring");
println!(" Spans automatically track operation duration\n");
let store = VecStore::open("tracing_demo.db")?;
for i in 0..5 {
let query_vec = vec![i as f32 * 0.1, (i + 1) as f32 * 0.1, (i + 2) as f32 * 0.1];
let query = Query::new(query_vec)
.with_limit(10)
.with_filter("category = 'demo'");
tracing::info!(query_iteration = i, "Executing monitored query");
let results = store.query(query)?;
tracing::info!(
query_iteration = i,
result_count = results.len(),
"Query completed"
);
}
println!(" Executed 5 queries - check traces for timing information");
println!(" Slow queries will be visible in span durations");
Ok(())
}