mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-26 20:15:07 +08:00
start handling reloads with profiling
This commit is contained in:
parent
3c3a258a22
commit
abaa72e2bf
@ -39,6 +39,7 @@ use meilisearch_types::versioning::{check_version_file, create_version_file};
|
|||||||
use meilisearch_types::{compression, milli, VERSION_FILE_NAME};
|
use meilisearch_types::{compression, milli, VERSION_FILE_NAME};
|
||||||
pub use option::Opt;
|
pub use option::Opt;
|
||||||
use option::ScheduleSnapshot;
|
use option::ScheduleSnapshot;
|
||||||
|
use tracing_subscriber::filter::Targets;
|
||||||
|
|
||||||
use crate::error::MeilisearchHttpError;
|
use crate::error::MeilisearchHttpError;
|
||||||
|
|
||||||
@ -89,9 +90,10 @@ fn is_empty_db(db_path: impl AsRef<Path>) -> bool {
|
|||||||
/// The handle used to update the logs at runtime. Must be accessible from the `main.rs` and the `route/logs.rs`.
|
/// The handle used to update the logs at runtime. Must be accessible from the `main.rs` and the `route/logs.rs`.
|
||||||
pub type LogRouteHandle =
|
pub type LogRouteHandle =
|
||||||
tracing_subscriber::reload::Handle<LogRouteType, tracing_subscriber::Registry>;
|
tracing_subscriber::reload::Handle<LogRouteType, tracing_subscriber::Registry>;
|
||||||
|
|
||||||
pub type LogRouteType = tracing_subscriber::filter::Filtered<
|
pub type LogRouteType = tracing_subscriber::filter::Filtered<
|
||||||
Option<Box<dyn tracing_subscriber::Layer<tracing_subscriber::Registry> + Send + Sync>>,
|
Option<Box<dyn tracing_subscriber::Layer<tracing_subscriber::Registry> + Send + Sync>>,
|
||||||
tracing_subscriber::filter::LevelFilter,
|
Targets,
|
||||||
tracing_subscriber::Registry,
|
tracing_subscriber::Registry,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@ use anyhow::Context;
|
|||||||
use index_scheduler::IndexScheduler;
|
use index_scheduler::IndexScheduler;
|
||||||
use is_terminal::IsTerminal;
|
use is_terminal::IsTerminal;
|
||||||
use meilisearch::analytics::Analytics;
|
use meilisearch::analytics::Analytics;
|
||||||
use meilisearch::{analytics, create_app, prototype_name, setup_meilisearch, LogRouteHandle, Opt};
|
use meilisearch::{
|
||||||
|
analytics, create_app, prototype_name, setup_meilisearch, LogRouteHandle, LogRouteType, Opt,
|
||||||
|
};
|
||||||
use meilisearch_auth::{generate_master_key, AuthController, MASTER_KEY_MIN_SIZE};
|
use meilisearch_auth::{generate_master_key, AuthController, MASTER_KEY_MIN_SIZE};
|
||||||
use mimalloc::MiMalloc;
|
use mimalloc::MiMalloc;
|
||||||
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
|
||||||
@ -28,9 +30,8 @@ static ALLOC: MiMalloc = MiMalloc;
|
|||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: stats_alloc::StatsAlloc<MiMalloc> = stats_alloc::StatsAlloc::new(MiMalloc);
|
static ALLOC: stats_alloc::StatsAlloc<MiMalloc> = stats_alloc::StatsAlloc::new(MiMalloc);
|
||||||
|
|
||||||
fn default_layer<S: tracing::Subscriber>(
|
fn default_layer() -> LogRouteType {
|
||||||
) -> tracing_subscriber::filter::Filtered<Option<Box<dyn Layer<S> + Send + Sync>>, LevelFilter, S> {
|
None.with_filter(tracing_subscriber::filter::Targets::new().with_target("", LevelFilter::OFF))
|
||||||
None.with_filter(tracing_subscriber::filter::LevelFilter::OFF)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// does all the setup before meilisearch is launched
|
/// does all the setup before meilisearch is launched
|
||||||
|
@ -2,6 +2,7 @@ use std::fmt;
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use actix_web::web::{Bytes, Data};
|
use actix_web::web::{Bytes, Data};
|
||||||
use actix_web::{web, HttpRequest, HttpResponse};
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
@ -13,6 +14,7 @@ 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::instrument::WithSubscriber;
|
use tracing::instrument::WithSubscriber;
|
||||||
|
use tracing_subscriber::filter::Targets;
|
||||||
use tracing_subscriber::Layer;
|
use tracing_subscriber::Layer;
|
||||||
|
|
||||||
use crate::error::MeilisearchHttpError;
|
use crate::error::MeilisearchHttpError;
|
||||||
@ -48,7 +50,7 @@ pub enum LogMode {
|
|||||||
#[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 target: String,
|
||||||
|
|
||||||
#[deserr(default, error = DeserrJsonError<BadRequest>)]
|
#[deserr(default, error = DeserrJsonError<BadRequest>)]
|
||||||
pub mode: LogMode,
|
pub mode: LogMode,
|
||||||
@ -70,6 +72,12 @@ struct LogWriter {
|
|||||||
sender: mpsc::UnboundedSender<Vec<u8>>,
|
sender: mpsc::UnboundedSender<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for LogWriter {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("hello");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Write for LogWriter {
|
impl Write for LogWriter {
|
||||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||||
self.sender.send(buf.to_vec()).map_err(std::io::Error::other)?;
|
self.sender.send(buf.to_vec()).map_err(std::io::Error::other)?;
|
||||||
@ -83,6 +91,17 @@ impl Write for LogWriter {
|
|||||||
|
|
||||||
struct LogStreamer {
|
struct LogStreamer {
|
||||||
receiver: mpsc::UnboundedReceiver<Vec<u8>>,
|
receiver: mpsc::UnboundedReceiver<Vec<u8>>,
|
||||||
|
/// We need to keep an handle on the logs to make it available again when the streamer is dropped
|
||||||
|
logs: Arc<LogRouteHandle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for LogStreamer {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
println!("log streamer being dropped");
|
||||||
|
if let Err(e) = self.logs.modify(|layer| *layer.inner_mut() = None) {
|
||||||
|
tracing::error!("Could not free the logs route: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LogStreamer {
|
impl LogStreamer {
|
||||||
@ -142,50 +161,16 @@ pub async fn get_logs(
|
|||||||
_req: HttpRequest,
|
_req: HttpRequest,
|
||||||
) -> Result<HttpResponse, ResponseError> {
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
let opt = body.into_inner();
|
let opt = body.into_inner();
|
||||||
|
|
||||||
// #[cfg(not(feature = "stats_alloc"))]
|
|
||||||
// let (mut trace, layer) = tracing_trace::Trace::new(file);
|
|
||||||
// #[cfg(feature = "stats_alloc")]
|
|
||||||
// let (mut trace, layer) = tracing_trace::Trace::with_stats_alloc(file, &ALLOC);
|
|
||||||
|
|
||||||
let (sender, receiver) = tokio::sync::mpsc::unbounded_channel();
|
let (sender, receiver) = tokio::sync::mpsc::unbounded_channel();
|
||||||
|
|
||||||
// let fmt_layer = tracing_subscriber::fmt::layer()
|
|
||||||
// .with_line_number(true)
|
|
||||||
// .with_writer(move || LogWriter { sender: sender.clone() })
|
|
||||||
// .with_span_events(tracing_subscriber::fmt::format::FmtSpan::ACTIVE)
|
|
||||||
// .with_filter(
|
|
||||||
// tracing_subscriber::filter::LevelFilter::from_str(&opt.level.to_string()).unwrap(),
|
|
||||||
// );
|
|
||||||
// let subscriber = tracing_subscriber::registry().with(fmt_layer);
|
|
||||||
// let subscriber = Box::new(subscriber) as Box<dyn Layer<S> + Send + Sync>;
|
|
||||||
|
|
||||||
let mut was_available = false;
|
let mut was_available = false;
|
||||||
|
|
||||||
logs.modify(|layer| match layer.inner_mut() {
|
logs.modify(|layer| match layer.inner_mut() {
|
||||||
None => {
|
None => {
|
||||||
// there is no one getting logs
|
// there is no one getting logs
|
||||||
was_available = true;
|
was_available = true;
|
||||||
match opt.mode {
|
|
||||||
LogMode::Fmt => {
|
|
||||||
*layer.filter_mut() =
|
*layer.filter_mut() =
|
||||||
tracing_subscriber::filter::LevelFilter::from_str(&opt.level.to_string())
|
tracing_subscriber::filter::Targets::from_str(&opt.target).unwrap();
|
||||||
.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)
|
||||||
@ -198,7 +183,8 @@ pub async fn get_logs(
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if was_available {
|
if was_available {
|
||||||
Ok(HttpResponse::Ok().streaming(LogStreamer { receiver }.into_stream()))
|
Ok(HttpResponse::Ok()
|
||||||
|
.streaming(LogStreamer { receiver, logs: logs.into_inner() }.into_stream()))
|
||||||
} else {
|
} else {
|
||||||
Err(MeilisearchHttpError::AlreadyUsedLogRoute.into())
|
Err(MeilisearchHttpError::AlreadyUsedLogRoute.into())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user