Mejora la gestión de la traza de seguimiento
Aprovecha la potencia de los crates propios del ecosistema tracing para proporcionar las funcionalidades más importantes vía ajustes de configuración.
This commit is contained in:
parent
83fd12b5cc
commit
0f185887a6
8 changed files with 119 additions and 73 deletions
|
|
@ -31,10 +31,8 @@ figlet-rs = "0.1.3"
|
|||
config_rs = { package = "config", version = "0.11.0", features = ["toml"] }
|
||||
|
||||
tracing = "0.1"
|
||||
tracing-log = "0.1"
|
||||
tracing-appender = "0.2"
|
||||
tracing-subscriber = { version = "0.3", features = ["registry", "env-filter"] }
|
||||
tracing-bunyan-formatter = "0.3"
|
||||
tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] }
|
||||
tracing-actix-web = "0.2"
|
||||
|
||||
fluent-templates = "0.6.1"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
[app]
|
||||
name = "PageTop Application"
|
||||
description = "Developed with the amazing PageTop framework."
|
||||
# Idioma (localización) predeterminado.
|
||||
language = "en-US"
|
||||
# Tema predeterminado.
|
||||
theme = "Bootsier"
|
||||
# Idioma (localización) predeterminado.
|
||||
language = "en-US"
|
||||
# Dirección predeterminada para el texto: "ltr", "rtl" o "auto".
|
||||
direction = "ltr"
|
||||
# Rótulo al inicio: "Off", "Slant", "Small", "Speed" o "Starwars".
|
||||
startup_banner = "Small"
|
||||
|
||||
|
|
@ -18,6 +20,8 @@ rolling = "Daily"
|
|||
path = "log"
|
||||
# Prefijo para los archivos de traza (si rolling != "Stdout").
|
||||
prefix = "tracing.log"
|
||||
# Presentación de las trazas: "Json", "Full", "Compact" o "Pretty".
|
||||
format = "Json"
|
||||
|
||||
[webserver]
|
||||
# Configuración del servidor web.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,12 @@ pub static CONFIG: Lazy<Config> = Lazy::new(|| {
|
|||
/// componente, en una estructura similar a [`SETTINGS`] con tipos de variables
|
||||
/// seguros. Produce un *panic!* en caso de asignaciones no válidas.
|
||||
macro_rules! config_map {
|
||||
( $COMM:expr, $CONF:ident, $TYPE:tt $(, $key:expr => $value:expr)* ) => {
|
||||
(
|
||||
$COMM:expr,
|
||||
$CONF:ident,
|
||||
$TYPE:tt
|
||||
$(, $key:expr => $value:expr)*
|
||||
) => {
|
||||
$crate::doc_comment! {
|
||||
concat!($COMM),
|
||||
|
||||
|
|
@ -64,8 +69,9 @@ macro_rules! config_map {
|
|||
pub struct App {
|
||||
pub name : String,
|
||||
pub description : String,
|
||||
pub language : String,
|
||||
pub theme : String,
|
||||
pub language : String,
|
||||
pub direction : String,
|
||||
pub startup_banner: String,
|
||||
pub run_mode : String,
|
||||
}
|
||||
|
|
@ -76,6 +82,7 @@ pub struct Log {
|
|||
pub rolling : String,
|
||||
pub path : String,
|
||||
pub prefix : String,
|
||||
pub format : String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
|
@ -100,8 +107,9 @@ Ajustes globales y valores predeterminados para las secciones *\[app\]*,
|
|||
// [app]
|
||||
"app.name" => "PageTop Application",
|
||||
"app.description" => "Developed with the amazing PageTop framework.",
|
||||
"app.language" => "en-US",
|
||||
"app.theme" => "Bootsier",
|
||||
"app.language" => "en-US",
|
||||
"app.direction" => "ltr",
|
||||
"app.startup_banner" => "Small",
|
||||
|
||||
// [log]
|
||||
|
|
@ -109,6 +117,7 @@ Ajustes globales y valores predeterminados para las secciones *\[app\]*,
|
|||
"log.rolling" => "Daily",
|
||||
"log.path" => "log",
|
||||
"log.prefix" => "tracing.log",
|
||||
"log.format" => "json",
|
||||
|
||||
// [webserver]
|
||||
"webserver.bind_address" => "localhost",
|
||||
|
|
|
|||
|
|
@ -1,59 +1,11 @@
|
|||
use crate::{base, trace};
|
||||
use crate::{Lazy, base, locale, trace};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::{Server, all, server};
|
||||
use crate::core::module::register_module;
|
||||
|
||||
use tracing_log::LogTracer;
|
||||
use tracing_subscriber::{EnvFilter, Registry};
|
||||
use tracing_subscriber::layer::SubscriberExt;
|
||||
use tracing::subscriber::set_global_default;
|
||||
use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer};
|
||||
use tracing_actix_web::TracingLogger;
|
||||
|
||||
use actix_web::middleware::normalize;
|
||||
|
||||
pub fn run(bootstrap: Option<fn()>) -> Result<Server, std::io::Error> {
|
||||
// Inicia la traza de ejecución de la aplicación.
|
||||
let env_filter = EnvFilter::try_new(&SETTINGS.log.tracing)
|
||||
.unwrap_or(EnvFilter::new("Info"));
|
||||
|
||||
let rolling = SETTINGS.log.rolling.to_lowercase();
|
||||
let (non_blocking, _guard) = match rolling.as_str() {
|
||||
"stdout" => tracing_appender::non_blocking(
|
||||
std::io::stdout()
|
||||
),
|
||||
_ => tracing_appender::non_blocking({
|
||||
let path = &SETTINGS.log.path;
|
||||
let prefix = &SETTINGS.log.prefix;
|
||||
match rolling.as_str() {
|
||||
"daily" => tracing_appender::rolling::daily(path, prefix),
|
||||
"hourly" => tracing_appender::rolling::hourly(path, prefix),
|
||||
"minutely" => tracing_appender::rolling::minutely(path, prefix),
|
||||
"endless" => tracing_appender::rolling::never(path, prefix),
|
||||
_ => {
|
||||
println!(
|
||||
"Rolling value \"{}\" not valid. Using \"daily\"",
|
||||
rolling
|
||||
);
|
||||
tracing_appender::rolling::daily(path, prefix)
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
let formatting_layer = BunyanFormattingLayer::new(
|
||||
String::from(&SETTINGS.app.name),
|
||||
non_blocking
|
||||
);
|
||||
|
||||
let subscriber = Registry::default()
|
||||
.with(env_filter)
|
||||
.with(JsonStorageLayer)
|
||||
.with(formatting_layer);
|
||||
|
||||
set_global_default(subscriber).expect("Unable to setup subscriber!");
|
||||
|
||||
LogTracer::init().expect("Unable to setup log tracer!");
|
||||
|
||||
// Imprime el rótulo (opcional) de bienvenida.
|
||||
if SETTINGS.app.startup_banner.to_lowercase() != "off" {
|
||||
let figfont = figlet_rs::FIGfont::from_content(
|
||||
|
|
@ -63,9 +15,11 @@ pub fn run(bootstrap: Option<fn()>) -> Result<Server, std::io::Error> {
|
|||
"speed" => include_str!("figfonts/speed.flf"),
|
||||
"starwars" => include_str!("figfonts/starwars.flf"),
|
||||
_ => {
|
||||
trace::warn!(
|
||||
"FIGfont \"{}\" not found for banner. Using \"{}\"",
|
||||
SETTINGS.app.startup_banner, "Small"
|
||||
println!(
|
||||
"FIGfont \"{}\" not found for banner. {}. {}.",
|
||||
SETTINGS.app.startup_banner,
|
||||
"Using \"Small\"",
|
||||
"Check the settings file",
|
||||
);
|
||||
include_str!("figfonts/small.flf")
|
||||
}
|
||||
|
|
@ -78,6 +32,12 @@ pub fn run(bootstrap: Option<fn()>) -> Result<Server, std::io::Error> {
|
|||
);
|
||||
}
|
||||
|
||||
// Traza de seguimiento.
|
||||
Lazy::force(&trace::TRACING);
|
||||
|
||||
// Identificador de idioma.
|
||||
Lazy::force(&locale::LANGID);
|
||||
|
||||
// Ejecuta la función de inicio de la aplicación.
|
||||
if bootstrap != None {
|
||||
trace::debug!("Calling application bootstrap");
|
||||
|
|
@ -92,7 +52,7 @@ pub fn run(bootstrap: Option<fn()>) -> Result<Server, std::io::Error> {
|
|||
// Inicializa el servidor web.
|
||||
let server = server::HttpServer::new(|| {
|
||||
server::App::new()
|
||||
.wrap(TracingLogger)
|
||||
.wrap(tracing_actix_web::TracingLogger)
|
||||
.wrap(normalize::NormalizePath::new(normalize::TrailingSlash::Trim))
|
||||
.configure(&all::themes)
|
||||
.configure(&all::modules)
|
||||
|
|
|
|||
23
src/locale/locale.rs
Normal file
23
src/locale/locale.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use crate::{Lazy, trace};
|
||||
use crate::config::SETTINGS;
|
||||
|
||||
use unic_langid::LanguageIdentifier;
|
||||
|
||||
/// Almacena el Identificador de Idioma Unicode ([Unicode Language Identifier]
|
||||
/// (https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier)) de
|
||||
/// la aplicación, obtenido de `SETTINGS.app.language`.
|
||||
pub static LANGID: Lazy<LanguageIdentifier> = Lazy::new(|| {
|
||||
match SETTINGS.app.language.parse() {
|
||||
Ok(language) => language,
|
||||
Err(_) => {
|
||||
trace::warn!(
|
||||
"Failed to parse language \"{}\". {}. {}. {}.",
|
||||
SETTINGS.app.language,
|
||||
"Unicode Language Identifier not recognized",
|
||||
"Using \"en-US\"",
|
||||
"Check the settings file",
|
||||
);
|
||||
"en-US".parse().unwrap()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -1,21 +1,12 @@
|
|||
use crate::Lazy;
|
||||
use crate::config::SETTINGS;
|
||||
|
||||
use unic_langid::LanguageIdentifier;
|
||||
|
||||
pub use fluent_templates::{static_loader as static_locale, Loader as Locale};
|
||||
pub use fluent_templates;
|
||||
pub use fluent_templates::fluent_bundle::FluentValue;
|
||||
|
||||
/// Almacena el Identificador de Idioma Unicode ([Unicode Language Identifier]
|
||||
/// (https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier)) de
|
||||
/// la aplicación, obtenido de `SETTINGS.app.language`.
|
||||
pub static LANGID: Lazy<LanguageIdentifier> = Lazy::new(|| {
|
||||
SETTINGS.app.language.parse().expect("Failed to parse.")
|
||||
});
|
||||
mod locale;
|
||||
pub use locale::LANGID;
|
||||
|
||||
#[macro_export]
|
||||
/// Permite integrar fácilmente localización en tus temas y módulos.
|
||||
/// Permite integrar fácilmente localización en temas, módulos y componentes.
|
||||
macro_rules! localize {
|
||||
( $DEF_LANGID:literal, $locales:literal $(, $core_locales:literal)? ) => {
|
||||
use $crate::locale::*;
|
||||
|
|
|
|||
|
|
@ -1 +1,5 @@
|
|||
pub use tracing::{Level, event, span};
|
||||
pub use tracing::{debug, error, info, trace, warn};
|
||||
|
||||
mod trace;
|
||||
pub use trace::TRACING;
|
||||
|
|
|
|||
57
src/trace/trace.rs
Normal file
57
src/trace/trace.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
use crate::Lazy;
|
||||
use crate::config::SETTINGS;
|
||||
|
||||
use tracing_appender::non_blocking::WorkerGuard;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
pub static TRACING: Lazy<WorkerGuard> = Lazy::new(|| {
|
||||
let env_filter = EnvFilter::try_new(&SETTINGS.log.tracing)
|
||||
.unwrap_or(EnvFilter::new("Info"));
|
||||
|
||||
let rolling = SETTINGS.log.rolling.to_lowercase();
|
||||
let (non_blocking, guard) = match rolling.as_str() {
|
||||
"stdout" => tracing_appender::non_blocking(
|
||||
std::io::stdout()
|
||||
),
|
||||
_ => tracing_appender::non_blocking({
|
||||
let path = &SETTINGS.log.path;
|
||||
let prefix = &SETTINGS.log.prefix;
|
||||
match rolling.as_str() {
|
||||
"daily" => tracing_appender::rolling::daily(path, prefix),
|
||||
"hourly" => tracing_appender::rolling::hourly(path, prefix),
|
||||
"minutely" => tracing_appender::rolling::minutely(path, prefix),
|
||||
"endless" => tracing_appender::rolling::never(path, prefix),
|
||||
_ => {
|
||||
println!(
|
||||
"Rolling value \"{}\" not valid. {}. {}.",
|
||||
SETTINGS.log.rolling,
|
||||
"Using \"daily\"",
|
||||
"Check the settings file",
|
||||
);
|
||||
tracing_appender::rolling::daily(path, prefix)
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
let subscriber = tracing_subscriber::fmt()
|
||||
.with_env_filter(env_filter)
|
||||
.with_writer(non_blocking)
|
||||
.with_ansi(rolling.as_str() == "stdout");
|
||||
match SETTINGS.log.format.to_lowercase().as_str() {
|
||||
"json" => subscriber.json().init(),
|
||||
"full" => subscriber.init(),
|
||||
"compact" => subscriber.compact().init(),
|
||||
"pretty" => subscriber.pretty().init(),
|
||||
_ => {
|
||||
println!(
|
||||
"Tracing format \"{}\" not valid. {}. {}.",
|
||||
SETTINGS.log.format,
|
||||
"Using \"Full\"",
|
||||
"Check the settings file",
|
||||
);
|
||||
subscriber.init();
|
||||
}
|
||||
}
|
||||
|
||||
guard
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue