Tracing: DAO layer + handler spans on tracing, drop all Context params (#141)
trace_db_call no longer takes an OpenTelemetry Context: it opens a db.<query_type>.<operation> span (same name via otel.name, same db.query_type / db.operation attrs) on the caller's ambient tracing span and runs the DAO body inside it. The cx / ctx / context parameter is gone from every DAO trait method, impl and call site, and from the helpers and background drains that only threaded it. The remaining request-handler spans (files, tags, faces, image, video, favorites, duplicates, memories) move to #[instrument]; the Context::current_with_span / with_remote_span_context plumbing is gone, as is extract_context_from_request (the tracing-actix-web root span covers it). otel::set_span_attributes replaces BoxedSpan::set_attributes. Background-job raw spans (thumbnails, video actors) are left for #142. tests/otel_db_spans.rs pins name, attributes, status and nesting (across an instrumented spawn); otel_traceparent now uses an #[instrument] handler. CLAUDE.md documents the tracing conventions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1c508cdabd
commit
b6deca2a52
55 files changed
+1942
-3852
No files matched your search
@@ -71,7 +71,6 @@ fn main() -> anyhow::Result<()> {
|
||||
);
|
||||
|
||||
let dao: Arc<Mutex<Box<dyn ExifDao>>> = Arc::new(Mutex::new(Box::new(SqliteExifDao::new())));
|
||||
let ctx = opentelemetry::Context::new();
|
||||
|
||||
let mut total_hashed = 0u64;
|
||||
let mut total_missing = 0u64;
|
||||
@@ -84,7 +83,7 @@ fn main() -> anyhow::Result<()> {
|
||||
let rows = {
|
||||
let mut guard = dao.lock().expect("Unable to lock ExifDao");
|
||||
guard
|
||||
.get_rows_missing_hash(&ctx, args.batch_size)
|
||||
.get_rows_missing_hash(args.batch_size)
|
||||
.map_err(|e| anyhow::anyhow!("DB error: {:?}", e))?
|
||||
};
|
||||
if rows.is_empty() {
|
||||
@@ -128,7 +127,6 @@ fn main() -> anyhow::Result<()> {
|
||||
match ident {
|
||||
Some(id) => {
|
||||
match guard.backfill_content_hash(
|
||||
&ctx,
|
||||
*library_id,
|
||||
rel_path,
|
||||
&id.content_hash,
|
||||
|
||||
@@ -78,7 +78,6 @@ fn main() -> anyhow::Result<()> {
|
||||
);
|
||||
|
||||
let dao: Arc<Mutex<Box<dyn ExifDao>>> = Arc::new(Mutex::new(Box::new(SqliteExifDao::new())));
|
||||
let ctx = opentelemetry::Context::new();
|
||||
|
||||
let mut total_hashed = 0u64;
|
||||
let mut total_missing = 0u64;
|
||||
@@ -92,7 +91,7 @@ fn main() -> anyhow::Result<()> {
|
||||
let rows = {
|
||||
let mut guard = dao.lock().expect("Unable to lock ExifDao");
|
||||
guard
|
||||
.get_rows_missing_perceptual_hash(&ctx, args.batch_size)
|
||||
.get_rows_missing_perceptual_hash(args.batch_size)
|
||||
.map_err(|e| anyhow::anyhow!("DB error: {:?}", e))?
|
||||
};
|
||||
if rows.is_empty() {
|
||||
@@ -137,7 +136,6 @@ fn main() -> anyhow::Result<()> {
|
||||
match result {
|
||||
FilePerceptualResult::Ok(id) => {
|
||||
match guard.backfill_perceptual_hash(
|
||||
&ctx,
|
||||
*library_id,
|
||||
rel_path,
|
||||
Some(id.phash_64),
|
||||
@@ -170,7 +168,6 @@ fn main() -> anyhow::Result<()> {
|
||||
library_id
|
||||
);
|
||||
match guard.backfill_perceptual_hash(
|
||||
&ctx,
|
||||
*library_id,
|
||||
rel_path,
|
||||
Some(0),
|
||||
|
||||
@@ -42,8 +42,6 @@ async fn main() -> Result<()> {
|
||||
|
||||
info!("Found {} calendar events", events.len());
|
||||
|
||||
let context = opentelemetry::Context::current();
|
||||
|
||||
// LocalLlm dispatches per LLM_BACKEND, so embeddings written here land
|
||||
// in the same vector space the query side searches.
|
||||
let llm = if args.generate_embeddings {
|
||||
@@ -65,11 +63,8 @@ async fn main() -> Result<()> {
|
||||
|
||||
// Check if event exists
|
||||
if args.skip_existing
|
||||
&& let Ok(exists) = dao_instance.event_exists(
|
||||
&context,
|
||||
event.event_uid.as_deref().unwrap_or(""),
|
||||
event.start_time,
|
||||
)
|
||||
&& let Ok(exists) = dao_instance
|
||||
.event_exists(event.event_uid.as_deref().unwrap_or(""), event.start_time)
|
||||
&& exists
|
||||
{
|
||||
skipped_count += 1;
|
||||
@@ -120,7 +115,7 @@ async fn main() -> Result<()> {
|
||||
source_file: Some(args.path.clone()),
|
||||
};
|
||||
|
||||
match dao_instance.store_event(&context, insert_event) {
|
||||
match dao_instance.store_event(insert_event) {
|
||||
Ok(_) => inserted_count += 1,
|
||||
Err(e) => {
|
||||
pb.println(format!("store failed for '{}': {:?}", event.summary, e));
|
||||
|
||||
@@ -37,8 +37,6 @@ async fn main() -> Result<()> {
|
||||
|
||||
info!("Found {} location records", locations.len());
|
||||
|
||||
let context = opentelemetry::Context::current();
|
||||
|
||||
let mut inserted_count = 0usize;
|
||||
let mut skipped_count = 0usize;
|
||||
let mut error_count = 0usize;
|
||||
@@ -58,7 +56,6 @@ async fn main() -> Result<()> {
|
||||
// Skip existing check if requested (makes import much slower)
|
||||
if args.skip_existing
|
||||
&& let Ok(exists) = dao_instance.location_exists(
|
||||
&context,
|
||||
location.timestamp,
|
||||
location.latitude,
|
||||
location.longitude,
|
||||
@@ -87,7 +84,7 @@ async fn main() -> Result<()> {
|
||||
|
||||
// Batch insert entire chunk in single transaction
|
||||
if !batch_inserts.is_empty() {
|
||||
match dao_instance.store_locations_batch(&context, batch_inserts) {
|
||||
match dao_instance.store_locations_batch(batch_inserts) {
|
||||
Ok(count) => inserted_count += count,
|
||||
Err(e) => {
|
||||
pb.println(format!("batch insert failed: {:?}", e));
|
||||
|
||||
@@ -41,7 +41,6 @@ async fn main() -> Result<()> {
|
||||
// LocalLlm dispatches per LLM_BACKEND, so embeddings written here land
|
||||
// in the same vector space the query side searches.
|
||||
let llm = LocalLlm::from_env();
|
||||
let context = opentelemetry::Context::current();
|
||||
|
||||
let mut inserted_count = 0usize;
|
||||
let mut skipped_count = 0usize;
|
||||
@@ -84,8 +83,7 @@ async fn main() -> Result<()> {
|
||||
for (search, embedding_opt) in chunk.iter().zip(embeddings_result.iter()) {
|
||||
// Check if search exists (optional for speed)
|
||||
if args.skip_existing
|
||||
&& let Ok(exists) =
|
||||
dao_instance.search_exists(&context, search.timestamp, &search.query)
|
||||
&& let Ok(exists) = dao_instance.search_exists(search.timestamp, &search.query)
|
||||
&& exists
|
||||
{
|
||||
skipped_count += 1;
|
||||
@@ -110,7 +108,7 @@ async fn main() -> Result<()> {
|
||||
|
||||
// Batch insert entire chunk in single transaction
|
||||
if !batch_inserts.is_empty() {
|
||||
match dao_instance.store_searches_batch(&context, batch_inserts) {
|
||||
match dao_instance.store_searches_batch(batch_inserts) {
|
||||
Ok(count) => inserted_count += count,
|
||||
Err(e) => {
|
||||
pb.println(format!("batch insert failed: {:?}", e));
|
||||
|
||||
@@ -305,7 +305,6 @@ async fn main() -> anyhow::Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let cx = opentelemetry::Context::new();
|
||||
let mut processed = 0usize;
|
||||
let mut skipped = 0usize;
|
||||
let mut errors = 0usize;
|
||||
@@ -319,7 +318,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
let has_insight = insight_dao
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_insight(&cx, relative)
|
||||
.get_insight(relative)
|
||||
.unwrap_or(None)
|
||||
.is_some();
|
||||
|
||||
|
||||
@@ -128,7 +128,6 @@ async fn main() -> anyhow::Result<()> {
|
||||
);
|
||||
|
||||
let dao: Arc<Mutex<Box<dyn ExifDao>>> = Arc::new(Mutex::new(Box::new(SqliteExifDao::new())));
|
||||
let ctx = opentelemetry::Context::new();
|
||||
|
||||
// Encode the query up-front so the long image-encode loop doesn't
|
||||
// race a slow query encode. Fails fast on a misspelled query.
|
||||
@@ -168,7 +167,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
let rows = {
|
||||
let mut guard = dao.lock().expect("dao lock");
|
||||
guard
|
||||
.list_rel_paths_for_library_page(&ctx, lib.id, PAGE, offset)
|
||||
.list_rel_paths_for_library_page(lib.id, PAGE, offset)
|
||||
.map_err(|e| anyhow::anyhow!("list rel_paths: {:?}", e))?
|
||||
};
|
||||
if rows.is_empty() {
|
||||
|
||||
@@ -251,9 +251,8 @@ async fn main() -> Result<()> {
|
||||
};
|
||||
|
||||
let mut dao = summary_dao.lock().expect("Unable to lock DailySummaryDao");
|
||||
let context = opentelemetry::Context::new();
|
||||
|
||||
match dao.store_summary(&context, insert) {
|
||||
match dao.store_summary(insert) {
|
||||
Ok(_) => println!("✓ Saved to database"),
|
||||
Err(e) => println!("✗ Database error: {:?}", e),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user