diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f1eab4b88..892a630be 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,6 +47,7 @@ jobs: - run: cargo test --verbose --features kv - run: cargo test --verbose --features kv_sval - run: cargo test --verbose --features kv_serde + - run: cargo test --verbose --features kv,std - run: cargo test --verbose --features "kv kv_std kv_sval kv_serde" - run: cargo run --verbose --manifest-path test_max_level_features/Cargo.toml - run: cargo run --verbose --manifest-path test_max_level_features/Cargo.toml --release diff --git a/.gitignore b/.gitignore index 2c96eb1b6..150301459 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target/ Cargo.lock +.idea/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c89834df..f0222892f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,30 @@ ## [Unreleased] +## [0.4.23] - 2025-01-10 + +## What's Changed +* Fix some typos by @Kleinmarb in https://github.com/rust-lang/log/pull/637 +* Add logforth to implementation by @tisonkun in https://github.com/rust-lang/log/pull/638 +* Add `spdlog-rs` link to README by @SpriteOvO in https://github.com/rust-lang/log/pull/639 +* Add correct lifetime to kv::Value::to_borrowed_str by @stevenroose in https://github.com/rust-lang/log/pull/643 +* docs: Add logforth as an impl by @tisonkun in https://github.com/rust-lang/log/pull/642 +* Add clang_log implementation by @DDAN-17 in https://github.com/rust-lang/log/pull/646 +* Bind lifetimes of &str returned from Key by the lifetime of 'k rather than the lifetime of the Key struct by @gbbosak in https://github.com/rust-lang/log/pull/648 +* Fix up key lifetimes and add method to try get a borrowed key by @KodrAus in https://github.com/rust-lang/log/pull/653 +* Add Ftail implementation by @tjardoo in https://github.com/rust-lang/log/pull/652 + +## New Contributors +* @Kleinmarb made their first contribution in https://github.com/rust-lang/log/pull/637 +* @tisonkun made their first contribution in https://github.com/rust-lang/log/pull/638 +* @SpriteOvO made their first contribution in https://github.com/rust-lang/log/pull/639 +* @stevenroose made their first contribution in https://github.com/rust-lang/log/pull/643 +* @DDAN-17 made their first contribution in https://github.com/rust-lang/log/pull/646 +* @gbbosak made their first contribution in https://github.com/rust-lang/log/pull/648 +* @tjardoo made their first contribution in https://github.com/rust-lang/log/pull/652 + +**Full Changelog**: https://github.com/rust-lang/log/compare/0.4.22...0.4.23 + ## [0.4.22] - 2024-06-27 ## What's Changed @@ -64,7 +88,7 @@ ## [0.4.18] - 2023-05-28 -* fix markdown links (again) by @hellow554 in https://github.com/rust-lang/log/pull/513 +* fix Markdown links (again) by @hellow554 in https://github.com/rust-lang/log/pull/513 * add cargo doc to workflow by @hellow554 in https://github.com/rust-lang/log/pull/515 * Apply Clippy lints by @hellow554 in https://github.com/rust-lang/log/pull/516 * Replace ad-hoc eq_ignore_ascii_case with slice::eq_ignore_ascii_case by @glandium in https://github.com/rust-lang/log/pull/519 @@ -99,7 +123,7 @@ * Improvements to test coverage. * Improvements to documentation. * Add key-value support to the `log!` macros. -* Tighten `kv_unstable` internal dependencies so they don't bump past their current alpha. +* Tighten `kv_unstable` internal dependencies, so they don't bump past their current alpha. * Add a simple visit API to `kv_unstable`. * Support `NonZero*` integers as values in structured logging * Support static strings as keys in structured logging @@ -149,7 +173,7 @@ as either a map of `{key: value, ..}` or as a list of `[(key, value), ..]`. ### Fixed -* Fixed the `log!` macros so they work in expression context (this regressed in `0.4.9`, which has been yanked). +* Fixed the `log!` macros, so they work in expression context (this regressed in `0.4.9`, which has been yanked). ## [0.4.9] - 2019-12-12 (yanked) @@ -260,7 +284,7 @@ version using log 0.4.x to avoid losing module and file information. * The `logger` free function returns a reference to the logger implementation. This, along with the ability to construct `Record`s, makes it possible to bridge from another logging framework to this one without digging into the private internals of the crate. The standard `error!` `warn!`, - etc, macros now exclusively use the public API of the crate rather than "secret" internal APIs. + etc., macros now exclusively use the public API of the crate rather than "secret" internal APIs. * `Log::flush` has been added to allow crates to tell the logging implementation to ensure that all "in flight" log events have been persisted. This can be used, for example, just before an application exits to ensure that asynchronous log sinks finish their work. @@ -298,7 +322,9 @@ version using log 0.4.x to avoid losing module and file information. Look at the [release tags] for information about older releases. -[Unreleased]: https://github.com/rust-lang-nursery/log/compare/0.4.21...HEAD +[Unreleased]: https://github.com/rust-lang-nursery/log/compare/0.4.23...HEAD +[0.4.23]: https://github.com/rust-lang/log/compare/0.4.22...0.4.23 +[0.4.22]: https://github.com/rust-lang/log/compare/0.4.21...0.4.22 [0.4.21]: https://github.com/rust-lang/log/compare/0.4.20...0.4.21 [0.4.20]: https://github.com/rust-lang-nursery/log/compare/0.4.19...0.4.20 [0.4.19]: https://github.com/rust-lang-nursery/log/compare/0.4.18...0.4.19 diff --git a/Cargo.toml b/Cargo.toml index c3ac8c67a..6b912508e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "log" -version = "0.4.22" # remember to update html_root_url +version = "0.4.23" # remember to update html_root_url authors = ["The Rust Project Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -72,10 +72,10 @@ sval = { version = "2.1" } sval_derive = { version = "2.1" } value-bag = { version = "1.7", features = ["test"] } -# NOTE: log doesn't actually depent on this crate. However our dependencies, +# NOTE: log doesn't actually depent on this crate. However, our dependencies, # serde and sval, dependent on version 1.0 of the crate, which has problem fixed # in 1.0.60, specifically in the following commit # https://github.com/dtolnay/proc-macro2/commit/e31d61910049e097afdd3d27c37786309082bdcb. -# By defining the crate as direct dependency we can increase it's minimal +# By defining the crate as direct dependency we can increase its minimal # version making the minimal (crate) version CI happy. proc-macro2 = { version = "1.0.63", default-features = false } diff --git a/README.md b/README.md index d4a08b12b..f8b544911 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,13 @@ There are many available implementations to choose from, here are some options: * [`call_logger`](https://docs.rs/call_logger/*/call_logger/) * [`std-logger`](https://docs.rs/std-logger/*/std_logger/) * [`structured-logger`](https://docs.rs/structured-logger/latest/structured_logger/) + * [`clang_log`](https://docs.rs/clang_log/latest/clang_log) + * [`ftail`](https://docs.rs/ftail/latest/ftail/) * Complex configurable frameworks: * [`log4rs`](https://docs.rs/log4rs/*/log4rs/) + * [`logforth`](https://docs.rs/logforth/*/logforth/) * [`fern`](https://docs.rs/fern/*/fern/) + * [`spdlog-rs`](https://docs.rs/spdlog-rs/*/spdlog/) * Adaptors for other facilities: * [`syslog`](https://docs.rs/syslog/*/syslog/) * [`systemd-journal-logger`](https://docs.rs/systemd-journal-logger/*/systemd_journal_logger/) diff --git a/rfcs/0296-structured-logging.md b/rfcs/0296-structured-logging.md index 3ee90a5cf..835588c6b 100644 --- a/rfcs/0296-structured-logging.md +++ b/rfcs/0296-structured-logging.md @@ -1633,7 +1633,7 @@ Structured logging is a paradigm that's supported by logging frameworks in many ## Rust -The `slog` library is a structured logging framework for Rust. Its API predates a stable `serde` crate so it defines its own traits that are similar to `serde::Serialize`. A log record consists of a rendered message and bag of structured key-value pairs. `slog` goes further than this RFC proposes by requiring callers of its `log!` macros to state whether key-values are owned or borrowed by the record, and whether the data is safe to share across threads. +The `slog` library is a structured logging framework for Rust. Its API predates a stable `serde` crate, so it defines its own traits that are similar to `serde::Serialize`. A log record consists of a rendered message and bag of structured key-value pairs. `slog` goes further than this RFC proposes by requiring callers of its `log!` macros to state whether key-values are owned or borrowed by the record, and whether the data is safe to share across threads. This RFC proposes an API that's inspired by `slog`, but doesn't directly support distinguishing between owned or borrowed key-value pairs. Everything is borrowed. That means the only way to send a `Record` to another thread is to serialize it into a different type. diff --git a/src/kv/key.rs b/src/kv/key.rs index 9a64b956f..6e00a2ca8 100644 --- a/src/kv/key.rs +++ b/src/kv/key.rs @@ -35,6 +35,7 @@ impl ToKey for str { // If a new field (such as an optional index) is added to the key they must not affect comparison #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Key<'k> { + // NOTE: This may become `Cow<'k, str>` key: &'k str, } @@ -45,9 +46,23 @@ impl<'k> Key<'k> { } /// Get a borrowed string from this key. + /// + /// The lifetime of the returned string is bound to the borrow of `self` rather + /// than to `'k`. pub fn as_str(&self) -> &str { self.key } + + /// Try get a borrowed string for the lifetime `'k` from this key. + /// + /// If the key is a borrow of a longer lived string, this method will return `Some`. + /// If the key is internally buffered, this method will return `None`. + pub fn to_borrowed_str(&self) -> Option<&'k str> { + // NOTE: If the internals of `Key` support buffering this + // won't be unconditionally `Some` anymore. We want to keep + // this option open + Some(self.key) + } } impl<'k> fmt::Display for Key<'k> { @@ -140,4 +155,9 @@ mod tests { fn key_from_string() { assert_eq!("a key", Key::from_str("a key").as_str()); } + + #[test] + fn key_to_borrowed() { + assert_eq!("a key", Key::from_str("a key").to_borrowed_str().unwrap()); + } } diff --git a/src/kv/mod.rs b/src/kv/mod.rs index 1ccb82514..8c71e0765 100644 --- a/src/kv/mod.rs +++ b/src/kv/mod.rs @@ -29,7 +29,7 @@ //! info!(a = 1; "Something of interest"); //! ``` //! -//! Key-values support the same shorthand identifer syntax as `format_args`: +//! Key-values support the same shorthand identifier syntax as `format_args`: //! //! ``` //! # use log::info; diff --git a/src/kv/value.rs b/src/kv/value.rs index 1511dd02e..6616ee961 100644 --- a/src/kv/value.rs +++ b/src/kv/value.rs @@ -101,7 +101,7 @@ impl<'v> ToValue for Value<'v> { /// Values provide a number of ways to be serialized. /// /// For basic types the [`Value::visit`] method can be used to extract the -/// underlying typed value. However this is limited in the amount of types +/// underlying typed value. However, this is limited in the amount of types /// supported (see the [`VisitValue`] trait methods). /// /// For more complex types one of the following traits can be used: @@ -373,19 +373,19 @@ impl_value_to_primitive![ ]; impl<'v> Value<'v> { - /// Try convert this value into an error. + /// Try to convert this value into an error. #[cfg(feature = "kv_std")] pub fn to_borrowed_error(&self) -> Option<&(dyn std::error::Error + 'static)> { self.inner.to_borrowed_error() } - /// Try convert this value into a borrowed string. - pub fn to_borrowed_str(&self) -> Option<&str> { + /// Try to convert this value into a borrowed string. + pub fn to_borrowed_str(&self) -> Option<&'v str> { self.inner.to_borrowed_str() } } -#[cfg(feature = "kv_std")] +#[cfg(feature = "std")] mod std_support { use std::borrow::Cow; use std::rc::Rc; @@ -432,13 +432,6 @@ mod std_support { } } - impl<'v> Value<'v> { - /// Try convert this value into a string. - pub fn to_cow_str(&self) -> Option> { - self.inner.to_str() - } - } - impl<'v> From<&'v String> for Value<'v> { fn from(v: &'v String) -> Self { Value::from(&**v) @@ -446,6 +439,22 @@ mod std_support { } } +#[cfg(all(feature = "std", feature = "value-bag"))] +impl<'v> Value<'v> { + /// Try to convert this value into a string. + pub fn to_cow_str(&self) -> Option> { + self.inner.to_str() + } +} + +#[cfg(all(feature = "std", not(feature = "value-bag")))] +impl<'v> Value<'v> { + /// Try to convert this value into a string. + pub fn to_cow_str(&self) -> Option> { + self.inner.to_borrowed_str().map(std::borrow::Cow::Borrowed) + } +} + /// A visitor for a [`Value`]. /// /// Also see [`Value`'s documentation on seralization]. Value visitors are a simple alternative @@ -725,7 +734,7 @@ pub(in crate::kv) mod inner { 1. Conversions should always produce the same results. If a conversion here returns `Some`, then the same `value_bag`-based conversion must also. Of particular note here are floats to ints; they're - based on the standard library's `TryInto` conversions, which need to be convert to `i32` or `u32`, + based on the standard library's `TryInto` conversions, which need to be converted to `i32` or `u32`, and then to `f64`. 2. VisitValues should always be called in the same way. If a particular type of value calls `visit_i64`, then the same `value_bag`-based visitor must also. diff --git a/src/lib.rs b/src/lib.rs index 6b43a9ae1..4988926db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -143,8 +143,11 @@ //! * [flexi_logger] //! * [call_logger] //! * [structured-logger] +//! * [clang_log] +//! * [ftail] //! * Complex configurable frameworks: //! * [log4rs] +//! * [logforth] //! * [fern] //! * Adaptors for other facilities: //! * [syslog] @@ -321,6 +324,7 @@ //! [syslog]: https://docs.rs/syslog/*/syslog/ //! [slog-stdlog]: https://docs.rs/slog-stdlog/*/slog_stdlog/ //! [log4rs]: https://docs.rs/log4rs/*/log4rs/ +//! [logforth]: https://docs.rs/logforth/*/logforth/ //! [fern]: https://docs.rs/fern/*/fern/ //! [systemd-journal-logger]: https://docs.rs/systemd-journal-logger/*/systemd_journal_logger/ //! [android_log]: https://docs.rs/android_log/*/android_log/ @@ -332,11 +336,13 @@ //! [logcontrol-log]: https://docs.rs/logcontrol-log/*/logcontrol_log/ //! [log_err]: https://docs.rs/log_err/*/log_err/ //! [log-reload]: https://docs.rs/log-reload/*/log_reload/ +//! [clang_log]: https://docs.rs/clang_log/latest/clang_log +//! [ftail]: https://docs.rs/ftail/latest/ftail #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://www.rust-lang.org/favicon.ico", - html_root_url = "https://docs.rs/log/0.4.22" + html_root_url = "https://docs.rs/log/0.4.23" )] #![warn(missing_docs)] #![deny(missing_debug_implementations, unconditional_recursion)] diff --git a/src/serde.rs b/src/serde.rs index 63bef7f97..db732395b 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -11,7 +11,7 @@ use crate::{Level, LevelFilter, LOG_LEVEL_NAMES}; use std::fmt; use std::str::{self, FromStr}; -// The Deserialize impls are handwritten to be case insensitive using FromStr. +// The Deserialize impls are handwritten to be case-insensitive using FromStr. impl Serialize for Level { fn serialize(&self, serializer: S) -> Result @@ -57,7 +57,7 @@ impl<'de> Deserialize<'de> for Level { where E: Error, { - // Case insensitive. + // Case-insensitive. FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES[1..])) } @@ -152,7 +152,7 @@ impl<'de> Deserialize<'de> for LevelFilter { where E: Error, { - // Case insensitive. + // Case-insensitive. FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES)) } diff --git a/tests/src/lib.rs b/tests/src/lib.rs index a791a0c87..a4835fabc 100644 --- a/tests/src/lib.rs +++ b/tests/src/lib.rs @@ -1,6 +1,6 @@ //! This crate is intentionally left empty. //! -//! We have an empty library depending on `log` here so we can run integration tests +//! We have an empty library depending on `log` here, so we can run integration tests //! on older compilers without depending on the unstable `no-dev-deps` flag. #![allow(dead_code)] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy