diff --git a/crates/meilisearch/src/routes/indexes/search.rs b/crates/meilisearch/src/routes/indexes/search.rs index 697ae9241..445a3bb54 100644 --- a/crates/meilisearch/src/routes/indexes/search.rs +++ b/crates/meilisearch/src/routes/indexes/search.rs @@ -13,6 +13,7 @@ use meilisearch_types::serde_cs::vec::CS; use serde_json::Value; use tracing::debug; use utoipa::{IntoParams, OpenApi}; +use uuid::Uuid; use crate::analytics::Analytics; use crate::error::MeilisearchHttpError; @@ -325,7 +326,8 @@ pub async fn search_with_url_query( req: HttpRequest, analytics: web::Data, ) -> Result { - debug!(parameters = ?params, "Search get"); + let request_uid = Uuid::now_v7(); + debug!(request_uid = ?request_uid, parameters = ?params, "Search get"); let index_uid = IndexUid::try_from(index_uid.into_inner())?; let mut query: SearchQuery = params.into_inner().try_into()?; @@ -351,6 +353,7 @@ pub async fn search_with_url_query( search_kind, retrieve_vector, index_scheduler.features(), + request_uid, ) }) .await; @@ -363,7 +366,7 @@ pub async fn search_with_url_query( let search_result = search_result?; - debug!(returns = ?search_result, "Search get"); + debug!(request_uid = ?request_uid, returns = ?search_result, "Search get"); Ok(HttpResponse::Ok().json(search_result)) } @@ -432,9 +435,10 @@ pub async fn search_with_post( analytics: web::Data, ) -> Result { let index_uid = IndexUid::try_from(index_uid.into_inner())?; + let request_uid = Uuid::now_v7(); let mut query = params.into_inner(); - debug!(parameters = ?query, "Search post"); + debug!(request_uid = ?request_uid, parameters = ?query, "Search post"); // Tenant token search_rules. if let Some(search_rules) = index_scheduler.filters().get_index_search_rules(&index_uid) { @@ -458,6 +462,7 @@ pub async fn search_with_post( search_kind, retrieve_vectors, index_scheduler.features(), + request_uid, ) }) .await; @@ -473,7 +478,7 @@ pub async fn search_with_post( let search_result = search_result?; - debug!(returns = ?search_result, "Search post"); + debug!(request_uid = ?request_uid, returns = ?search_result, "Search post"); Ok(HttpResponse::Ok().json(search_result)) } diff --git a/crates/meilisearch/src/routes/indexes/search_analytics.rs b/crates/meilisearch/src/routes/indexes/search_analytics.rs index e27e6347b..9f095b007 100644 --- a/crates/meilisearch/src/routes/indexes/search_analytics.rs +++ b/crates/meilisearch/src/routes/indexes/search_analytics.rs @@ -234,6 +234,7 @@ impl SearchAggregator { facet_stats: _, degraded, used_negative_operator, + request_uid: _, } = result; self.total_succeeded = self.total_succeeded.saturating_add(1); diff --git a/crates/meilisearch/src/routes/multi_search.rs b/crates/meilisearch/src/routes/multi_search.rs index b3af98fd5..15931644f 100644 --- a/crates/meilisearch/src/routes/multi_search.rs +++ b/crates/meilisearch/src/routes/multi_search.rs @@ -9,6 +9,7 @@ use meilisearch_types::keys::actions; use serde::Serialize; use tracing::debug; use utoipa::{OpenApi, ToSchema}; +use uuid::Uuid; use super::multi_search_analytics::MultiSearchAggregator; use crate::analytics::Analytics; @@ -151,6 +152,7 @@ pub async fn multi_search_with_post( // Since we don't want to process half of the search requests and then get a permit refused // we're going to get one permit for the whole duration of the multi-search request. let permit = search_queue.try_get_search_permit().await?; + let request_uid = Uuid::now_v7(); let federated_search = params.into_inner(); @@ -188,14 +190,27 @@ pub async fn multi_search_with_post( let response = match federation { Some(federation) => { + debug!( + request_uid = ?request_uid, + federation = ?federation, + parameters = ?queries, + "Federated-search" + ); + // check remote header let is_proxy = req .headers() .get(PROXY_SEARCH_HEADER) .is_some_and(|value| value.as_bytes() == PROXY_SEARCH_HEADER_VALUE.as_bytes()); - let search_result = - perform_federated_search(&index_scheduler, queries, federation, features, is_proxy) - .await; + let search_result = perform_federated_search( + &index_scheduler, + queries, + federation, + features, + is_proxy, + request_uid, + ) + .await; permit.drop().await; if search_result.is_ok() { @@ -203,6 +218,13 @@ pub async fn multi_search_with_post( } analytics.publish(multi_aggregate, &req); + + debug!( + request_uid = ?request_uid, + returns = ?search_result, + "Federated-search" + ); + HttpResponse::Ok().json(search_result?) } None => { @@ -216,7 +238,12 @@ pub async fn multi_search_with_post( .map(SearchQueryWithIndex::into_index_query_federation) .enumerate() { - debug!(on_index = query_index, parameters = ?query, "Multi-search"); + debug!( + request_uid = ?request_uid, + on_index = query_index, + parameters = ?query, + "Multi-search" + ); if federation_options.is_some() { return Err(( @@ -258,6 +285,7 @@ pub async fn multi_search_with_post( search_kind, retrieve_vector, features, + request_uid, ) }) .await @@ -286,7 +314,11 @@ pub async fn multi_search_with_post( err })?; - debug!(returns = ?search_results, "Multi-search"); + debug!( + request_uid = ?request_uid, + returns = ?search_results, + "Multi-search" + ); HttpResponse::Ok().json(SearchResults { results: search_results }) } diff --git a/crates/meilisearch/src/search/federated/perform.rs b/crates/meilisearch/src/search/federated/perform.rs index 1af932c07..bf2c99a55 100644 --- a/crates/meilisearch/src/search/federated/perform.rs +++ b/crates/meilisearch/src/search/federated/perform.rs @@ -17,6 +17,7 @@ use meilisearch_types::milli::vector::Embedding; use meilisearch_types::milli::{self, DocumentId, OrderBy, TimeBudget, DEFAULT_VALUES_PER_FACET}; use roaring::RoaringBitmap; use tokio::task::JoinHandle; +use uuid::Uuid; use super::super::ranking_rules::{self, RankingRules}; use super::super::{ @@ -39,6 +40,7 @@ pub async fn perform_federated_search( federation: Federation, features: RoFeatures, is_proxy: bool, + request_uid: Uuid, ) -> Result { if is_proxy { features.check_network("Performing a remote federated search")?; @@ -170,6 +172,7 @@ pub async fn perform_federated_search( facet_stats, facets_by_index, remote_errors: partitioned_queries.has_remote.then_some(remote_errors), + request_uid: Some(request_uid), }) } @@ -439,6 +442,7 @@ fn merge_metadata( degraded: degraded_for_host, used_negative_operator: host_used_negative_operator, remote_errors: _, + request_uid: _, } in remote_results { let this_remote_duration = Duration::from_millis(*processing_time_ms as u64); diff --git a/crates/meilisearch/src/search/federated/types.rs b/crates/meilisearch/src/search/federated/types.rs index 9c96fe768..db30314ee 100644 --- a/crates/meilisearch/src/search/federated/types.rs +++ b/crates/meilisearch/src/search/federated/types.rs @@ -16,6 +16,7 @@ use meilisearch_types::milli::order_by_map::OrderByMap; use meilisearch_types::milli::OrderBy; use serde::{Deserialize, Serialize}; use utoipa::ToSchema; +use uuid::Uuid; use super::super::{ComputedFacets, FacetStats, HitsInfo, SearchHit, SearchQueryWithIndex}; use crate::milli::vector::Embedding; @@ -131,6 +132,8 @@ pub struct FederatedSearchResult { pub facet_stats: Option>, #[serde(default, skip_serializing_if = "FederatedFacets::is_empty")] pub facets_by_index: FederatedFacets, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub request_uid: Option, #[serde(default, skip_serializing_if = "Option::is_none")] pub remote_errors: Option>, @@ -156,6 +159,7 @@ impl fmt::Debug for FederatedSearchResult { facet_stats, facets_by_index, remote_errors, + request_uid, } = self; let mut debug = f.debug_struct("SearchResult"); @@ -188,6 +192,9 @@ impl fmt::Debug for FederatedSearchResult { if let Some(remote_errors) = remote_errors { debug.field("remote_errors", &remote_errors); } + if let Some(request_uid) = request_uid { + debug.field("request_uid", &request_uid); + } debug.finish() } diff --git a/crates/meilisearch/src/search/mod.rs b/crates/meilisearch/src/search/mod.rs index 057e469c3..329263271 100644 --- a/crates/meilisearch/src/search/mod.rs +++ b/crates/meilisearch/src/search/mod.rs @@ -36,6 +36,7 @@ use serde_json::{json, Value}; #[cfg(test)] mod mod_test; use utoipa::ToSchema; +use uuid::Uuid; use crate::error::MeilisearchHttpError; @@ -851,6 +852,8 @@ pub struct SearchResult { pub facet_distribution: Option>>, #[serde(skip_serializing_if = "Option::is_none")] pub facet_stats: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub request_uid: Option, #[serde(skip_serializing_if = "Option::is_none")] pub semantic_hit_count: Option, @@ -872,6 +875,7 @@ impl fmt::Debug for SearchResult { hits_info, facet_distribution, facet_stats, + request_uid, semantic_hit_count, degraded, used_negative_operator, @@ -901,6 +905,9 @@ impl fmt::Debug for SearchResult { if let Some(semantic_hit_count) = semantic_hit_count { debug.field("semantic_hit_count", &semantic_hit_count); } + if let Some(request_uid) = request_uid { + debug.field("request_uid", &request_uid); + } debug.finish() } @@ -1120,6 +1127,7 @@ pub fn perform_search( search_kind: SearchKind, retrieve_vectors: RetrieveVectors, features: RoFeatures, + request_uid: Uuid, ) -> Result { let before_search = Instant::now(); let rtxn = index.read_txn()?; @@ -1237,6 +1245,7 @@ pub fn perform_search( degraded, used_negative_operator, semantic_hit_count, + request_uid: Some(request_uid), }; Ok(result) }