mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-26 20:15:07 +08:00
start exposing the profiling layer
This commit is contained in:
parent
73e66d5a97
commit
3c3a258a22
@ -1,34 +1,32 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::pin::Pin;
|
use std::ops::ControlFlow;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::task::Poll;
|
|
||||||
|
|
||||||
use actix_web::web::{Bytes, Data};
|
use actix_web::web::{Bytes, Data};
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
use deserr::actix_web::AwebJson;
|
use deserr::actix_web::AwebJson;
|
||||||
use deserr::Deserr;
|
use deserr::Deserr;
|
||||||
use futures_util::{pin_mut, FutureExt};
|
|
||||||
use meilisearch_auth::AuthController;
|
use meilisearch_auth::AuthController;
|
||||||
use meilisearch_types::deserr::DeserrJsonError;
|
use meilisearch_types::deserr::DeserrJsonError;
|
||||||
use meilisearch_types::error::deserr_codes::*;
|
use meilisearch_types::error::deserr_codes::*;
|
||||||
use meilisearch_types::error::ResponseError;
|
use meilisearch_types::error::ResponseError;
|
||||||
use tokio::sync::mpsc::{self, UnboundedSender};
|
use tokio::sync::mpsc::{self, UnboundedSender};
|
||||||
use tracing_subscriber::layer::SubscriberExt;
|
use tracing::instrument::WithSubscriber;
|
||||||
use tracing_subscriber::Layer;
|
use tracing_subscriber::Layer;
|
||||||
|
|
||||||
use crate::error::MeilisearchHttpError;
|
use crate::error::MeilisearchHttpError;
|
||||||
use crate::extractors::authentication::policies::*;
|
use crate::extractors::authentication::policies::*;
|
||||||
use crate::extractors::authentication::GuardedData;
|
use crate::extractors::authentication::GuardedData;
|
||||||
use crate::extractors::sequential_extractor::SeqHandler;
|
use crate::extractors::sequential_extractor::SeqHandler;
|
||||||
use crate::{LogRouteHandle, LogRouteType};
|
use crate::LogRouteHandle;
|
||||||
|
|
||||||
pub fn configure(cfg: &mut web::ServiceConfig) {
|
pub fn configure(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.service(web::resource("").route(web::post().to(SeqHandler(get_logs))));
|
cfg.service(web::resource("").route(web::post().to(SeqHandler(get_logs))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, Deserr)]
|
#[derive(Debug, Default, Clone, Copy, Deserr)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[deserr(rename_all = lowercase)]
|
||||||
pub enum LogLevel {
|
pub enum LogLevel {
|
||||||
Error,
|
Error,
|
||||||
Warn,
|
Warn,
|
||||||
@ -38,11 +36,22 @@ pub enum LogLevel {
|
|||||||
Trace,
|
Trace,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, Copy, Deserr)]
|
||||||
|
#[deserr(rename_all = lowercase)]
|
||||||
|
pub enum LogMode {
|
||||||
|
#[default]
|
||||||
|
Fmt,
|
||||||
|
Profile,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserr)]
|
#[derive(Debug, Deserr)]
|
||||||
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
|
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
|
||||||
pub struct GetLogs {
|
pub struct GetLogs {
|
||||||
#[deserr(default, error = DeserrJsonError<BadRequest>)]
|
#[deserr(default, error = DeserrJsonError<BadRequest>)]
|
||||||
pub level: LogLevel,
|
pub level: LogLevel,
|
||||||
|
|
||||||
|
#[deserr(default, error = DeserrJsonError<BadRequest>)]
|
||||||
|
pub mode: LogMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for LogLevel {
|
impl fmt::Display for LogLevel {
|
||||||
@ -76,29 +85,6 @@ struct LogStreamer {
|
|||||||
receiver: mpsc::UnboundedReceiver<Vec<u8>>,
|
receiver: mpsc::UnboundedReceiver<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl futures_util::Stream for LogStreamer {
|
|
||||||
type Item = Result<Bytes, ResponseError>;
|
|
||||||
|
|
||||||
fn poll_next(
|
|
||||||
self: Pin<&mut Self>,
|
|
||||||
cx: &mut std::task::Context<'_>,
|
|
||||||
) -> Poll<Option<Self::Item>> {
|
|
||||||
let future = self.get_mut().receiver.recv();
|
|
||||||
pin_mut!(future);
|
|
||||||
|
|
||||||
match future.poll_unpin(cx) {
|
|
||||||
std::task::Poll::Ready(recv) => match recv {
|
|
||||||
Some(buf) => {
|
|
||||||
// let bytes = Bytes::copy_from_slice(buf.as_slice());
|
|
||||||
Poll::Ready(Some(Ok(buf.into())))
|
|
||||||
}
|
|
||||||
None => Poll::Ready(None),
|
|
||||||
},
|
|
||||||
Poll::Pending => Poll::Pending,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LogStreamer {
|
impl LogStreamer {
|
||||||
pub fn into_stream(self) -> impl futures_util::Stream<Item = Result<Bytes, ResponseError>> {
|
pub fn into_stream(self) -> impl futures_util::Stream<Item = Result<Bytes, ResponseError>> {
|
||||||
futures_util::stream::unfold(self, move |mut this| async move {
|
futures_util::stream::unfold(self, move |mut this| async move {
|
||||||
@ -115,13 +101,38 @@ pub fn make_layer<
|
|||||||
opt: &GetLogs,
|
opt: &GetLogs,
|
||||||
sender: UnboundedSender<Vec<u8>>,
|
sender: UnboundedSender<Vec<u8>>,
|
||||||
) -> Box<dyn Layer<S> + Send + Sync> {
|
) -> Box<dyn Layer<S> + Send + Sync> {
|
||||||
|
match opt.mode {
|
||||||
|
LogMode::Fmt => {
|
||||||
let fmt_layer = tracing_subscriber::fmt::layer()
|
let fmt_layer = tracing_subscriber::fmt::layer()
|
||||||
.with_line_number(true)
|
.with_line_number(true)
|
||||||
.with_writer(move || LogWriter { sender: sender.clone() })
|
.with_writer(move || LogWriter { sender: sender.clone() })
|
||||||
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::ACTIVE);
|
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::ACTIVE);
|
||||||
// let subscriber = tracing_subscriber::registry().with(fmt_layer);
|
|
||||||
|
|
||||||
Box::new(fmt_layer) as Box<dyn Layer<S> + Send + Sync>
|
Box::new(fmt_layer) as Box<dyn Layer<S> + Send + Sync>
|
||||||
|
}
|
||||||
|
LogMode::Profile => {
|
||||||
|
let (mut trace, layer) =
|
||||||
|
tracing_trace::Trace::new(LogWriter { sender: sender.clone() });
|
||||||
|
|
||||||
|
tokio::task::spawn(async move {
|
||||||
|
loop {
|
||||||
|
match tokio::time::timeout(std::time::Duration::from_secs(1), trace.receive())
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(Ok(ControlFlow::Continue(()))) => continue,
|
||||||
|
Ok(Ok(ControlFlow::Break(_))) => break,
|
||||||
|
// the other half of the channel was dropped
|
||||||
|
Ok(Err(_)) => break,
|
||||||
|
Err(_) => trace.flush().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while trace.try_receive().is_ok() {}
|
||||||
|
trace.flush().unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
|
Box::new(layer) as Box<dyn Layer<S> + Send + Sync>
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_logs(
|
pub async fn get_logs(
|
||||||
@ -153,10 +164,28 @@ pub async fn get_logs(
|
|||||||
|
|
||||||
logs.modify(|layer| match layer.inner_mut() {
|
logs.modify(|layer| match layer.inner_mut() {
|
||||||
None => {
|
None => {
|
||||||
was_available = true;
|
|
||||||
*layer.filter_mut() =
|
|
||||||
tracing_subscriber::filter::LevelFilter::from_str(&opt.level.to_string()).unwrap();
|
|
||||||
// there is no one getting logs
|
// there is no one getting logs
|
||||||
|
was_available = true;
|
||||||
|
match opt.mode {
|
||||||
|
LogMode::Fmt => {
|
||||||
|
*layer.filter_mut() =
|
||||||
|
tracing_subscriber::filter::LevelFilter::from_str(&opt.level.to_string())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
LogMode::Profile => {
|
||||||
|
*layer.filter_mut() =
|
||||||
|
tracing_subscriber::filter::LevelFilter::from_str(&opt.level.to_string())
|
||||||
|
.unwrap();
|
||||||
|
// *layer.filter_mut() = tracing_subscriber::filter::Targets::new()
|
||||||
|
// .with_target("indexing::", tracing::Level::TRACE)
|
||||||
|
// .with_filter(
|
||||||
|
// tracing_subscriber::filter::LevelFilter::from_str(
|
||||||
|
// &opt.level.to_string(),
|
||||||
|
// )
|
||||||
|
// .unwrap(),
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
}
|
||||||
let new_layer = make_layer(&opt, sender);
|
let new_layer = make_layer(&opt, sender);
|
||||||
|
|
||||||
*layer.inner_mut() = Some(new_layer)
|
*layer.inner_mut() = Some(new_layer)
|
||||||
|
Loading…
Reference in New Issue
Block a user