Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add more docs #29

Merged
merged 1 commit into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ license = "Apache-2.0"
readme = "README.md"
repository = "https://github.com/tisonkun/logforth"
rust-version = "1.71.0"
version = "0.7.1"
version = "0.7.2"

[package.metadata.docs.rs]
all-features = true
Expand Down
1 change: 1 addition & 0 deletions src/append/fastrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use log::Record;
use crate::append::Append;
use crate::layout::KvDisplay;

/// An appender that adds log records to fastrace as an event associated to the current span.
#[derive(Default, Debug, Clone)]
pub struct FastraceEvent;

Expand Down
4 changes: 3 additions & 1 deletion src/append/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Dispatch log records to the appropriate target.

use std::fmt;

#[cfg(feature = "fastrace")]
Expand Down Expand Up @@ -41,7 +43,7 @@ pub trait Append: fmt::Debug + Send + Sync + 'static {
/// Flushes any buffered records.
fn flush(&self) {}

/// Default layout to use when [Dispatch][crate::logger::Dispatch] does not configure a
/// Default layout to use when [`Dispatch`][crate::logger::Dispatch] does not configure a
/// preferred layout.
fn default_layout(&self) -> Layout {
Layout::Identical(IdenticalLayout)
Expand Down
5 changes: 5 additions & 0 deletions src/append/opentelemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ use opentelemetry_sdk::logs::LoggerProvider;

use crate::append::Append;

/// The communication protocol to opentelemetry that used when exporting data.
///
/// This is a logical re-exported [`opentelemetry_otlp::Protocol`] to avoid version lock-in to
/// `opentelemetry_otlp`.
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum OpentelemetryWireProtocol {
Expand All @@ -36,6 +40,7 @@ pub enum OpentelemetryWireProtocol {
HttpJson,
}

/// An appender that sends log records to opentelemetry.
#[derive(Debug)]
pub struct OpentelemetryLog {
name: String,
Expand Down
2 changes: 2 additions & 0 deletions src/append/rolling_file/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use log::Record;
use crate::append::rolling_file::non_blocking::NonBlocking;
use crate::append::Append;

/// An appender that writes log records to a file that rolls over when it reaches a certain date
/// time.
#[derive(Debug)]
pub struct RollingFile {
writer: NonBlocking,
Expand Down
2 changes: 2 additions & 0 deletions src/append/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::io::Write;

use crate::append::Append;

/// An appender that prints log records to stdout.
#[derive(Default, Debug)]
pub struct Stdout;

Expand All @@ -31,6 +32,7 @@ impl Append for Stdout {
}
}

/// An appender that prints log records to stderr.
#[derive(Default, Debug)]
pub struct Stderr;

Expand Down
18 changes: 18 additions & 0 deletions src/filter/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,24 @@ use log::Metadata;
use crate::filter::Filter;
use crate::filter::FilterResult;

/// A filter that you can pass the custom filter function.
///
/// The custom filter function accepts [`&log::Metadata`][Metadata] and returns the
/// [`FilterResult`]. For example:
///
/// ```rust
/// use log::Metadata;
/// use logforth::filter::CustomFilter;
/// use logforth::filter::FilterResult;
///
/// let filter = CustomFilter::new(|metadata: &Metadata| {
/// if metadata.target() == "my_crate" {
/// FilterResult::Accept
/// } else {
/// FilterResult::Neutral
/// }
/// });
/// ```
pub struct CustomFilter {
f: Box<dyn Fn(&Metadata) -> FilterResult + Send + Sync + 'static>,
}
Expand Down
3 changes: 3 additions & 0 deletions src/filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Determinate whether a log record should be processed.

pub use self::custom::CustomFilter;
pub use self::level::LevelFilter;

mod custom;
mod level;

/// The result of a filter may return.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FilterResult {
/// The record will be processed without further filtering.
Expand Down
17 changes: 17 additions & 0 deletions src/layout/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@ type FormatFunction = dyn Fn(&Record, &dyn Fn(Arguments) -> anyhow::Result<()>)
+ Sync
+ 'static;

/// A layout that you can pass the custom layout function.
///
/// The custom layout function accepts [`&log::Record`][Record], formats it into [Arguments], and
/// then passes to the closure. For example:
///
/// ```rust
/// use std::fmt::Arguments;
///
/// use log::Record;
/// use logforth::layout::CustomLayout;
///
/// let layout = CustomLayout::new(
/// |record: &Record, f: &dyn Fn(Arguments) -> anyhow::Result<()>| {
/// f(format_args!("{} - {}", record.level(), record.args()))
/// },
/// );
/// ```
pub struct CustomLayout {
f: Box<FormatFunction>,
}
Expand Down
4 changes: 4 additions & 0 deletions src/layout/identical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ use std::fmt::Arguments;

use crate::layout::Layout;

/// A layout that returns log record as is.
///
/// This is mainly used as the default implementation for
/// [`Append::default_layout`][crate::append::Append::default_layout].
#[derive(Debug, Default, Clone, Copy)]
pub struct IdenticalLayout;

Expand Down
11 changes: 11 additions & 0 deletions src/layout/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ use serde_json::Value;

use crate::layout::Layout;

/// A layout that formats log record as JSON lines.
///
/// Output format:
///
/// ```json
/// {"timestamp":"2024-08-01T13:57:05.099261Z","level":"ERROR","module_path":"rolling_file","file":"rolling_file.rs","line":48,"message":"Hello error!","kvs":{}}
/// {"timestamp":"2024-08-01T13:57:05.099313Z","level":"WARN","module_path":"rolling_file","file":"rolling_file.rs","line":49,"message":"Hello warn!","kvs":{}}
/// {"timestamp":"2024-08-01T13:57:05.099338Z","level":"INFO","module_path":"rolling_file","file":"rolling_file.rs","line":50,"message":"Hello info!","kvs":{}}
/// {"timestamp":"2024-08-01T13:57:05.099362Z","level":"DEBUG","module_path":"rolling_file","file":"rolling_file.rs","line":51,"message":"Hello debug!","kvs":{}}
/// {"timestamp":"2024-08-01T13:57:05.099386Z","level":"TRACE","module_path":"rolling_file","file":"rolling_file.rs","line":52,"message":"Hello trace!","kvs":{}}
/// ```
#[derive(Default, Debug, Clone)]
pub struct JsonLayout;

Expand Down
1 change: 1 addition & 0 deletions src/layout/kv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

/// A helper struct to format log's key-value pairs.
pub struct KvDisplay<'kvs> {
kv: &'kvs dyn log::kv::Source,
}
Expand Down
3 changes: 3 additions & 0 deletions src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Describe how to format a log record.

pub use custom::CustomLayout;
pub use identical::IdenticalLayout;
#[cfg(feature = "json")]
Expand All @@ -27,6 +29,7 @@ mod json;
mod kv;
mod text;

/// A layout describes how to format a log record.
#[derive(Debug)]
pub enum Layout {
Identical(IdenticalLayout),
Expand Down
18 changes: 18 additions & 0 deletions src/layout/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,29 @@ use log::Level;
use crate::layout::KvDisplay;
use crate::layout::Layout;

/// A layout that formats log record as text.
///
/// Output format:
///
/// ```text
/// 2024-08-02T12:49:03.102343Z ERROR simple_stdio: examples/simple_stdio.rs:32 Hello error!
/// 2024-08-02T12:49:03.102442Z WARN simple_stdio: examples/simple_stdio.rs:33 Hello warn!
/// 2024-08-02T12:49:03.102447Z INFO simple_stdio: examples/simple_stdio.rs:34 Hello info!
/// 2024-08-02T12:49:03.102450Z DEBUG simple_stdio: examples/simple_stdio.rs:35 Hello debug!
/// 2024-08-02T12:49:03.102453Z TRACE simple_stdio: examples/simple_stdio.rs:36 Hello trace!
/// ```
///
/// By default, log levels are colored. You can turn on the `no-color` feature flag to disable this
/// feature.
///
/// You can also customize the color of each log level by setting the `colors` field with a
/// [`LevelColor`] instance.
#[derive(Default, Debug, Clone)]
pub struct TextLayout {
pub colors: LevelColor,
}

/// Customize the color of each log level.
#[derive(Debug, Clone)]
pub struct LevelColor {
pub error: Color,
Expand Down
41 changes: 41 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,47 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! # A versatile and extensible logging implementation
//!
//! ## Usage
//!
//! Add the dependencies to your `Cargo.toml` with:
//!
//! ```shell
//! cargo add log
//! cargo add logforth
//! ```
//!
//! Here, [`log`] is the logging facade and `logforth` is the logging implementation.
//!
//! Then, you can use the logger with:
//!
//! ```rust
//! use log::LevelFilter;
//! use logforth::append;
//! use logforth::layout::TextLayout;
//! use logforth::Dispatch;
//! use logforth::Logger;
//!
//! Logger::new()
//! .dispatch(
//! Dispatch::new()
//! .filter(LevelFilter::Trace)
//! .layout(TextLayout::default())
//! .append(append::Stdout),
//! )
//! .apply()
//! .unwrap();
//!
//! log::error!("Hello error!");
//! log::warn!("Hello warn!");
//! log::info!("Hello info!");
//! log::debug!("Hello debug!");
//! log::trace!("Hello trace!");
//! ```
//!
//! Read more demos under the [examples](https://github.com/tisonkun/logforth/tree/main/examples) directory.

pub mod append;
pub mod filter;
pub mod layout;
Expand Down
30 changes: 15 additions & 15 deletions src/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ use crate::layout::Layout;

/// A grouped set of appenders, filters, and optional layout.
///
/// The [Logger] facade dispatches log records to one or more [Dispatch] instances.
/// Each [Dispatch] instance contains a set of filters, appenders, and an optional layout.
/// The [`Logger`] facade dispatches log records to one or more [`Dispatch`] instances.
/// Each [`Dispatch`] instance contains a set of filters, appenders, and an optional layout.
///
/// `filters` are used to determine whether a log record should be passed to the appenders.
/// `appends` are used to write log records to a destination. Each appender has its own
/// default layout. If the [Dispatch] has a layout, it will be used instead of the default layout.
/// default layout. If the [`Dispatch`] has a layout, it will be used instead of the default layout.
#[derive(Debug)]
pub struct Dispatch<const LAYOUT: bool = true, const APPEND: bool = true> {
filters: Vec<Filter>,
Expand All @@ -45,9 +45,9 @@ impl Default for Dispatch<false, false> {
}

impl Dispatch<false, false> {
/// Create a new incomplete [Dispatch] instance.
/// Create a new incomplete [`Dispatch`] instance.
///
/// At least one append must be added to the [Dispatch] before it can be used.
/// At least one append must be added to the [`Dispatch`] before it can be used.
pub fn new() -> Dispatch<false, false> {
Self {
filters: vec![],
Expand All @@ -56,14 +56,14 @@ impl Dispatch<false, false> {
}
}

/// Add a [Filter] to the [Dispatch].
/// Add a [`Filter`] to the [`Dispatch`].
pub fn filter(mut self, filter: impl Into<Filter>) -> Dispatch<false, false> {
self.filters.push(filter.into());
self
}

/// Add the preferred [Layout] to the [Dispatch]. At most one layout can be added to a
/// [Dispatch].
/// Add the preferred [`Layout`] to the [`Dispatch`]. At most one layout can be added to a
/// [`Dispatch`].
pub fn layout(self, layout: impl Into<Layout>) -> Dispatch<true, false> {
Dispatch {
filters: self.filters,
Expand All @@ -74,7 +74,7 @@ impl Dispatch<false, false> {
}

impl<const LAYOUT: bool, const APPEND: bool> Dispatch<LAYOUT, APPEND> {
/// Add an [Append] to the [Dispatch].
/// Add an [`Append`] to the [`Dispatch`].
pub fn append(mut self, append: impl Append) -> Dispatch<true, true> {
self.appends.push(Box::new(append));

Expand Down Expand Up @@ -119,10 +119,10 @@ impl Dispatch {
}
}

/// A logger facade that dispatches log records to one or more [Dispatch] instances.
/// A logger facade that dispatches log records to one or more [`Dispatch`] instances.
///
/// This struct implements [log::Log] to bridge Logforth's logging implementations
/// with the [log] crate.
/// This struct implements [`log::Log`] to bridge Logforth's logging implementations
/// with the [`log`] crate.
#[derive(Debug)]
pub struct Logger {
dispatches: Vec<Dispatch>,
Expand All @@ -135,20 +135,20 @@ impl Default for Logger {
}

impl Logger {
/// Create a new [Logger] instance.
/// Create a new [`Logger`] instance.
pub fn new() -> Logger {
Self { dispatches: vec![] }
}
}

impl Logger {
/// Add a [Dispatch] to the [Logger].
/// Add a [`Dispatch`] to the [`Logger`].
pub fn dispatch(mut self, dispatch: Dispatch) -> Logger {
self.dispatches.push(dispatch);
self
}

/// Set up the global logger with the [Logger] instance.
/// Set up the global logger with the [`Logger`] instance.
///
/// # Errors
///
Expand Down