Skip to content

Commit 7f8ad65

Browse files
fix: add support for __from and __to variables in alert queries (#180)
Fixes variable interpolation for Grafana alerting by adding support for: - ${__from} and ${__to} variables (millisecond timestamps) - ${__from:date:iso} and ${__to:date:iso} variables (ISO format)
1 parent 6a9e340 commit 7f8ad65

File tree

1 file changed

+19
-3
lines changed

1 file changed

+19
-3
lines changed

pkg/druid.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ var (
3232
varRangeS = variableVariants("__range_s")
3333
varRangeMs = variableVariants("__range_ms")
3434
varRateInterval = variableVariants("__rate_interval")
35+
varFrom = variableVariants("__from")
36+
varTo = variableVariants("__to")
37+
varFromDateISO = variableVariants("__from:date:iso")
38+
varToDateISO = variableVariants("__to:date:iso")
3539
)
3640

3741
func variableVariants(base string) []string {
@@ -348,7 +352,7 @@ func (ds *druidDatasource) QueryData(ctx context.Context, req *backend.QueryData
348352

349353
func (ds *druidDatasource) query(qry backend.DataQuery, s *druidInstanceSettings) backend.DataResponse {
350354
log.DefaultLogger.Debug("DRUID EXECUTE QUERY", "grafana_query", qry)
351-
rawQuery := interpolateVariables(string(qry.JSON), qry.Interval, qry.TimeRange.Duration())
355+
rawQuery := interpolateVariables(string(qry.JSON), qry.Interval, qry.TimeRange)
352356

353357
// feature: probably implement a short (1s ? 500ms ? configurable in datasource ? beware memory: constrain size ?) life cache (druidInstanceSettings.cache ?) and early return then
354358
response := backend.DataResponse{}
@@ -373,16 +377,28 @@ func (ds *druidDatasource) query(qry backend.DataQuery, s *druidInstanceSettings
373377
return response
374378
}
375379

376-
func interpolateVariables(expr string, interval time.Duration, timeRange time.Duration) string {
377-
rangeMs := timeRange.Milliseconds()
380+
func interpolateVariables(expr string, interval time.Duration, timeRange backend.TimeRange) string {
381+
duration := timeRange.Duration()
382+
rangeMs := duration.Milliseconds()
378383
rangeSRounded := int64(math.Round(float64(rangeMs) / 1000.0))
379384

385+
fromMs := timeRange.From.UnixMilli()
386+
toMs := timeRange.To.UnixMilli()
387+
388+
// Format timestamps for ISO format
389+
fromISO := timeRange.From.Format("2006-01-02T15:04:05.000Z")
390+
toISO := timeRange.To.Format("2006-01-02T15:04:05.000Z")
391+
380392
expr = multiReplace(expr, varIntervalMs, strconv.FormatInt(int64(interval/time.Millisecond), 10))
381393
expr = multiReplace(expr, varInterval, formatDuration(interval))
382394
expr = multiReplace(expr, varRangeMs, strconv.FormatInt(rangeMs, 10))
383395
expr = multiReplace(expr, varRangeS, strconv.FormatInt(rangeSRounded, 10))
384396
expr = multiReplace(expr, varRange, strconv.FormatInt(rangeSRounded, 10)+"s")
385397
expr = multiReplace(expr, varRateInterval, interval.String())
398+
expr = multiReplace(expr, varFromDateISO, fromISO)
399+
expr = multiReplace(expr, varToDateISO, toISO)
400+
expr = multiReplace(expr, varFrom, strconv.FormatInt(fromMs, 10))
401+
expr = multiReplace(expr, varTo, strconv.FormatInt(toMs, 10))
386402

387403
return expr
388404
}

0 commit comments

Comments
 (0)