Skip to content
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.

## Unreleased

## [0.27.0] 2025-08-18

### Notable changes

* Bump the Rust edition to 2024.
* Claim stabilize targets for the crate.

## [0.26.2] 2025-07-13

### Bug fixes
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
name = "logforth"

description = "A versatile and extensible logging implementation."
edition = "2021"
edition = "2024"
homepage = "https://github.com/fast/logforth"
license = "Apache-2.0"
readme = "README.md"
repository = "https://github.com/fast/logforth"
rust-version = "1.85.0"
version = "0.26.2"
version = "0.27.0"

categories = ["development-tools::debugging"]
keywords = ["logging", "log", "opentelemetry", "fastrace"]
Expand Down
60 changes: 51 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,64 @@ This crate is built against the latest stable release, and its minimum supported

The policy is that the minimum Rust version required to use this crate can be increased in minor version updates. For example, if Logforth 1.0 requires Rust 1.60.0, then Logforth 1.0.z for all values of z will also require Rust 1.60.0 or newer. However, Logforth 1.y for y > 0 may require a newer minimum version of Rust.

## When to release version 1.0
## Maturity

After one year of practicing the interfaces, if there are no further blockers, I'll release version 1.0. So consequently, it can be as early as 2025-08.
This crates has been in development since 2024-08. It is being used in several production systems stable enough to be considered mature, but it is still evolving. Read the following sections for what is stabilized and what is planned for the future.

### Stabilize targets

To release version 1.0, it's essential to declare what targets this crate wants to stabilize. Even after 1.0, it's helpful to distinguish different portions of this crate to allow unstable modules to make breaking changes to improve their quality, just as how rust-lang's stabilization mechanism works.
Fundamental logging APIs are stabilized, including:

Basically, this crate contains:
* Traits: [`Append`][append-url], [`Layout`][layout-url], [`Filter`][filter-url], [`Diagnostic`][diagnostic-url] and its [`Visitor`][diagnostic-visitor-url]
* Facades: [`DispatchBuilder`][dispatch-builder-url], [`LoggerBuilder`][logger-builder-url], and [`Logger`][logger-url]

* Fundamental logging APIs (Appender, Layout, Filter, Dispatch, Logger, etc.) MUST be stabilized before 1.0.
* Basic layouts and filters (all current existing) SHOULD be stabilized before 1.0.
* Basic appenders (Stdout, Stderr, RollingFile) SHOULD be stabilized before 1.0.
* Advanced appenders (Fastrace, OpentelemetryLog, Syslog, etc.) to-be-determined how to stabilize them.
[append-url]: https://docs.rs/logforth/*/logforth/append/trait.Append.html
[layout-url]: https://docs.rs/logforth/*/logforth/layout/trait.Layout.html
[filter-url]: https://docs.rs/logforth/*/logforth/filter/trait.Filter.html
[diagnostic-url]: https://docs.rs/logforth/*/logforth/diagnostic/trait.Diagnostic.html
[diagnostic-visitor-url]: https://docs.rs/logforth/*/logforth/diagnostic/trait.Visitor.html
[dispatch-builder-url]: https://docs.rs/logforth/*/logforth/struct.DispatchBuilder.html
[logger-builder-url]: https://docs.rs/logforth/*/logforth/struct.LoggerBuilder.html
[logger-url]: https://docs.rs/logforth/*/logforth/struct.Logger.html

Generally, there are known usage for Fastrace and OpentelemetryLog, so we can confidently announce their stable version; others are still waiting for feedback.
Core appenders, filters, layouts, and diagnostics are also stabilized, including:

* Appenders: `Stdout`, `Stderr`, and `Testing`
* Filters: `EnvFilter`
* Layouts: `TestLayout` and `JsonLayout`
* Diagnostics: `StaticDiagnostic` and `ThreadLocalDiagnostic`

Other appenders, filters, layouts, and diagnostics are still evolving and may change in future versions.

The following components yet to be unstabilized have known production usage and are considered reliable:

* Appenders: `Fastrace`, `OpentelemetryLog`, `SingleFile`, and `RollingFile`
* Layouts: `LogfmtLayout` and `GoogleCloudLoggingLayout`
* Diagnostics: `FastraceDiagnostic`

### Future plans

**What about a 1.0 release?**

The fundamental APIs and core components are stable. It's possible to factor out a separate `logforth-api` (or `logforth-core`) crate that contains only the stable APIs, and then release `logforth-api` 1.0 with the stable APIs and core components. I just don't decide its name and project layout yet.

The rest components, due to their external dependencies and several missing features, are still evolving and may change in future versions. They will be released as `logforth-append-foo`, `logforth-filter-bar`, `logforth-layout-baz`, and `logforth-diagnostic-qux` crates, which will depend on the stable `logforth-api` crate.

**What are the missing features?**

