refactor(journaldriver): Use time crate directly instead of chrono
With this change, we still depend on chrono (through medallion), but but I'm going to try and fix that upstream as well. Change-Id: Iefd3d8578ea8870961107f3222dea7f936c2dd9a Reviewed-on: https://cl.tvl.fyi/c/depot/+/5311 Tested-by: BuildkiteCI Autosubmit: tazjin <tazjin@tvl.su> Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
parent
af512558e6
commit
71d6a02ca1
4 changed files with 47 additions and 25 deletions
35
ops/journaldriver/Cargo.lock
generated
35
ops/journaldriver/Cargo.lock
generated
|
@ -94,8 +94,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"serde",
|
"time 0.1.44",
|
||||||
"time",
|
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -112,7 +111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "80f6044740a4a516b8aac14c140cdf35c1a640b1bd6b98b6224e49143b2f1566"
|
checksum = "80f6044740a4a516b8aac14c140cdf35c1a640b1bd6b98b6224e49143b2f1566"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"percent-encoding 2.1.0",
|
"percent-encoding 2.1.0",
|
||||||
"time",
|
"time 0.1.44",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -227,7 +226,6 @@ name = "journaldriver"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
|
@ -237,6 +235,7 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"systemd",
|
"systemd",
|
||||||
|
"time 0.3.7",
|
||||||
"ureq",
|
"ureq",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -343,6 +342,15 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97ba99ba6393e2c3734791401b66902d981cb03bf190af674ca69949b6d5fb15"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
|
@ -596,6 +604,25 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"num_threads",
|
||||||
|
"serde",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
|
|
@ -7,7 +7,6 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
chrono = { version = "0.4", features = [ "serde" ]}
|
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
lazy_static = "1.0"
|
lazy_static = "1.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
@ -16,6 +15,7 @@ serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
systemd = "0.3"
|
systemd = "0.3"
|
||||||
|
time = { version = "0.3", features = [ "serde-well-known", "macros" ]}
|
||||||
ureq = { version = "0.6.2", features = [ "json" ]}
|
ureq = { version = "0.6.2", features = [ "json" ]}
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -31,13 +31,12 @@
|
||||||
//! `GOOGLE_APPLICATION_CREDENTIALS`, `GOOGLE_CLOUD_PROJECT` and
|
//! `GOOGLE_APPLICATION_CREDENTIALS`, `GOOGLE_CLOUD_PROJECT` and
|
||||||
//! `LOG_NAME` environment variables.
|
//! `LOG_NAME` environment variables.
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use chrono::offset::LocalResult;
|
|
||||||
use chrono::prelude::{DateTime, TimeZone, Utc};
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use log::{debug, error, info, trace};
|
use log::{debug, error, info, trace};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{from_str, json, Value};
|
use serde_json::{from_str, json, Value};
|
||||||
|
use std::convert::TryInto;
|
||||||
use std::fs::{self, rename, File};
|
use std::fs::{self, rename, File};
|
||||||
use std::io::{self, ErrorKind, Read, Write};
|
use std::io::{self, ErrorKind, Read, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -239,10 +238,8 @@ fn get_metadata_token() -> Result<Token> {
|
||||||
fn sign_service_account_token(credentials: &Credentials) -> Result<Token> {
|
fn sign_service_account_token(credentials: &Credentials) -> Result<Token> {
|
||||||
use medallion::{Algorithm, Header, Payload};
|
use medallion::{Algorithm, Header, Payload};
|
||||||
|
|
||||||
let iat = Utc::now();
|
let iat = time::OffsetDateTime::now_utc();
|
||||||
let exp = iat
|
let exp = iat + time::Duration::seconds(3600);
|
||||||
.checked_add_signed(chrono::Duration::seconds(3600))
|
|
||||||
.ok_or_else(|| format_err!("Failed to calculate token expiry"))?;
|
|
||||||
|
|
||||||
let header = Header {
|
let header = Header {
|
||||||
alg: Algorithm::RS256,
|
alg: Algorithm::RS256,
|
||||||
|
@ -255,8 +252,8 @@ fn sign_service_account_token(credentials: &Credentials) -> Result<Token> {
|
||||||
iss: Some(credentials.client_email.clone()),
|
iss: Some(credentials.client_email.clone()),
|
||||||
sub: Some(credentials.client_email.clone()),
|
sub: Some(credentials.client_email.clone()),
|
||||||
aud: Some(LOGGING_SERVICE.to_string()),
|
aud: Some(LOGGING_SERVICE.to_string()),
|
||||||
iat: Some(iat.timestamp() as u64),
|
iat: Some(iat.unix_timestamp().try_into().unwrap()),
|
||||||
exp: Some(exp.timestamp() as u64),
|
exp: Some(exp.unix_timestamp().try_into().unwrap()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -338,18 +335,15 @@ fn message_to_payload(message: Option<String>) -> Payload {
|
||||||
/// Parse errors are dismissed and returned as empty options: There
|
/// Parse errors are dismissed and returned as empty options: There
|
||||||
/// simply aren't any useful fallback mechanisms other than defaulting
|
/// simply aren't any useful fallback mechanisms other than defaulting
|
||||||
/// to ingestion time for journaldriver's use-case.
|
/// to ingestion time for journaldriver's use-case.
|
||||||
fn parse_microseconds(input: String) -> Option<DateTime<Utc>> {
|
fn parse_microseconds(input: String) -> Option<time::OffsetDateTime> {
|
||||||
if input.len() != 16 {
|
if input.len() != 16 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let seconds: i64 = (&input[..10]).parse().ok()?;
|
let micros: i128 = input.parse().ok()?;
|
||||||
let micros: u32 = (&input[10..]).parse().ok()?;
|
let nanos: i128 = micros * 1000;
|
||||||
|
|
||||||
match Utc.timestamp_opt(seconds, micros * 1000) {
|
time::OffsetDateTime::from_unix_timestamp_nanos(nanos).ok()
|
||||||
LocalResult::Single(time) => Some(time),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a journald log message priority to a
|
/// Converts a journald log message priority to a
|
||||||
|
@ -398,7 +392,8 @@ struct LogEntry {
|
||||||
labels: Value,
|
labels: Value,
|
||||||
|
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
timestamp: Option<DateTime<Utc>>,
|
#[serde(with = "time::serde::rfc3339::option")]
|
||||||
|
timestamp: Option<time::OffsetDateTime>,
|
||||||
|
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use serde_json::to_string;
|
use serde_json::to_string;
|
||||||
|
use time::macros::datetime;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_text_entry_serialization() {
|
fn test_text_entry_serialization() {
|
||||||
|
@ -23,10 +24,9 @@ fn test_text_entry_serialization() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_timestamped_entry_serialization() {
|
fn test_timestamped_entry_serialization() {
|
||||||
let timestamp: DateTime<Utc> = "1952-10-07T12:00:00Z".to_string().parse().unwrap();
|
|
||||||
let entry = LogEntry {
|
let entry = LogEntry {
|
||||||
labels: Value::Null,
|
labels: Value::Null,
|
||||||
timestamp: Some(timestamp),
|
timestamp: Some(datetime!(1952-10-07 12:00:00 UTC)),
|
||||||
payload: Payload::TextPayload {
|
payload: Payload::TextPayload {
|
||||||
text_payload: "test entry".into(),
|
text_payload: "test entry".into(),
|
||||||
},
|
},
|
||||||
|
@ -125,7 +125,7 @@ fn test_json_no_object() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_microseconds() {
|
fn test_parse_microseconds() {
|
||||||
let input: String = "1529175149291187".into();
|
let input: String = "1529175149291187".into();
|
||||||
let expected: DateTime<Utc> = "2018-06-16T18:52:29.291187Z".to_string().parse().unwrap();
|
let expected: time::OffsetDateTime = datetime!(2018-06-16 18:52:29.291187 UTC);
|
||||||
|
|
||||||
assert_eq!(Some(expected), parse_microseconds(input));
|
assert_eq!(Some(expected), parse_microseconds(input));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue