Skip to content

Commit

Permalink
Merge pull request #137 from tmccombs/structured
Browse files Browse the repository at this point in the history
Add support for Key-Value data in log records.
  • Loading branch information
epage committed Mar 5, 2024
2 parents 8962096 + f6e2d45 commit e55af6f
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 67 deletions.
13 changes: 2 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ color = ["dep:anstream", "dep:anstyle"]
auto-color = ["color", "anstream/auto"]
humantime = ["dep:humantime"]
regex = ["env_filter/regex"]
unstable-kv = ["log/kv"]

[dependencies]
log = { version = "0.4.8", features = ["std"] }
log = { version = "0.4.21", features = ["std"] }
env_filter = { version = "0.1.0", path = "crates/env_filter", default-features = false }
humantime = { version = "2.0.0", optional = true }
anstream = { version = "0.6.11", default-features = false, features = ["wincon"], optional = true }
Expand Down
14 changes: 11 additions & 3 deletions examples/direct_logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,27 @@ use env_logger::{Builder, WriteStyle};

use log::{Level, LevelFilter, Log, MetadataBuilder, Record};

#[cfg(feature = "unstable-kv")]
static KVS: (&str, &str) = ("test", "something");

fn record() -> Record<'static> {
let error_metadata = MetadataBuilder::new()
.target("myApp")
.level(Level::Error)
.build();

Record::builder()
let mut builder = Record::builder();
builder
.metadata(error_metadata)
.args(format_args!("Error!"))
.line(Some(433))
.file(Some("app.rs"))
.module_path(Some("server"))
.build()
.module_path(Some("server"));
#[cfg(feature = "unstable-kv")]
{
builder.key_values(&KVS);
}
builder.build()
}

fn main() {
Expand Down
69 changes: 69 additions & 0 deletions src/fmt/kv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::io::{self, Write};

#[cfg(feature = "color")]
use super::WriteStyle;
use super::{Formatter, StyledValue};
#[cfg(feature = "color")]
use anstyle::Style;
use log::kv::{Error, Key, Source, Value, VisitSource};

/// Format function for serializing key/value pairs
///
/// This function determines how key/value pairs for structured logs are serialized within the default
/// format.
pub(crate) type KvFormatFn = dyn Fn(&mut Formatter, &dyn Source) -> io::Result<()> + Sync + Send;

/// Null Key Value Format
///
/// This function is intended to be passed to
/// [`Builder::format_key_values`](crate::Builder::format_key_values).
///
/// This key value format simply ignores any key/value fields and doesn't include them in the
/// output.
pub fn hidden_kv_format(_formatter: &mut Formatter, _fields: &dyn Source) -> io::Result<()> {
Ok(())
}

/// Default Key Value Format
///
/// This function is intended to be passed to
/// [`Builder::format_key_values`](crate::Builder::format_key_values).
///
/// This is the default key/value format. Which uses an "=" as the separator between the key and
/// value and a " " between each pair.
///
/// For example: `ip=127.0.0.1 port=123456 path=/example`
pub fn default_kv_format(formatter: &mut Formatter, fields: &dyn Source) -> io::Result<()> {
fields
.visit(&mut DefaultVisitSource(formatter))
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
}

struct DefaultVisitSource<'a>(&'a mut Formatter);

impl<'a, 'kvs> VisitSource<'kvs> for DefaultVisitSource<'a> {
fn visit_pair(&mut self, key: Key, value: Value<'kvs>) -> Result<(), Error> {
write!(self.0, " {}={}", self.style_key(key), value)?;
Ok(())
}
}

impl DefaultVisitSource<'_> {
fn style_key<'k>(&self, text: Key<'k>) -> StyledValue<Key<'k>> {
#[cfg(feature = "color")]
{
StyledValue {
style: if self.0.write_style == WriteStyle::Never {
Style::new()
} else {
Style::new().italic()
},
value: text,
}
}
#[cfg(not(feature = "color"))]
{
text
}
}
}
Loading

0 comments on commit e55af6f

Please sign in to comment.