Skip to content

Commit

Permalink
add number timestamps
Browse files Browse the repository at this point in the history
  • Loading branch information
bomgar committed May 21, 2024
1 parent 1fae472 commit 0447dd3
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 2 deletions.
137 changes: 137 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ clap_complete = "4"
serde = { version = "1", features = ["derive"] }
toml = "0.8"
dirs = "5"
chrono = "0.4.38"

[dependencies.clap]
version = "4"
Expand Down
1 change: 1 addition & 0 deletions sample.json.log
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ with prefix and not parsable | {"level
with prefix | {"level":"xyz","msg":"<>Trust key rsa-43fe6c3d-6242-11e7-8b0c-02420a000007 found in cache","package":"trust","process":"gatekeeper","store":"cache","time":"2017-07-06T15:21:16Z","version":"0.1.20170620v0125"}
with prefix | {"level":"debug","msg":"Trust key rsa-43fe6c3d-6242-11e7-8b0c-02420a000007 found in cache","package":"trust","process":"gatekeeper","store":"cache","time":"2017-07-06T15:21:16Z","version":"0.1.20170620v0125"}
{"level":"info","msg":"<>Trust key rsa-43fe6c3d-6242-11e7-8b0c-02420a000007 found in cache","package":"trust","process":"gatekeeper","store":"cache","time":"2017-07-06T15:21:16Z","version":"0.1.20170620v0125"}
{"level":"info","msg":"<>Trust key rsa-43fe6c3d-6242-11e7-8b0c-02420a000007 found in cache","package":"trust","process":"gatekeeper","store":"cache","time":"1716292213381","version":"-1.1.20170620v0125"}
{"timestamp":"<>2017-07-06T15:21:16.378+00:00","@version":1,"short_message":"Content-Type set both in header (application/json) and attached to entity (text/plain; charset=utf-8), ignoring content type from entity. To remove this warning, use Result.as(...) to set the content type, rather than setting the header manually.","logger_name":"play.core.server.netty.NettyModelConversion","thread_name":"application-akka.actor.default-dispatcher-114","severity":"WARN","level_value":30000,"HOSTNAME":"b54f64d212ac","application.home":"/opt/docker","process":"play"}
{"bytes":0,"fields.time":"13.288673ms","flow_id":"c1114163-625e-11e7-90fe-02420a000016","level":"info","method":"GET","millis":13.288673,"msg":"Request: Success","package":"proxy","process":"gatekeeper","status":200,"time":"2017-07-06T15:21:16Z","type":"access","uri":"/internal/metrics","version":"0.1.20170620v0125"}
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ mod tests {
"#,
)
.unwrap();
assert_eq!(config.level_map.is_empty(), true);
assert!(config.level_map.is_empty());
}

#[test]
Expand Down
3 changes: 2 additions & 1 deletion src/log.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::log_settings::LogSettings;
use crate::time::try_convert_timestamp_to_readable;
use handlebars::Handlebars;
use serde_json::{Map, Value};
use std::borrow::ToOwned;
Expand All @@ -21,7 +22,7 @@ pub fn print_log_line(

let trimmed_prefix = maybe_prefix.map(|p| p.trim()).unwrap_or_else(|| "").to_string();
let mut message = get_string_value_or_default(&string_log_entry, &log_settings.message_keys, "");
let timestamp = get_string_value_or_default(&string_log_entry, &log_settings.time_keys, "");
let timestamp = try_convert_timestamp_to_readable(get_string_value_or_default(&string_log_entry, &log_settings.time_keys, ""));

if let Some(message_template) = &log_settings.substitution {
if let Some(templated_message) = message_template.apply(&message, log_entry) {
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod log_settings;
mod process;
mod substitution;
mod template;
mod time;

use crate::log_settings::LogSettings;
use clap_complete::{generate, Shell};
Expand Down
73 changes: 73 additions & 0 deletions src/time.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use chrono::{LocalResult, TimeZone, Utc};

fn timestamp_to_iso8601(timestamp: i64) -> Option<String> {
let now = Utc::now();

let dt_secs = Utc.timestamp_opt(timestamp, 0);
let dt_millis = Utc.timestamp_millis_opt(timestamp);

match (dt_secs, dt_millis) {
(LocalResult::Single(dt_secs), LocalResult::Single(dt_millis)) => {
let diff_secs = (now - dt_secs).num_milliseconds().abs();
let diff_millis = (now - dt_millis).num_milliseconds().abs();

if diff_secs < diff_millis {
Some(dt_secs.to_rfc3339_opts(chrono::SecondsFormat::Millis, true))
} else {
Some(dt_millis.to_rfc3339_opts(chrono::SecondsFormat::Millis, true))
}
}
(LocalResult::Single(dt_secs), _) => Some(dt_secs.to_rfc3339_opts(chrono::SecondsFormat::Millis, true)),
(_, LocalResult::Single(dt_millis)) => Some(dt_millis.to_rfc3339_opts(chrono::SecondsFormat::Millis, true)),
_ => None, // Neither is valid (or ambiguous due to time zone transitions)
}
}

fn is_only_digits(input: &str) -> bool {
input.chars().all(char::is_numeric)
}

pub fn try_convert_timestamp_to_readable(input: String) -> String {
if input.is_empty() {
return input;
}

if is_only_digits(&input) {
if let Some(parsed) = input.parse::<i64>().ok().and_then(timestamp_to_iso8601) {
return parsed;
}
}

input
}

#[cfg(test)]
mod tests {
use chrono::DateTime;

use super::*;

#[test]
fn test_valid_second_timestamp() {
let iso = "2024-05-21T11:21:29.000Z";
let timestamp = DateTime::parse_from_rfc3339(iso).expect("should be valid").timestamp();
let result = timestamp_to_iso8601(timestamp).unwrap();
assert_eq!(iso, result)
}

#[test]
fn test_valid_millis_timestamp() {
let iso = "2024-05-21T11:21:29.536Z";
let timestamp = DateTime::parse_from_rfc3339(iso).expect("should be valid").timestamp_millis();
let result = timestamp_to_iso8601(timestamp).unwrap();
assert_eq!(iso, result)
}

#[test]
fn test_try_convert() {
assert_eq!(try_convert_timestamp_to_readable("1716292213381".to_string()), "2024-05-21T11:50:13.381Z");
assert_eq!(try_convert_timestamp_to_readable("1716292213".to_string()), "2024-05-21T11:50:13.000Z");
assert_eq!(try_convert_timestamp_to_readable("bla".to_string()), "bla");
assert_eq!(try_convert_timestamp_to_readable("".to_string()), "");
}
}

0 comments on commit 0447dd3

Please sign in to comment.