diff --git a/pkg/plugin/query.go b/pkg/plugin/query.go index fd3a3ad..f50c4e8 100644 --- a/pkg/plugin/query.go +++ b/pkg/plugin/query.go @@ -6,6 +6,8 @@ import ( "path" "strconv" "time" + + "github.com/VictoriaMetrics/victorialogs-datasource/pkg/utils" ) const ( @@ -20,6 +22,7 @@ type Query struct { LegendFormat string `json:"legendFormat"` MaxLines int `json:"maxLines"` TimeRange TimeRange + IntervalMs int `json:"intervalMs"` url *url.URL } @@ -72,6 +75,7 @@ func (q *Query) queryInstantURL(queryParams url.Values) string { q.TimeRange.To = now } + q.Expr = utils.ReplaceTemplateVariable(q.Expr, q.IntervalMs) values.Set("query", q.Expr) values.Set("limit", strconv.Itoa(q.MaxLines)) values.Set("start", strconv.FormatInt(q.TimeRange.From.Unix(), 10)) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index bfe24b0..094f157 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -9,6 +9,16 @@ import ( "github.com/VictoriaMetrics/metricsql" ) +const ( + varInterval = "$__interval" +) + +var ( + defaultResolution int64 = 1500 + year = time.Hour * 24 * 365 + day = time.Hour * 24 +) + const ( // These values prevent from overflow when storing msec-precision time in int64. minTimeMsecs = 0 // use 0 instead of `int64(-1<<63) / 1e6` because the storage engine doesn't actually support negative time @@ -172,3 +182,28 @@ func ParseDuration(s string) (time.Duration, error) { } return time.Duration(ms) * time.Millisecond, nil } + +// ReplaceTemplateVariable get query and use it expression to remove grafana template variables with +func ReplaceTemplateVariable(expr string, interval int) string { + expr = strings.ReplaceAll(expr, varInterval, formatDuration(time.Duration(interval)*time.Millisecond)) + return expr +} + +func formatDuration(inter time.Duration) string { + switch { + case inter >= year: + return fmt.Sprintf("%dy", inter/year) + case inter >= day: + return fmt.Sprintf("%dd", inter/day) + case inter >= time.Hour: + return fmt.Sprintf("%dh", inter/time.Hour) + case inter >= time.Minute: + return fmt.Sprintf("%dm", inter/time.Minute) + case inter >= time.Second: + return fmt.Sprintf("%ds", inter/time.Second) + case inter >= time.Millisecond: + return fmt.Sprintf("%dms", inter/time.Millisecond) + default: + return "1ms" + } +}