Skip to content

Commit 52f440d

Browse files
authored
SEARCH-8423 Fix time field type (#34)
1 parent efa16d5 commit 52f440d

File tree

3 files changed

+29
-23
lines changed

3 files changed

+29
-23
lines changed

pkg/plugin/datasource.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,13 @@ func (d *Datasource) query(_ context.Context, _ backend.PluginContext, dataQuery
208208
// Grab the keys and values from the event and populate fields in the frame
209209
for fieldName, value := range event {
210210
if fieldName == CRIBL_TIME_FIELD {
211-
// _time is in seconds, and Grafana needs it in ISO format. If the conversion is successful
212-
// (which it will be most of the time), we use Grafana's well-known "time" field name instead.
213-
// If the conversion fails, _time is something other than seconds, and it will pass-through
214-
// as is with the "_time" field name.
215-
if ok, isoString := timeToIsoString(value); ok {
211+
// Two things are happening here:
212+
// 1. Instead of our "_time" we use Grafana's well-known "time" field name.
213+
// 2. Convert from seconds to time.Time struct. If the conversion fails, _time must be something
214+
// other than seconds, and it will pass-through as is with the original "_time" field name.
215+
if ok, time := criblTimeToGrafanaTime(value); ok {
216216
fieldName = GRAFANA_TIME_FIELD_NAME
217-
value = isoString
217+
value = time
218218
}
219219
}
220220

pkg/plugin/utils.go

+8-6
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,24 @@ func collapseToSingleLine(query string) string {
5757
return regexp.MustCompile("[\r\n\t]+").ReplaceAllString(query, " ")
5858
}
5959

60-
// Convert the value of the "_time" field to an ISO timestamp string
61-
func timeToIsoString(timeValue interface{}) (bool, string) {
60+
// Convert the value of the "_time" field (expected to be in seconds) to a time.Time in UTC
61+
func criblTimeToGrafanaTime(timeValue interface{}) (bool, time.Time) {
6262
var seconds float64
6363
switch v := timeValue.(type) {
6464
case float64:
6565
seconds = v
6666
case string:
6767
s, err := strconv.ParseFloat(v, 64)
6868
if err != nil {
69-
return false, ""
69+
return false, time.Time{}
7070
}
7171
seconds = s
7272
default:
73-
return false, ""
73+
return false, time.Time{}
7474
}
7575
wholeSec := int64(seconds)
76-
nanoSec := int64(math.Round((seconds-float64(wholeSec))*1000.0)) * 1000000 // ms precision
77-
return true, time.Unix(wholeSec, nanoSec).UTC().Format(time.RFC3339Nano)
76+
nanoSec := int64(math.Round((seconds-float64(wholeSec))*1000000.0)) * 1000 // microsec precision
77+
return true, time.Unix(wholeSec, nanoSec).UTC()
7878
}
7979

8080
// Grafana's data.NewField() is super finicky. You're force to supply an array of values,
@@ -90,6 +90,8 @@ func makeEmptyConcreteTypeArray(val interface{}) (interface{}, error) {
9090
return []float64{}, nil
9191
case bool:
9292
return []bool{}, nil
93+
case time.Time:
94+
return []time.Time{}, nil
9395
default:
9496
return nil, fmt.Errorf("unsupported type: %T (%v)", t, t)
9597
}

pkg/plugin/utils_test.go

+15-11
Original file line numberDiff line numberDiff line change
@@ -63,42 +63,46 @@ func TestCollapseToSingleLine(t *testing.T) {
6363
assert.Equal(t, `hello there aw yeah`, collapseToSingleLine("hello\nthere\taw\r\nyeah"))
6464
}
6565

66-
func TestTimeToIsoString(t *testing.T) {
66+
func TestCriblTimeToGrafanaTime(t *testing.T) {
6767
for _, test := range []struct {
6868
In interface{}
69-
Expected string
69+
Expected int64
7070
}{
7171
{
7272
In: nil,
73-
Expected: "",
73+
Expected: 0,
7474
},
7575
{
7676
In: false,
77-
Expected: "",
77+
Expected: 0,
7878
},
7979
{
8080
In: true,
81-
Expected: "",
81+
Expected: 0,
8282
},
8383
{
8484
In: "whatever",
85-
Expected: "",
85+
Expected: 0,
8686
},
8787
{
8888
In: float64(1728744793),
89-
Expected: "2024-10-12T14:53:13Z",
89+
Expected: 1728744793000000,
9090
},
9191
{
9292
In: float64(1728744793.123),
93-
Expected: "2024-10-12T14:53:13.123Z",
93+
Expected: 1728744793123000,
94+
},
95+
{
96+
In: float64(1728744793.123456),
97+
Expected: 1728744793123456,
9498
},
9599
} {
96-
ok, out := timeToIsoString(test.In)
97-
if len(test.Expected) == 0 {
100+
ok, out := criblTimeToGrafanaTime(test.In)
101+
if test.Expected == 0 {
98102
assert.Equal(t, false, ok, fmt.Sprintf("input %v produced ok=%v, out=%v", test.In, ok, out))
99103
} else {
100104
assert.Equal(t, true, ok, fmt.Sprintf("input %v produced ok=%v, out=%v", test.In, ok, out))
101-
assert.Equal(t, test.Expected, out, test.In)
105+
assert.Equal(t, test.Expected, out.UnixMicro(), test.In)
102106
}
103107
}
104108
}

0 commit comments

Comments
 (0)