Skip to content

Commit 8dcebae

Browse files
committed
Increase stack sizes for flusher threads from very minimal 128 to 1024 bytes
1 parent cf85859 commit 8dcebae

File tree

10 files changed

+93
-29
lines changed

10 files changed

+93
-29
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this
66
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [unpublished] - 202?-??-??
9+
10+
Add badge for OpenSSF Best Practices.
11+
12+
Increase stack sizes for flusher threads from very minimal 128 to 1024 bytes.
13+
814
## [0.29.4] - 2024-10-21
915

1016
Fix [issue #179](https://github.com/emabee/flexi_logger/issues/179) that in rotation with

docs/Threads in flexi_logger.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Threads in `flexi_logger`
2+
3+
## src/threads.rs
4+
5+
### "flexi_logger-flusher"
6+
7+
* called in Logger::build if NOT WriteMode::Direct, WriteMode::SupportCapture,
8+
WriteMode::BufferDontFlush or WriteMode::BufferDontFlushWith(_) is chosen
9+
* pub(crate) fn start_flusher_thread(
10+
* flushes primary writer and other writers with flush_interval cadence
11+
* stack_size(1024)
12+
13+
### "flexi_logger-async_std_writer"
14+
15+
* only available with feature "async"
16+
* called in constructor of StdWriter if WriteMode::Async or WriteMode::AsyncWith is chosen
17+
* [cfg(feature = "async")] pub(crate) fn start_async_stdwriter(
18+
* flushes, or writes to stdout or stderr
19+
* rust default stack_size = 2 \* 1024 \* 1024
20+
21+
## src/writers/file_log_writer/state.rs
22+
23+
### FLW: "flexi_logger-async_file_writer"
24+
25+
* only available with feature "async"
26+
* Called in intialization of the FLW, if WriteMode::Async or WriteMode::AsyncWith is chosen
27+
* [cfg(feature = "async")] pub(super) fn start_async_fs_writer(
28+
* flushes, or writes to the FLW's buffer
29+
* rust default stack_size = 2 \* 1024 \* 1024
30+
31+
### FLW: "flexi_logger-file_flusher"
32+
33+
* ONLY USED if FLW is used in custom LogWriter implementation
34+
* Called in intialization of the FLW, if WriteMode::Direct, WriteMode::SupportCapture,
35+
WriteMode::BufferDontFlush or WriteMode::BufferDontFlushWith(_) is chosen and if flush_interval > 0
36+
Note that flexi_logger sets flush_interval = 0 for its "embedded" FLW!
37+
* pub(super) fn start_sync_flusher(
38+
* flushes the FLW's file
39+
* stack_size(1024)
40+
41+
### "flexi_logger-fs-async_flusher"
42+
43+
* only available with feature "async"
44+
* Called in intialization of the FLW if WriteMode::Async/With and if flush_interval > 0
45+
* pub(crate) fn start_async_fs_flusher(
46+
* triggers the flush on the "flexi_logger-async_file_writer"
47+
* stack_size(1024)
48+
49+
## src/writers/file_log_writer/state/list_and_cleanup.rs
50+
51+
### "flexi_logger-fs-cleanup"
52+
53+
* only called when explicitly configured
54+
* pub(super) fn start_cleanup_thread(
55+
* calls remove_or_compress_too_old_logfiles_impl
56+
* stack_size(512 * 1024)

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ pub use crate::{
7979
/// Re-exports from log crate
8080
pub use log::{Level, LevelFilter, Record};
8181

82+
pub(crate) const ZERO_DURATION: std::time::Duration = std::time::Duration::from_secs(0);
83+
8284
/// Shortest form to get started.
8385
///
8486
/// `flexi_logger::init();`.

src/logger.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::formats::AdaptiveFormat;
21
#[cfg(feature = "colors")]
32
use crate::set_palette;
43
use crate::{
@@ -12,6 +11,7 @@ use crate::{
1211
Cleanup, Criterion, DeferredNow, FileSpec, FlexiLoggerError, FormatFunction, LogSpecification,
1312
LoggerHandle, Naming, WriteMode,
1413
};
14+
use crate::{formats::AdaptiveFormat, ZERO_DURATION};
1515

1616
use log::LevelFilter;
1717
#[cfg(feature = "specfile")]
@@ -21,7 +21,6 @@ use std::{
2121
io::IsTerminal,
2222
path::PathBuf,
2323
sync::{Arc, RwLock},
24-
time::Duration,
2524
};
2625
#[cfg(feature = "specfile_without_notification")]
2726
use {crate::logger_handle::LogSpecSubscriber, std::io::Read, std::path::Path};
@@ -165,7 +164,7 @@ impl Logger {
165164
format_for_writer: default_format,
166165
#[cfg(feature = "colors")]
167166
o_palette: None,
168-
flush_interval: Duration::from_secs(0),
167+
flush_interval: ZERO_DURATION,
169168
flwb: FileLogWriter::builder(FileSpec::default()),
170169
other_writers: HashMap::<String, Box<dyn LogWriter>>::new(),
171170
filter: None,
@@ -720,7 +719,7 @@ impl Logger {
720719

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

723-
if self.flush_interval.as_secs() != 0 || self.flush_interval.subsec_nanos() != 0 {
722+
if self.flush_interval != ZERO_DURATION {
724723
start_flusher_thread(
725724
Arc::clone(&a_primary_writer),
726725
Arc::clone(&a_other_writers),

src/primary_writer/std_writer.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use {
1010
crate::{
1111
util::{io_err, write_buffered},
1212
writers::LogWriter,
13-
DeferredNow, EffectiveWriteMode, FormatFunction, WriteMode,
13+
DeferredNow, EffectiveWriteMode, FormatFunction, WriteMode, ZERO_DURATION,
1414
},
1515
log::Record,
1616
std::io::{BufWriter, Write},
@@ -94,7 +94,7 @@ impl StdWriter {
9494
#[cfg(test)]
9595
let validation_buffer = Arc::new(Mutex::new(Cursor::new(Vec::<u8>::new())));
9696

97-
let writer = match write_mode.inner() {
97+
let writer = match write_mode.effective_write_mode() {
9898
EffectiveWriteMode::Direct => InnerStdWriter::Unbuffered(stdstream),
9999
EffectiveWriteMode::BufferDontFlushWith(capacity) => {
100100
InnerStdWriter::Buffered(Mutex::new(BufWriter::with_capacity(capacity, stdstream)))
@@ -109,8 +109,7 @@ impl StdWriter {
109109
flush_interval,
110110
} => {
111111
assert_eq!(
112-
flush_interval,
113-
std::time::Duration::from_secs(0),
112+
flush_interval, ZERO_DURATION,
114113
"Async InnerStdWriter with own flushing is not implemented"
115114
);
116115
InnerStdWriter::Async(AsyncHandle::new(

src/threads.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub(crate) fn start_flusher_thread(
3737
) -> Result<(), FlexiLoggerError> {
3838
let builder = ThreadBuilder::new().name(FLUSHER.to_string());
3939
#[cfg(not(feature = "dont_minimize_extra_stacks"))]
40-
let builder = builder.stack_size(128);
40+
let builder = builder.stack_size(1024);
4141

4242
builder.spawn(move || {
4343
let (_sender, receiver): (Sender<()>, Receiver<()>) = channel();

src/write_mode.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::ZERO_DURATION;
12
use std::time::Duration;
23

34
/// Default buffer capacity (8k), when buffering is used.
@@ -45,10 +46,10 @@ pub const DEFAULT_MESSAGE_CAPA: usize = 200;
4546
/// is dropped (and all output is flushed automatically).
4647
///
4748
/// `WriteMode::Direct` (i.e. without buffering) is the slowest option with all output devices,
48-
/// showing that buffered I/O pays off. But it takes slightly more resources, especially
49-
/// if you do not suppress flushing.
49+
/// showing that buffered I/O pays off.
5050
///
51-
/// Using `log_to_stdout()` and then redirecting the output to a file makes things faster,
51+
/// Using `log_to_stdout()` and then redirecting the output to a file can make things faster,
52+
/// likely because the operating system's adds buffering,
5253
/// but is still significantly slower than writing to files directly.
5354
///
5455
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -115,7 +116,7 @@ pub enum WriteMode {
115116
},
116117
}
117118
impl WriteMode {
118-
pub(crate) fn inner(&self) -> EffectiveWriteMode {
119+
pub(crate) fn effective_write_mode(&self) -> EffectiveWriteMode {
119120
match *self {
120121
Self::Direct | Self::SupportCapture => EffectiveWriteMode::Direct,
121122
Self::BufferDontFlush => {
@@ -158,7 +159,7 @@ impl WriteMode {
158159
Self::Async => Self::AsyncWith {
159160
pool_capa: DEFAULT_POOL_CAPA,
160161
message_capa: DEFAULT_MESSAGE_CAPA,
161-
flush_interval: Duration::from_secs(0),
162+
flush_interval: ZERO_DURATION,
162163
},
163164
#[cfg(feature = "async")]
164165
Self::AsyncWith {
@@ -168,12 +169,12 @@ impl WriteMode {
168169
} => Self::AsyncWith {
169170
pool_capa: *pool_capa,
170171
message_capa: *message_capa,
171-
flush_interval: Duration::from_secs(0),
172+
flush_interval: ZERO_DURATION,
172173
},
173174
}
174175
}
175176
pub(crate) fn buffersize(&self) -> Option<usize> {
176-
match self.inner() {
177+
match self.effective_write_mode() {
177178
EffectiveWriteMode::Direct => None,
178179
EffectiveWriteMode::BufferAndFlushWith(bufsize)
179180
| EffectiveWriteMode::BufferDontFlushWith(bufsize) => Some(bufsize),
@@ -190,7 +191,7 @@ impl WriteMode {
190191
Self::Direct
191192
| Self::SupportCapture
192193
| Self::BufferDontFlush
193-
| Self::BufferDontFlushWith(_) => Duration::from_secs(0),
194+
| Self::BufferDontFlushWith(_) => ZERO_DURATION,
194195
Self::BufferAndFlush => DEFAULT_FLUSH_INTERVAL,
195196
#[cfg(feature = "async")]
196197
Self::Async => DEFAULT_FLUSH_INTERVAL,

src/writers/file_log_writer.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ impl FileLogWriter {
3636
max_log_level: log::LevelFilter,
3737
format_function: FormatFunction,
3838
) -> FileLogWriter {
39-
let state_handle = match state.config().write_mode.inner() {
39+
let state_handle = match state.config().write_mode.effective_write_mode() {
4040
EffectiveWriteMode::Direct
4141
| EffectiveWriteMode::BufferAndFlushWith(_)
4242
| EffectiveWriteMode::BufferDontFlushWith(_) => {
@@ -199,6 +199,7 @@ impl Drop for FileLogWriter {
199199

200200
#[cfg(test)]
201201
mod test {
202+
use crate::ZERO_DURATION;
202203
use crate::{writers::LogWriter, Cleanup, Criterion, DeferredNow, FileSpec, Naming, WriteMode};
203204
use chrono::Local;
204205
use std::ops::Add;
@@ -402,7 +403,7 @@ mod test {
402403
let flwb = flwb.write_mode(WriteMode::AsyncWith {
403404
pool_capa: 5,
404405
message_capa: 400,
405-
flush_interval: Duration::from_secs(0),
406+
flush_interval: ZERO_DURATION,
406407
});
407408

408409
let flw = flwb.try_build().unwrap();
@@ -458,7 +459,7 @@ mod test {
458459
let write_mode = WriteMode::AsyncWith {
459460
pool_capa: 7,
460461
message_capa: 8,
461-
flush_interval: Duration::from_secs(0),
462+
flush_interval: ZERO_DURATION,
462463
};
463464
let flw = super::FileLogWriter::builder(
464465
FileSpec::default()

src/writers/file_log_writer/state.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ mod numbers;
33
mod timestamps;
44

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

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

3436
const CURRENT_INFIX: &str = "rCURRENT";
3537

@@ -688,9 +690,9 @@ pub(super) fn start_async_fs_writer(
688690
}
689691

690692
pub(super) fn start_sync_flusher(am_state: Arc<Mutex<State>>, flush_interval: std::time::Duration) {
691-
let builder = std::thread::Builder::new().name("flexi_logger-flusher".to_string());
693+
let builder = std::thread::Builder::new().name("flexi_logger-file_flusher".to_string());
692694
#[cfg(not(feature = "dont_minimize_extra_stacks"))]
693-
let builder = builder.stack_size(128);
695+
let builder = builder.stack_size(1024);
694696
builder.spawn(move || {
695697
let (_tx, rx) = std::sync::mpsc::channel::<()>();
696698
loop {
@@ -711,11 +713,9 @@ pub(crate) fn start_async_fs_flusher(
711713
async_writer: CrossbeamSender<Vec<u8>>,
712714
flush_interval: std::time::Duration,
713715
) {
714-
use crate::util::eprint_msg;
715-
716716
let builder = std::thread::Builder::new().name(ASYNC_FLUSHER.to_string());
717717
#[cfg(not(feature = "dont_minimize_extra_stacks"))]
718-
let builder = builder.stack_size(128);
718+
let builder = builder.stack_size(1024);
719719
builder.spawn(move || {
720720
let (_tx, rx) = std::sync::mpsc::channel::<()>();
721721
loop {

src/writers/file_log_writer/state_handle.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use super::{builder::FileLogWriterBuilder, config::FileLogWriterConfig, state::S
33
use crate::util::{ASYNC_FLUSH, ASYNC_SHUTDOWN};
44
use crate::{
55
util::{buffer_with, eprint_err, io_err, ErrorCode},
6-
LogfileSelector,
6+
LogfileSelector, ZERO_DURATION,
77
};
88
use crate::{DeferredNow, FlexiLoggerError, FormatFunction};
99
use log::Record;
@@ -35,7 +35,7 @@ impl SyncHandle {
3535
let flush_interval = state.config().write_mode.get_flush_interval();
3636
let am_state = Arc::new(Mutex::new(state));
3737

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

@@ -85,7 +85,7 @@ impl AsyncHandle {
8585
Arc::clone(&a_pool),
8686
);
8787

88-
if flush_interval != std::time::Duration::from_secs(0) {
88+
if flush_interval != ZERO_DURATION {
8989
super::state::start_async_fs_flusher(sender.clone(), flush_interval);
9090
}
9191

0 commit comments

Comments
 (0)