作者:rajde
项目:bosu
func (c *Conf) alert(s *expr.State, T miniprofiler.Timer, name, key string) (results *expr.Results, err error) {
_, e, err := c.getAlertExpr(name, key)
if err != nil {
return nil, err
}
results, _, err = e.ExecuteState(s, T)
if err != nil {
return nil, err
}
if s.History != nil {
unknownTags, unevalTags := s.History.GetUnknownAndUnevaluatedAlertKeys(name)
// For currently unknown tags NOT in the result set, add an error result
for _, ak := range unknownTags {
found := false
for _, result := range results.Results {
if result.Group.Equal(ak.Group()) {
found = true
break
}
}
if !found {
res := expr.Result{
Value: expr.Number(1),
Group: ak.Group(),
}
results.Results = append(results.Results, &res)
}
}
//For all unevaluated tags in run history, make sure we report a nonzero result.
for _, ak := range unevalTags {
found := false
for _, result := range results.Results {
if result.Group.Equal(ak.Group()) {
result.Value = expr.Number(1)
found = true
break
}
}
if !found {
res := expr.Result{
Value: expr.Number(1),
Group: ak.Group(),
}
results.Results = append(results.Results, &res)
}
}
}
return results, nil
}
作者:jm
项目:bosu
// LeftJoin takes slices of results and expressions for which it gets the slices of results.
// Then it joins the 2nd and higher slice of results onto the first slice of results.
// Joining is performed by group: a group that includes all tags (with same values) of the first group is a match.
func (c *Context) LeftJoin(v ...interface{}) (interface{}, error) {
if len(v) < 2 {
return nil, fmt.Errorf("need at least two values (each can be an expression or result slice), got %v", len(v))
}
// temporarily store the results in a results[M][Ni] Result matrix:
// for M queries, tracks Ni results per each i'th query
results := make([][]*expr.Result, len(v))
for col, val := range v {
queryResults, _, err := c.eval(val, false, false, 0)
if err != nil {
return nil, err
}
results[col] = queryResults
}
// perform the joining by storing all results in a joined[N0][M] Result matrix:
// for N tagsets (based on first query results), tracks all M Results (results with matching group, from all other queries)
joined := make([][]*expr.Result, 0)
for row, firstQueryResult := range results[0] {
joined = append(joined, make([]*expr.Result, len(v)))
joined[row][0] = firstQueryResult
// join results of 2nd to M queries
for col, queryResults := range results[1:] {
for _, laterQueryResult := range queryResults {
if firstQueryResult.Group.Subset(laterQueryResult.Group) {
joined[row][col+1] = laterQueryResult
break
}
// Fill emtpy cells with NaN Value, so calling .Value is not a nil pointer dereference
joined[row][col+1] = &expr.Result{Value: expr.Number(math.NaN())}
}
}
}
return joined, nil
}
作者:bridgewel
项目:bosu
func init() {
gob.Register(expr.Number(0))
gob.Register(expr.Scalar(0))
}
作者:rajde
项目:bosu
func (c *Conf) Funcs() map[string]eparse.Func {
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
vals, err := e.Search.TagValuesByTagKey(tag, 0)
if err != nil {
return nil, err
}
for _, value := range vals {
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
}
lookupSeries := func(e *expr.State, T miniprofiler.Timer, series *expr.Results, 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
}
for _, res := range series.Results {
value, ok := lookups.Get(key, res.Group)
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: res.Group,
})
}
return results, nil
}
lookupTags := func(args []eparse.Node) (eparse.Tags, error) {
name := args[0].(*eparse.StringNode).Text
lookup := c.Lookups[name]
if lookup == nil {
return nil, fmt.Errorf("bad lookup table %v", name)
}
t := make(eparse.Tags)
for _, v := range lookup.Tags {
t[v] = struct{}{}
}
return t, nil
}
lookupSeriesTags := func(args []eparse.Node) (eparse.Tags, error) {
name := args[1].(*eparse.StringNode).Text
lookup := c.Lookups[name]
if lookup == nil {
return nil, fmt.Errorf("bad lookup table %v", name)
}
t := make(eparse.Tags)
for _, v := range lookup.Tags {
t[v] = struct{}{}
}
//.........这里部分代码省略.........