Skip to content

Commit

Permalink
refactor: improve api doc
Browse files Browse the repository at this point in the history
  • Loading branch information
andylokandy committed Oct 30, 2024
1 parent d3394df commit 5aeac74
Show file tree
Hide file tree
Showing 25 changed files with 514 additions and 264 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ jobs:
run: cargo test --all-features -- --nocapture
- name: Run examples
run: |
cargo run --example text_stdio
cargo run --example simple_stdio
cargo run --example multiple_dispatches
cargo run --example custom_layout_filter
cargo run --example env_filter
cargo run --features="no-color" --example text_stdio
cargo run --features="json" --example json_stdio
cargo run --features="no-color" --example simple_stdio
cargo run --features="json" --example json_stdout
cargo run --features="json,rolling_file" --example rolling_file
required:
Expand Down
19 changes: 9 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ colored = { version = "2.1" }
env_filter = { version = "0.1" }
jiff = { version = "0.1.13" }
log = { version = "0.4", features = ["std", "kv_unstable"] }
paste = { version = "1.0" }

[dev-dependencies]
rand = "0.8"
tempfile = "3.13"
tokio = { version = "1", features = ["rt-multi-thread"] }

## Serde dependencies
[dependencies.serde]
Expand Down Expand Up @@ -96,13 +96,16 @@ version = "0.26"

## Examples
[[example]]
name = "text_stdio"
path = "examples/text_stdio.rs"
name = "simple_stdout"
path = "examples/simple_stdout.rs"

[[example]]
name = "json_stdio"
path = "examples/json_stdio.rs"
required-features = ["json"]
name = "json_stdout"
path = "examples/json_stdout.rs"

[[example]]
name = "multiple_dispatches"
path = "examples/multiple_dispatches.rs"

[[example]]
name = "rolling_file"
Expand All @@ -112,7 +115,3 @@ required-features = ["rolling_file", "json"]
[[example]]
name = "custom_layout_filter"
path = "examples/custom_layout_filter.rs"

[[example]]
name = "env_filter"
path = "examples/env_filter.rs"
46 changes: 32 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Logforth Project
# Logforth

[![Crates.io][crates-badge]][crates-url]
[![Documentation][docs-badge]][docs-url]
Expand All @@ -16,40 +16,58 @@
[actions-badge]: https://github.com/fast/logforth/workflows/CI/badge.svg
[actions-url]:https://github.com/fast/logforth/actions?query=workflow%3ACI

## Overview
Logforth is a flexible and easy-to-use logging framework for Rust applications. It allows you to configure multiple dispatches, filters, and appenders to customize your logging setup according to your needs.

A versatile and extensible logging implementation.
## Features

## Usage
- **Multiple Dispatches**: Configure different logging behaviors for different parts of your application.
- **Flexible Filters**: Use built-in or custom filters to control which log records are processed.
- **Various Appenders**: Output logs to stdout, stderr, files, or even send them to OpenTelemetry collectors.
- **Custom Layouts**: Format log records using predefined layouts or create your own.

Add the dependencies to your `Cargo.toml` with:
## Getting Started

Add `log` and `logforth` to your `Cargo.toml`:

```shell
cargo add log
cargo add logforth
> cargo add log
> cargo add logforth
```

