Merge pull request #1339 from prometheus/range-parsing

Consolidate offset modifier parsing
This commit is contained in:
Tobias Schmidt 2016-01-25 10:52:17 -05:00
commit 40ab0da398
2 changed files with 46 additions and 38 deletions

View File

@ -598,6 +598,21 @@ func (p *parser) unaryExpr() Expr {
}
e = p.rangeSelector(vs)
}
// Parse optional offset.
if p.peek().typ == itemOffset {
offset := p.offset()
switch s := e.(type) {
case *VectorSelector:
s.Offset = offset
case *MatrixSelector:
s.Offset = offset
default:
p.errorf("offset modifier must be preceded by a metric or range selector, but follows a %T instead", e)
}
}
return e
}
@ -609,7 +624,7 @@ func (p *parser) rangeSelector(vs *VectorSelector) *MatrixSelector {
const ctx = "matrix selector"
p.next()
var erange, offset time.Duration
var erange time.Duration
var err error
erangeStr := p.expect(itemDuration, ctx).val
@ -620,27 +635,15 @@ func (p *parser) rangeSelector(vs *VectorSelector) *MatrixSelector {
p.expect(itemRightBracket, ctx)
// Parse optional offset.
if p.peek().typ == itemOffset {
p.next()
offi := p.expect(itemDuration, ctx)
offset, err = parseDuration(offi.val)
if err != nil {
p.error(err)
}
}
e := &MatrixSelector{
Name: vs.Name,
LabelMatchers: vs.LabelMatchers,
Range: erange,
Offset: offset,
}
return e
}
// parseNumber parses a number.
// number parses a number.
func (p *parser) number(val string) float64 {
n, err := strconv.ParseInt(val, 0, 64)
f := float64(n)
@ -927,10 +930,28 @@ func (p *parser) metric() model.Metric {
return m
}
// metricSelector parses a new metric selector.
// offset parses an offset modifier.
//
// <metric_identifier> [<label_matchers>] [ offset <duration> ]
// [<metric_identifier>] <label_matchers> [ offset <duration> ]
// offset <duration>
//
func (p *parser) offset() time.Duration {
const ctx = "offset"
p.next()
offi := p.expect(itemDuration, ctx)
offset, err := parseDuration(offi.val)
if err != nil {
p.error(err)
}
return offset
}
// vectorSelector parses a new vector selector.
//
// <metric_identifier> [<label_matchers>]
// [<metric_identifier>] <label_matchers>
//
func (p *parser) vectorSelector(name string) *VectorSelector {
const ctx = "metric selector"
@ -978,22 +999,9 @@ func (p *parser) vectorSelector(name string) *VectorSelector {
p.errorf("vector selector must contain at least one non-empty matcher")
}
var err error
var offset time.Duration
// Parse optional offset.
if p.peek().typ == itemOffset {
p.next()
offi := p.expect(itemDuration, ctx)
offset, err = parseDuration(offi.val)
if err != nil {
p.error(err)
}
}
return &VectorSelector{
Name: name,
LabelMatchers: matchers,
Offset: offset,
}
}

View File

@ -758,7 +758,7 @@ var testExpr = []struct {
}, {
input: `some_metric[5m] OFFSET 1`,
fail: true,
errMsg: "unexpected number \"1\" in matrix selector, expected duration",
errMsg: "unexpected number \"1\" in offset, expected duration",
}, {
input: `some_metric[5m] OFFSET 1mm`,
fail: true,
@ -766,7 +766,11 @@ var testExpr = []struct {
}, {
input: `some_metric[5m] OFFSET`,
fail: true,
errMsg: "unexpected end of input in matrix selector, expected duration",
errMsg: "unexpected end of input in offset, expected duration",
}, {
input: `some_metric OFFSET 1m[5m]`,
fail: true,
errMsg: "could not parse remaining input \"[5m]\"...",
}, {
input: `(foo + bar)[5m]`,
fail: true,
@ -900,10 +904,6 @@ var testExpr = []struct {
input: `sum (some_metric) by test`,
fail: true,
errMsg: "unexpected identifier \"test\" in grouping opts, expected \"(\"",
}, {
input: `some_metric[5m] OFFSET`,
fail: true,
errMsg: "unexpected end of input in matrix selector, expected duration",
}, {
input: `sum () by (test)`,
fail: true,
@ -1147,7 +1147,7 @@ var testStatement = []struct {
input: `
# A simple test recording rule.
dc:http_request:rate5m = sum(rate(http_request_count[5m])) by (dc)
# A simple test alerting rule.
ALERT GlobalRequestRateLow IF(dc:http_request:rate5m < 10000) FOR 5m
LABELS {
@ -1315,7 +1315,7 @@ var testStatement = []struct {
ALERT GlobalRequestRateLow IF(dc:http_request:rate5m < 10000) FOR 5
LABELS {
service = "testservice"
# ... more fields here ...
# ... more fields here ...
}
ANNOTATIONS {
summary = "Global request rate low"