add alert duration in wecom.tpl
This commit is contained in:
parent
aff0dbfea1
commit
5332f797a6
|
@ -1,7 +1,9 @@
|
||||||
**级别状态**: {{if .IsRecovered}}<font color="info">S{{.Severity}} Recovered</font>{{else}}<font color="warning">S{{.Severity}} Triggered</font>{{end}}
|
**级别状态**: {{if .IsRecovered}}<font color="info">S{{.Severity}} Recovered</font>{{else}}<font color="warning">S{{.Severity}} Triggered</font>{{end}}
|
||||||
**规则标题**: {{.RuleName}}{{if .RuleNote}}
|
**规则标题**: {{.RuleName}}{{if .RuleNote}}
|
||||||
**规则备注**: {{.RuleNote}}{{end}}
|
**规则备注**: {{.RuleNote}}{{end}}{{if .TargetIdent}}
|
||||||
**监控指标**: {{.TagsJSON}}
|
**监控对象**: {{.TargetIdent}}{{end}}
|
||||||
{{if .IsRecovered}}**恢复时间**:{{timeformat .LastEvalTime}}{{else}}**触发时间**: {{timeformat .TriggerTime}}
|
**监控指标**: {{.TagsJSON}}{{if not .IsRecovered}}
|
||||||
**触发时值**: {{.TriggerValue}}{{end}}
|
**触发时值**: {{.TriggerValue}}{{end}}
|
||||||
|
{{if .IsRecovered}}**恢复时间**: {{timeformat .LastEvalTime}}{{else}}**首次触发时间**: {{timeformat .FirstTriggerTime}}{{end}}
|
||||||
|
{{$time_duration := sub now.Unix .FirstTriggerTime }}{{if .IsRecovered}}{{$time_duration = sub .LastEvalTime .FirstTriggerTime }}{{end}}**持续时长**: {{humanizeDurationInterface $time_duration}}
|
||||||
**发送时间**: {{timestamp}}
|
**发送时间**: {{timestamp}}
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"math"
|
"math"
|
||||||
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
@ -33,6 +34,10 @@ func Timestamp(pattern ...string) string {
|
||||||
return time.Now().Format(defp)
|
return time.Now().Format(defp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Now() time.Time {
|
||||||
|
return time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
func Args(args ...interface{}) map[string]interface{} {
|
func Args(args ...interface{}) map[string]interface{} {
|
||||||
result := make(map[string]interface{})
|
result := make(map[string]interface{})
|
||||||
for i, a := range args {
|
for i, a := range args {
|
||||||
|
@ -95,11 +100,27 @@ func Humanize1024(s string) string {
|
||||||
return fmt.Sprintf("%.4g%s", v, prefix)
|
return fmt.Sprintf("%.4g%s", v, prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToString(v interface{}) string {
|
||||||
|
return fmt.Sprint(v)
|
||||||
|
}
|
||||||
|
|
||||||
func HumanizeDuration(s string) string {
|
func HumanizeDuration(s string) string {
|
||||||
v, err := strconv.ParseFloat(s, 64)
|
v, err := strconv.ParseFloat(s, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
return HumanizeDurationFloat64(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HumanizeDurationInterface(i interface{}) string {
|
||||||
|
f, err := ToFloat64(i)
|
||||||
|
if err != nil {
|
||||||
|
return ToString(i)
|
||||||
|
}
|
||||||
|
return HumanizeDurationFloat64(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HumanizeDurationFloat64(v float64) string {
|
||||||
if math.IsNaN(v) || math.IsInf(v, 0) {
|
if math.IsNaN(v) || math.IsInf(v, 0) {
|
||||||
return fmt.Sprintf("%.4g", v)
|
return fmt.Sprintf("%.4g", v)
|
||||||
}
|
}
|
||||||
|
@ -155,3 +176,179 @@ func HumanizePercentageH(s string) string {
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%.2f%%", v)
|
return fmt.Sprintf("%.2f%%", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add returns the sum of a and b.
|
||||||
|
func Add(a, b interface{}) (interface{}, error) {
|
||||||
|
av := reflect.ValueOf(a)
|
||||||
|
bv := reflect.ValueOf(b)
|
||||||
|
|
||||||
|
switch av.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return av.Int() + bv.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Int() + int64(bv.Uint()), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return float64(av.Int()) + bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("add: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return int64(av.Uint()) + bv.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Uint() + bv.Uint(), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return float64(av.Uint()) + bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("add: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return av.Float() + float64(bv.Int()), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Float() + float64(bv.Uint()), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return av.Float() + bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("add: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("add: unknown type for %q (%T)", av, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtract returns the difference of b from a.
|
||||||
|
func Subtract(a, b interface{}) (interface{}, error) {
|
||||||
|
av := reflect.ValueOf(a)
|
||||||
|
bv := reflect.ValueOf(b)
|
||||||
|
|
||||||
|
switch av.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return av.Int() - bv.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Int() - int64(bv.Uint()), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return float64(av.Int()) - bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("subtract: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return int64(av.Uint()) - bv.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Uint() - bv.Uint(), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return float64(av.Uint()) - bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("subtract: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return av.Float() - float64(bv.Int()), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Float() - float64(bv.Uint()), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return av.Float() - bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("subtract: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("subtract: unknown type for %q (%T)", av, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiply returns the product of a and b.
|
||||||
|
func Multiply(a, b interface{}) (interface{}, error) {
|
||||||
|
av := reflect.ValueOf(a)
|
||||||
|
bv := reflect.ValueOf(b)
|
||||||
|
|
||||||
|
switch av.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return av.Int() * bv.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Int() * int64(bv.Uint()), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return float64(av.Int()) * bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("multiply: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return int64(av.Uint()) * bv.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Uint() * bv.Uint(), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return float64(av.Uint()) * bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("multiply: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return av.Float() * float64(bv.Int()), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Float() * float64(bv.Uint()), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return av.Float() * bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("multiply: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("multiply: unknown type for %q (%T)", av, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Divide returns the division of b from a.
|
||||||
|
func Divide(a, b interface{}) (interface{}, error) {
|
||||||
|
av := reflect.ValueOf(a)
|
||||||
|
bv := reflect.ValueOf(b)
|
||||||
|
|
||||||
|
switch av.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return av.Int() / bv.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Int() / int64(bv.Uint()), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return float64(av.Int()) / bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("divide: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return int64(av.Uint()) / bv.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Uint() / bv.Uint(), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return float64(av.Uint()) / bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("divide: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
switch bv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return av.Float() / float64(bv.Int()), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return av.Float() / float64(bv.Uint()), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return av.Float() / bv.Float(), nil
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("divide: unknown type for %q (%T)", bv, b)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("divide: unknown type for %q (%T)", av, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package tplx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ToFloat64 convert interface to float64
|
||||||
|
func ToFloat64(val interface{}) (float64, error) {
|
||||||
|
switch v := val.(type) {
|
||||||
|
case string:
|
||||||
|
if f, err := strconv.ParseFloat(v, 64); err == nil {
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// try int
|
||||||
|
if i, err := strconv.ParseInt(v, 0, 64); err == nil {
|
||||||
|
return float64(i), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// try bool
|
||||||
|
b, err := strconv.ParseBool(v)
|
||||||
|
if err == nil {
|
||||||
|
if b {
|
||||||
|
return 1, nil
|
||||||
|
} else {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if v == "Yes" || v == "yes" || v == "YES" || v == "Y" || v == "ON" || v == "on" || v == "On" || v == "ok" || v == "up" {
|
||||||
|
return 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if v == "No" || v == "no" || v == "NO" || v == "N" || v == "OFF" || v == "off" || v == "Off" || v == "fail" || v == "err" || v == "down" {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, fmt.Errorf("unparseable value %v", v)
|
||||||
|
case float64:
|
||||||
|
return v, nil
|
||||||
|
case uint64:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint32:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint16:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint8:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint:
|
||||||
|
return float64(v), nil
|
||||||
|
case int64:
|
||||||
|
return float64(v), nil
|
||||||
|
case int32:
|
||||||
|
return float64(v), nil
|
||||||
|
case int16:
|
||||||
|
return float64(v), nil
|
||||||
|
case int8:
|
||||||
|
return float64(v), nil
|
||||||
|
case bool:
|
||||||
|
if v {
|
||||||
|
return 1, nil
|
||||||
|
} else {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
case int:
|
||||||
|
return float64(v), nil
|
||||||
|
case float32:
|
||||||
|
return float64(v), nil
|
||||||
|
default:
|
||||||
|
return strconv.ParseFloat(fmt.Sprint(v), 64)
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,20 +8,27 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var TemplateFuncMap = template.FuncMap{
|
var TemplateFuncMap = template.FuncMap{
|
||||||
"escape": url.PathEscape,
|
"escape": url.PathEscape,
|
||||||
"unescaped": Unescaped,
|
"unescaped": Unescaped,
|
||||||
"urlconvert": Urlconvert,
|
"urlconvert": Urlconvert,
|
||||||
"timeformat": Timeformat,
|
"timeformat": Timeformat,
|
||||||
"timestamp": Timestamp,
|
"timestamp": Timestamp,
|
||||||
"args": Args,
|
"args": Args,
|
||||||
"reReplaceAll": ReReplaceAll,
|
"reReplaceAll": ReReplaceAll,
|
||||||
"match": regexp.MatchString,
|
"match": regexp.MatchString,
|
||||||
"toUpper": strings.ToUpper,
|
"toUpper": strings.ToUpper,
|
||||||
"toLower": strings.ToLower,
|
"toLower": strings.ToLower,
|
||||||
"contains": strings.Contains,
|
"contains": strings.Contains,
|
||||||
"humanize": Humanize,
|
"humanize": Humanize,
|
||||||
"humanize1024": Humanize1024,
|
"humanize1024": Humanize1024,
|
||||||
"humanizeDuration": HumanizeDuration,
|
"humanizeDuration": HumanizeDuration,
|
||||||
"humanizePercentage": HumanizePercentage,
|
"humanizeDurationInterface": HumanizeDurationInterface,
|
||||||
"humanizePercentageH": HumanizePercentageH,
|
"humanizePercentage": HumanizePercentage,
|
||||||
|
"humanizePercentageH": HumanizePercentageH,
|
||||||
|
"add": Add,
|
||||||
|
"sub": Subtract,
|
||||||
|
"mul": Multiply,
|
||||||
|
"div": Divide,
|
||||||
|
"now": Now,
|
||||||
|
"toString": ToString,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue