Tips of Bosun
-
-
Save leapar/c3d49f00aa5cdddf04f38becf58d2eb6 to your computer and use it in GitHub Desktop.
linelr
linelr(seriesSet, d Duration) seriesSet
线性回归线,也不懂
len
func length(dps Series, args ...float64) (a float64) {
return float64(len(dps))
}
max && min && median && percentile
max(seriesSet) numberSet
Returns the maximum value of each series, same as calling percentile(series, 1).
median(seriesSet) numberSet
Returns the median value of each series, same as calling percentile(series, .5).
min(seriesSet) numberSet
Returns the minimum value of each series, same as calling percentile(series, 0).
percentile(seriesSet, p numberSet|scalar) numberSet
Returns the value from each series at the percentile p. Min and Max can be simulated using p <= 0 and p >= 1, respectively.
func percentile(dps Series, args ...float64) (a float64) {
p := args[0]
var x []float64
for _, v := range dps {
x = append(x, float64(v))
}
sort.Float64s(x)
if p <= 0 {
return x[0]
}
if p >= 1 {
return x[len(x)-1]
}
i := p * float64(len(x)-1)
i = math.Ceil(i)
return x[int(i)]
}
先大小排序,然后乘以小数点倍数以后向上取整。
Math.round() 标准四舍五入
Math.floor() 向下取整
since
func (e *State) since(dps Series, args ...float64) (a float64) {
var last time.Time
for k, v := range dps {
if k.After(last) {
a = v
last = k
}
}
s := e.now.Sub(last)//查询时候的区间结束时间
return s.Seconds()
}
序列化数据中,最近的时间差
sum
func sum(dps Series, args ...float64) (a float64) {
for _, v := range dps {
a += float64(v)
}
return
}
没什么说的
streak
func streak(dps Series, args ...float64) (a float64) {
max := func(a, b int) int {
if a > b {
return a
}
return b
}
series := NewSortedSeries(dps)
current := 0
longest := 0
for _, p := range series {
if p.V != 0 {
current++
} else {
longest = max(current, longest)
current = 0
}
}
longest = max(current, longest)
return float64(longest)
}
统计最长的持续不为零的数量。
[1,0,1,1,1,1,2,5,0,1,0,2,3,5,4]返回6
Rule
Macros
宏定义(macro)区块里面定义的任何东西(关键字)包括变量都会展开到它的引用者中。引用者通过macro = name来进行引用,并可以循环引用循环展开。
$default_time = "2m"
macro m1 {
$w = 80
warnNotification = default
}
macro m2 {
macro = m1
$c = 90
}
alert os.high_cpu {
$q = avg(q("avg:rate:os.cpu{host=ny-nexpose01}", $default_time, ""))
macro = m2
warn = $q > $w
crit = $q >= $c
}
上面这个会给alert区块展开$w,$c,以及warnNotification,相当于:
alert os.high_cpu {
$w = 80
warnNotification = default
$c = 90
$q = avg(q("avg:rate:os.cpu{host=ny-nexpose01}", $default_time, ""))
macro = m2
warn = $q > $w
crit = $q >= $c
}
Lookup tables
Lookup这个东西经常使用,它的用法有以下几个:
- 为不同的tag设置不同的表达式值 (i.e. thresholds)
- 根据不同的tag修改相应的通知或者告警 (notification lookups)
- 提供不同的tag信息,给模板使用
notification uhura {
print = true
}
notification spock {
print = true
}
lookup exampleTable {
entry host=a {
threshold = 9
fish = Ohhh... a Red Snapper - Hmmm... Very Tasty
contact_crew = spock
}
# You took the Box! Lets see whats in the box!
entry host=* {
threshold = 3
fish = Nothing! Absolutely Nothing! Stupid! You so Stupid!
contact_crew = uhura
}
}
alert exampleTable {
template = lookup
$series = merge(series("host=a", 0, 10), series("host=b", 0, 2))
$r = avg($series)
# lookup depends on Bosun's index of datapoints to get possible tag values
$lk = $r > lookup("exampleTable", "threshold")
# lookupSeries uses the series to get the possible tag values
$lks = $r > lookupSeries($series, "exampleTable", "threshold")
warn = $lks
# spock will be contacted for host a, uhura for all others
warnNotification = lookup("exampleTable", "contact_crew")
}
template lookup {
body = `
<h1>.Lookup</h1>
<p>You Got a: {{ .Lookup "exampleTable" "fish" }}</p>
<!-- For host a this will render to "Ohhh... a Red Snapper - Hmmm... Very Tasty" -->
<!-- It is just a shorthand for {{.LookupAll "exampleTable" "fish" .Group }} -->
<h2>.LookupAll</h2>
<p>The fish for host "b" will always be {{ .LookupAll "exampleTable" "fish" "host=b" }}</p>
<!-- For host a this will render to "Nothing! Absolutely Nothing! Stupid! You so Stupid!"
since we requested host=b specifically -->
`
subject = `lookup example`
}
Lookup函数
lookup依赖bosun内置的索引,即redis里面的index。lookup函数会提取lookup模板的所有entry中的key,注意所有的entry中key的个数必须一致这个有要求。拿到key以后到redis里面查询key的所有value,然后进行排列组合。排列组合以后产生的key1=value1,key2=value2然后到lookup表中查找对应的entry是否有对应的,然后拿里面对应的值。
注意:
$series = merge(series("host=10-redmine,device=udev", 0, 10), series("host=nonono,device=nonono", 0, 2))
$r = avg($series)
# lookup depends on Bosun's index of datapoints to get possible tag values
$lk = $r > lookup("exampleTable", "threshold")
上面这个$series 是两条线,一条0:10{host=10-redmine,device=udev}一条0:2{host=nonono,device=nonono}
第一条因为host device对应的value(10-redmine,udev)在opentsdb里面存在,能够命中。
第二条因为value都是nononono,命中不了,也不能命中lookup table 的host=* device=*这条entry。
lookup := func(e *expr.State, T miniprofiler.Timer, lookup, key string) (results *expr.Results, err error) {
results = new(expr.Results)
results.IgnoreUnjoined = true
l := c.Lookups[lookup]
if l == nil {
return nil, fmt.Errorf("lookup table not found: %v", lookup)
}
lookups := l.ToExpr()
if lookups == nil {
err = fmt.Errorf("lookup table not found: %v", lookup)
return
}
var tags []opentsdb.TagSet
for _, tag := range lookups.Tags {
var next []opentsdb.TagSet
uid := "1"
vals, err := e.Search.TagValuesByTagKey(tag, uid, 0)
if err != nil {
return nil, err
}
for _, value := range vals {
fmt.Println("%s:%s",tag,value)
for _, s := range tags {
t := s.Copy()
t[tag] = value
next = append(next, t)
}
if len(tags) == 0 {
next = append(next, opentsdb.TagSet{tag: value})
}
}
tags = next
}
for _, tag := range tags {
value, ok := lookups.Get(key, tag)
if !ok {
continue
}
var num float64
num, err = strconv.ParseFloat(value, 64)
if err != nil {
return nil, err
}
results.Results = append(results.Results, &expr.Result{
Value: expr.Number(num),
Group: tag,
})
}
return results, nil
}
lookup exampleTable {
entry host=10-redmine,device=udev {
threshold = 100
fish = Ohhh... a Red Snapper - Hmmm... Very Tasty
contact_crew = spock
}
# You took the Box! Lets see whats in the box!
entry host=*,device=* {
threshold = 1
fish = Nothing! Absolutely Nothing! Stupid! You so Stupid!
contact_crew = uhura
}
}
alert exampleTable {
template = lookup
$series = merge(series("host=10-redmine,device=udev", 0, 10), series("host=89-gpmaster,device=d", 0, 2))
$r = avg($series)
# lookup depends on Bosun's index of datapoints to get possible tag values
$lk = $r > lookup("exampleTable", "threshold")
# lookupSeries uses the series to get the possible tag values
$lks = $r > lookupSeries($series, "exampleTable", "threshold")
warn = $lk
# spock will be contacted for host a, uhura for all others
warnNotification = lookup("exampleTable", "contact_crew")
}
lookupSeries 函数
lookupSeries 跟lookup一样,这个好理解。因为他是基于指标序列中的tagv=tagk到lookup表中查询,不需要基于bosun的索引。
Notifications
通知告警,alert区块通过 warnNotification 和 critNotification 来指定使用哪个告警。每个告警都会使用当前alert里面指定的模板Template。所有告警互相都是独立的而且同步执行,不会产生依赖于阻塞。
next && timeout
链式通知,当前这个Notifications可以指定下一个通知。例如先发邮件再执行post,那么next就指定一个post的通知对象。timeout不写表示立即执行第二个通知。当然,next也可以写自身。
body && contentType
覆盖post操作时候的body与默认的application/x-www-form-urlencoded头信息
收件人信息,可以是多个用逗号隔开。格式如下[email protected] ,shuai[email protected]
get && post
执行http请求
控制台输出
useBody
目前body内容还是html格式,有bug,暂时别使用,bosun-monitor/bosun#1743
runOnActions
发送ack/close/forget给alert的所有根级别通知,感觉没什么偄用
下面的不需要解释了,看不懂自扇耳光然后继续看上面。
# HTTP Post to a chatroom, email in 10m if not ack'd
notification chat {
next = email
timeout = 10m
post = http://chat.example.com/room/1?key=KEY&message=whatever
}
# email foo and bar each day until ack'd
notification email {
email = [email protected], [email protected]
next = email
timeout = 1d
}
# post to a slack.com chatroom via Incoming Webhooks integration
notification slack{
post = https://hooks.slack.com/services/abcdef
body = {"text": {{.|json}}}
}
#post json
notification json{
post = https://someurl.com/submit
body = {"text": {{.|json}}, apiKey="2847abc23"}
contentType = application/json
}
变量
$foo = value
使用方法$foo 或者 ${foo}
全局变量定义在任何区块之外,但是在区块内部可以定义一个跟它名字一样的变量覆盖它的值,生命周期仅仅在当前区块内部。
模板全局函数
var defaultFuncs = ttemplate.FuncMap{
"bytes": func(v interface{}) string {
switch v := v.(type) {
case string:
f, err := strconv.ParseFloat(v, 64)
if err != nil {
return err.Error()
}
return conf.ByteSize(f).String()
case int:
return conf.ByteSize(v).String()
case float64:
return conf.ByteSize(v).String()
case expr.Number:
return conf.ByteSize(v).String()
case expr.Scalar:
return conf.ByteSize(v).String()
}
return fmt.Errorf("unexpected type passed to bytes function: %T (%v)", v, v).Error()
},
"pct": func(i interface{}) string {
return fmt.Sprintf("%.2f%%", i)
},
"replace": strings.Replace,
"short": func(v string) string {
return strings.SplitN(v, ".", 2)[0]
},
"html": func(value interface{}) htemplate.HTML {
return htemplate.HTML(fmt.Sprint(value))
},
"parseDuration": func(s string) *time.Duration {
d, err := time.ParseDuration(s)
if err != nil {
return nil
}
return &d
},
}
V函数
让你在模板中使用全局变量,全局变量在区块中被覆盖的生命周期到不了模板中。下面overRide覆盖也没用。
$myGlobalVar = Kon'nichiwa
$overRide = I shall be seen
template globalvar {
body = `
<p>{{ V "$myGlobalVar" }}</p>
<!-- renders to Kon'nichiwa -->
<p>{{ .Alert.Vars.myGlobalVar }}</p>
<!-- renders an empty string -->
<p>{{ V "$overRide" }}</p>
<!-- render to "I shall be seen" since expression variable overrides do *not* work in templates -->
`
subject = `V example`
}
alert globalvar {
template = globalvar
$overRide = I am not seen
warn = 1
}
.Ack()
.Ack创建一个查看alert的链接
body = `<a href="{{.Ack}}">Acknowledge alert</a>
. Eval(string|Expression) (resultValue)
执行表达式,并返回第一个值
func (c *Context) Eval(v interface{}) interface{} {
res, _, err := c.eval(v, true, false, 0)
if err != nil {
c.addError(err)
return nil
}
if len(res) == 0 {
return math.NaN()
}
// TODO: don't choose a random result, make sure there's exactly 1
return res[0].Value
}
alert eval {
template = eval
$series = merge(series("host=a", 0, .2), series("host=b", 0, .5))
$r = avg($series)
crit = $r
}
template eval {
body = `
{{$v := .Eval .Alert.Vars.r }}
<!-- If $v is not nil (which is what .Eval returns on errors) -->
{{ if notNil $v }}
{{ $v }}
{{ else }}
{{ .LastError }}
{{ end }}
`
subject = `eval example`
}
avg(merge(series("host=a", 0, .2), series("host=b", 0, .5)))
返回是0:0.2{host=a} 和 0:5{host=b}然后给返回第一个值得value就是0.2
.Graph(string|Expression, yAxisLabel string) (image)
这个比较帅,直接返回查询表达式的图片,第二个参数是y轴的label
alert graph {
template = graph
$series = merge(series("host=a", 0, 1, 15, 2, 30, 3), series("host=b", 0, 2, 15, 3, 30, 1))
$r = avg($series)
crit = $r
}
template graph {
body = `
{{$v := .Graph .Alert.Vars.series "Y label" }}
<!-- If $v is not nil (which is what .Graph returns on errors) -->
{{ if notNil $v }}
{{ $v }}
{{ else }}
{{ .LastError }}
{{ end }}
`
subject = `graph example`
}
.GraphAll
.GraphAll 所有线都会画出来,.Graph只画第一条
GraphLink(string) (string)
创建一个base64的连接
http://apmsys.com/expr?date=2017-08-24&expr=WSBsYWJlbA%3D%3D&tab=graph&time=07%3A11%3A31
HTTPGet(url string) string
这个叼,5秒超时,把获取到的结果插入body中
template httpget {
body = `
{{ .HTTPGet "http://localhost:9090"}}
`
subject = `httpget example`
}
alert httpget {
template = httpget
warn = 1
}
.HTTPGetJSON(url string) (*jsonq.JsonQuery)
.HTTPPost(url, bodyType, data string) (string)
template httppost {
body = `
{{ .HTTPPost "http://localhost:9090" "application/json" "{ \"Foo\": \"bar\" }" }}
`
subject = `httppost example`
}
alert httppost {
template = httppost
warn = 1
}
.Lookup(table string, key string) (string)
.LookupAll(table string, key string, tags string|tagset) (string)
一个不指定tagset一个指定tagset
template lookup {
body = `
<h1>.Lookup</h1>
<p>You Got a: {{ .Lookup "exampleTable" "fish" }}</p>
<!-- For host a this will render to "Ohhh... a Red Snapper - Hmmm... Very Tasty" -->
<!-- It is just a shorthand for {{.LookupAll "exampleTable" "fish" .Group }} -->
<h2>.LookupAll</h2>
<p>The fish for host "b" will always be {{ .LookupAll "exampleTable" "fish" "host=b" }}</p>
<!-- For host a this will render to "Nothing! Absolutely Nothing! Stupid! You so Stupid!"
since we requested host=b specifically -->
`
subject = `lookup example`
}
不指定时候,用的是alert中的tagset
Available Variables
{
"Id": 0,
"Start": "2017-08-24T07:20:40.223333767Z",
"End": null,
"AlertKey": "graph{host=a}",
"Tags": "host=a",
"Computations": [
{
"Text": "avg(merge(series(\"host=a\", 0, 1, 15, 2, 30, 3), series(\"host=b\", 0, 2, 15, 3, 30, 1)))",
"Value": 2
}
],
函数调用
这个很重要,调用方式有两种
template global_type_example {
body = `
<!-- Regular Format -->
{{ bytes 12312313 }}
<!-- Pipe Format -->
{{ 12312313 | bytes }}
`
subject = `global example`
}
fun arg1 arg2
arg1 arg2 | fun
Template
这玩意相当重要.关键字就两个body和subject
subject用的是http://golang.org/pkg/text/template/
body用的是https://golang.org/pkg/html/template/
简明教程http://www.cnblogs.com/Pynix/p/4154630.html
模板嵌套
template include {
body = `<p>This gets included!</p>`
subject = `include example`
}
template includes {
body = `{{ template "include" . }}others`
subject = `{{ template "include" . }} others.others.others.includes example`
}
alert include {
template = includes
warn = 1
}
Alert的属性获取
- .Alert.Name
- .Alert.TemplateName
- .Alert.Text 把alert的定义全部显示出来,包含注释
- .Alert.Vars
.Alert.Vars.arg1 .Alert.Vars.arg2
告警存储格式
- lastTouched:{alert} - ZSET of alert key to last touched time stamp
keys lastTouched:*
1) "lastTouched:example.opentsdb.cpu.lookup"
2) "lastTouched:system.mem.free"
3) "lastTouched:exampleTable"
zrange lastTouched:system.mem.free 0 -1 WITHSCORES
1) "system.mem.free{host=7f-2-3}"
2) "1504163065"
3) "system.mem.free{host=aficiompc4501}"
4) "1504163065"
5) "system.mem.free{host=cheng_f}"
6) "1504163065"
7) "system.mem.free{host=jiaKeSi}"
8) "1504163065"
9) "system.mem.free{host=paas-177}"
10) "1504163065"
11) "system.mem.free{host=sec001599ec6804}"
12) "1504163065"
13) "system.mem.free{host=tashifuwuqi-switch}"
14) "1504163065"
15) "system.mem.free{host=toshibae-studio456}"
16) "1504163065"
17) "system.mem.free{host=yin_p.hold.founder.com}"
18) "1504163065"
- openIncidents - Hash of open incident Ids. Alert Key -> incident id
hgetall openIncidents
1) "example.opentsdb.cpu.lookup{host=song-centos78}"
2) "326"
3) "example.opentsdb.cpu.lookup{host=75-\xe5\x8d\x97\xe6\x98\x8c02-win2003-4cpu-8G-200G}"
4) "384"
5) "example.opentsdb.cpu.lookup{host=24-\xe6\xaf\x8f\xe6\x97\xa5web-RHEL6.3-1CPU-8G-160G}"
6) "460"
7) "example.opentsdb.cpu.lookup{host=194-jekins-win2008-2cpu-4g-100g}"
8) "332"
9) "example.opentsdb.cpu.lookup{host=87-bg02-centos7-2cpu-15g-100g}"
10) "374"
11) "example.opentsdb.cpu.lookup{host=29-sponichi01-rhel5_4-1cpu-2G-80G}"
12) "387"
13) "example.opentsdb.cpu.lookup{host=73-\xe4\xb8\xad\xe5\xb1\xb102-win2003-4cpu-8G-200G}"
14) "323"
15) "system.mem.free{host=7f-2-3}"
16) "466"
17) "example.opentsdb.cpu.lookup{host=16-\xe6\x9c\x9d\xe6\x97\xa5mq-RHEL6-2CPU-4G-80G}"
18) "380"
19) "example.opentsdb.cpu.lookup{host=119-\xe5\xad\xa6\xe7\xa0\x94web-rhel5-1cpu-2-30g}"
20) "321"
21) "example.opentsdb.cpu.lookup{host=jiaKeSi}"
22) "379"
23) "example.opentsdb.cpu.lookup{host=win2008_r2_64bit_enterprise}"
24) "405"
25) "example.opentsdb.cpu.lookup{host=80-\xe5\x9b\xbd\xe5\x86\x85\xe4\xb8\x9a\xe5\x8a\xa1-\xe5\xbe\x90\xe9\xbe\x992}"
26) "424"
27) "example.opentsdb.cpu.lookup{host=66-\xe7\x9c\x81\xe4\xba\xba\xe6\xb0\x9101-win2003-2cpu-8G-80G}"
28) "364"
29) "example.opentsdb.cpu.lookup{host=wdm-windows}"
30) "409"
- incidents:{ak} - List of incidents for alert key
lrange incidents:example.opentsdb.cpu.lookup{host=paas-70} 0 -1
1) "366"
2) "188"
3) "112"
- allIncidents - List of all incidents ever. Value is "incidentId:timestamp:ak"
lrange allIncidents 0 -1
1) "466:1504160964:system.mem.free{host=7f-2-3}"
2) "465:1504158864:system.mem.free{host=tashifuwuqi-switch}"
3) "464:1504158564:system.mem.free{host=aficiompc4501}"
4) "463:1504150463:example.opentsdb.cpu.lookup{host=OA2QQ-190}"
5) "462:1504150463:example.opentsdb.cpu.lookup{host=96-bg04-centos7-2cpu-15g-100g}"
6) "461:1504150463:example.opentsdb.cpu.lookup{host=200-HR}"
- incidentById:{id} - json encoded state. Authoritative source.
get incidentById:189
"{\"Id\":189,\"Start\":\"2017-08-30T07:02:30.852168007Z\",\"End\":\"2017-08-31T03:14:23.803436177Z\",\"AlertKey\":\"example.opentsdb.cpu.lookup{host=15-\xe6\x9c\x9d\xe6\x97\xa5web-RHEL6-2CPU-4G-40G}\",\"Alert\":\"example.opentsdb.cpu.lookup\",\"Tags\":\"host=15-\xe6\x9c\x9d\xe6\x97\xa5web-RHEL6-2CPU-4G-40G\",\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\",\"Events\":[{\"Crit\":{\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\"},\"Status\":\"critical\",\"Time\":\"2017-08-30T07:02:30.629897306Z\",\"Unevaluated\":false},{\"Status\":\"unknown\",\"Time\":\"2017-08-31T03:04:23.574629619Z\",\"Unevaluated\":false}],\"Actions\":[{\"User\":\"anonymous\",\"Message\":\"dddd\",\"Time\":\"2017-08-31T02:52:42.242084747Z\",\"Type\":\"DelayedClose\",\"Deadline\":\"2017-08-31T03:11:51.077158889Z\",\"Fullfilled\":false,\"Cancelled\":true},{\"User\":\"anonymous\",\"Message\":\"dd\",\"Time\":\"2017-08-31T02:53:03.862737552Z\",\"Type\":\"DelayedClose\",\"Deadline\":\"2017-08-31T03:11:51.077158889Z\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"anonymous\",\"Message\":\"1\",\"Time\":\"2017-08-31T03:01:51.077158889Z\",\"Type\":\"DelayedClose\",\"Deadline\":\"2017-08-31T03:11:51.077158889Z\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"bosun\",\"Message\":\"cancelled delayed close due to severity increase\",\"Time\":\"2017-08-31T03:04:23.628038863Z\",\"Type\":\"CancelClose\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"bosun\",\"Message\":\"forceclose on behalf of delayed close by anonymous\",\"Time\":\"2017-08-31T03:14:23.803436177Z\",\"Type\":\"ForceClosed\",\"Fullfilled\":false,\"Cancelled\":false}],\"Subject\":\"critical: example.opentsdb.cpu.lookup: \\u003cno value\\u003e on 15-\xe6\x9c\x9d\xe6\x97\xa5web-RHEL6-2CPU-4G-40G\",\"NeedAck\":true,\"Open\":false,\"Unevaluated\":false,\"CurrentStatus\":\"unknown\",\"WorstStatus\":\"unknown\",\"LastAbnormalStatus\":\"unknown\",\"LastAbnormalTime\":1504148663}"
- renderedTemplatesById:{id} - json encoded RenderedTemplates by Incident Id
get renderedTemplatesById:189
"{\"Body\":\"\\u003chtml\\u003e\\u003chead\\u003e\\u003c/head\\u003e\\u003cbody\\u003e\\u003ca href=\\\"http://apmsys.com/action?key=example.opentsdb.cpu.lookup%7Bhost%3D15-%E6%9C%9D%E6%97%A5web-RHEL6-2CPU-4G-40G%7D\\u0026amp;type=ack\\\"\\u003eAcknowledge alert\\u003c/a\\u003e\\n\\t\\u003cp\\u003eAlert definition:\\n\\t\\u003c/p\\u003e\\u003cp\\u003eName: example.opentsdb.cpu.lookup\\n\\t\\u003c/p\\u003e\\u003cp\\u003eCrit: lookup(\\u0026#34;cpu\\u0026#34;, \\u0026#34;high\\u0026#34;)\\n\\t\\n\\t\\u003c/p\\u003e\\u003cp\\u003eTags\\n\\t\\n\\t\\u003ctable\\u003e\\n\\t\\t\\n\\t\\t\\t\\n\\t\\t\\t\\t\\u003ctbody\\u003e\\u003ctr\\u003e\\u003ctd\\u003ehost\\u003c/td\\u003e\\u003ctd\\u003e\\u003ca href=\\\"http://apmsys.com/host?host=15-%E6%9C%9D%E6%97%A5web-RHEL6-2CPU-4G-40G\\u0026amp;time=1d-ago\\\"\\u003e15-\xe6\x9c\x9d\xe6\x97\xa5web-RHEL6-2CPU-4G-40G\\u003c/a\\u003e\\u003c/td\\u003e\\u003c/tr\\u003e\\n\\t\\t\\t\\n\\t\\t\\n\\t\\u003c/tbody\\u003e\\u003c/table\\u003e\\n\\n\\t\\u003c/p\\u003e\\u003cp\\u003eComputation\\n\\t\\n\\t\\u003ctable\\u003e\\n\\t\\t\\n\\t\\u003c/table\\u003e\\u003c/p\\u003e\\u003c/body\\u003e\\u003c/html\\u003e\",\"EmailBody\":\"PGh0bWw+PGhlYWQ+PC9oZWFkPjxib2R5PjxhIGhyZWY9Imh0dHA6Ly9hcG1zeXMuY29tL2FjdGlvbj9rZXk9ZXhhbXBsZS5vcGVudHNkYi5jcHUubG9va3VwJTdCaG9zdCUzRDE1LSVFNiU5QyU5RCVFNiU5NyVBNXdlYi1SSEVMNi0yQ1BVLTRHLTQwRyU3RCZhbXA7dHlwZT1hY2siPkFja25vd2xlZGdlIGFsZXJ0PC9hPgoJPHA+QWxlcnQgZGVmaW5pdGlvbjoKCTwvcD48cD5OYW1lOiBleGFtcGxlLm9wZW50c2RiLmNwdS5sb29rdXAKCTwvcD48cD5Dcml0OiBsb29rdXAoJiMzNDtjcHUmIzM0OywgJiMzNDtoaWdoJiMzNDspCgkKCTwvcD48cD5UYWdzCgkKCTx0YWJsZT4KCQkKCQkJCgkJCQk8dGJvZHk+PHRyPjx0ZD5ob3N0PC90ZD48dGQ+PGEgaHJlZj0iaHR0cDovL2FwbXN5cy5jb20vaG9zdD9ob3N0PTE1LSVFNiU5QyU5RCVFNiU5NyVBNXdlYi1SSEVMNi0yQ1BVLTRHLTQwRyZhbXA7dGltZT0xZC1hZ28iPjE1LeacneaXpXdlYi1SSEVMNi0yQ1BVLTRHLTQwRzwvYT48L3RkPjwvdHI+CgkJCQoJCQoJPC90Ym9keT48L3RhYmxlPgoKCTwvcD48cD5Db21wdXRhdGlvbgoJCgk8dGFibGU+CgkJCgk8L3RhYmxlPjwvcD48L2JvZHk+PC9odG1sPg==\",\"EmailSubject\":\"Y3JpdGljYWw6IGV4YW1wbGUub3BlbnRzZGIuY3B1Lmxvb2t1cDogPG5vIHZhbHVlPiBvbiAxNS3mnJ3ml6V3ZWItUkhFTDYtMkNQVS00Ry00MEc=\",\"Attachments\":null}"
信息获取
HVALS openIncidents
mget incidentById:384 incidentById:326
1) "{\"Id\":384,\"Start\":\"2017-08-31T03:29:23.749703309Z\",\"End\":null,\"AlertKey\":\"example.opentsdb.cpu.lookup{host=75-\xe5\x8d\x97\xe6\x98\x8c02-win2003-4cpu-8G-200G}\",\"Alert\":\"example.opentsdb.cpu.lookup\",\"Tags\":\"host=75-\xe5\x8d\x97\xe6\x98\x8c02-win2003-4cpu-8G-200G\",\"Value\":0,\"Expr\":\"\",\"Events\":[{\"Status\":\"unknown\",\"Time\":\"2017-08-31T03:29:23.652781328Z\",\"Unevaluated\":false}],\"Subject\":\"\",\"NeedAck\":true,\"Open\":true,\"Unevaluated\":false,\"CurrentStatus\":\"unknown\",\"WorstStatus\":\"unknown\",\"LastAbnormalStatus\":\"unknown\",\"LastAbnormalTime\":1504165465}"
2) "{\"Id\":326,\"Start\":\"2017-08-31T03:24:23.699746332Z\",\"End\":null,\"AlertKey\":\"example.opentsdb.cpu.lookup{host=song-centos78}\",\"Alert\":\"example.opentsdb.cpu.lookup\",\"Tags\":\"host=song-centos78\",\"Value\":0,\"Expr\":\"\",\"Events\":[{\"Status\":\"unknown\",\"Time\":\"2017-08-31T03:24:23.636628031Z\",\"Unevaluated\":false}],\"Subject\":\"\",\"NeedAck\":true,\"Open\":true,\"Unevaluated\":false,\"CurrentStatus\":\"unknown\",\"WorstStatus\":\"unknown\",\"LastAbnormalStatus\":\"unknown\",\"LastAbnormalTime\":1504165465}"
lrange incidents:example.opentsdb.cpu.lookup{host=31-圣教-win2003-2CPU-2G-80G} 0 -1
1) "398"
2) "200"
3) "52"
mget incidentById:398 incidentById:200 incidentById:52
1) "{\"Id\":398,\"Start\":\"2017-08-31T03:29:23.820220915Z\",\"End\":null,\"AlertKey\":\"example.opentsdb.cpu.lookup{host=31-\xe5\x9c\xa3\xe6\x95\x99-win2003-2CPU-2G-80G}\",\"Alert\":\"example.opentsdb.cpu.lookup\",\"Tags\":\"host=31-\xe5\x9c\xa3\xe6\x95\x99-win2003-2CPU-2G-80G\",\"Value\":0,\"Expr\":\"\",\"Events\":[{\"Status\":\"unknown\",\"Time\":\"2017-08-31T03:29:23.652781328Z\",\"Unevaluated\":false}],\"Subject\":\"\",\"NeedAck\":true,\"Open\":true,\"Unevaluated\":false,\"CurrentStatus\":\"unknown\",\"WorstStatus\":\"unknown\",\"LastAbnormalStatus\":\"unknown\",\"LastAbnormalTime\":1504168985}"
2) "{\"Id\":200,\"Start\":\"2017-08-30T07:02:30.917346789Z\",\"End\":\"2017-08-31T03:19:23.933408826Z\",\"AlertKey\":\"example.opentsdb.cpu.lookup{host=31-\xe5\x9c\xa3\xe6\x95\x99-win2003-2CPU-2G-80G}\",\"Alert\":\"example.opentsdb.cpu.lookup\",\"Tags\":\"host=31-\xe5\x9c\xa3\xe6\x95\x99-win2003-2CPU-2G-80G\",\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\",\"Events\":[{\"Crit\":{\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\"},\"Status\":\"critical\",\"Time\":\"2017-08-30T07:02:30.629897306Z\",\"Unevaluated\":false},{\"Status\":\"unknown\",\"Time\":\"2017-08-31T03:04:23.574629619Z\",\"Unevaluated\":false}],\"Actions\":[{\"User\":\"anonymous\",\"Message\":\"dddd\",\"Time\":\"2017-08-31T02:52:42.42310899Z\",\"Type\":\"DelayedClose\",\"Deadline\":\"2017-08-31T03:11:51.301864413Z\",\"Fullfilled\":false,\"Cancelled\":true},{\"User\":\"anonymous\",\"Message\":\"dd\",\"Time\":\"2017-08-31T02:53:04.04064137Z\",\"Type\":\"DelayedClose\",\"Deadline\":\"2017-08-31T03:11:51.301864413Z\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"anonymous\",\"Message\":\"1\",\"Time\":\"2017-08-31T03:01:51.301864413Z\",\"Type\":\"DelayedClose\",\"Deadline\":\"2017-08-31T03:11:51.301864413Z\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"bosun\",\"Message\":\"cancelled delayed close due to severity increase\",\"Time\":\"2017-08-31T03:04:24.447429044Z\",\"Type\":\"CancelClose\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"bosun\",\"Message\":\"forceclose on behalf of delayed close by anonymous\",\"Time\":\"2017-08-31T03:19:23.933408826Z\",\"Type\":\"ForceClosed\",\"Fullfilled\":false,\"Cancelled\":false}],\"Subject\":\"critical: example.opentsdb.cpu.lookup: \\u003cno value\\u003e on 31-\xe5\x9c\xa3\xe6\x95\x99-win2003-2CPU-2G-80G\",\"NeedAck\":true,\"Open\":false,\"Unevaluated\":false,\"CurrentStatus\":\"unknown\",\"WorstStatus\":\"unknown\",\"LastAbnormalStatus\":\"unknown\",\"LastAbnormalTime\":1504148663}"
3) "{\"Id\":52,\"Start\":\"2017-08-29T07:09:07.238049496Z\",\"End\":\"2017-08-30T06:57:32.054459434Z\",\"AlertKey\":\"example.opentsdb.cpu.lookup{host=31-\xe5\x9c\xa3\xe6\x95\x99-win2003-2CPU-2G-80G}\",\"Alert\":\"example.opentsdb.cpu.lookup\",\"Tags\":\"host=31-\xe5\x9c\xa3\xe6\x95\x99-win2003-2CPU-2G-80G\",\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\",\"Events\":[{\"Crit\":{\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\"},\"Status\":\"critical\",\"Time\":\"2017-08-29T07:09:06.448644876Z\",\"Unevaluated\":false},{\"Status\":\"unknown\",\"Time\":\"2017-08-29T07:26:14.177130794Z\",\"Unevaluated\":false},{\"Crit\":{\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\"},\"Status\":\"critical\",\"Time\":\"2017-08-29T08:39:45.64638889Z\",\"Unevaluated\":false},{\"Status\":\"unknown\",\"Time\":\"2017-08-29T09:04:16.137392882Z\",\"Unevaluated\":false},{\"Crit\":{\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\"},\"Status\":\"critical\",\"Time\":\"2017-08-29T09:05:21.919396931Z\",\"Unevaluated\":false},{\"Status\":\"unknown\",\"Time\":\"2017-08-29T09:26:45.292935927Z\",\"Unevaluated\":false},{\"Crit\":{\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\"},\"Status\":\"critical\",\"Time\":\"2017-08-29T09:32:12.522198488Z\",\"Unevaluated\":false},{\"Status\":\"unknown\",\"Time\":\"2017-08-29T09:47:21.007183963Z\",\"Unevaluated\":false},{\"Crit\":{\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\"},\"Status\":\"critical\",\"Time\":\"2017-08-29T09:55:35.467184821Z\",\"Unevaluated\":false},{\"Status\":\"unknown\",\"Time\":\"2017-08-30T06:33:55.065820902Z\",\"Unevaluated\":false},{\"Crit\":{\"Value\":3,\"Expr\":\"lookup(\\\"cpu\\\", \\\"high\\\")\"},\"Status\":\"critical\",\"Time\":\"2017-08-30T06:34:19.691807729Z\",\"Unevaluated\":false}],\"Actions\":[{\"User\":\"anonymous\",\"Message\":\"ddddd\",\"Time\":\"2017-08-30T06:48:51.111363884Z\",\"Type\":\"DelayedClose\",\"Deadline\":\"2017-08-30T06:54:50.888Z\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"anonymous\",\"Message\":\"sssd\",\"Time\":\"2017-08-30T06:52:39.235770893Z\",\"Type\":\"DelayedClose\",\"Deadline\":\"2017-08-30T06:54:50.888Z\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"anonymous\",\"Message\":\"fd\",\"Time\":\"2017-08-30T06:53:00.185661807Z\",\"Type\":\"Note\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"anonymous\",\"Message\":\"d\",\"Time\":\"2017-08-30T06:53:51.428219013Z\",\"Type\":\"DelayedClose\",\"Deadline\":\"2017-08-30T06:54:50.888Z\",\"Fullfilled\":false,\"Cancelled\":false},{\"User\":\"bosun\",\"Message\":\"forceclose on behalf of delayed close by anonymous\",\"Time\":\"2017-08-30T06:57:32.054459434Z\",\"Type\":\"ForceClosed\",\"Fullfilled\":false,\"Cancelled\":false}],\"Subject\":\"error: template rendering error for alert example.opentsdb.cpu.lookup{host=31-\xe5\x9c\xa3\xe6\x95\x99-win2003-2CPU-2G-80G}\",\"NeedAck\":false,\"Open\":false,\"Unevaluated\":false,\"CurrentStatus\":\"critical\",\"WorstStatus\":\"unknown\",\"LastAbnormalStatus\":\"critical\",\"LastAbnormalTime\":1504075651}"
forecastlr
返回达到y_val线性回归所需时间数。数学不行,已经忘记了线性回归。