Skip to content

Commit

Permalink
Allow specification of the time zone in pattern
Browse files Browse the repository at this point in the history
Closes #20
  • Loading branch information
sfackler committed May 26, 2016
1 parent 6a569b0 commit ac1276a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
50 changes: 40 additions & 10 deletions src/encode/pattern/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//! ```not_rust
//! format_string := <text> [ format <text> ] *
//! format := '{' formatter [ ':' format_spec ] '}'
//! formatter := [ name ] [ '(' argument ')' ]
//! formatter := [ name ] [ '(' argument ')' ] *
//! name := identifier
//! argument := format_string
//!
Expand All @@ -21,17 +21,19 @@
//!
//! A formatter inserts a dynamic portion of text into the pattern. It may be
//! text derived from a log event or from some other context like the current
//! time. Formatters may be passed an argument consisting of a parenthesized
//! format string. If an argument is not provided, it is equivalent to an empty
//! format string (i.e. `{foo}` `{foo()}` are equivalent).
//! time. Formatters may be passed arguments consisting of parenthesized format
//! strings.
//!
//! The following formatters are currently supported. Unless otherwise stated,
//! a formatter does not accept any argument.
//!
//! * `d`, `date` - The current time. By default, the ISO 8601 format is used.
//! A custom format may be provided in the syntax accepted by `chrono`.
//! The timezone defaults to UTC, but can be specified explicitly by passing
//! a second argument of `utc` for UTC or `local` for local time.
//! * `{d}` - `2016-03-20T22:22:20.644420340+00:00`
//! * `{d(%Y-%m-%d %H:%M:%S)}` - `2016-03-20 22:22:20`
//! * `{d(%Y-%m-%d %H:%M:%S %Z)(local)}` - `2016-03-20 14:22:20 PST`
//! * `f`, `file` - The source file that the log message came from.
//! * `h`, `highlight` - Styles its argument according to the log level. The
//! style is intense red for errors, red for warnings, blue for info, and
Expand Down Expand Up @@ -352,11 +354,14 @@ impl<'a> From<Piece<'a>> for Chunk {
match formatter.name {
"d" |
"date" => {
let format = match formatter.args.len() {
0 => "%+".to_owned(),
1 => {
if formatter.args.len() > 2 {
return Chunk::Error("expected at most two arguments".to_owned());
}

let format = match formatter.args.get(0) {
Some(arg) => {
let mut format = String::new();
for piece in &formatter.args[0] {
for piece in arg {
match *piece {
Piece::Text(text) => format.push_str(text),
Piece::Argument { .. } => {
Expand All @@ -369,16 +374,34 @@ impl<'a> From<Piece<'a>> for Chunk {
}
}
}
// FIXME remove in next breaking release
if format.is_empty() {
format.push_str("%+");
}
format
}
_ => return Chunk::Error("expected at most one argument".to_owned()),
None => "%+".to_owned(),
};

let timezone = match formatter.args.get(1) {
Some(arg) => {
if arg.len() != 1 {
return Chunk::Error("invalid timezone".to_owned());
}
match arg[0] {
Piece::Text(ref z) if *z == "utc" => Timezone::Utc,
Piece::Text(ref z) if *z == "local" => Timezone::Local,
Piece::Text(ref z) => {
return Chunk::Error(format!("invalid timezone `{}`", z));
}
_ => return Chunk::Error("invalid timezone".to_owned()),
}
}
None => Timezone::Utc,
};

Chunk::Formatted {
chunk: FormattedChunk::Time(format, Timezone::Utc),
chunk: FormattedChunk::Time(format, timezone),
params: parameters,
}
}
Expand Down Expand Up @@ -781,4 +804,11 @@ mod tests {
fn custom_date_format() {
assert!(error_free(&PatternEncoder::new("{d(%Y-%m-%d %H:%M:%S)} {m}{n}")));
}

#[test]
fn timezones() {
assert!(error_free(&PatternEncoder::new("{d(%+)(utc)}")));
assert!(error_free(&PatternEncoder::new("{d(%+)(local)}")));
assert!(!error_free(&PatternEncoder::new("{d(%+)(foo)}")));
}
}
4 changes: 2 additions & 2 deletions test/log.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
refresh_rate = 5
refresh_rate = "5 seconds"

[appenders.console]
kind = "console"

[appenders.console.encoder]
pattern = "{d} [{t}] {h({l})} {M}:{m}{n}"
pattern = "{d(%+)(local)} [{t}] {h({l})} {M}:{m}{n}"

[[appenders.console.filter]]
kind = "threshold"
Expand Down

0 comments on commit ac1276a

Please sign in to comment.