Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion cmd/bosun/expr/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,16 @@ func (e *State) walkFunc(node *parse.FuncNode, T miniprofiler.Timer) *Results {
default:
panic(fmt.Errorf("expr: unknown func arg type"))
}
if f, ok := v.(float64); ok && node.F.Args[i] == models.TypeNumberSet {
var argType models.FuncType
if i >= len(node.F.Args) {
if !node.F.VArgs {
panic("expr: shouldn't be here, more args then expected and not variable argument type func")
}
argType = node.F.Args[node.F.VArgsPos]
} else {
argType = node.F.Args[i]
}
if f, ok := v.(float64); ok && argType == models.TypeNumberSet {
v = fromScalar(f)
}
in = append(in, reflect.ValueOf(v))
Expand Down
36 changes: 36 additions & 0 deletions cmd/bosun/expr/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,15 @@ var builtins = map[string]parse.Func{
Tags: tagFirst,
F: NV,
},
"series": {
Args: []models.FuncType{models.TypeString, models.TypeScalar},
VArgs: true,
VArgsPos: 1,
VArgsOmit: true,
Return: models.TypeSeriesSet,
Tags: tagFirst,
F: SeriesFunc,
},
"sort": {
Args: []models.FuncType{models.TypeNumberSet, models.TypeString},
Return: models.TypeNumberSet,
Expand All @@ -352,6 +361,28 @@ var builtins = map[string]parse.Func{
},
}

func SeriesFunc(e *State, T miniprofiler.Timer, tags string, pairs ...float64) (*Results, error) {
if len(pairs)%2 != 0 {
return nil, fmt.Errorf("uneven number of time stamps and values")
}
group, err := opentsdb.ParseTags(tags)
if err != nil {
return nil, fmt.Errorf("unable to parse tags: %v", err)
}
series := make(Series)
for i := 0; i < len(pairs); i += 2 {
series[time.Unix(int64(pairs[i]), 0)] = pairs[i+1]
}
return &Results{
Results: []*Result{
{
Value: series,
Group: group,
},
},
}, nil
}

func Epoch(e *State, T miniprofiler.Timer) (*Results, error) {
return &Results{
Results: []*Result{
Expand All @@ -361,6 +392,11 @@ func Epoch(e *State, T miniprofiler.Timer) (*Results, error) {
}

func NV(e *State, T miniprofiler.Timer, series *Results, v float64) (results *Results, err error) {
// If there are no results in the set, promote it to a number with the empty group ({})
if len(series.Results) == 0 {
series.Results = append(series.Results, &Result{Value: Number(v), Group: make(opentsdb.TagSet)})
return series, nil
}
series.NaNValue = &v
return series, nil
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/bosun/expr/parse/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func (f *FuncNode) Check(t *Tree) error {
const errFuncType = "parse: bad argument type in %s, expected %s, got %s"
// For VArgs we make sure they are all of the expected type
if f.F.VArgs {
if len(f.Args) < len(f.F.Args) {
if len(f.Args) < len(f.F.Args) && !f.F.VArgsOmit {
return fmt.Errorf("parse: variable argument functions need at least one arg")
}
} else {
Expand Down
15 changes: 8 additions & 7 deletions cmd/bosun/expr/parse/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ type Tree struct {
}

type Func struct {
Args []models.FuncType
Return models.FuncType
Tags func([]Node) (Tags, error)
F interface{}
VArgs bool
VArgsPos int
Check func(*Tree, *FuncNode) error
Args []models.FuncType
Return models.FuncType
Tags func([]Node) (Tags, error)
F interface{}
VArgs bool
VArgsPos int
VArgsOmit bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does VArgsOmit do?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@captncraig Makes it so the vargs are optional. You are allowed to omit them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about inverting it. Maybe VArgsRequired or even MinVArgs would be clearer.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the time it isn't true. So when defining funcs you don't have to
include it. So false is a better default

On Mon, Mar 14, 2016 at 1:19 PM, Craig Peterson [email protected]
wrote:

In cmd/bosun/expr/parse/parse.go
#1667 (comment):

@@ -31,13 +31,14 @@ type Tree struct {
}

type Func struct {

  • Args []models.FuncType
  • Return models.FuncType
  • Tags func([]Node) (Tags, error)
  • F interface{}
  • VArgs bool
  • VArgsPos int
  • Check func(*Tree, *FuncNode) error
  • Args []models.FuncType
  • Return models.FuncType
  • Tags func([]Node) (Tags, error)
  • F interface{}
  • VArgs bool
  • VArgsPos int
  • VArgsOmit bool

How about inverting it. Maybe VArgsRequired or even MinVArgs would be
clearer.


Reply to this email directly or view it on GitHub
https://github.com/bosun-monitor/bosun/pull/1667/files#r56038601.

Check func(*Tree, *FuncNode) error
}

type Tags map[string]struct{}
Expand Down
4 changes: 4 additions & 0 deletions cmd/bosun/expr/parse/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ var builtins = map[string]Func{
nil,
false,
0,
false,
nil,
},
"band": {
Expand All @@ -167,6 +168,7 @@ var builtins = map[string]Func{
nil,
false,
0,
false,
nil,
},
"q": {
Expand All @@ -176,6 +178,7 @@ var builtins = map[string]Func{
nil,
false,
0,
false,
nil,
},
"forecastlr": {
Expand All @@ -185,6 +188,7 @@ var builtins = map[string]Func{
nil,
false,
0,
false,
nil,
},
}
12 changes: 11 additions & 1 deletion docs/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,17 @@ Returns the first count (scalar) results of number.

Returns the first key from the given lookup table with matching tags.

##shift(seriesSet, dur string) seriesSet
## series(tagset string, epoch, value, ...) seriesSet

Returns a seriesSet with one series. The series will have a group (a.k.a tagset). You can then optionally pass epoch value pairs (if non are provided, the series will be empty). This is can be used for testing or drawing arbitary lines. For example:

```
$now = epoch()
$hourAgo = $now-d("1h")
merge(series("foo=bar", $hourAgo, 5, $now, 10), series("foo=bar2", $hourAgo, 6, $now, 11))
```

## shift(seriesSet, dur string) seriesSet

Shift takes a seriesSet and shifts the time forward by the value of dur ([OpenTSDB duration string](http://opentsdb.net/docs/build/html/user_guide/query/dates.html)) and adds a tag for representing the shift duration. This is meant so you can overlay times visually in a graph.

Expand Down