... where [log](https://crates.io/crates/log) is the logging facade and [logforth](https://crates.io/crates/logforth) is the logging implementation.
## Simple Usage

Then, you can use the logger with the simplest default setup:
Set up a basic logger that outputs to stdout:

```rust
fn main() {
logforth::stderr().apply();
logforth::stdout().apply();

log::info!("This is an info message.");
log::debug!("This debug message will not be printed by default.");
}
```

Or configure the logger in a more fine-grained way:
## Advanced Usage

Configure multiple dispatches with different filters and appenders:

```rust
use log::LevelFilter;
use logforth::append;
use log::LevelFilter;

fn main() {
logforth::builder()
.dispatch(|d| d.filter(LevelFilter::Debug).append(append::Stderr::default()))
.dispatch(|d| d.filter(LevelFilter::Info).append(append::Stdout::default()))
.dispatch(|d| d
.filter(LevelFilter::Error)
.append(append::Stderr::default()))
.dispatch(|d| d
.filter(LevelFilter::Info)
.append(append::Stdout::default()))
.apply();

log::error!("This error will be logged to stderr.");
log::info!("This info will be logged to stdout.");
log::debug!("This debug message will not be logged.");
}
```

Expand Down
15 changes: 6 additions & 9 deletions examples/custom_layout_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use log::LevelFilter;
use logforth::append;
use logforth::filter::CustomFilter;
use logforth::filter::FilterResult;
Expand All @@ -21,24 +20,22 @@ use logforth::layout::CustomLayout;
fn main() {
logforth::builder()
.dispatch(|d| {
d.filter(CustomFilter::new(|metadata: &log::Metadata| {
if metadata.level() > LevelFilter::Info {
d.filter(CustomFilter::new(|metadata| {
if metadata.level() > log::Level::Info {
FilterResult::Accept
} else {
FilterResult::Reject
}
}))
.append(
append::Stdout::default().with_layout(CustomLayout::new(|record| {
Ok(format!("[system alert] {}", record.args()).into_bytes())
Ok(format!("[Alert] {}", record.args()).into_bytes())
})),
)
})
.apply();

log::error!("Hello error!");
log::warn!("Hello warn!");
log::info!("Hello info!");
log::debug!("Hello debug!");
log::trace!("Hello trace!");
log::error!("This is an error.");
log::warn!("This is a warning.");
log::info!("This info will not be logged.");
}
7 changes: 2 additions & 5 deletions examples/json_stdio.rs → examples/json_stdout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ fn main() {
.dispatch(|d| d.append(append::Stdout::default().with_layout(JsonLayout::default())))
.apply();

log::error!("Hello error!");
log::warn!("Hello warn!");
log::info!("Hello info!");
log::debug!("Hello debug!");
log::trace!("Hello trace!");
log::info!("This is an info message.");
log::debug!("This debug message will not be printed by default.");
}
15 changes: 8 additions & 7 deletions examples/text_stdio.rs → examples/multiple_dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ use logforth::append;
fn main() {
logforth::builder()
.dispatch(|d| {
d.filter(LevelFilter::Trace)
.append(append::Stdout::default())
d.filter(LevelFilter::Error)
.append(append::Stderr::default())
})
.dispatch(|d| {
d.filter(LevelFilter::Info)
.append(append::Stdout::default())
})
.apply();

log::error!("Hello error!");
log::warn!("Hello warn!");
log::info!("Hello info!");
log::debug!("Hello debug!");
log::trace!("Hello trace!");
log::error!("This error will be logged to stderr.");
log::info!("This info will be logged to stdout.");
log::debug!("This debug message will not be logged.");
}
32 changes: 8 additions & 24 deletions examples/rolling_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,23 @@ use logforth::append::rolling_file::NonBlockingBuilder;
use logforth::append::rolling_file::RollingFile;
use logforth::append::rolling_file::RollingFileWriter;
use logforth::append::rolling_file::Rotation;
use logforth::append::Stdout;
use logforth::layout::JsonLayout;

fn main() {
let rolling = RollingFileWriter::builder()
.rotation(Rotation::Minutely)
.filename_prefix("example")
.filename_suffix("log")
.max_log_files(10)
.max_file_size(1024 * 1024)
let rolling_writer = RollingFileWriter::builder()
.rotation(Rotation::Daily)
.filename_prefix("app_log")
.build("logs")
.unwrap();
let (writer, _guard) = NonBlockingBuilder::default().finish(rolling);

let (non_blocking, _guard) = NonBlockingBuilder::default().finish(rolling_writer);

logforth::builder()
.dispatch(|d| {
d.filter("trace")
.append(RollingFile::new(writer).with_layout(JsonLayout::default()))
d.filter(log::LevelFilter::Trace)
.append(RollingFile::new(non_blocking).with_layout(JsonLayout::default()))
})
.dispatch(|d| d.filter("info").append(Stdout::default()))
.apply();

let repeat = 1;

for i in 0..repeat {
log::error!("Hello error!");
log::warn!("Hello warn!");
log::info!("Hello info!");
log::debug!("Hello debug!");
log::trace!("Hello trace!");

if i + 1 < repeat {
std::thread::sleep(std::time::Duration::from_secs(10));
}
}
log::info!("This log will be written to a rolling file.");
}
7 changes: 2 additions & 5 deletions examples/env_filter.rs → examples/simple_stdout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
fn main() {
logforth::stdout().apply();

log::error!("Hello error!");
log::warn!("Hello warn!");
log::info!("Hello info!");
log::debug!("Hello debug!");
log::trace!("Hello trace!");
log::info!("This is an info message.");
log::debug!("This debug message will not be printed by default.");
}
10 changes: 10 additions & 0 deletions src/append/fastrace.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.

//! Appender for integrating with [fastrace](https://crates.io/crates/fastrace).

use std::borrow::Cow;

use jiff::Zoned;
Expand All @@ -21,6 +23,14 @@ use crate::append::Append;
use crate::layout::collect_kvs;

/// An appender that adds log records to fastrace as an event associated to the current span.
///
/// # Examples
///
/// ```
/// use logforth::append::FastraceEvent;
///
/// let fastrace_appender = FastraceEvent::default();
/// ```
#[derive(Default, Debug, Clone)]
pub struct FastraceEvent {
_private: (), // suppress structure literal syntax
Expand Down
23 changes: 13 additions & 10 deletions src/append/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.

//! Dispatch log records to the appropriate target.
//! Various appenders for log records.

use std::fmt;

#[cfg(feature = "fastrace")]
mod fastrace;
#[cfg(feature = "opentelemetry")]
pub mod opentelemetry;
#[cfg(feature = "rolling_file")]
pub mod rolling_file;
mod stdio;

#[cfg(feature = "fastrace")]
pub use self::fastrace::FastraceEvent;
#[cfg(feature = "opentelemetry")]
Expand All @@ -25,16 +33,11 @@ pub use self::rolling_file::RollingFile;
pub use self::stdio::Stderr;
pub use self::stdio::Stdout;

#[cfg(feature = "fastrace")]
mod fastrace;
#[cfg(feature = "opentelemetry")]
pub mod opentelemetry;
#[cfg(feature = "rolling_file")]
pub mod rolling_file;
mod stdio;

/// A trait representing an appender that can process log records.
///
/// Implementors of this trait can handle log records in custom ways.
pub trait Append: fmt::Debug + Send + Sync + 'static {
/// Dispatches a log record to the append target.
/// Processes a log record.
fn append(&self, record: &log::Record) -> anyhow::Result<()>;

/// Flushes any buffered records.
Expand Down
Loading

0 comments on commit 5aeac74

Please sign in to comment.