| Crates.io | logform |
| lib.rs | logform |
| version | 0.5.2 |
| created_at | 2024-08-24 00:39:48.407504+00 |
| updated_at | 2025-09-05 15:51:05.749885+00 |
| description | logform for rust |
| homepage | |
| repository | https://github.com/ifeanyi-ugwu/logform_rs |
| max_upload_size | |
| id | 1349745 |
| size | 169,880 |
logform
A flexible log formatting library designed for chaining and composing log transformations in Rust.
logform provides a powerful, extensible system to transform structured log messages via composable formatters called Formats. Each format implements a common Format trait, enabling flexible composition and transformation pipelines.
use logform::{timestamp, colorize, align, Format, LogInfo};
fn main() {
// Compose multiple formats using chaining
let formatter = timestamp()
.chain(colorize())
.chain(align());
let info = LogInfo::new("info", "Hello, logform!");
// Apply the composed formatter
if let Some(transformed) = formatter.transform(info) {
println!("{}", transformed.message);
}
}
LogInfo — Structured Log DataAt the core is the LogInfo struct representing a single log message:
pub struct LogInfo {
pub level: String,
pub message: String,
pub meta: std::collections::HashMap<String, serde_json::Value>,
}
Create a new LogInfo:
let info = LogInfo::new("info", "User logged in");
Add metadata fields:
let info = info.with_meta("user_id", 12345)
.with_meta("session_id", "abcde12345");
Remove metadata:
let info = info.without_meta("session_id");
Access metadata:
if let Some(serde_json::Value::Number(id)) = info.meta.get("user_id") {
// use id...
}
Format TraitFormats implement the Format trait to transform log messages:
pub trait Format {
type Input;
/// Transforms the input log message, returning:
/// - `Some(LogInfo)` for transformed logs
/// - `None` to filter out the log (skip it)
fn transform(&self, input: Self::Input) -> Option<LogInfo>;
/// Chain two formats, applying one after another
fn chain<F>(self, next: F) -> ChainedFormat<Self, F>
where
Self: Sized,
F: Format<Input = Self::Input>,
{
ChainedFormat { first: self, next }
}
}
None): Skip processing or output for certain logs.You can chain multiple formats using the chain method:
let combined = timestamp().chain(json()).chain(colorize());
Or use the chain! macro for succinct chaining of multiple formats:
use logform::chain;
let combined = chain!(timestamp(), json(), colorize());
Chaining stops early when any format returns None (useful for filtering logs).
timestampAdds a timestamp to the log metadata.
Builder methods:
.with_format(&str) — Customize timestamp display format (uses chrono formatting)..with_alias(&str) — Add an alias field for the timestamp.let ts = timestamp()
.with_format("%Y-%m-%d %H:%M:%S")
.with_alias("time");
simpleA minimal text formatter producing output like:
level: message { ...metadata... }
Respects padding stored in meta under "padding" to align levels nicely.
jsonSerializes the log info into a JSON string:
{ "level": "info", "message": "User logged in", "user_id": 12345 }
alignAdds a tab character before the message, useful for aligned output.
cliCombines colorizing and padding:
.with_levels(), .with_colors(), .with_filler(), and .with_all().Example:
let cli_format = cli()
.with_filler("*")
.with_all(true);
let out = cli_format.transform(info).unwrap();
colorizeProvides colorization for levels and messages via colored crate.
Configurable options include:
.with_all(bool).with_level(bool).with_message(bool).with_colors(...) to specify colors for levels.uncolorizeStrips ANSI color codes from level and/or message.
labelAdds a label either as a prefix to the message or into metadata.
Builder:
.with_label("MY_LABEL").with_message(true|false) — if true, prefix message; else add to meta.logstashTransforms the log info into a Logstash-compatible JSON string with fields like @timestamp, @message, and @fields.
metadataCollects metadata keys into a single key.
Builder methods:
.with_key(&str) — metadata container key (default: "metadata")..with_fill_except(Vec<&str>) — exclude keys..with_fill_with(Vec<&str>) — include only these keys.msAdds time elapsed since the previous log message in milliseconds in the meta key "ms".
pad_levelsPads the message to align levels uniformly.
Configurable:
.with_levels(...).with_filler(...)pretty_printPrettifies log output in a human-friendly format, optionally colorized.
Builder:
.with_colorize(bool)printfCustomize the output with any formatting closure:
let printf_format = printf(|info| {
format!("{} - {}: {}",
info.level,
info.message,
serde_json::to_string(&info.meta).unwrap()
)
});
A format can filter out unwanted logs by returning None from transform.
Example:
struct IgnorePrivate;
impl Format for IgnorePrivate {
type Input = LogInfo;
fn transform(&self, info: LogInfo) -> Option<LogInfo> {
if let Some(private) = info.meta.get("private") {
use serde_json::Value;
if matches!(private, Value::Bool(true)) || private == "true" {
return None;
}
}
Some(info)
}
}
When chained, subsequent formats will not run if any upstream returns None.
logformImplement Format for custom transformations over any input type:
struct UpperCase;
impl Format for UpperCase {
type Input = String;
fn transform(&self, input: String) -> Option<String> {
if input.is_empty() {
None
} else {
Some(input.to_uppercase())
}
}
}
Then chain with other formats for composable log processing.
Add to your Cargo.toml:
[dependencies]
logform = "0.5"
Or use cargo:
cargo add logform
This project is licensed under the MIT License.