mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-07-27 08:41:00 +00:00
Add analytics
This commit is contained in:
@ -28,6 +28,7 @@ use crate::analytics::Analytics;
|
|||||||
use crate::extractors::authentication::policies::DoubleActionPolicy;
|
use crate::extractors::authentication::policies::DoubleActionPolicy;
|
||||||
use crate::extractors::authentication::GuardedData;
|
use crate::extractors::authentication::GuardedData;
|
||||||
use crate::extractors::sequential_extractor::SeqHandler;
|
use crate::extractors::sequential_extractor::SeqHandler;
|
||||||
|
use crate::routes::indexes::render_analytics::RenderAggregator;
|
||||||
|
|
||||||
#[derive(OpenApi)]
|
#[derive(OpenApi)]
|
||||||
#[openapi(
|
#[openapi(
|
||||||
@ -92,14 +93,16 @@ pub async fn render_post(
|
|||||||
let query = params.into_inner();
|
let query = params.into_inner();
|
||||||
debug!(parameters = ?query, "Render template");
|
debug!(parameters = ?query, "Render template");
|
||||||
|
|
||||||
//let mut aggregate = SimilarAggregator::<SimilarPOST>::from_query(&query);
|
let mut aggregate = RenderAggregator::from_query(&query);
|
||||||
|
|
||||||
let result = render(index, query).await?;
|
let result = render(index, query).await;
|
||||||
|
|
||||||
// if let Ok(similar) = &similar {
|
if result.is_ok() {
|
||||||
// aggregate.succeed(similar);
|
aggregate.succeed();
|
||||||
// }
|
}
|
||||||
// analytics.publish(aggregate, &req);
|
analytics.publish(aggregate, &req);
|
||||||
|
|
||||||
|
let result = result?;
|
||||||
|
|
||||||
debug!(returns = ?result, "Render template");
|
debug!(returns = ?result, "Render template");
|
||||||
Ok(HttpResponse::Ok().json(result))
|
Ok(HttpResponse::Ok().json(result))
|
||||||
@ -551,20 +554,20 @@ pub struct RenderQuery {
|
|||||||
#[deserr(error = DeserrJsonError<InvalidRenderTemplate>, rename_all = camelCase, deny_unknown_fields)]
|
#[deserr(error = DeserrJsonError<InvalidRenderTemplate>, rename_all = camelCase, deny_unknown_fields)]
|
||||||
pub struct RenderQueryTemplate {
|
pub struct RenderQueryTemplate {
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidRenderTemplateId>)]
|
#[deserr(default, error = DeserrJsonError<InvalidRenderTemplateId>)]
|
||||||
id: Option<String>,
|
pub id: Option<String>,
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidRenderTemplateInline>)]
|
#[deserr(default, error = DeserrJsonError<InvalidRenderTemplateInline>)]
|
||||||
inline: Option<serde_json::Value>,
|
pub inline: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, PartialEq, Deserr, ToSchema)]
|
#[derive(Debug, Clone, Default, PartialEq, Deserr, ToSchema)]
|
||||||
#[deserr(error = DeserrJsonError<InvalidRenderInput>, rename_all = camelCase, deny_unknown_fields)]
|
#[deserr(error = DeserrJsonError<InvalidRenderInput>, rename_all = camelCase, deny_unknown_fields)]
|
||||||
pub struct RenderQueryInput {
|
pub struct RenderQueryInput {
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidRenderInputDocumentId>)]
|
#[deserr(default, error = DeserrJsonError<InvalidRenderInputDocumentId>)]
|
||||||
document_id: Option<String>,
|
pub document_id: Option<String>,
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidRenderInputFields>)]
|
#[deserr(default, error = DeserrJsonError<InvalidRenderInputFields>)]
|
||||||
insert_fields: Option<bool>,
|
pub insert_fields: Option<bool>,
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidRenderInputInline>)]
|
#[deserr(default, error = DeserrJsonError<InvalidRenderInputInline>)]
|
||||||
inline: Option<BTreeMap<String, serde_json::Value>>,
|
pub inline: Option<BTreeMap<String, serde_json::Value>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, PartialEq, ToSchema)]
|
#[derive(Debug, Clone, Serialize, PartialEq, ToSchema)]
|
||||||
|
@ -1 +1,102 @@
|
|||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
use crate::analytics::Aggregate;
|
||||||
|
use crate::routes::indexes::render::RenderQuery;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct RenderAggregator {
|
||||||
|
// requests
|
||||||
|
total_received: usize,
|
||||||
|
total_succeeded: usize,
|
||||||
|
|
||||||
|
// parameters
|
||||||
|
template_inline: bool,
|
||||||
|
template_id: bool,
|
||||||
|
input_inline: bool,
|
||||||
|
input_id: bool,
|
||||||
|
input_omitted: bool,
|
||||||
|
fields_forced: bool,
|
||||||
|
fields_disabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderAggregator {
|
||||||
|
#[allow(clippy::field_reassign_with_default)]
|
||||||
|
pub fn from_query(query: &RenderQuery) -> Self {
|
||||||
|
let RenderQuery {
|
||||||
|
template,
|
||||||
|
input,
|
||||||
|
} = query;
|
||||||
|
|
||||||
|
let mut ret = Self::default();
|
||||||
|
|
||||||
|
ret.total_received = 1;
|
||||||
|
|
||||||
|
ret.template_inline = template.inline.is_some();
|
||||||
|
ret.template_id = template.id.is_some();
|
||||||
|
ret.input_inline = input.as_ref().is_some_and(|i| i.inline.is_some());
|
||||||
|
ret.input_id = input.as_ref().is_some_and(|i| i.document_id.is_some());
|
||||||
|
ret.input_omitted = input.as_ref().is_none();
|
||||||
|
ret.fields_forced = input.as_ref().is_some_and(|i| i.insert_fields.is_some());
|
||||||
|
ret.fields_disabled = input.as_ref().is_some_and(|i| i.insert_fields.is_none());
|
||||||
|
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn succeed(&mut self) {
|
||||||
|
self.total_succeeded += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Aggregate for RenderAggregator {
|
||||||
|
fn event_name(&self) -> &'static str {
|
||||||
|
"Documents Rendered"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn aggregate(mut self: Box<Self>, new: Box<Self>) -> Box<Self> {
|
||||||
|
self.total_received += new.total_received;
|
||||||
|
self.total_succeeded += new.total_succeeded;
|
||||||
|
|
||||||
|
self.template_inline |= new.template_inline;
|
||||||
|
self.template_id |= new.template_id;
|
||||||
|
self.input_inline |= new.input_inline;
|
||||||
|
self.input_id |= new.input_id;
|
||||||
|
self.input_omitted |= new.input_omitted;
|
||||||
|
self.fields_forced |= new.fields_forced;
|
||||||
|
self.fields_disabled |= new.fields_disabled;
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_event(self: Box<Self>) -> serde_json::Value {
|
||||||
|
let Self {
|
||||||
|
total_received,
|
||||||
|
total_succeeded,
|
||||||
|
template_inline,
|
||||||
|
template_id,
|
||||||
|
input_inline,
|
||||||
|
input_id,
|
||||||
|
input_omitted,
|
||||||
|
fields_forced,
|
||||||
|
fields_disabled,
|
||||||
|
} = *self;
|
||||||
|
|
||||||
|
json!({
|
||||||
|
"requests": {
|
||||||
|
"total_received": total_received,
|
||||||
|
"total_succeeded": total_succeeded,
|
||||||
|
"total_failed": total_received.saturating_sub(total_succeeded) // just to be sure we never panics
|
||||||
|
},
|
||||||
|
"template": {
|
||||||
|
"inline": template_inline,
|
||||||
|
"id": template_id,
|
||||||
|
},
|
||||||
|
"input": {
|
||||||
|
"inline": input_inline,
|
||||||
|
"id": input_id,
|
||||||
|
"omitted": input_omitted,
|
||||||
|
"fields_forced": fields_forced,
|
||||||
|
"fields_disabled": fields_disabled,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user