Skip to content

Commit

Permalink
Increase stack sizes for flusher threads from very minimal 128 to 102…
Browse files Browse the repository at this point in the history
…4 bytes
  • Loading branch information
emabee committed Oct 23, 2024
1 parent cf85859 commit 8dcebae
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 29 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

## [unpublished] - 202?-??-??

Add badge for OpenSSF Best Practices.

Increase stack sizes for flusher threads from very minimal 128 to 1024 bytes.

## [0.29.4] - 2024-10-21

Fix [issue #179](https://github.com/emabee/flexi_logger/issues/179) that in rotation with
Expand Down
56 changes: 56 additions & 0 deletions docs/Threads in flexi_logger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Threads in `flexi_logger`

## src/threads.rs

### "flexi_logger-flusher"

* called in Logger::build if NOT WriteMode::Direct, WriteMode::SupportCapture,
WriteMode::BufferDontFlush or WriteMode::BufferDontFlushWith(_) is chosen
* pub(crate) fn start_flusher_thread(
* flushes primary writer and other writers with flush_interval cadence
* stack_size(1024)

### "flexi_logger-async_std_writer"

* only available with feature "async"
* called in constructor of StdWriter if WriteMode::Async or WriteMode::AsyncWith is chosen
* [cfg(feature = "async")] pub(crate) fn start_async_stdwriter(
* flushes, or writes to stdout or stderr
* rust default stack_size = 2 \* 1024 \* 1024

## src/writers/file_log_writer/state.rs

### FLW: "flexi_logger-async_file_writer"

* only available with feature "async"
* Called in intialization of the FLW, if WriteMode::Async or WriteMode::AsyncWith is chosen
* [cfg(feature = "async")] pub(super) fn start_async_fs_writer(
* flushes, or writes to the FLW's buffer
* rust default stack_size = 2 \* 1024 \* 1024

### FLW: "flexi_logger-file_flusher"

* ONLY USED if FLW is used in custom LogWriter implementation
* Called in intialization of the FLW, if WriteMode::Direct, WriteMode::SupportCapture,
WriteMode::BufferDontFlush or WriteMode::BufferDontFlushWith(_) is chosen and if flush_interval > 0
Note that flexi_logger sets flush_interval = 0 for its "embedded" FLW!
* pub(super) fn start_sync_flusher(
* flushes the FLW's file
* stack_size(1024)

### "flexi_logger-fs-async_flusher"

* only available with feature "async"
* Called in intialization of the FLW if WriteMode::Async/With and if flush_interval > 0
* pub(crate) fn start_async_fs_flusher(
* triggers the flush on the "flexi_logger-async_file_writer"
* stack_size(1024)

## src/writers/file_log_writer/state/list_and_cleanup.rs

### "flexi_logger-fs-cleanup"

* only called when explicitly configured
* pub(super) fn start_cleanup_thread(
* calls remove_or_compress_too_old_logfiles_impl
* stack_size(512 * 1024)
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub use crate::{
/// Re-exports from log crate
pub use log::{Level, LevelFilter, Record};

pub(crate) const ZERO_DURATION: std::time::Duration = std::time::Duration::from_secs(0);

/// Shortest form to get started.
///
/// `flexi_logger::init();`.
Expand Down
7 changes: 3 additions & 4 deletions src/logger.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::formats::AdaptiveFormat;
#[cfg(feature = "colors")]
use crate::set_palette;
use crate::{
Expand All @@ -12,6 +11,7 @@ use crate::{
Cleanup, Criterion, DeferredNow, FileSpec, FlexiLoggerError, FormatFunction, LogSpecification,
LoggerHandle, Naming, WriteMode,
};
use crate::{formats::AdaptiveFormat, ZERO_DURATION};

use log::LevelFilter;
#[cfg(feature = "specfile")]
Expand All @@ -21,7 +21,6 @@ use std::{
io::IsTerminal,
path::PathBuf,
sync::{Arc, RwLock},
time::Duration,
};
#[cfg(feature = "specfile_without_notification")]
use {crate::logger_handle::LogSpecSubscriber, std::io::Read, std::path::Path};
Expand Down Expand Up @@ -165,7 +164,7 @@ impl Logger {
format_for_writer: default_format,
#[cfg(feature = "colors")]
o_palette: None,
flush_interval: Duration::from_secs(0),
flush_interval: ZERO_DURATION,
flwb: FileLogWriter::builder(FileSpec::default()),
other_writers: HashMap::<String, Box<dyn LogWriter>>::new(),
filter: None,
Expand Down Expand Up @@ -720,7 +719,7 @@ impl Logger {

let a_other_writers = Arc::new(self.other_writers);

if self.flush_interval.as_secs() != 0 || self.flush_interval.subsec_nanos() != 0 {
if self.flush_interval != ZERO_DURATION {
start_flusher_thread(
Arc::clone(&a_primary_writer),
Arc::clone(&a_other_writers),
Expand Down
7 changes: 3 additions & 4 deletions src/primary_writer/std_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use {
crate::{
util::{io_err, write_buffered},
writers::LogWriter,
DeferredNow, EffectiveWriteMode, FormatFunction, WriteMode,
DeferredNow, EffectiveWriteMode, FormatFunction, WriteMode, ZERO_DURATION,

Check warning on line 13 in src/primary_writer/std_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (ubuntu-latest, stable)

unused import: `ZERO_DURATION`

Check warning on line 13 in src/primary_writer/std_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (ubuntu-latest, 1.70.0)

unused import: `ZERO_DURATION`

Check warning on line 13 in src/primary_writer/std_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (windows-latest, stable)

unused import: `ZERO_DURATION`

Check warning on line 13 in src/primary_writer/std_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (macos-latest, stable)

unused import: `ZERO_DURATION`

Check warning on line 13 in src/primary_writer/std_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (windows-latest, 1.70.0)

unused import: `ZERO_DURATION`

Check warning on line 13 in src/primary_writer/std_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (macos-latest, 1.70.0)

unused import: `ZERO_DURATION`
},
log::Record,
std::io::{BufWriter, Write},
Expand Down Expand Up @@ -94,7 +94,7 @@ impl StdWriter {
#[cfg(test)]
let validation_buffer = Arc::new(Mutex::new(Cursor::new(Vec::<u8>::new())));

let writer = match write_mode.inner() {
let writer = match write_mode.effective_write_mode() {
EffectiveWriteMode::Direct => InnerStdWriter::Unbuffered(stdstream),
EffectiveWriteMode::BufferDontFlushWith(capacity) => {
InnerStdWriter::Buffered(Mutex::new(BufWriter::with_capacity(capacity, stdstream)))
Expand All @@ -109,8 +109,7 @@ impl StdWriter {
flush_interval,
} => {
assert_eq!(
flush_interval,
std::time::Duration::from_secs(0),
flush_interval, ZERO_DURATION,
"Async InnerStdWriter with own flushing is not implemented"
);
InnerStdWriter::Async(AsyncHandle::new(
Expand Down
2 changes: 1 addition & 1 deletion src/threads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub(crate) fn start_flusher_thread(
) -> Result<(), FlexiLoggerError> {
let builder = ThreadBuilder::new().name(FLUSHER.to_string());
#[cfg(not(feature = "dont_minimize_extra_stacks"))]
let builder = builder.stack_size(128);
let builder = builder.stack_size(1024);

builder.spawn(move || {
let (_sender, receiver): (Sender<()>, Receiver<()>) = channel();
Expand Down
17 changes: 9 additions & 8 deletions src/write_mode.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::ZERO_DURATION;
use std::time::Duration;

/// Default buffer capacity (8k), when buffering is used.
Expand Down Expand Up @@ -45,10 +46,10 @@ pub const DEFAULT_MESSAGE_CAPA: usize = 200;
/// is dropped (and all output is flushed automatically).
///
/// `WriteMode::Direct` (i.e. without buffering) is the slowest option with all output devices,
/// showing that buffered I/O pays off. But it takes slightly more resources, especially
/// if you do not suppress flushing.
/// showing that buffered I/O pays off.
///
/// Using `log_to_stdout()` and then redirecting the output to a file makes things faster,
/// Using `log_to_stdout()` and then redirecting the output to a file can make things faster,
/// likely because the operating system's adds buffering,
/// but is still significantly slower than writing to files directly.
///
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -115,7 +116,7 @@ pub enum WriteMode {
},
}
impl WriteMode {
pub(crate) fn inner(&self) -> EffectiveWriteMode {
pub(crate) fn effective_write_mode(&self) -> EffectiveWriteMode {
match *self {
Self::Direct | Self::SupportCapture => EffectiveWriteMode::Direct,
Self::BufferDontFlush => {
Expand Down Expand Up @@ -158,7 +159,7 @@ impl WriteMode {
Self::Async => Self::AsyncWith {
pool_capa: DEFAULT_POOL_CAPA,
message_capa: DEFAULT_MESSAGE_CAPA,
flush_interval: Duration::from_secs(0),
flush_interval: ZERO_DURATION,
},
#[cfg(feature = "async")]
Self::AsyncWith {
Expand All @@ -168,12 +169,12 @@ impl WriteMode {
} => Self::AsyncWith {
pool_capa: *pool_capa,
message_capa: *message_capa,
flush_interval: Duration::from_secs(0),
flush_interval: ZERO_DURATION,
},
}
}
pub(crate) fn buffersize(&self) -> Option<usize> {
match self.inner() {
match self.effective_write_mode() {
EffectiveWriteMode::Direct => None,
EffectiveWriteMode::BufferAndFlushWith(bufsize)
| EffectiveWriteMode::BufferDontFlushWith(bufsize) => Some(bufsize),
Expand All @@ -190,7 +191,7 @@ impl WriteMode {
Self::Direct
| Self::SupportCapture
| Self::BufferDontFlush
| Self::BufferDontFlushWith(_) => Duration::from_secs(0),
| Self::BufferDontFlushWith(_) => ZERO_DURATION,
Self::BufferAndFlush => DEFAULT_FLUSH_INTERVAL,
#[cfg(feature = "async")]
Self::Async => DEFAULT_FLUSH_INTERVAL,
Expand Down
7 changes: 4 additions & 3 deletions src/writers/file_log_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl FileLogWriter {
max_log_level: log::LevelFilter,
format_function: FormatFunction,
) -> FileLogWriter {
let state_handle = match state.config().write_mode.inner() {
let state_handle = match state.config().write_mode.effective_write_mode() {
EffectiveWriteMode::Direct
| EffectiveWriteMode::BufferAndFlushWith(_)
| EffectiveWriteMode::BufferDontFlushWith(_) => {
Expand Down Expand Up @@ -199,6 +199,7 @@ impl Drop for FileLogWriter {

#[cfg(test)]
mod test {
use crate::ZERO_DURATION;

Check warning on line 202 in src/writers/file_log_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (windows-latest, stable)

unused import: `crate::ZERO_DURATION`

Check warning on line 202 in src/writers/file_log_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (macos-latest, stable)

unused import: `crate::ZERO_DURATION`

Check warning on line 202 in src/writers/file_log_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (windows-latest, 1.70.0)

unused import: `crate::ZERO_DURATION`

Check warning on line 202 in src/writers/file_log_writer.rs

View workflow job for this annotation

GitHub Actions / Build and test (macos-latest, 1.70.0)

unused import: `crate::ZERO_DURATION`
use crate::{writers::LogWriter, Cleanup, Criterion, DeferredNow, FileSpec, Naming, WriteMode};
use chrono::Local;
use std::ops::Add;
Expand Down Expand Up @@ -402,7 +403,7 @@ mod test {
let flwb = flwb.write_mode(WriteMode::AsyncWith {
pool_capa: 5,
message_capa: 400,
flush_interval: Duration::from_secs(0),
flush_interval: ZERO_DURATION,
});

let flw = flwb.try_build().unwrap();
Expand Down Expand Up @@ -458,7 +459,7 @@ mod test {
let write_mode = WriteMode::AsyncWith {
pool_capa: 7,
message_capa: 8,
flush_interval: Duration::from_secs(0),
flush_interval: ZERO_DURATION,
};
let flw = super::FileLogWriter::builder(
FileSpec::default()
Expand Down
12 changes: 6 additions & 6 deletions src/writers/file_log_writer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ mod numbers;
mod timestamps;

use super::config::{FileLogWriterConfig, RotationConfig};
#[cfg(feature = "async")]
use crate::util::eprint_msg;
use crate::{
util::{eprint_err, ErrorCode},
Age, Cleanup, Criterion, FlexiLoggerError, LogfileSelector, Naming,
Expand All @@ -29,7 +31,7 @@ use {
};

#[cfg(feature = "async")]
const ASYNC_WRITER: &str = "flexi_logger-fs-async_writer";
const ASYNC_WRITER: &str = "flexi_logger-async_file_writer";

const CURRENT_INFIX: &str = "rCURRENT";

Expand Down Expand Up @@ -688,9 +690,9 @@ pub(super) fn start_async_fs_writer(
}

pub(super) fn start_sync_flusher(am_state: Arc<Mutex<State>>, flush_interval: std::time::Duration) {
let builder = std::thread::Builder::new().name("flexi_logger-flusher".to_string());
let builder = std::thread::Builder::new().name("flexi_logger-file_flusher".to_string());
#[cfg(not(feature = "dont_minimize_extra_stacks"))]
let builder = builder.stack_size(128);
let builder = builder.stack_size(1024);
builder.spawn(move || {
let (_tx, rx) = std::sync::mpsc::channel::<()>();
loop {
Expand All @@ -711,11 +713,9 @@ pub(crate) fn start_async_fs_flusher(
async_writer: CrossbeamSender<Vec<u8>>,
flush_interval: std::time::Duration,
) {
use crate::util::eprint_msg;

let builder = std::thread::Builder::new().name(ASYNC_FLUSHER.to_string());
#[cfg(not(feature = "dont_minimize_extra_stacks"))]
let builder = builder.stack_size(128);
let builder = builder.stack_size(1024);
builder.spawn(move || {
let (_tx, rx) = std::sync::mpsc::channel::<()>();
loop {
Expand Down
6 changes: 3 additions & 3 deletions src/writers/file_log_writer/state_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use super::{builder::FileLogWriterBuilder, config::FileLogWriterConfig, state::S
use crate::util::{ASYNC_FLUSH, ASYNC_SHUTDOWN};
use crate::{
util::{buffer_with, eprint_err, io_err, ErrorCode},
LogfileSelector,
LogfileSelector, ZERO_DURATION,
};
use crate::{DeferredNow, FlexiLoggerError, FormatFunction};
use log::Record;
Expand Down Expand Up @@ -35,7 +35,7 @@ impl SyncHandle {
let flush_interval = state.config().write_mode.get_flush_interval();
let am_state = Arc::new(Mutex::new(state));

if flush_interval.as_secs() != 0 || flush_interval.subsec_nanos() != 0 {
if flush_interval != ZERO_DURATION {
super::state::start_sync_flusher(Arc::clone(&am_state), flush_interval);
}

Expand Down Expand Up @@ -85,7 +85,7 @@ impl AsyncHandle {
Arc::clone(&a_pool),
);

if flush_interval != std::time::Duration::from_secs(0) {
if flush_interval != ZERO_DURATION {
super::state::start_async_fs_flusher(sender.clone(), flush_interval);
}

Expand Down

0 comments on commit 8dcebae

Please sign in to comment.