Before stabilize `SingleFile`, `RollingFile` and `Syslog` appenders that depend on the `NonBlocking` utility, I need to decide whether an `AsyncAppend` composition is better (see [#145](https://github.com/fast/logforth/issues/145)).

Otherwise, how to share utilities like `NonBlocking` and `LevelColor` between different separate crates without duplicating code is still an open question.

**What about components that have external dependencies?**

Fastrace's appenders and diagnostic, OpenTelemetry's appender, etc. have external dependencies that are not stable yet. The best option should be to release them as separate crates, such as `logforth-append-fastrace`, `logforth-diagnostic-fastrace`, `logforth-append-opentelemetry`, etc. This way, they can evolve independently and be used in projects that require them without affecting the core logging functionality.

This is blocked by not having a stable `logforth-api` crate yet, as these components depend on the stable APIs.

**What is the future of the `logforth` crate?**

It will continue to be the main crate that assembles all the features and provides a one-for-all dependency.

## License and Origin

Expand Down
4 changes: 2 additions & 2 deletions examples/custom_layout_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

use log::Metadata;
use log::Record;
use logforth::append;
use logforth::filter::FilterResult;
use logforth::Diagnostic;
use logforth::Filter;
use logforth::Layout;
use logforth::append;
use logforth::filter::FilterResult;

#[derive(Debug)]
struct CustomFilter;
Expand Down
2 changes: 1 addition & 1 deletion examples/fastrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use fastrace::Span;
use fastrace::collector::Config;
use fastrace::collector::ConsoleReporter;
use fastrace::collector::SpanContext;
use fastrace::Span;
use logforth::diagnostic;

fn main() {
Expand Down
2 changes: 1 addition & 1 deletion examples/google_cloud_logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use fastrace::Span;
use fastrace::collector::Config;
use fastrace::collector::ConsoleReporter;
use fastrace::collector::SpanContext;
use fastrace::prelude::SpanId;
use fastrace::prelude::TraceId;
use fastrace::Span;
use logforth::append;
use logforth::diagnostic;
use logforth::layout::GoogleCloudLoggingLayout;
Expand Down
2 changes: 1 addition & 1 deletion src/append/fastrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ use std::borrow::Cow;
use jiff::Zoned;
use log::Record;

use crate::Diagnostic;
use crate::append::Append;
use crate::diagnostic::Visitor;
use crate::Diagnostic;

/// An appender that adds log records to fastrace as an event associated to the current span.
///
Expand Down
2 changes: 1 addition & 1 deletion src/append/journald/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ use std::os::unix::net::UnixDatagram;
use log::Level;
use log::Record;

use crate::diagnostic::Visitor;
use crate::Append;
use crate::Diagnostic;
use crate::diagnostic::Visitor;

mod field;
#[cfg(target_os = "linux")]
Expand Down
6 changes: 3 additions & 3 deletions src/append/opentelemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ use std::fmt;
use std::time::SystemTime;

use log::Record;
use opentelemetry::InstrumentationScope;
use opentelemetry::logs::AnyValue;
use opentelemetry::logs::LogRecord;
use opentelemetry::logs::Logger;
use opentelemetry::logs::LoggerProvider;
use opentelemetry::InstrumentationScope;
use opentelemetry_otlp::LogExporter;
use opentelemetry_sdk::logs::SdkLogRecord;
use opentelemetry_sdk::logs::SdkLoggerProvider;

use crate::append::Append;
use crate::diagnostic::Visitor;
use crate::Diagnostic;
use crate::Layout;
use crate::append::Append;
use crate::diagnostic::Visitor;

/// A builder to configure and create an [`OpentelemetryLog`] appender.
#[derive(Debug)]
Expand Down
10 changes: 5 additions & 5 deletions src/append/rolling_file/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ use std::time::Duration;

use log::Record;

use crate::Diagnostic;
use crate::DropGuard;
use crate::Layout;
use crate::append::Append;
use crate::append::rolling_file::Rotation;
use crate::append::rolling_file::rolling::RollingFileWriter;
use crate::append::rolling_file::rolling::RollingFileWriterBuilder;
use crate::append::rolling_file::Rotation;
use crate::append::Append;
use crate::layout::TextLayout;
use crate::non_blocking::NonBlocking;
use crate::non_blocking::NonBlockingBuilder;
use crate::Diagnostic;
use crate::DropGuard;
use crate::Layout;

/// A builder to configure and create an [`RollingFile`] appender.
#[derive(Debug)]
Expand Down
11 changes: 6 additions & 5 deletions src/append/rolling_file/rolling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ use std::path::PathBuf;
use anyhow::Context;
use jiff::Zoned;

use crate::append::rolling_file::clock::Clock;
use crate::append::rolling_file::Rotation;
use crate::append::rolling_file::clock::Clock;

/// A writer for rolling files.
#[derive(Debug)]
Expand Down Expand Up @@ -277,8 +277,9 @@ impl State {
return None;
}

// On Linux (e.g., CentOS), `metadata.created()` may return an error due to lack of filesystem support.
// Fallback to `metadata.modified()` ensures compatibility across platforms.
// On Linux (e.g., CentOS), `metadata.created()` may return an error due to lack of
// filesystem support. Fallback to `metadata.modified()` ensures
// compatibility across platforms.
let created = metadata.created().or_else(|_| metadata.modified()).ok()?;
Some((entry, created))
})
Expand Down Expand Up @@ -345,14 +346,14 @@ mod tests {

use jiff::Span;
use jiff::Zoned;
use rand::distr::Alphanumeric;
use rand::Rng;
use rand::distr::Alphanumeric;
use tempfile::TempDir;

use crate::append::rolling_file::Rotation;
use crate::append::rolling_file::clock::Clock;
use crate::append::rolling_file::clock::ManualClock;
use crate::append::rolling_file::rolling::RollingFileWriterBuilder;
use crate::append::rolling_file::Rotation;

#[test]
fn test_file_rolling_via_file_size() {
Expand Down
8 changes: 4 additions & 4 deletions src/append/single_file/append.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ use std::time::Duration;

use log::Record;

use crate::Diagnostic;
use crate::DropGuard;
use crate::Layout;
use crate::append::Append;
use crate::append::single_file::single::SingleFileWriter;
use crate::append::single_file::single::SingleFileWriterBuilder;
use crate::append::Append;
use crate::layout::TextLayout;
use crate::non_blocking::NonBlocking;
use crate::non_blocking::NonBlockingBuilder;
use crate::Diagnostic;
use crate::DropGuard;
use crate::Layout;

/// A builder to configure and create an [`SingleFile`] appender.
#[derive(Debug)]
Expand Down
2 changes: 1 addition & 1 deletion src/append/single_file/single.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ impl SingleFileWriterBuilder {
mod tests {
use std::io::Write;

use rand::distr::Alphanumeric;
use rand::Rng;
use rand::distr::Alphanumeric;
use tempfile::NamedTempFile;

use crate::append::single_file::single::SingleFileWriterBuilder;
Expand Down
4 changes: 2 additions & 2 deletions src/append/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ use std::io::Write;

use log::Record;

use crate::append::Append;
use crate::layout::TextLayout;
use crate::Diagnostic;
use crate::Layout;
use crate::append::Append;
use crate::layout::TextLayout;

/// An appender that writes log records to standard output.
///
Expand Down
8 changes: 4 additions & 4 deletions src/append/syslog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@
use std::io;
use std::time::Duration;

use fasyslog::SDElement;
use fasyslog::format::SyslogContext;
use fasyslog::sender::SyslogSender;
use fasyslog::SDElement;
use log::Record;

use crate::non_blocking::NonBlocking;
use crate::non_blocking::NonBlockingBuilder;
use crate::non_blocking::Writer;
use crate::Append;
use crate::Diagnostic;
use crate::DropGuard;
use crate::Layout;
use crate::non_blocking::NonBlocking;
use crate::non_blocking::NonBlockingBuilder;
use crate::non_blocking::Writer;

pub extern crate fasyslog;

Expand Down
4 changes: 2 additions & 2 deletions src/append/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

use log::Record;

use crate::append::Append;
use crate::layout::TextLayout;
use crate::Diagnostic;
use crate::Layout;
use crate::append::Append;
use crate::layout::TextLayout;

/// An appender that writes log records that can be captured by a test harness (like `cargo test`),
/// and thus the outputs are suppressed unless `--nocapture` or `--show-output` is specified.
Expand Down
2 changes: 1 addition & 1 deletion src/diagnostic/fastrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::diagnostic::Visitor;
use crate::Diagnostic;
use crate::diagnostic::Visitor;

/// A diagnostic that enriches log records with trace ID provided by the Fastrace library.
///
Expand Down
2 changes: 1 addition & 1 deletion src/diagnostic/static_global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

use std::collections::BTreeMap;

use crate::diagnostic::Visitor;
use crate::Diagnostic;
use crate::diagnostic::Visitor;

/// A diagnostic that stores key-value pairs in a static global map.
///
Expand Down
2 changes: 1 addition & 1 deletion src/diagnostic/thread_local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
use std::cell::RefCell;
use std::collections::BTreeMap;

use crate::diagnostic::Visitor;
use crate::Diagnostic;
use crate::diagnostic::Visitor;

thread_local! {
static CONTEXT: RefCell<BTreeMap<String, String>> = const { RefCell::new(BTreeMap::new()) };
Expand Down
2 changes: 1 addition & 1 deletion src/filter/env_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ use std::str::FromStr;
use log::LevelFilter;
use log::Metadata;

use crate::filter::FilterResult;
use crate::Diagnostic;
use crate::Filter;
use crate::filter::FilterResult;

/// The default environment variable for filtering logs.
pub const DEFAULT_FILTER_ENV: &str = "RUST_LOG";
Expand Down
2 changes: 1 addition & 1 deletion src/layout/google_cloud_logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ use log::Record;
use serde::Serialize;
use serde_json::Value;

use crate::Diagnostic;
use crate::diagnostic::Visitor;
use crate::layout::Layout;
use crate::Diagnostic;

/// A layout for Google Cloud Structured Logging.
///
Expand Down
Loading
Loading