mod collector;
mod filter;
mod formatter;
mod output;
pub use collector::{LogCollector, LogEntry, LogSource, StopHandle};
pub use filter::{LogFilter, LogLevel};
pub use formatter::{LogFormatter, OutputFormat};
pub use output::{FileRotation, LogOutput, OutputConfig};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LogConfig {
pub format: OutputFormat,
pub output: OutputConfig,
pub filter: LogFilter,
pub domain_id: u32,
pub topic_pattern: String,
}
impl Default for LogConfig {
fn default() -> Self {
Self {
format: OutputFormat::Text,
output: OutputConfig::Stdout,
filter: LogFilter::default(),
domain_id: 0,
topic_pattern: "rt/rosout".to_string(),
}
}
}
impl LogConfig {
pub fn builder() -> LogConfigBuilder {
LogConfigBuilder::default()
}
}
#[derive(Debug, Default)]
pub struct LogConfigBuilder {
format: Option<OutputFormat>,
output: Option<OutputConfig>,
filter: Option<LogFilter>,
domain_id: Option<u32>,
topic_pattern: Option<String>,
}
impl LogConfigBuilder {
pub fn format(mut self, format: OutputFormat) -> Self {
self.format = Some(format);
self
}
pub fn output_file(mut self, path: impl Into<PathBuf>) -> Self {
self.output = Some(OutputConfig::File {
path: path.into(),
rotation: None,
});
self
}
pub fn output_file_rotated(mut self, path: impl Into<PathBuf>, rotation: FileRotation) -> Self {
self.output = Some(OutputConfig::File {
path: path.into(),
rotation: Some(rotation),
});
self
}
pub fn output_stdout(mut self) -> Self {
self.output = Some(OutputConfig::Stdout);
self
}
pub fn output_syslog(mut self, facility: SyslogFacility) -> Self {
self.output = Some(OutputConfig::Syslog { facility });
self
}
pub fn level(mut self, level: LogLevel) -> Self {
let mut filter = self.filter.take().unwrap_or_default();
filter.min_level = level;
self.filter = Some(filter);
self
}
pub fn participant_filter(mut self, pattern: impl Into<String>) -> Self {
let mut filter = self.filter.take().unwrap_or_default();
filter.participant_pattern = Some(pattern.into());
self.filter = Some(filter);
self
}
pub fn topic_filter(mut self, pattern: impl Into<String>) -> Self {
let mut filter = self.filter.take().unwrap_or_default();
filter.topic_pattern = Some(pattern.into());
self.filter = Some(filter);
self
}
pub fn domain_id(mut self, id: u32) -> Self {
self.domain_id = Some(id);
self
}
pub fn topic_pattern(mut self, pattern: impl Into<String>) -> Self {
self.topic_pattern = Some(pattern.into());
self
}
pub fn build(self) -> LogConfig {
LogConfig {
format: self.format.unwrap_or(OutputFormat::Text),
output: self.output.unwrap_or(OutputConfig::Stdout),
filter: self.filter.unwrap_or_default(),
domain_id: self.domain_id.unwrap_or(0),
topic_pattern: self
.topic_pattern
.unwrap_or_else(|| "rt/rosout".to_string()),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
pub enum SyslogFacility {
Kern,
User,
Mail,
Daemon,
Auth,
Syslog,
Lpr,
News,
Uucp,
Cron,
#[default]
Local0,
Local1,
Local2,
Local3,
Local4,
Local5,
Local6,
Local7,
}
impl SyslogFacility {
pub fn code(&self) -> u8 {
match self {
Self::Kern => 0,
Self::User => 1,
Self::Mail => 2,
Self::Daemon => 3,
Self::Auth => 4,
Self::Syslog => 5,
Self::Lpr => 6,
Self::News => 7,
Self::Uucp => 8,
Self::Cron => 9,
Self::Local0 => 16,
Self::Local1 => 17,
Self::Local2 => 18,
Self::Local3 => 19,
Self::Local4 => 20,
Self::Local5 => 21,
Self::Local6 => 22,
Self::Local7 => 23,
}
}
}