From 982142e87df8a60e056a6e9e7a6b9c8c709947d9 Mon Sep 17 00:00:00 2001 From: Greg Linton Date: Fri, 14 Dec 2018 11:28:58 -0700 Subject: [PATCH] Add micro and nanosecond unix timestamp support to JSON parser --- plugins/parsers/json/README.md | 9 +++++---- plugins/parsers/json/parser.go | 11 ++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/plugins/parsers/json/README.md b/plugins/parsers/json/README.md index 05ed6242fe770..a48575cba544a 100644 --- a/plugins/parsers/json/README.md +++ b/plugins/parsers/json/README.md @@ -41,8 +41,8 @@ ignored unless specified in the `tag_key` or `json_string_fields` options. ## metric. json_time_key = "" - ## Time format is the time layout that should be used to interprete the - ## json_time_key. The time must be `unix`, `unix_ms` or a time in the + ## Time format is the time layout that should be used to interprete the json_time_key. + ## The time must be `unix`, `unix_ms`, `unix_us`, `unix_ns`, or a time in the ## "reference time". To define a different format, arrange the values from ## the "reference time" in the example to match the format you will be ## using. For more information on the "reference time", visit @@ -70,8 +70,9 @@ time using the JSON document you can use the `json_time_key` and document. The `json_time_key` option specifies the key containing the time value and -`json_time_format` must be set to `unix`, `unix_ms`, or the Go "reference -time" which is defined to be the specific time: `Mon Jan 2 15:04:05 MST 2006`. +`json_time_format` must be set to `unix`, `unix_ms`, `unix_us`, `unix_ns`, or +the Go "reference time" which is defined to be the specific time: +`Mon Jan 2 15:04:05 MST 2006`. Consult the Go [time][time parse] package for details and additional examples on how to set the time format. diff --git a/plugins/parsers/json/parser.go b/plugins/parsers/json/parser.go index 19a92275bf210..b3bb9a488b6dd 100644 --- a/plugins/parsers/json/parser.go +++ b/plugins/parsers/json/parser.go @@ -52,6 +52,8 @@ func (p *JSONParser) parseArray(buf []byte) ([]telegraf.Metric, error) { // format = "unix": epoch is assumed to be in seconds and can come as number or string. Can have a decimal part. // format = "unix_ms": epoch is assumed to be in milliseconds and can come as number or string. Cannot have a decimal part. +// format = "unix_us": epoch is assumed to be in microseconds and can come as number or string. Cannot have a decimal part. +// format = "unix_ns": epoch is assumed to be in nanoseconds and can come as number or string. Cannot have a decimal part. func parseUnixTimestamp(jsonValue interface{}, format string) (time.Time, error) { timeInt, timeFractional := int64(0), int64(0) timeEpochStr, ok := jsonValue.(string) @@ -88,6 +90,10 @@ func parseUnixTimestamp(jsonValue interface{}, format string) (time.Time, error) return time.Unix(timeInt, timeFractional).UTC(), nil } else if strings.EqualFold(format, "unix_ms") { return time.Unix(timeInt/1000, (timeInt%1000)*1e6).UTC(), nil + } else if strings.EqualFold(format, "unix_us") { + return time.Unix(0, timeInt*1e3).UTC(), nil + } else if strings.EqualFold(format, "unix_ns") { + return time.Unix(0, timeInt).UTC(), nil } else { return time.Time{}, errors.New("Invalid unix format") } @@ -126,7 +132,10 @@ func (p *JSONParser) parseObject(metrics []telegraf.Metric, jsonOut map[string]i return nil, err } - if strings.EqualFold(p.JSONTimeFormat, "unix") || strings.EqualFold(p.JSONTimeFormat, "unix_ms") { + if strings.EqualFold(p.JSONTimeFormat, "unix") || + strings.EqualFold(p.JSONTimeFormat, "unix_ms") || + strings.EqualFold(p.JSONTimeFormat, "unix_us") || + strings.EqualFold(p.JSONTimeFormat, "unix_ns") { nTime, err = parseUnixTimestamp(f.Fields[p.JSONTimeKey], p.JSONTimeFormat) if err != nil { return nil, err