From b55a868b9ca32a5c53e94b22e852ace4e5db445c Mon Sep 17 00:00:00 2001 From: emabee Date: Sat, 1 Jun 2024 10:14:10 +0200 Subject: [PATCH] [0.28.1] Introduce `flexi_logger::init()` as super-minimal entry usage. Update dependencies. --- CHANGELOG.md | 6 +++++ Cargo.toml | 8 +++---- README.md | 14 +++++++---- examples/dedup.rs | 4 ++-- src/code_examples.md | 6 +++++ src/flexi_error.rs | 6 ----- src/lib.rs | 28 ++++++++++++++++++++++ src/logger.rs | 35 +++++++++++----------------- src/logger_handle.rs | 22 ++++++++++++----- tests/test_restart_with_no_suffix.rs | 2 +- tests/test_write_modes.rs | 2 +- 11 files changed, 87 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d22463c..19ad288 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.28.1] - 2024-06-01 + +Introduce `flexi_logger::init()` as super-minimal entry usage. + +Update dependencies. + ## [0.28.0] - 2024-03-16 Detach from `lazy_static`, use `std::sync::OnceLock` instead. diff --git a/Cargo.toml b/Cargo.toml index 911f792..5f3f82a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flexi_logger" -version = "0.28.0" +version = "0.28.1" authors = ["emabee "] categories = ["development-tools::debugging"] description = """ @@ -43,15 +43,15 @@ trc = ["async", "specfile", "dep:tracing", "dep:tracing-subscriber"] [dependencies] is-terminal = { version = "0.4", optional = true } -nu-ansi-term = { version = "0.49", optional = true } +nu-ansi-term = { version = "0.50", optional = true } chrono = { version = "0.4.22", default-features = false, features = ["clock"] } crossbeam-channel = { version = "0.5", optional = true } crossbeam-queue = { version = "0.3", optional = true } flate2 = { version = "1.0", optional = true } glob = "0.3" -hostname = { version = "0.3", optional = true } +hostname = { version = "0.4", optional = true } log = { version = "0.4", features = ["std"] } -notify-debouncer-mini = { version = "0.3", optional = true, default-features = false } +notify-debouncer-mini = { version = "0.4.1", optional = true, default-features = false } regex = { version = "1.1", optional = true } serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } diff --git a/README.md b/README.md index 6bafa3e..02df4ab 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ other output streams, and that can be influenced while the program is running.** [![Documentation](https://docs.rs/flexi_logger/badge.svg)](https://docs.rs/flexi_logger) [![License](https://img.shields.io/crates/l/flexi_logger.svg)](https://github.com/emabee/flexi_logger) [![Build](https://img.shields.io/github/actions/workflow/status/emabee/flexi_logger/ci_test.yml?branch=master)](https://github.com/emabee/flexi_logger/actions?query=workflow%3ACI) +[![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) ## Usage @@ -21,12 +22,17 @@ flexi_logger = "0.28" log = "0.4" ``` -To get the log simply written to stderr, add to an early place in your main +To provide the log specification via env variable `RUST_LOG` and get the log written to stderr, +add to an early place in your main: ```rust -use flexi_logger::Logger; +flexi_logger::init(); +``` + +Or, to provide a default log spec programmatically, use -Logger::try_with_str("info, my::critical::module=trace")?.start()?; +```rust +flexi_logger::Logger::try_with_env_or_str("info, my::critical::module=trace")?.start()?; ``` or, to get the log e.g. written with high performance to a file, @@ -40,7 +46,7 @@ let _logger = Logger::try_with_str("info, my::critical::module=trace")? .start()?; ``` -There are many configuration options to e.g. +There are many more configuration options to e.g. * decide whether you want to write your logs to stdout or to a file, * configure the path and the filenames of the log files, diff --git a/examples/dedup.rs b/examples/dedup.rs index 40bc365..82449d0 100644 --- a/examples/dedup.rs +++ b/examples/dedup.rs @@ -6,9 +6,9 @@ use log::Record; use std::{cmp::Ordering, num::NonZeroUsize, sync::Mutex}; fn main() { - #[cfg(colors)] + #[cfg(feature = "colors")] let format = flexi_logger::colored_detailed_format; - #[cfg(not(colors))] + #[cfg(not(feature = "colors"))] let format = flexi_logger::detailed_format; flexi_logger::Logger::try_with_str("info") diff --git a/src/code_examples.md b/src/code_examples.md index a7beccd..4098a29 100644 --- a/src/code_examples.md +++ b/src/code_examples.md @@ -45,6 +45,12 @@ and call `start()` immediately: # Ok(())} ``` +or, even shorter, use: + +```rust +flexi_logger::init(); +``` + After that, you just use the log-macros from the log crate. Those log lines that match the log specification are then written to the default output channel (stderr). diff --git a/src/flexi_error.rs b/src/flexi_error.rs index fba4a25..b72d879 100644 --- a/src/flexi_error.rs +++ b/src/flexi_error.rs @@ -38,12 +38,6 @@ pub enum FlexiLoggerError { )] OutputIo(#[from] std::io::Error), - /// Filesystem notifications for the specfile could not be set up. - #[error("Filesystem notifications for the specfile or the log file could not be set up")] - #[cfg(feature = "notify")] - #[cfg_attr(docsrs, doc(cfg(feature = "notify")))] - Notify(#[from] notify::Error), - /// Parsing the configured logspec toml-file failed. #[error("Parsing the configured logspec toml-file failed")] #[cfg(feature = "specfile_without_notification")] diff --git a/src/lib.rs b/src/lib.rs index 535018e..5fdc107 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ #![deny(missing_docs)] #![deny(clippy::all)] #![deny(clippy::pedantic)] +#![forbid(unsafe_code)] //! A flexible and easy-to-use logger that writes logs to stderr and/or to files //! or other output streams. //! @@ -77,3 +78,30 @@ pub use crate::write_mode::{DEFAULT_MESSAGE_CAPA, DEFAULT_POOL_CAPA}; /// Re-exports from log crate pub use log::{Level, LevelFilter, Record}; + +/// Shortest form to get started. +/// +/// `flexi_logger::init();`. +/// +/// Equivalent to +/// ```rust +/// # use flexi_logger::{Logger,LogSpecification}; +/// Logger::try_with_env_or_str("info") +/// .unwrap_or_else(|_e| Logger::with(LogSpecification::info())) +/// .log_to_stderr() +/// .start() +/// .ok(); +/// ``` +/// that means, +/// +/// - you configure the log specification via the environment variable `RUST_LOG`, +/// or use the default log specification (`'info'`) +/// - logs are directly written to `stderr`, without any buffering, so implicitly dropping the +/// `LogHandle` (which is returned from `Logger::start()`) is ok. +pub fn init() { + Logger::try_with_env_or_str("info") + .unwrap_or_else(|_e| Logger::with(LogSpecification::info())) + .log_to_stderr() + .start() + .ok(); +} diff --git a/src/logger.rs b/src/logger.rs index 6b2356a..0f7f696 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "is-terminal")] +use crate::formats::AdaptiveFormat; use crate::{ filter::LogLineFilter, flexi_logger::FlexiLogger, @@ -9,22 +11,19 @@ use crate::{ Cleanup, Criterion, DeferredNow, FileSpec, FlexiLoggerError, FormatFunction, LogSpecification, LoggerHandle, Naming, WriteMode, }; +#[cfg(feature = "is-terminal")] +use is_terminal::IsTerminal; use log::LevelFilter; +#[cfg(feature = "specfile")] +use std::sync::Mutex; use std::{ collections::HashMap, path::PathBuf, sync::{Arc, RwLock}, time::Duration, }; - -#[cfg(feature = "is-terminal")] -use crate::formats::AdaptiveFormat; -#[cfg(feature = "is-terminal")] -use is_terminal::IsTerminal; - #[cfg(feature = "specfile_without_notification")] use {crate::logger_handle::LogSpecSubscriber, std::io::Read, std::path::Path}; - #[cfg(feature = "specfile")] use { crate::util::{eprint_err, ErrorCode}, @@ -847,10 +846,10 @@ impl Logger { #[cfg(feature = "specfile")] { - handle.ao_specfile_watcher = Some(Arc::new(create_specfile_watcher( + handle.oam_specfile_watcher = Some(Arc::new(Mutex::new(create_specfile_watcher( specfile, handle.writers_handle.clone(), - )?)); + )?))); } Ok((boxed_log, handle)) @@ -871,7 +870,6 @@ pub(crate) fn create_specfile_watcher( let mut debouncer = new_debouncer( std::time::Duration::from_millis(1000), - None, // <--- goes away with notify-debouncer-mini version 0.4 move |res: DebounceEventResult| match res { Ok(events) => events.iter().for_each(|e| { if e.path @@ -894,18 +892,11 @@ pub(crate) fn create_specfile_watcher( .ok(); } }), - Err(errors) => errors.iter().for_each(|e| { - eprint_err( - ErrorCode::LogSpecFile, - "error while watching the specfile", - &e, - ); - }), - // Err(e) => eprint_err( - // ErrorCode::LogSpecFile, - // "error while watching the specfile", - // &e, - // ), + Err(e) => eprint_err( + ErrorCode::LogSpecFile, + "error while watching the specfile", + &e, + ), }, ) .unwrap(); diff --git a/src/logger_handle.rs b/src/logger_handle.rs index 300e260..1b424e7 100644 --- a/src/logger_handle.rs +++ b/src/logger_handle.rs @@ -1,12 +1,13 @@ -#[cfg(feature = "specfile")] -use notify_debouncer_mini::{notify::RecommendedWatcher, Debouncer}; - use crate::{ primary_writer::PrimaryWriter, util::{eprint_err, ErrorCode}, writers::{FileLogWriterBuilder, FileLogWriterConfig, LogWriter}, Duplicate, FlexiLoggerError, LogSpecification, }; +#[cfg(feature = "specfile")] +use notify_debouncer_mini::{notify::RecommendedWatcher, Debouncer}; +#[cfg(feature = "specfile")] +use std::sync::Mutex; use std::{ collections::HashMap, path::PathBuf, @@ -94,10 +95,19 @@ use std::{ /// # } /// ``` #[derive(Clone)] -pub struct LoggerHandle { +pub struct LoggerHandle +where + Self: Send + Sync, + // Note: we demand Send and Sync explicitly because we want to be able to move a + // `LoggerHandle` between threads. + // At least with notify_debouncer_mini version 0.4.1 this would not be given if we omitted + // the Mutex (which we don't need otherwise): we'd then get + // `std::sync::mpsc::Sender` cannot be shared \ + // between threads safely +{ pub(crate) writers_handle: WritersHandle, #[cfg(feature = "specfile")] - pub(crate) ao_specfile_watcher: Option>>, + pub(crate) oam_specfile_watcher: Option>>>, } impl LoggerHandle { pub(crate) fn new( @@ -113,7 +123,7 @@ impl LoggerHandle { other_writers, }, #[cfg(feature = "specfile")] - ao_specfile_watcher: None, + oam_specfile_watcher: None, } } diff --git a/tests/test_restart_with_no_suffix.rs b/tests/test_restart_with_no_suffix.rs index 7be3bf7..df7a370 100644 --- a/tests/test_restart_with_no_suffix.rs +++ b/tests/test_restart_with_no_suffix.rs @@ -20,7 +20,7 @@ fn work(value: u8) { .o_suffix(match value { 0 => None, 1 => Some("log".to_string()), - COUNT..=std::u8::MAX => { + COUNT..=u8::MAX => { unreachable!("got unexpected value {}", value) } }); diff --git a/tests/test_write_modes.rs b/tests/test_write_modes.rs index b9b949e..713abf5 100644 --- a/tests/test_write_modes.rs +++ b/tests/test_write_modes.rs @@ -117,7 +117,7 @@ fn work(value: u8) { ) .write_mode(WriteMode::BufferDontFlush) } - COUNT..=std::u8::MAX => { + COUNT..=u8::MAX => { unreachable!("got unexpected value {}", value) } };