Skip to content

Commit d241fb3

Browse files
authored
issue-147: show the correct response with nanosecond precision (#155)
* issue-147: show the correct response with nanosecond precision * issue-147: fix changelog * issue-147: fix test filename * issue-147: remove nanoseconds to milliseconds, clarify errors * issue-147: fix changes
1 parent 440430c commit d241fb3

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
* FEATURE: add compatibility for Grafana `v10.x.x` to ensure `/select/logs/hits` displays precise logs volume on the Explore page. See [this comment](https://github.com/VictoriaMetrics/victorialogs-datasource/pull/146#issuecomment-2533419498).
66

7+
* BUGFIX: properly parse timestamps with milliseconds precision in datasource response. See [this issue](https://github.com/VictoriaMetrics/victorialogs-datasource/issues/147).
8+
79
## v0.11.1
810

911
* BUGFIX: fix the check for the stats pipe functions in expressions.

pkg/plugin/response.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,17 @@ func (ls logStats) vectorDataFrames() (data.Frames, error) {
378378
for i, res := range ls.Result {
379379
f, err := strconv.ParseFloat(res.Value[1].(string), 64)
380380
if err != nil {
381-
return nil, fmt.Errorf("metric %v, unable to parse float64 from %s: %w", res, res.Value[1], err)
381+
return nil, fmt.Errorf("metric %v, unable to parse timestamp to float64 from %s: %w", res, res.Value[1], err)
382382
}
383383

384-
ts := time.Unix(int64(res.Value[0].(float64)), 0)
384+
v, ok := res.Value[0].(float64)
385+
if !ok {
386+
return nil, fmt.Errorf("metric %v, unable to convert metrics value to float64 from %s", res, res.Value[0])
387+
}
388+
389+
seconds := int64(v) // get only seconds
390+
nanoseconds := int64((v - float64(seconds)) * 1e9) // get only nanoseconds
391+
ts := time.Unix(seconds, nanoseconds)
385392
frames[i] = data.NewFrame("",
386393
data.NewField(data.TimeSeriesTimeFieldName, nil, []time.Time{ts}),
387394
data.NewField(data.TimeSeriesValueFieldName, data.Labels(res.Labels), []float64{f}))
@@ -398,13 +405,15 @@ func (ls logStats) matrixDataFrames() (data.Frames, error) {
398405
for j, value := range res.Values {
399406
v, ok := value[0].(float64)
400407
if !ok {
401-
return nil, fmt.Errorf("error get time from dataframes")
408+
return nil, fmt.Errorf("metric %v, value: %v unable to parse timestamp to float64 from %s", res, value, value[0])
402409
}
403-
timestamps[j] = time.Unix(int64(v), 0)
410+
seconds := int64(v) // get only seconds
411+
nanoseconds := int64((v - float64(seconds)) * 1e9) // get only nanoseconds
412+
timestamps[j] = time.Unix(seconds, nanoseconds)
404413

405414
f, err := strconv.ParseFloat(value[1].(string), 64)
406415
if err != nil {
407-
return nil, fmt.Errorf("erro get value from dataframes: %s", err)
416+
return nil, fmt.Errorf("metric %v, value: %v unable to convert metrics value to float64 from %s", res, value, value[1])
408417
}
409418
values[j] = f
410419
}

pkg/plugin/response_test.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,31 @@ func Test_getStatsResponse(t *testing.T) {
582582
return rsp
583583
},
584584
},
585+
{
586+
name: "response with milliseconds in timestamps",
587+
filename: "test-data/stats_response_milliseconds",
588+
q: &Query{
589+
DataQuery: backend.DataQuery{
590+
RefID: "A",
591+
},
592+
LegendFormat: "legend {{app}}",
593+
Step: "10ms",
594+
},
595+
want: func() backend.DataResponse {
596+
frames := []*data.Frame{
597+
data.NewFrame("legend ",
598+
data.NewField(data.TimeSeriesTimeFieldName, nil, []time.Time{
599+
time.Unix(1733187134, 0),
600+
time.Unix(1733187134, 449999809),
601+
}),
602+
data.NewField(data.TimeSeriesValueFieldName, data.Labels{"__name__": "count(*)"}, []float64{58, 1}).SetConfig(&data.FieldConfig{DisplayNameFromDS: "legend "}),
603+
),
604+
}
605+
rsp := backend.DataResponse{}
606+
rsp.Frames = append(rsp.Frames, frames...)
607+
return rsp
608+
},
609+
},
585610
}
586611
for _, tt := range tests {
587612
t.Run(tt.name, func(t *testing.T) {
@@ -611,7 +636,7 @@ func Test_getStatsResponse(t *testing.T) {
611636
t.Fatalf("error marshal want response: %s", err)
612637
}
613638
if !bytes.Equal(got, want) {
614-
t.Fatalf("got value: %s, want value: %s", got, want)
639+
t.Fatalf("\n got value: %s, \n want value: %s", got, want)
615640
}
616641
}
617642
})
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"status":"success","data":{"resultType":"matrix","result":[{"metric":{"__name__":"count(*)"},"values":[[1733187134,"58"],[1733187134.4499998,"1"]]}]}}

0 commit comments

Comments
 (0)