Skip to main content

LogBuilder

Struct LogBuilder 

Source
pub struct LogBuilder<'a> { /* private fields */ }
Expand description

Fluent, component-scoped log emitter with an immutable per-event override.

Implementations§

Source§

impl<'a> LogBuilder<'a>

Source

pub fn component(&self, component: impl Into<Cow<'a, str>>) -> Self

Replaces the stable component used for filtering and rendering.

Source

pub fn verbosity(&self, verbosity: u8) -> Self

Sets a V1–V9 threshold for this event; invalid values retain V4.

Use Self::try_verbosity when invalid configuration must be reported.

Examples found in repository?
examples/component_filter.rs (line 31)
19fn main() {
20    // All components start at V4, keeping normal output concise.
21    let mut policy = LogPolicy::new(Verbosity::V4);
22
23    // Synchronization may need temporary I/O and timing diagnostics.
24    policy.set_component("sync", Verbosity::V8);
25
26    let log = LogDispatcher::new(policy, vec![Arc::new(ConsoleSink::new())]);
27
28    let event = log.event(0, "sync");
29
30    // This V7 event is selected only because the sync override allows it.
31    event.verbosity(7).debug("batch details");
32}
More examples
Hide additional examples
examples/sensitive_diagnostics.rs (line 50)
24fn main() -> Result<(), appcore_log::LogError> {
25    let key_id = KeyId::new("example-log-key").map_err(|_| appcore_log::LogError::Encryption)?;
26
27    let provider =
28        StaticDntKeyProvider::new().with_key(key_id.clone(), SecretKey::new(demo_key()?));
29
30    // The sink bounds the encrypted snapshot by both bytes and event count.
31    let sink = SensitiveDntSink::new(
32        SensitiveDntSinkConfig {
33            path: std::env::temp_dir().join("appcore-sensitive-log.dnt"),
34            application_id: ApplicationId::new("example-log")
35                .map_err(|_| appcore_log::LogError::Encryption)?,
36            key_id,
37            max_bytes: 4096,
38            max_events: 8,
39            retention: 2,
40        },
41        provider,
42    )?;
43
44    // Sensitive mode must be explicit and has no console or JSONL fallback.
45    let mut policy = LogPolicy::default();
46    policy.sensitivity = Sensitivity::Sensitive;
47
48    let log = LogDispatcher::new(policy, vec![Arc::new(sink)]);
49
50    log.event(0, "security").verbosity(2).error("diagnostic");
51
52    Ok(())
53}
examples/file_logging.rs (line 58)
22fn main() -> Result<(), appcore_log::LogConfigError> {
23    // Keep generated output predictable and inside Cargo's ignored target tree.
24    let output_directory = PathBuf::from("target/appcore-log-example");
25    std::fs::create_dir_all(&output_directory).map_err(|_| LogConfigError::Sink(LogError::Io))?;
26
27    let active_file = output_directory.join("application.jsonl");
28
29    // Two rotations stay beside the active file. Older rotations move into
30    // archive/YYYY/MM and the complete archive never exceeds 120 files.
31    let archive_directory = output_directory.join("archive");
32    let mut policy = LogPolicy::new(Verbosity::V4);
33    policy.set_component("sync", Verbosity::V8);
34
35    let logger = LoggerConfig {
36        policy,
37        output: LogOutputMode::TerminalAndFile,
38        file: Some(FileSinkConfig {
39            path: active_file,
40            max_bytes: LOG_SIZE_8_MIB,
41            sync_each_write: false,
42            retention: 2,
43            archive: Some(FileArchiveConfig {
44                directory: archive_directory,
45                max_files: 120,
46            }),
47        }),
48        ..LoggerConfig::default()
49    }
50    .build()?;
51
52    let application = logger.dispatcher().event(0, "application");
53    let sync = logger.dispatcher().event(1, "sync.transport");
54
55    application.info("application ready; inspect target/appcore-log-example/application.jsonl");
56
57    // The parent component policy makes this V7 diagnostic visible.
58    sync.verbosity(7).debug("replication batch sent");
59
60    sync.warn("peer response was delayed");
61
62    let stats = logger.dispatcher().stats();
63    assert_eq!(stats.sink_failures, 0);
64
65    Ok(())
66}
Source

pub fn try_verbosity(&self, verbosity: u8) -> Result<Self, VerbosityError>

Sets a V1–V9 threshold and returns invalid configuration explicitly.

Source

pub fn trace(&self, message: impl Into<String>)

Emits a trace event.

Source

pub fn debug(&self, message: impl Into<String>)

Emits a debug event.

Examples found in repository?
examples/component_filter.rs (line 31)
19fn main() {
20    // All components start at V4, keeping normal output concise.
21    let mut policy = LogPolicy::new(Verbosity::V4);
22
23    // Synchronization may need temporary I/O and timing diagnostics.
24    policy.set_component("sync", Verbosity::V8);
25
26    let log = LogDispatcher::new(policy, vec![Arc::new(ConsoleSink::new())]);
27
28    let event = log.event(0, "sync");
29
30    // This V7 event is selected only because the sync override allows it.
31    event.verbosity(7).debug("batch details");
32}
More examples
Hide additional examples
examples/file_logging.rs (line 58)
22fn main() -> Result<(), appcore_log::LogConfigError> {
23    // Keep generated output predictable and inside Cargo's ignored target tree.
24    let output_directory = PathBuf::from("target/appcore-log-example");
25    std::fs::create_dir_all(&output_directory).map_err(|_| LogConfigError::Sink(LogError::Io))?;
26
27    let active_file = output_directory.join("application.jsonl");
28
29    // Two rotations stay beside the active file. Older rotations move into
30    // archive/YYYY/MM and the complete archive never exceeds 120 files.
31    let archive_directory = output_directory.join("archive");
32    let mut policy = LogPolicy::new(Verbosity::V4);
33    policy.set_component("sync", Verbosity::V8);
34
35    let logger = LoggerConfig {
36        policy,
37        output: LogOutputMode::TerminalAndFile,
38        file: Some(FileSinkConfig {
39            path: active_file,
40            max_bytes: LOG_SIZE_8_MIB,
41            sync_each_write: false,
42            retention: 2,
43            archive: Some(FileArchiveConfig {
44                directory: archive_directory,
45                max_files: 120,
46            }),
47        }),
48        ..LoggerConfig::default()
49    }
50    .build()?;
51
52    let application = logger.dispatcher().event(0, "application");
53    let sync = logger.dispatcher().event(1, "sync.transport");
54
55    application.info("application ready; inspect target/appcore-log-example/application.jsonl");
56
57    // The parent component policy makes this V7 diagnostic visible.
58    sync.verbosity(7).debug("replication batch sent");
59
60    sync.warn("peer response was delayed");
61
62    let stats = logger.dispatcher().stats();
63    assert_eq!(stats.sink_failures, 0);
64
65    Ok(())
66}
Source

pub fn info(&self, message: impl Into<String>)

Emits an informational event.

Examples found in repository?
examples/basic.rs (line 29)
18fn main() -> Result<(), appcore_log::LogConfigError> {
19    // Safe V4 terminal logging is explicit and creates no global state.
20    let logger = LoggerConfig {
21        output: LogOutputMode::Terminal,
22        ..LoggerConfig::default()
23    }
24    .build()?;
25
26    // The builder defaults to V4 and can be kept for related events.
27    let log = logger.dispatcher().event(0, "application");
28
29    log.info("application started");
30    log.warn("connection is slower than expected");
31    log.error("document could not be saved");
32
33    Ok(())
34}
More examples
Hide additional examples
examples/output_modes.rs (line 36)
15fn main() -> Result<(), appcore_log::LogConfigError> {
16    // Replace this with Disabled, Terminal, File, TerminalAndFile or CrashOnly.
17    let output = LogOutputMode::CrashOnly;
18
19    let logger = LoggerConfig {
20        output,
21        file: Some(FileSinkConfig {
22            path: std::env::temp_dir().join("my-application-crash.jsonl"),
23            max_bytes: LOG_SIZE_2_MIB,
24            sync_each_write: true,
25            retention: 1,
26            archive: None,
27        }),
28        crash_events: 128,
29        crash_bytes: 512 * 1024,
30        ..LoggerConfig::default()
31    }
32    .build()?;
33
34    let log = logger.dispatcher().event(0, "application");
35
36    log.info("kept only in the bounded crash ring");
37
38    // Call this from the application's panic/crash boundary. In every other
39    // mode it is a no-op and returns zero.
40    let _written_events = logger.dump_crash()?;
41
42    Ok(())
43}
examples/async_file.rs (line 43)
19fn main() -> Result<(), LogError> {
20    let directory = std::path::PathBuf::from("target/appcore-log-example");
21    std::fs::create_dir_all(&directory).map_err(|_| LogError::Io)?;
22
23    let path = directory.join("async.jsonl");
24    let file = Arc::new(FileSink::new(FileSinkConfig {
25        path: path.clone(),
26        max_bytes: LOG_SIZE_8_MIB,
27        sync_each_write: true,
28        retention: 2,
29        archive: None,
30    })?);
31
32    // This queue retains at most 256 events and 1 MiB, including active I/O.
33    let asynchronous = Arc::new(AsyncSink::new(
34        AsyncSinkConfig {
35            max_events: 256,
36            max_bytes: 1024 * 1024,
37        },
38        file,
39    )?);
40    let dispatcher = LogDispatcher::new(LogPolicy::default(), vec![asynchronous.clone()]);
41    let log = dispatcher.event(0, "application");
42
43    log.info("application started");
44    log.warn("storage response is slow");
45
46    // The lifecycle owner drains durable writes before exiting.
47    asynchronous.shutdown()?;
48    let path = std::fs::canonicalize(path).map_err(|_| LogError::Io)?;
49    println!("log written to {}", path.display());
50    Ok(())
51}
examples/file_logging.rs (line 55)
22fn main() -> Result<(), appcore_log::LogConfigError> {
23    // Keep generated output predictable and inside Cargo's ignored target tree.
24    let output_directory = PathBuf::from("target/appcore-log-example");
25    std::fs::create_dir_all(&output_directory).map_err(|_| LogConfigError::Sink(LogError::Io))?;
26
27    let active_file = output_directory.join("application.jsonl");
28
29    // Two rotations stay beside the active file. Older rotations move into
30    // archive/YYYY/MM and the complete archive never exceeds 120 files.
31    let archive_directory = output_directory.join("archive");
32    let mut policy = LogPolicy::new(Verbosity::V4);
33    policy.set_component("sync", Verbosity::V8);
34
35    let logger = LoggerConfig {
36        policy,
37        output: LogOutputMode::TerminalAndFile,
38        file: Some(FileSinkConfig {
39            path: active_file,
40            max_bytes: LOG_SIZE_8_MIB,
41            sync_each_write: false,
42            retention: 2,
43            archive: Some(FileArchiveConfig {
44                directory: archive_directory,
45                max_files: 120,
46            }),
47        }),
48        ..LoggerConfig::default()
49    }
50    .build()?;
51
52    let application = logger.dispatcher().event(0, "application");
53    let sync = logger.dispatcher().event(1, "sync.transport");
54
55    application.info("application ready; inspect target/appcore-log-example/application.jsonl");
56
57    // The parent component policy makes this V7 diagnostic visible.
58    sync.verbosity(7).debug("replication batch sent");
59
60    sync.warn("peer response was delayed");
61
62    let stats = logger.dispatcher().stats();
63    assert_eq!(stats.sink_failures, 0);
64
65    Ok(())
66}
Source

pub fn warn(&self, message: impl Into<String>)

Emits a warning event.

Examples found in repository?
examples/basic.rs (line 30)
18fn main() -> Result<(), appcore_log::LogConfigError> {
19    // Safe V4 terminal logging is explicit and creates no global state.
20    let logger = LoggerConfig {
21        output: LogOutputMode::Terminal,
22        ..LoggerConfig::default()
23    }
24    .build()?;
25
26    // The builder defaults to V4 and can be kept for related events.
27    let log = logger.dispatcher().event(0, "application");
28
29    log.info("application started");
30    log.warn("connection is slower than expected");
31    log.error("document could not be saved");
32
33    Ok(())
34}
More examples
Hide additional examples
examples/async_file.rs (line 44)
19fn main() -> Result<(), LogError> {
20    let directory = std::path::PathBuf::from("target/appcore-log-example");
21    std::fs::create_dir_all(&directory).map_err(|_| LogError::Io)?;
22
23    let path = directory.join("async.jsonl");
24    let file = Arc::new(FileSink::new(FileSinkConfig {
25        path: path.clone(),
26        max_bytes: LOG_SIZE_8_MIB,
27        sync_each_write: true,
28        retention: 2,
29        archive: None,
30    })?);
31
32    // This queue retains at most 256 events and 1 MiB, including active I/O.
33    let asynchronous = Arc::new(AsyncSink::new(
34        AsyncSinkConfig {
35            max_events: 256,
36            max_bytes: 1024 * 1024,
37        },
38        file,
39    )?);
40    let dispatcher = LogDispatcher::new(LogPolicy::default(), vec![asynchronous.clone()]);
41    let log = dispatcher.event(0, "application");
42
43    log.info("application started");
44    log.warn("storage response is slow");
45
46    // The lifecycle owner drains durable writes before exiting.
47    asynchronous.shutdown()?;
48    let path = std::fs::canonicalize(path).map_err(|_| LogError::Io)?;
49    println!("log written to {}", path.display());
50    Ok(())
51}
examples/file_logging.rs (line 60)
22fn main() -> Result<(), appcore_log::LogConfigError> {
23    // Keep generated output predictable and inside Cargo's ignored target tree.
24    let output_directory = PathBuf::from("target/appcore-log-example");
25    std::fs::create_dir_all(&output_directory).map_err(|_| LogConfigError::Sink(LogError::Io))?;
26
27    let active_file = output_directory.join("application.jsonl");
28
29    // Two rotations stay beside the active file. Older rotations move into
30    // archive/YYYY/MM and the complete archive never exceeds 120 files.
31    let archive_directory = output_directory.join("archive");
32    let mut policy = LogPolicy::new(Verbosity::V4);
33    policy.set_component("sync", Verbosity::V8);
34
35    let logger = LoggerConfig {
36        policy,
37        output: LogOutputMode::TerminalAndFile,
38        file: Some(FileSinkConfig {
39            path: active_file,
40            max_bytes: LOG_SIZE_8_MIB,
41            sync_each_write: false,
42            retention: 2,
43            archive: Some(FileArchiveConfig {
44                directory: archive_directory,
45                max_files: 120,
46            }),
47        }),
48        ..LoggerConfig::default()
49    }
50    .build()?;
51
52    let application = logger.dispatcher().event(0, "application");
53    let sync = logger.dispatcher().event(1, "sync.transport");
54
55    application.info("application ready; inspect target/appcore-log-example/application.jsonl");
56
57    // The parent component policy makes this V7 diagnostic visible.
58    sync.verbosity(7).debug("replication batch sent");
59
60    sync.warn("peer response was delayed");
61
62    let stats = logger.dispatcher().stats();
63    assert_eq!(stats.sink_failures, 0);
64
65    Ok(())
66}
Source

pub fn error(&self, message: impl Into<String>)

Emits an error event.

Examples found in repository?
examples/basic.rs (line 31)
18fn main() -> Result<(), appcore_log::LogConfigError> {
19    // Safe V4 terminal logging is explicit and creates no global state.
20    let logger = LoggerConfig {
21        output: LogOutputMode::Terminal,
22        ..LoggerConfig::default()
23    }
24    .build()?;
25
26    // The builder defaults to V4 and can be kept for related events.
27    let log = logger.dispatcher().event(0, "application");
28
29    log.info("application started");
30    log.warn("connection is slower than expected");
31    log.error("document could not be saved");
32
33    Ok(())
34}
More examples
Hide additional examples
examples/sensitive_diagnostics.rs (line 50)
24fn main() -> Result<(), appcore_log::LogError> {
25    let key_id = KeyId::new("example-log-key").map_err(|_| appcore_log::LogError::Encryption)?;
26
27    let provider =
28        StaticDntKeyProvider::new().with_key(key_id.clone(), SecretKey::new(demo_key()?));
29
30    // The sink bounds the encrypted snapshot by both bytes and event count.
31    let sink = SensitiveDntSink::new(
32        SensitiveDntSinkConfig {
33            path: std::env::temp_dir().join("appcore-sensitive-log.dnt"),
34            application_id: ApplicationId::new("example-log")
35                .map_err(|_| appcore_log::LogError::Encryption)?,
36            key_id,
37            max_bytes: 4096,
38            max_events: 8,
39            retention: 2,
40        },
41        provider,
42    )?;
43
44    // Sensitive mode must be explicit and has no console or JSONL fallback.
45    let mut policy = LogPolicy::default();
46    policy.sensitivity = Sensitivity::Sensitive;
47
48    let log = LogDispatcher::new(policy, vec![Arc::new(sink)]);
49
50    log.event(0, "security").verbosity(2).error("diagnostic");
51
52    Ok(())
53}
Source

pub fn critical(&self, message: impl Into<String>)

Emits a critical event.

Trait Implementations§

Source§

impl<'a> Clone for LogBuilder<'a>

Source§

fn clone(&self) -> LogBuilder<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for LogBuilder<'a>

§

impl<'a> !UnwindSafe for LogBuilder<'a>

§

impl<'a> Freeze for LogBuilder<'a>

§

impl<'a> Send for LogBuilder<'a>

§

impl<'a> Sync for LogBuilder<'a>

§

impl<'a> Unpin for LogBuilder<'a>

§

impl<'a> UnsafeUnpin for LogBuilder<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.