From 8eb53dee120f1349493a45c6b5acbd5bb2628730 Mon Sep 17 00:00:00 2001 From: Nathaniel May Date: Wed, 1 Dec 2021 16:44:50 -0500 Subject: [PATCH] preformat rfc3339 --- core/dbt/events/base_types.py | 11 ++++++++++- core/dbt/events/functions.py | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/dbt/events/base_types.py b/core/dbt/events/base_types.py index 5e7ae57f154..cdf80a36628 100644 --- a/core/dbt/events/base_types.py +++ b/core/dbt/events/base_types.py @@ -75,6 +75,7 @@ class Event(metaclass=ABCMeta): # fields that should be on all events with their default implementations log_version: int = 1 ts: Optional[datetime] = None # use getter for non-optional + ts_rfc3339: Optional[str] = None # use getter for non-optional pid: Optional[int] = None # use getter for non-optional node_info: Optional[Node] @@ -119,9 +120,17 @@ def fields_to_json(self, field_value: Any) -> Any: # exactly one time stamp per concrete event def get_ts(self) -> datetime: if not self.ts: - self.ts = datetime.now() + self.ts = datetime.utcnow() + self.ts_rfc3339 = self.ts.strftime('%Y-%m-%dT%H:%M:%S.%fZ') return self.ts + # preformatted time stamp + def get_ts_rfc3339(self) -> str: + if not self.ts_rfc3339: + # get_ts() creates the formatted string too so all time logic is centralized + self.get_ts() + return self.ts_rfc3339 # type: ignore + # exactly one pid per concrete event def get_pid(self) -> int: if not self.pid: diff --git a/core/dbt/events/functions.py b/core/dbt/events/functions.py index e67cbd8b8b8..844f3dae083 100644 --- a/core/dbt/events/functions.py +++ b/core/dbt/events/functions.py @@ -174,7 +174,8 @@ def create_text_log_line(e: T_Event, msg_fn: Callable[[T_Event], str]) -> str: # translates an Event to a completely formatted json log line # you have to specify which message you want. (i.e. - e.message(), e.cli_msg(), e.file_msg()) def create_json_log_line(e: T_Event, msg_fn: Callable[[T_Event], str]) -> str: - values = event_to_serializable_dict(e, lambda dt: dt.isoformat(), lambda x: msg_fn(x)) + # using preformatted string instead of formatting it here to be extra careful about timezone + values = event_to_serializable_dict(e, lambda _: e.get_ts_rfc3339(), lambda x: msg_fn(x)) raw_log_line = json.dumps(values, sort_keys=True) return scrub_secrets(raw_log_line, env_secrets())