chore: add ai metrics (#1169)
This commit is contained in:
parent
0f7a1f41d0
commit
ab9932a943
|
|
@ -53,7 +53,7 @@ pub enum OutputLayout {
|
||||||
SimpleTable = 3,
|
SimpleTable = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Serialize_repr, Deserialize_repr)]
|
#[derive(Clone, Debug, Default, Serialize_repr, Deserialize_repr, Eq, PartialEq)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum OutputContent {
|
pub enum OutputContent {
|
||||||
#[default]
|
#[default]
|
||||||
|
|
@ -62,6 +62,12 @@ pub enum OutputContent {
|
||||||
RichTextImage = 2,
|
RichTextImage = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl OutputContent {
|
||||||
|
pub fn is_image(&self) -> bool {
|
||||||
|
*self == OutputContent::IMAGE || *self == OutputContent::RichTextImage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
||||||
pub struct OutputContentMetadata {
|
pub struct OutputContentMetadata {
|
||||||
/// Custom prompt for image generation.
|
/// Custom prompt for image generation.
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,7 @@ async fn answer_stream_handler(
|
||||||
chat::chat_ops::select_chat_message_content(&state.pg_pool, question_id).await?;
|
chat::chat_ops::select_chat_message_content(&state.pg_pool, question_id).await?;
|
||||||
let rag_ids = chat::chat_ops::select_chat_rag_ids(&state.pg_pool, &chat_id).await?;
|
let rag_ids = chat::chat_ops::select_chat_rag_ids(&state.pg_pool, &chat_id).await?;
|
||||||
let ai_model = ai_model_from_header(&req);
|
let ai_model = ai_model_from_header(&req);
|
||||||
|
state.metrics.ai_metrics.record_total_stream_count(1);
|
||||||
match state
|
match state
|
||||||
.ai_client
|
.ai_client
|
||||||
.stream_question(
|
.stream_question(
|
||||||
|
|
@ -291,13 +292,16 @@ async fn answer_stream_handler(
|
||||||
.streaming(new_answer_stream),
|
.streaming(new_answer_stream),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
Err(err) => Ok(
|
Err(err) => {
|
||||||
HttpResponse::Ok()
|
state.metrics.ai_metrics.record_failed_stream_count(1);
|
||||||
.content_type("text/event-stream")
|
Ok(
|
||||||
.streaming(stream::once(async move {
|
HttpResponse::Ok()
|
||||||
Err(AppError::AIServiceUnavailable(err.to_string()))
|
.content_type("text/event-stream")
|
||||||
})),
|
.streaming(stream::once(async move {
|
||||||
),
|
Err(AppError::AIServiceUnavailable(err.to_string()))
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -313,6 +317,7 @@ async fn answer_stream_v2_handler(
|
||||||
let rag_ids = chat::chat_ops::select_chat_rag_ids(&state.pg_pool, &chat_id).await?;
|
let rag_ids = chat::chat_ops::select_chat_rag_ids(&state.pg_pool, &chat_id).await?;
|
||||||
let ai_model = ai_model_from_header(&req);
|
let ai_model = ai_model_from_header(&req);
|
||||||
|
|
||||||
|
state.metrics.ai_metrics.record_total_stream_count(1);
|
||||||
trace!(
|
trace!(
|
||||||
"[Chat] stream answer for chat: {}, question: {}, rag_ids: {:?}",
|
"[Chat] stream answer for chat: {}, question: {}, rag_ids: {:?}",
|
||||||
chat_id,
|
chat_id,
|
||||||
|
|
@ -340,13 +345,16 @@ async fn answer_stream_v2_handler(
|
||||||
.streaming(new_answer_stream),
|
.streaming(new_answer_stream),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
Err(err) => Ok(
|
Err(err) => {
|
||||||
HttpResponse::ServiceUnavailable()
|
state.metrics.ai_metrics.record_failed_stream_count(1);
|
||||||
.content_type("text/event-stream")
|
Ok(
|
||||||
.streaming(stream::once(async move {
|
HttpResponse::ServiceUnavailable()
|
||||||
Err(AppError::AIServiceUnavailable(err.to_string()))
|
.content_type("text/event-stream")
|
||||||
})),
|
.streaming(stream::once(async move {
|
||||||
),
|
Err(AppError::AIServiceUnavailable(err.to_string()))
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -363,6 +371,10 @@ async fn answer_stream_v3_handler(
|
||||||
chat::chat_ops::select_chat_message_content(&state.pg_pool, payload.question_id).await?;
|
chat::chat_ops::select_chat_message_content(&state.pg_pool, payload.question_id).await?;
|
||||||
let rag_ids = chat::chat_ops::select_chat_rag_ids(&state.pg_pool, &payload.chat_id).await?;
|
let rag_ids = chat::chat_ops::select_chat_rag_ids(&state.pg_pool, &payload.chat_id).await?;
|
||||||
let ai_model = ai_model_from_header(&req);
|
let ai_model = ai_model_from_header(&req);
|
||||||
|
state.metrics.ai_metrics.record_total_stream_count(1);
|
||||||
|
if payload.format.output_content.is_image() {
|
||||||
|
state.metrics.ai_metrics.record_stream_image_count(1);
|
||||||
|
}
|
||||||
|
|
||||||
let question = ChatQuestion {
|
let question = ChatQuestion {
|
||||||
chat_id: payload.chat_id,
|
chat_id: payload.chat_id,
|
||||||
|
|
@ -377,6 +389,7 @@ async fn answer_stream_v3_handler(
|
||||||
rag_ids,
|
rag_ids,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("[Chat] stream v3 {:?}", question);
|
trace!("[Chat] stream v3 {:?}", question);
|
||||||
match state
|
match state
|
||||||
.ai_client
|
.ai_client
|
||||||
|
|
@ -391,13 +404,16 @@ async fn answer_stream_v3_handler(
|
||||||
.streaming(new_answer_stream),
|
.streaming(new_answer_stream),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
Err(err) => Ok(
|
Err(err) => {
|
||||||
HttpResponse::ServiceUnavailable()
|
state.metrics.ai_metrics.record_failed_stream_count(1);
|
||||||
.content_type("text/event-stream")
|
Ok(
|
||||||
.streaming(stream::once(async move {
|
HttpResponse::ServiceUnavailable()
|
||||||
Err(AppError::AIServiceUnavailable(err.to_string()))
|
.content_type("text/event-stream")
|
||||||
})),
|
.streaming(stream::once(async move {
|
||||||
),
|
Err(AppError::AIServiceUnavailable(err.to_string()))
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
use prometheus_client::metrics::counter::Counter;
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub struct AIMetrics {
|
||||||
|
total_stream_count: Counter,
|
||||||
|
failed_stream_count: Counter,
|
||||||
|
stream_image_count: Counter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AIMetrics {
|
||||||
|
pub fn register(registry: &mut prometheus_client::registry::Registry) -> Self {
|
||||||
|
let metrics = Self::default();
|
||||||
|
let realtime_registry = registry.sub_registry_with_prefix("ai");
|
||||||
|
|
||||||
|
// Register each metric with the Prometheus registry
|
||||||
|
realtime_registry.register(
|
||||||
|
"total_stream_count",
|
||||||
|
"Total count of streams processed",
|
||||||
|
metrics.total_stream_count.clone(),
|
||||||
|
);
|
||||||
|
realtime_registry.register(
|
||||||
|
"failed_stream_count",
|
||||||
|
"Total count of failed streams",
|
||||||
|
metrics.failed_stream_count.clone(),
|
||||||
|
);
|
||||||
|
realtime_registry.register(
|
||||||
|
"image_stream_count",
|
||||||
|
"Total count of image streams processed",
|
||||||
|
metrics.stream_image_count.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
metrics
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn record_total_stream_count(&self, count: u64) {
|
||||||
|
self.total_stream_count.inc_by(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn record_failed_stream_count(&self, count: u64) {
|
||||||
|
self.failed_stream_count.inc_by(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn record_stream_image_count(&self, count: u64) {
|
||||||
|
self.stream_image_count.inc_by(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
pub mod metrics;
|
||||||
pub mod ops;
|
pub mod ops;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ use snowflake::Snowflake;
|
||||||
use tonic_proto::history::history_client::HistoryClient;
|
use tonic_proto::history::history_client::HistoryClient;
|
||||||
|
|
||||||
use crate::api::metrics::{AppFlowyWebMetrics, PublishedCollabMetrics, RequestMetrics};
|
use crate::api::metrics::{AppFlowyWebMetrics, PublishedCollabMetrics, RequestMetrics};
|
||||||
|
use crate::biz::chat::metrics::AIMetrics;
|
||||||
use crate::biz::pg_listener::PgListeners;
|
use crate::biz::pg_listener::PgListeners;
|
||||||
use crate::biz::workspace::publish::PublishedCollabStore;
|
use crate::biz::workspace::publish::PublishedCollabStore;
|
||||||
use crate::config::config::Config;
|
use crate::config::config::Config;
|
||||||
|
|
@ -130,6 +131,7 @@ pub struct AppMetrics {
|
||||||
pub appflowy_web_metrics: Arc<AppFlowyWebMetrics>,
|
pub appflowy_web_metrics: Arc<AppFlowyWebMetrics>,
|
||||||
pub embedding_metrics: Arc<EmbeddingMetrics>,
|
pub embedding_metrics: Arc<EmbeddingMetrics>,
|
||||||
pub collab_stream_metrics: Arc<CollabStreamMetrics>,
|
pub collab_stream_metrics: Arc<CollabStreamMetrics>,
|
||||||
|
pub ai_metrics: Arc<AIMetrics>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AppMetrics {
|
impl Default for AppMetrics {
|
||||||
|
|
@ -149,6 +151,7 @@ impl AppMetrics {
|
||||||
let appflowy_web_metrics = Arc::new(AppFlowyWebMetrics::register(&mut registry));
|
let appflowy_web_metrics = Arc::new(AppFlowyWebMetrics::register(&mut registry));
|
||||||
let embedding_metrics = Arc::new(EmbeddingMetrics::register(&mut registry));
|
let embedding_metrics = Arc::new(EmbeddingMetrics::register(&mut registry));
|
||||||
let collab_stream_metrics = Arc::new(CollabStreamMetrics::register(&mut registry));
|
let collab_stream_metrics = Arc::new(CollabStreamMetrics::register(&mut registry));
|
||||||
|
let ai_metrics = Arc::new(AIMetrics::register(&mut registry));
|
||||||
Self {
|
Self {
|
||||||
registry: Arc::new(registry),
|
registry: Arc::new(registry),
|
||||||
request_metrics,
|
request_metrics,
|
||||||
|
|
@ -159,6 +162,7 @@ impl AppMetrics {
|
||||||
appflowy_web_metrics,
|
appflowy_web_metrics,
|
||||||
embedding_metrics,
|
embedding_metrics,
|
||||||
collab_stream_metrics,
|
collab_stream_metrics,
|
||||||
|
ai_metrics,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue