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

SEARCH-8423 Fix time field type #34

Merged
merged 1 commit into from
Jan 27, 2025

Conversation

dcheckoway
Copy link
Collaborator

What Was Wrong

Grafana was saying Data is missing a time field and wouldn't let you graph the data as a time series (or anything related to time). It was confusing, since clearly there's a Time field with valid timestamps.

We were passing back the time field as an ISO string...which was more or less fine, but we were inadvertently setting the field type to string -- implicitly because of the value's native type. Apparently the name time alone and the ISO format wasn't enough for Grafana to recognize it.

And the real problem is: Grafana's Go data library doesn't let you explicitly set the type on a field. This is kinda crummy API design, but they're trying to make it easy -- just set the value and the data layer figures out what it is. But when we pass a string, it thinks the type is string.

What's Changing

Use the time.Time struct so Grafana's data layer knows that it's actually time.

To Verify

Run a query that produces timestats (or anything with time, really) and try to add it to a dashboard as a Time Series visualization.

@@ -90,6 +90,8 @@ func makeEmptyConcreteTypeArray(val interface{}) (interface{}, error) {
return []float64{}, nil
case bool:
return []bool{}, nil
case time.Time:
return []time.Time{}, nil
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really key. As you populate fields in a data frame, Grafana's data layer infers the field type from this array type.

nanoSec := int64(math.Round((seconds-float64(wholeSec))*1000.0)) * 1000000 // ms precision
return true, time.Unix(wholeSec, nanoSec).UTC().Format(time.RFC3339Nano)
nanoSec := int64(math.Round((seconds-float64(wholeSec))*1000000.0)) * 1000 // microsec precision
return true, time.Unix(wholeSec, nanoSec).UTC()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: I changed this to microsec because we can, and it provides additional granularly should it be needed. I tried nanoseconds and was getting some floating point precision garbage (i.e. 122999 instead of 123000), so I figured this is good enough for ~100% of the likely scenarios.

Copy link
Collaborator

@natecanfield822 natecanfield822 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice - Verified as well!

@dcheckoway dcheckoway merged commit 52f440d into main Jan 27, 2025
10 checks passed
@dcheckoway dcheckoway deleted the dc/SEARCH-8423-data-is-missing-a-time-field branch January 27, 2025 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants