From b49d04b3dcfcd309270abd750cde96c3624c7aaa Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Mon, 19 Jun 2023 21:21:27 -0700 Subject: [PATCH] lib/promutils.ParseTime(): add support for timestamps in milliseconds See https://stackoverflow.com/questions/76437098/how-to-handle-time-unit-and-step-while-ingesting-or-querying-in-victoriametrics/76438405 Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4459 --- README.md | 1 + docs/CHANGELOG.md | 1 + docs/README.md | 1 + docs/Single-server-VictoriaMetrics.md | 1 + lib/promutils/time.go | 12 ++++++++++-- lib/promutils/time_test.go | 7 +++++++ 6 files changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 387f6c4dc..6a9c3cb48 100644 --- a/README.md +++ b/README.md @@ -823,6 +823,7 @@ in [query APIs](https://docs.victoriametrics.com/#prometheus-querying-api-usage) in [export APIs](https://docs.victoriametrics.com/#how-to-export-time-series). - Unix timestamps in seconds with optional milliseconds after the point. For example, `1562529662.678`. +- Unix timestamps in milliseconds. For example, `1562529662678`. - [RFC3339](https://www.ietf.org/rfc/rfc3339.txt). For example, `2022-03-29T01:02:03Z` or `2022-03-29T01:02:03+02:30`. - Partial RFC3339. Examples: `2022`, `2022-03`, `2022-03-29`, `2022-03-29T01`, `2022-03-29T01:02`, `2022-03-29T01:02:03`. The partial RFC3339 time is in UTC timezone by default. It is possible to specify timezone there by adding `+hh:mm` or `-hh:mm` suffix to partial time. diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index dc61c396a..987dfac9d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -32,6 +32,7 @@ The following tip changes can be tested by building VictoriaMetrics components f * FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): update backoff policy on retries to reduce probability of overloading for `source` or `destination` databases. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4442). * FEATURE: vmstorage: suppress "broken pipe" errors for search queries on vmstorage side. See [this commit](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4418/commits/a6a7795b9e1f210d614a2c5f9a3016b97ded4792). * FEATURE: [Official Grafana dashboards for VictoriaMetrics](https://grafana.com/orgs/victoriametrics): add panel for tracking rate of syscalls while writing or reading from disk via `process_io_(read|write)_syscalls_total` metrics. +* FEATURE: accept timestamps in milliseconds at `start`, `end` and `time` query args in [Prometheus querying API](https://docs.victoriametrics.com/#prometheus-querying-api-usage). See [these docs](https://docs.victoriametrics.com/#timestamp-formats) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4459). * BUGFIX: add the following command-line flags, which can be used for limiting Graphite API calls: `--search.maxGraphiteTagKeys` for limiting the number of tag keys returned from Graphite `/tags`, `/tags/autoComplete/*`, `/tags/findSeries` API. diff --git a/docs/README.md b/docs/README.md index 1cdd98492..869cdeff7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -826,6 +826,7 @@ in [query APIs](https://docs.victoriametrics.com/#prometheus-querying-api-usage) in [export APIs](https://docs.victoriametrics.com/#how-to-export-time-series). - Unix timestamps in seconds with optional milliseconds after the point. For example, `1562529662.678`. +- Unix timestamps in milliseconds. For example, `1562529662678`. - [RFC3339](https://www.ietf.org/rfc/rfc3339.txt). For example, `2022-03-29T01:02:03Z` or `2022-03-29T01:02:03+02:30`. - Partial RFC3339. Examples: `2022`, `2022-03`, `2022-03-29`, `2022-03-29T01`, `2022-03-29T01:02`, `2022-03-29T01:02:03`. The partial RFC3339 time is in UTC timezone by default. It is possible to specify timezone there by adding `+hh:mm` or `-hh:mm` suffix to partial time. diff --git a/docs/Single-server-VictoriaMetrics.md b/docs/Single-server-VictoriaMetrics.md index d7accfbef..487e608ba 100644 --- a/docs/Single-server-VictoriaMetrics.md +++ b/docs/Single-server-VictoriaMetrics.md @@ -834,6 +834,7 @@ in [query APIs](https://docs.victoriametrics.com/#prometheus-querying-api-usage) in [export APIs](https://docs.victoriametrics.com/#how-to-export-time-series). - Unix timestamps in seconds with optional milliseconds after the point. For example, `1562529662.678`. +- Unix timestamps in milliseconds. For example, `1562529662678`. - [RFC3339](https://www.ietf.org/rfc/rfc3339.txt). For example, `2022-03-29T01:02:03Z` or `2022-03-29T01:02:03+02:30`. - Partial RFC3339. Examples: `2022`, `2022-03`, `2022-03-29`, `2022-03-29T01`, `2022-03-29T01:02`, `2022-03-29T01:02:03`. The partial RFC3339 time is in UTC timezone by default. It is possible to specify timezone there by adding `+hh:mm` or `-hh:mm` suffix to partial time. diff --git a/lib/promutils/time.go b/lib/promutils/time.go index 986790f43..1f644ef40 100644 --- a/lib/promutils/time.go +++ b/lib/promutils/time.go @@ -70,8 +70,16 @@ func ParseTimeAt(s string, currentTimestamp float64) (float64, error) { return tzOffset + float64(t.UnixNano())/1e9, nil } if !strings.Contains(sOrig, "-") { - // Parse the timestamp in seconds - return strconv.ParseFloat(sOrig, 64) + // Parse the timestamp in seconds or in milliseconds + ts, err := strconv.ParseFloat(sOrig, 64) + if err != nil { + return 0, err + } + if ts >= (1 << 32) { + // The timestamp is in milliseconds. Convert it to seconds. + ts /= 1000 + } + return ts, nil } if len(s) == 7 { // Parse YYYY-MM diff --git a/lib/promutils/time_test.go b/lib/promutils/time_test.go index fec51f6ac..cb311348d 100644 --- a/lib/promutils/time_test.go +++ b/lib/promutils/time_test.go @@ -19,6 +19,13 @@ func TestParseTimeAtSuccess(t *testing.T) { now := float64(time.Now().UnixNano()) / 1e9 + // unix timestamp in seconds + f("1562529662", now, 1562529662) + f("1562529662.678", now, 1562529662.678) + + // unix timestamp in milliseconds + f("1562529662678", now, 1562529662.678) + // duration relative to the current time f("now", now, now) f("1h5s", now, now-3605)