add template funcs
This commit is contained in:
parent
f091535690
commit
a656326203
|
@ -19,6 +19,7 @@ import (
|
||||||
"infini.sh/framework/modules/elastic/api"
|
"infini.sh/framework/modules/elastic/api"
|
||||||
"infini.sh/framework/modules/elastic/common"
|
"infini.sh/framework/modules/elastic/common"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -523,11 +524,15 @@ func (alertAPI *AlertAPI) getMetricData(w http.ResponseWriter, req *http.Request
|
||||||
Ticks: 5},
|
Ticks: 5},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
var sampleData []alerting.TimeMetricData
|
||||||
for _, md := range metricData {
|
for _, md := range metricData {
|
||||||
if len(md.Data) == 0 {
|
if len(md.Data) == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//filteredMetricData = append(filteredMetricData, md)
|
//filteredMetricData = append(filteredMetricData, md)
|
||||||
|
if sampleData == nil {
|
||||||
|
sampleData = md.Data["result"]
|
||||||
|
}
|
||||||
metricItem.Lines = append(metricItem.Lines, &common.MetricLine{
|
metricItem.Lines = append(metricItem.Lines, &common.MetricLine{
|
||||||
Data: md.Data["result"],
|
Data: md.Data["result"],
|
||||||
BucketSize: filterParam.BucketSize,
|
BucketSize: filterParam.BucketSize,
|
||||||
|
@ -539,6 +544,37 @@ func (alertAPI *AlertAPI) getMetricData(w http.ResponseWriter, req *http.Request
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//add guidelines
|
||||||
|
for _, cond := range rule.Conditions.Items{
|
||||||
|
if len(cond.Values) > 0 {
|
||||||
|
val, err := strconv.ParseFloat(cond.Values[0], 64)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("parse condition value error: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if sampleData != nil {
|
||||||
|
newData := make([]alerting.TimeMetricData,0, len(sampleData))
|
||||||
|
for _, td := range sampleData {
|
||||||
|
if len(td) < 2{
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newData = append(newData, alerting.TimeMetricData{
|
||||||
|
td[0], val,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
metricItem.Lines = append(metricItem.Lines, &common.MetricLine{
|
||||||
|
Data: newData,
|
||||||
|
BucketSize: filterParam.BucketSize,
|
||||||
|
Metric: common.MetricSummary{
|
||||||
|
Label: "",
|
||||||
|
Group: rule.ID,
|
||||||
|
TickFormat: "0,0.[00]",
|
||||||
|
FormatType: "num",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
alertAPI.WriteJSON(w, util.MapStr{
|
alertAPI.WriteJSON(w, util.MapStr{
|
||||||
"metric": metricItem,
|
"metric": metricItem,
|
||||||
}, http.StatusOK)
|
}, http.StatusOK)
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"infini.sh/console/model/alerting"
|
"infini.sh/console/model/alerting"
|
||||||
alerting2 "infini.sh/console/service/alerting"
|
alerting2 "infini.sh/console/service/alerting"
|
||||||
"infini.sh/console/service/alerting/action"
|
"infini.sh/console/service/alerting/action"
|
||||||
|
"infini.sh/console/service/alerting/funcs"
|
||||||
"infini.sh/framework/core/elastic"
|
"infini.sh/framework/core/elastic"
|
||||||
"infini.sh/framework/core/kv"
|
"infini.sh/framework/core/kv"
|
||||||
"infini.sh/framework/core/orm"
|
"infini.sh/framework/core/orm"
|
||||||
|
@ -758,9 +759,7 @@ func performChannels(channels []alerting.Channel, ctx map[string]interface{}) ([
|
||||||
|
|
||||||
func resolveMessage(messageTemplate string, ctx map[string]interface{}) ([]byte, error){
|
func resolveMessage(messageTemplate string, ctx map[string]interface{}) ([]byte, error){
|
||||||
msg := messageTemplate
|
msg := messageTemplate
|
||||||
tmpl, err := template.New("alert-message").Funcs(template.FuncMap{
|
tmpl, err := template.New("alert-message").Funcs(funcs.GenericFuncMap()).Parse(msg)
|
||||||
"format_bytes": func(precision int, bytes float64) string { return util.FormatBytes(bytes, precision)},
|
|
||||||
}).Parse(msg)
|
|
||||||
if err !=nil {
|
if err !=nil {
|
||||||
return nil, fmt.Errorf("parse message temlate error: %w", err)
|
return nil, fmt.Errorf("parse message temlate error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* Copyright © INFINI Ltd. All rights reserved.
|
||||||
|
* web: https://infinilabs.com
|
||||||
|
* mail: hello#infini.ltd */
|
||||||
|
|
||||||
|
package funcs
|
||||||
|
|
||||||
|
import "infini.sh/framework/core/util"
|
||||||
|
|
||||||
|
func formatBytes(precision int, bytes float64) string {
|
||||||
|
return util.FormatBytes(bytes, precision)
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
/* Copyright © INFINI Ltd. All rights reserved.
|
||||||
|
* web: https://infinilabs.com
|
||||||
|
* mail: hello#infini.ltd */
|
||||||
|
|
||||||
|
package funcs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func date(fmt string, date interface{}) string {
|
||||||
|
return dateInZone(fmt, date, "Local")
|
||||||
|
}
|
||||||
|
|
||||||
|
func htmlDate(date interface{}) string {
|
||||||
|
return dateInZone("2006-01-02", date, "Local")
|
||||||
|
}
|
||||||
|
|
||||||
|
func htmlDateInZone(date interface{}, zone string) string {
|
||||||
|
return dateInZone("2006-01-02", date, zone)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dateInZone(fmt string, date interface{}, zone string) string {
|
||||||
|
var t time.Time
|
||||||
|
switch date := date.(type) {
|
||||||
|
default:
|
||||||
|
t = time.Now()
|
||||||
|
case time.Time:
|
||||||
|
t = date
|
||||||
|
case *time.Time:
|
||||||
|
t = *date
|
||||||
|
case int64:
|
||||||
|
t = time.Unix(date, 0)
|
||||||
|
case int:
|
||||||
|
t = time.Unix(int64(date), 0)
|
||||||
|
case int32:
|
||||||
|
t = time.Unix(int64(date), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
loc, err := time.LoadLocation(zone)
|
||||||
|
if err != nil {
|
||||||
|
loc, _ = time.LoadLocation("UTC")
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.In(loc).Format(fmt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dateModify(fmt string, date time.Time) time.Time {
|
||||||
|
d, err := time.ParseDuration(fmt)
|
||||||
|
if err != nil {
|
||||||
|
return date
|
||||||
|
}
|
||||||
|
return date.Add(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustDateModify(fmt string, date time.Time) (time.Time, error) {
|
||||||
|
d, err := time.ParseDuration(fmt)
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}, err
|
||||||
|
}
|
||||||
|
return date.Add(d), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dateAgo(date interface{}) string {
|
||||||
|
var t time.Time
|
||||||
|
|
||||||
|
switch date := date.(type) {
|
||||||
|
default:
|
||||||
|
t = time.Now()
|
||||||
|
case time.Time:
|
||||||
|
t = date
|
||||||
|
case int64:
|
||||||
|
t = time.Unix(date, 0)
|
||||||
|
case int:
|
||||||
|
t = time.Unix(int64(date), 0)
|
||||||
|
}
|
||||||
|
// Drop resolution to seconds
|
||||||
|
duration := time.Since(t).Round(time.Second)
|
||||||
|
return duration.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func duration(sec interface{}) string {
|
||||||
|
var n int64
|
||||||
|
switch value := sec.(type) {
|
||||||
|
default:
|
||||||
|
n = 0
|
||||||
|
case string:
|
||||||
|
n, _ = strconv.ParseInt(value, 10, 64)
|
||||||
|
case int64:
|
||||||
|
n = value
|
||||||
|
}
|
||||||
|
return (time.Duration(n) * time.Second).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func durationRound(duration interface{}) string {
|
||||||
|
var d time.Duration
|
||||||
|
switch duration := duration.(type) {
|
||||||
|
default:
|
||||||
|
d = 0
|
||||||
|
case string:
|
||||||
|
d, _ = time.ParseDuration(duration)
|
||||||
|
case int64:
|
||||||
|
d = time.Duration(duration)
|
||||||
|
case time.Time:
|
||||||
|
d = time.Since(duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
u := uint64(d)
|
||||||
|
neg := d < 0
|
||||||
|
if neg {
|
||||||
|
u = -u
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
year = uint64(time.Hour) * 24 * 365
|
||||||
|
month = uint64(time.Hour) * 24 * 30
|
||||||
|
day = uint64(time.Hour) * 24
|
||||||
|
hour = uint64(time.Hour)
|
||||||
|
minute = uint64(time.Minute)
|
||||||
|
second = uint64(time.Second)
|
||||||
|
)
|
||||||
|
switch {
|
||||||
|
case u > year:
|
||||||
|
return strconv.FormatUint(u/year, 10) + "y"
|
||||||
|
case u > month:
|
||||||
|
return strconv.FormatUint(u/month, 10) + "mo"
|
||||||
|
case u > day:
|
||||||
|
return strconv.FormatUint(u/day, 10) + "d"
|
||||||
|
case u > hour:
|
||||||
|
return strconv.FormatUint(u/hour, 10) + "h"
|
||||||
|
case u > minute:
|
||||||
|
return strconv.FormatUint(u/minute, 10) + "m"
|
||||||
|
case u > second:
|
||||||
|
return strconv.FormatUint(u/second, 10) + "s"
|
||||||
|
}
|
||||||
|
return "0s"
|
||||||
|
}
|
||||||
|
|
||||||
|
func toDate(fmt, str string) time.Time {
|
||||||
|
t, _ := time.ParseInLocation(fmt, str, time.Local)
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustToDate(fmt, str string) (time.Time, error) {
|
||||||
|
return time.ParseInLocation(fmt, str, time.Local)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unixEpoch(date time.Time) string {
|
||||||
|
return strconv.FormatInt(date.Unix(), 10)
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* Copyright © INFINI Ltd. All rights reserved.
|
||||||
|
* web: https://infinilabs.com
|
||||||
|
* mail: hello#infini.ltd */
|
||||||
|
|
||||||
|
package funcs
|
||||||
|
|
||||||
|
import "text/template"
|
||||||
|
|
||||||
|
func GenericFuncMap() template.FuncMap {
|
||||||
|
gfm := make(map[string]interface{}, len(genericMap))
|
||||||
|
for k, v := range genericMap {
|
||||||
|
gfm[k] = v
|
||||||
|
}
|
||||||
|
return gfm
|
||||||
|
}
|
||||||
|
|
||||||
|
var genericMap = map[string]interface{}{
|
||||||
|
"hello": func() string { return "Hello!" },
|
||||||
|
"format_bytes": formatBytes,
|
||||||
|
"to_fixed": toFixed,
|
||||||
|
"date": date,
|
||||||
|
"date_in_zone": dateInZone,
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* Copyright © INFINI Ltd. All rights reserved.
|
||||||
|
* web: https://infinilabs.com
|
||||||
|
* mail: hello#infini.ltd */
|
||||||
|
|
||||||
|
package funcs
|
||||||
|
|
||||||
|
import "infini.sh/framework/core/util"
|
||||||
|
|
||||||
|
func toFixed(precision int, num float64) float64{
|
||||||
|
return util.ToFixed(num, precision)
|
||||||
|
}
|
Loading…
Reference in New Issue