Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API passes model.Earliest incorrectly #951

Open
bboreham opened this issue Dec 20, 2021 · 3 comments
Open

API passes model.Earliest incorrectly #951

bboreham opened this issue Dec 20, 2021 · 3 comments

Comments

@bboreham
Copy link
Member

If you pass model.Earliest.Time() to prometheus/client_golang it sends -9223372036854776, which is 192 milliseconds less than the original. This value will cause an overflow when read by prometheus/web/api/v1, turning it into a very large positive time.

I am using github.com/prometheus/client_golang v1.11.0
and github.com/prometheus/client_model v0.2.0.

To illustrate:
https://go.dev/play/p/b_75bSN2Gyr

package main

import (
	"fmt"
	"strconv"
	"time"

	"github.com/prometheus/common/model"
)

// As found in github.com/prometheus/common/model
func formatTime(t time.Time) string {
	return strconv.FormatFloat(float64(t.Unix())+float64(t.Nanosecond())/1e9, 'f', -1, 64)
}

// As found in github.com/prometheus/prometheus/model/timestamp
func FromTime(t time.Time) int64 {
	return t.Unix()*1000 + int64(t.Nanosecond())/int64(time.Millisecond)
}

func main() {
	t1 := model.Earliest.Time()
	fmt.Println(formatTime(t1))
	t2 := time.Unix(-9223372036854776, 0)  // this is the number output by the previous line
	fmt.Println(t1, FromTime(t1))
	fmt.Println(t2, FromTime(t2))
}

I believe the problem arises because strconv.FormatFloat() is asked to round the number as if it came from a float64, and model.Earliest is the largest negative int64 so it doesn't fit in a float64, and the milliseconds get dropped.

This arose while trying to work round #621

@bboreham bboreham changed the title API passes time.Earliest incorrectly API passes model.Earliest incorrectly Dec 20, 2021
@kakkoyun kakkoyun added the bug label Dec 21, 2021
@kakkoyun
Copy link
Member

kakkoyun commented Jan 5, 2022

Thanks for reporting @bboreham. Help wanted if anyone is interested for a chance to contribute.

@bboreham
Copy link
Member Author

bboreham commented Jan 5, 2022

I couldn't think of a clean and painless way to fix it. Maybe special-case the exact numbers/strings?

Conceptually I'd like model.Earliest to be this value: https://github.com/prometheus/prometheus/blob/d26fd5c97b0c505f5cb36f719abd6ccc8130bdc9/web/api/v1/api.go#L689

but it seems unlikely we can make that change without breaking people.
Maybe add that as a new model constant and deprecate Earliest ?

@bwplotka
Copy link
Member

I think we should first of all detect too high or too low timestamp, before conversion. It's easy thx to prometheus/prometheus#14986 experments and docs.

Now we need another Earliest / max time indeed.... perhaps exactly the Max and Min time in api for completness? prometheus/prometheus#14986

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants