From 0f57c868061c95c135867efdc6cfc028f3937a75 Mon Sep 17 00:00:00 2001 From: Antoine Grondin Date: Tue, 29 Oct 2024 16:31:23 +0900 Subject: [PATCH] fix(scanner): bring up to Unix(0) if parsed timestamp is negative --- json_handler.go | 9 --------- scanner.go | 9 +++++++++ time_parse.go | 22 ++++++++++++++++++---- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/json_handler.go b/json_handler.go index ca1e7c3f..25919825 100644 --- a/json_handler.go +++ b/json_handler.go @@ -50,15 +50,6 @@ func searchJSON(kvs map[string]interface{}, fieldList []string, found func(key s return false } -func checkEachUntilFound(fieldList []string, found func(string) bool) bool { - for _, field := range fieldList { - if found(field) { - return true - } - } - return false -} - func (h *JSONHandler) clear() { h.Level = "" h.Time = time.Time{} diff --git a/scanner.go b/scanner.go index be265f0f..e7df025b 100644 --- a/scanner.go +++ b/scanner.go @@ -80,3 +80,12 @@ func Scan(ctx context.Context, src io.Reader, sink sink.Sink, opts *HandlerOptio return err } } + +func checkEachUntilFound(fieldList []string, found func(string) bool) bool { + for _, field := range fieldList { + if found(field) { + return true + } + } + return false +} diff --git a/time_parse.go b/time_parse.go index 90ede7bb..2c216d5b 100644 --- a/time_parse.go +++ b/time_parse.go @@ -37,23 +37,37 @@ func parseTimeFloat64(value float64) time.Time { case v > 1e12: v *= 1e6 default: - return time.Unix(v, 0) + return fixTimebeforeUnixZero(time.Unix(v, 0)) } - return time.Unix(v/1e9, v%1e9) + return fixTimebeforeUnixZero(time.Unix(v/1e9, v%1e9)) +} + +var zeroTime = time.Time{} + +func fixTimebeforeUnixZero(t time.Time) time.Time { + if t.Unix() >= 0 { + return t + } + // fast forward in the future at unix 0... unfortunately + // we can't handle times before that, the JSON API stack + // fails to marshal negative UNIX seconds (ConnectRPC) + t = t.AddDate(zeroTime.Year(), 0, 0) + return t } // tries to parse time using a couple of formats before giving up func tryParseTime(value interface{}) (time.Time, bool) { var t time.Time - var err error switch v := value.(type) { case string: for _, layout := range TimeFormats { - t, err = time.Parse(layout, v) + t, err := time.Parse(layout, v) if err == nil { + t = fixTimebeforeUnixZero(t) return t, true } + } // try to parse unix time number from string floatVal, err := strconv.ParseFloat(v, 64)