diff --git a/promql/functions.go b/promql/functions.go index e4d896e237..6ac6c385b4 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -18,6 +18,7 @@ import ( "regexp" "sort" "strconv" + "time" "github.com/prometheus/common/model" @@ -859,6 +860,57 @@ func funcVector(ev *evaluator, args Expressions) model.Value { } } +// === day_of_month(v vector) scalar === +func funcDayOfMonth(ev *evaluator, args Expressions) model.Value { + vector := ev.evalVector(args[0]) + for _, el := range vector { + el.Metric.Del(model.MetricNameLabel) + el.Value = model.SampleValue(time.Unix(int64(el.Value), 0).UTC().Day()) + } + return vector +} + +// === day_of_week(v vector) scalar === +func funcDayOfWeek(ev *evaluator, args Expressions) model.Value { + vector := ev.evalVector(args[0]) + for _, el := range vector { + el.Metric.Del(model.MetricNameLabel) + // Sunday = 0. + el.Value = model.SampleValue(time.Unix(int64(el.Value), 0).UTC().Weekday()) + } + return vector +} + +// === hour_of_day(v vector) scalar === +func funcHourOfDay(ev *evaluator, args Expressions) model.Value { + vector := ev.evalVector(args[0]) + for _, el := range vector { + el.Metric.Del(model.MetricNameLabel) + el.Value = model.SampleValue(time.Unix(int64(el.Value), 0).UTC().Hour()) + } + return vector +} + +// === month_of_year(v vector) scalar === +func funcMonthOfYear(ev *evaluator, args Expressions) model.Value { + vector := ev.evalVector(args[0]) + for _, el := range vector { + el.Metric.Del(model.MetricNameLabel) + el.Value = model.SampleValue(time.Unix(int64(el.Value), 0).UTC().Month()) + } + return vector +} + +// === year(v vector) scalar === +func funcYear(ev *evaluator, args Expressions) model.Value { + vector := ev.evalVector(args[0]) + for _, el := range vector { + el.Metric.Del(model.MetricNameLabel) + el.Value = model.SampleValue(time.Unix(int64(el.Value), 0).UTC().Year()) + } + return vector +} + var functions = map[string]*Function{ "abs": { Name: "abs", @@ -920,6 +972,18 @@ var functions = map[string]*Function{ ReturnType: model.ValScalar, Call: funcCountScalar, }, + "day_of_month": { + Name: "day_of_month", + ArgTypes: []model.ValueType{model.ValVector}, + ReturnType: model.ValVector, + Call: funcDayOfMonth, + }, + "day_of_week": { + Name: "day_of_week", + ArgTypes: []model.ValueType{model.ValVector}, + ReturnType: model.ValVector, + Call: funcDayOfWeek, + }, "delta": { Name: "delta", ArgTypes: []model.ValueType{model.ValMatrix}, @@ -962,6 +1026,12 @@ var functions = map[string]*Function{ ReturnType: model.ValVector, Call: funcHoltWinters, }, + "hour_of_day": { + Name: "hour_of_day", + ArgTypes: []model.ValueType{model.ValVector}, + ReturnType: model.ValVector, + Call: funcHourOfDay, + }, "irate": { Name: "irate", ArgTypes: []model.ValueType{model.ValMatrix}, @@ -1010,6 +1080,12 @@ var functions = map[string]*Function{ ReturnType: model.ValVector, Call: funcMinOverTime, }, + "month_of_year": { + Name: "month_of_year", + ArgTypes: []model.ValueType{model.ValVector}, + ReturnType: model.ValVector, + Call: funcMonthOfYear, + }, "predict_linear": { Name: "predict_linear", ArgTypes: []model.ValueType{model.ValMatrix, model.ValScalar}, @@ -1095,6 +1171,12 @@ var functions = map[string]*Function{ ReturnType: model.ValVector, Call: funcVector, }, + "year": { + Name: "year", + ArgTypes: []model.ValueType{model.ValVector}, + ReturnType: model.ValVector, + Call: funcYear, + }, } // getFunction returns a predefined Function object for the given name. diff --git a/promql/testdata/functions.test b/promql/testdata/functions.test index 7ee67adad1..4d49f6f302 100644 --- a/promql/testdata/functions.test +++ b/promql/testdata/functions.test @@ -363,3 +363,38 @@ eval instant at 1m quantile_over_time(2, data[1m]) {test="two samples"} +Inf {test="three samples"} +Inf {test="uneven samples"} +Inf + +clear + +# Test time-related functions. +eval instant at 0m year(vector(0)) + {} 1970 + +eval instant at 0m month_of_year(vector(0)) + {} 1 + +eval instant at 0m day_of_month(vector(0)) + {} 1 + +# Thursday. +eval instant at 0m day_of_week(vector(0)) + {} 4 + +eval instant at 0m hour_of_day(vector(0)) + {} 0 + +# 2008-12-31 23:59:59 just before leap second. +eval instant at 0m year(vector(1230767999)) + {} 2008 + +# 2009-01-01 00:00:00 just after leap second. +eval instant at 0m year(vector(1230768000)) + {} 2009 + +# 2016-02-29 23:59:59 Febuary 29th in leap year. +eval instant at 0m month_of_year(vector(1456790399)) + day_of_month(vector(1456790399)) / 100 + {} 2.29 + +# 2016-03-01 00:00:00 March 1st in leap year. +eval instant at 0m month_of_year(vector(1456790400)) + day_of_month(vector(1456790400)) / 100 + {} 3.01