mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Move durationToString to common place and cleanup error handling.
This commit is contained in:
parent
ae01bce5f1
commit
c3d31febd6
|
@ -17,6 +17,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/prometheus/model"
|
"github.com/prometheus/prometheus/model"
|
||||||
|
"github.com/prometheus/prometheus/utility"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ func (config *Config) AddJob(options map[string]string, targets []Targets) error
|
||||||
return errors.New("Missing job name")
|
return errors.New("Missing job name")
|
||||||
}
|
}
|
||||||
if len(targets) == 0 {
|
if len(targets) == 0 {
|
||||||
return errors.New(fmt.Sprintf("No targets configured for job '%v'", name))
|
return fmt.Errorf("No targets configured for job '%v'", name)
|
||||||
}
|
}
|
||||||
job := &JobConfig{
|
job := &JobConfig{
|
||||||
Targets: tmpJobTargets,
|
Targets: tmpJobTargets,
|
||||||
|
@ -69,18 +70,18 @@ func (config *Config) AddJob(options map[string]string, targets []Targets) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *GlobalConfig) SetOption(option string, value string) error {
|
func (config *GlobalConfig) SetOption(option string, value string) (err error) {
|
||||||
switch option {
|
switch option {
|
||||||
case "scrape_interval":
|
case "scrape_interval":
|
||||||
config.ScrapeInterval = stringToDuration(value)
|
config.ScrapeInterval, err = utility.StringToDuration(value)
|
||||||
return nil
|
return nil
|
||||||
case "evaluation_interval":
|
case "evaluation_interval":
|
||||||
config.EvaluationInterval = stringToDuration(value)
|
config.EvaluationInterval, err = utility.StringToDuration(value)
|
||||||
return nil
|
return err
|
||||||
default:
|
default:
|
||||||
return errors.New(fmt.Sprintf("Unrecognized global configuration option '%v'", option))
|
err = fmt.Errorf("Unrecognized global configuration option '%v'", option)
|
||||||
}
|
}
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *GlobalConfig) SetLabels(labels model.LabelSet) {
|
func (config *GlobalConfig) SetLabels(labels model.LabelSet) {
|
||||||
|
@ -95,18 +96,16 @@ func (config *GlobalConfig) AddRuleFiles(ruleFiles []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (job *JobConfig) SetOption(option string, value string) error {
|
func (job *JobConfig) SetOption(option string, value string) (err error) {
|
||||||
switch option {
|
switch option {
|
||||||
case "name":
|
case "name":
|
||||||
job.Name = value
|
job.Name = value
|
||||||
return nil
|
|
||||||
case "scrape_interval":
|
case "scrape_interval":
|
||||||
job.ScrapeInterval = stringToDuration(value)
|
job.ScrapeInterval, err = utility.StringToDuration(value)
|
||||||
return nil
|
|
||||||
default:
|
default:
|
||||||
return errors.New(fmt.Sprintf("Unrecognized job configuration option '%v'", option))
|
err = fmt.Errorf("Unrecognized job configuration option '%v'", option)
|
||||||
}
|
}
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (job *JobConfig) AddTargets(endpoints []string, labels model.LabelSet) {
|
func (job *JobConfig) AddTargets(endpoints []string, labels model.LabelSet) {
|
||||||
|
|
|
@ -17,9 +17,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/prometheus/model"
|
"github.com/prometheus/prometheus/model"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Unfortunately, more global variables that are needed for parsing.
|
// Unfortunately, more global variables that are needed for parsing.
|
||||||
|
@ -30,7 +27,9 @@ var tmpTargetLabels = model.LabelSet{}
|
||||||
|
|
||||||
func configError(error string, v ...interface{}) {
|
func configError(error string, v ...interface{}) {
|
||||||
message := fmt.Sprintf(error, v...)
|
message := fmt.Sprintf(error, v...)
|
||||||
log.Fatal(fmt.Sprintf("Line %v, char %v: %s", yyline, yypos, message))
|
// TODO: Don't just die here. Pass errors back all the way to the caller
|
||||||
|
// instead.
|
||||||
|
log.Fatalf("Line %v, char %v: %s", yyline, yypos, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PushJobOption(option string, value string) {
|
func PushJobOption(option string, value string) {
|
||||||
|
@ -66,26 +65,3 @@ func PopJob() {
|
||||||
tmpJobOptions = map[string]string{}
|
tmpJobOptions = map[string]string{}
|
||||||
tmpJobTargets = []Targets{}
|
tmpJobTargets = []Targets{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func stringToDuration(durationStr string) time.Duration {
|
|
||||||
durationRE := regexp.MustCompile("^([0-9]+)([ywdhms]+)$")
|
|
||||||
matches := durationRE.FindStringSubmatch(durationStr)
|
|
||||||
if len(matches) != 3 {
|
|
||||||
configError("Not a valid duration string: '%v'", durationStr)
|
|
||||||
}
|
|
||||||
value, _ := strconv.Atoi(matches[1])
|
|
||||||
unit := matches[2]
|
|
||||||
switch unit {
|
|
||||||
case "y":
|
|
||||||
value *= 60 * 60 * 24 * 365
|
|
||||||
case "w":
|
|
||||||
value *= 60 * 60 * 24 * 7
|
|
||||||
case "d":
|
|
||||||
value *= 60 * 60 * 24
|
|
||||||
case "h":
|
|
||||||
value *= 60 * 60
|
|
||||||
case "m":
|
|
||||||
value *= 60
|
|
||||||
}
|
|
||||||
return time.Duration(value) * time.Second
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ package config
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/prometheus/model"
|
"github.com/prometheus/prometheus/model"
|
||||||
|
"github.com/prometheus/prometheus/utility"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,8 +48,8 @@ func labelsToString(indent int, labels model.LabelSet) string {
|
||||||
|
|
||||||
func (global *GlobalConfig) ToString(indent int) string {
|
func (global *GlobalConfig) ToString(indent int) string {
|
||||||
str := indentStr(indent, "global {\n")
|
str := indentStr(indent, "global {\n")
|
||||||
str += indentStr(indent+1, "scrape_interval = \"%vs\"\n", global.ScrapeInterval)
|
str += indentStr(indent+1, "scrape_interval = \"%s\"\n", utility.DurationToString(global.ScrapeInterval))
|
||||||
str += indentStr(indent+1, "evaluation_interval = \"%vs\"\n", global.EvaluationInterval)
|
str += indentStr(indent+1, "evaluation_interval = \"%s\"\n", utility.DurationToString(global.EvaluationInterval))
|
||||||
str += labelsToString(indent+1, global.Labels)
|
str += labelsToString(indent+1, global.Labels)
|
||||||
str += indentStr(indent, "}\n")
|
str += indentStr(indent, "}\n")
|
||||||
str += indentStr(indent+1, "rule_files = [\n")
|
str += indentStr(indent+1, "rule_files = [\n")
|
||||||
|
@ -61,9 +62,8 @@ func (global *GlobalConfig) ToString(indent int) string {
|
||||||
|
|
||||||
func (job *JobConfig) ToString(indent int) string {
|
func (job *JobConfig) ToString(indent int) string {
|
||||||
str := indentStr(indent, "job {\n")
|
str := indentStr(indent, "job {\n")
|
||||||
str += indentStr(indent+1, "job {\n")
|
|
||||||
str += indentStr(indent+1, "name = \"%v\"\n", job.Name)
|
str += indentStr(indent+1, "name = \"%v\"\n", job.Name)
|
||||||
str += indentStr(indent+1, "scrape_interval = \"%vs\"\n", job.ScrapeInterval)
|
str += indentStr(indent+1, "scrape_interval = \"%s\"\n", utility.DurationToString(job.ScrapeInterval))
|
||||||
for _, targets := range job.Targets {
|
for _, targets := range job.Targets {
|
||||||
str += indentStr(indent+1, "targets {\n")
|
str += indentStr(indent+1, "targets {\n")
|
||||||
str += indentStr(indent+2, "endpoints = [\n")
|
str += indentStr(indent+2, "endpoints = [\n")
|
||||||
|
|
|
@ -16,6 +16,7 @@ package ast
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/prometheus/prometheus/utility"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -65,29 +66,6 @@ func exprTypeToString(exprType ExprType) string {
|
||||||
return exprTypeMap[exprType]
|
return exprTypeMap[exprType]
|
||||||
}
|
}
|
||||||
|
|
||||||
func durationToString(duration time.Duration) string {
|
|
||||||
seconds := int64(duration / time.Second)
|
|
||||||
factors := map[string]int64{
|
|
||||||
"y": 60 * 60 * 24 * 365,
|
|
||||||
"d": 60 * 60 * 24,
|
|
||||||
"h": 60 * 60,
|
|
||||||
"m": 60,
|
|
||||||
"s": 1,
|
|
||||||
}
|
|
||||||
unit := "s"
|
|
||||||
switch int64(0) {
|
|
||||||
case seconds % factors["y"]:
|
|
||||||
unit = "y"
|
|
||||||
case seconds % factors["d"]:
|
|
||||||
unit = "d"
|
|
||||||
case seconds % factors["h"]:
|
|
||||||
unit = "h"
|
|
||||||
case seconds % factors["m"]:
|
|
||||||
unit = "m"
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%v%v", seconds/factors[unit], unit)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (vector Vector) ToString() string {
|
func (vector Vector) ToString() string {
|
||||||
metricStrings := []string{}
|
metricStrings := []string{}
|
||||||
for _, sample := range vector {
|
for _, sample := range vector {
|
||||||
|
@ -228,7 +206,7 @@ func (node *VectorLiteral) ToString() string {
|
||||||
|
|
||||||
func (node *MatrixLiteral) ToString() string {
|
func (node *MatrixLiteral) ToString() string {
|
||||||
vectorString := (&VectorLiteral{labels: node.labels}).ToString()
|
vectorString := (&VectorLiteral{labels: node.labels}).ToString()
|
||||||
intervalString := fmt.Sprintf("['%v']", durationToString(node.interval))
|
intervalString := fmt.Sprintf("['%v']", utility.DurationToString(node.interval))
|
||||||
return vectorString + intervalString
|
return vectorString + intervalString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,48 +14,15 @@
|
||||||
package rules
|
package rules
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/prometheus/prometheus/model"
|
"github.com/prometheus/prometheus/model"
|
||||||
"github.com/prometheus/prometheus/rules/ast"
|
"github.com/prometheus/prometheus/rules/ast"
|
||||||
"regexp"
|
"github.com/prometheus/prometheus/utility"
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func rulesError(error string, v ...interface{}) error {
|
|
||||||
return errors.New(fmt.Sprintf(error, v...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO move to common place, currently duplicated in config/
|
|
||||||
func stringToDuration(durationStr string) (time.Duration, error) {
|
|
||||||
durationRE := regexp.MustCompile("^([0-9]+)([ywdhms]+)$")
|
|
||||||
matches := durationRE.FindStringSubmatch(durationStr)
|
|
||||||
if len(matches) != 3 {
|
|
||||||
return 0, rulesError("Not a valid duration string: '%v'", durationStr)
|
|
||||||
}
|
|
||||||
value, _ := strconv.Atoi(matches[1])
|
|
||||||
unit := matches[2]
|
|
||||||
switch unit {
|
|
||||||
case "y":
|
|
||||||
value *= 60 * 60 * 24 * 365
|
|
||||||
case "w":
|
|
||||||
value *= 60 * 60 * 24
|
|
||||||
case "d":
|
|
||||||
value *= 60 * 60 * 24
|
|
||||||
case "h":
|
|
||||||
value *= 60 * 60
|
|
||||||
case "m":
|
|
||||||
value *= 60
|
|
||||||
case "s":
|
|
||||||
value *= 1
|
|
||||||
}
|
|
||||||
return time.Duration(value) * time.Second, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateRule(name string, labels model.LabelSet, root ast.Node, permanent bool) (*Rule, error) {
|
func CreateRule(name string, labels model.LabelSet, root ast.Node, permanent bool) (*Rule, error) {
|
||||||
if root.Type() != ast.VECTOR {
|
if root.Type() != ast.VECTOR {
|
||||||
return nil, rulesError("Rule %v does not evaluate to vector type", name)
|
return nil, fmt.Errorf("Rule %v does not evaluate to vector type", name)
|
||||||
}
|
}
|
||||||
return NewRule(name, labels, root.(ast.VectorNode), permanent), nil
|
return NewRule(name, labels, root.(ast.VectorNode), permanent), nil
|
||||||
}
|
}
|
||||||
|
@ -63,18 +30,18 @@ func CreateRule(name string, labels model.LabelSet, root ast.Node, permanent boo
|
||||||
func NewFunctionCall(name string, args []ast.Node) (ast.Node, error) {
|
func NewFunctionCall(name string, args []ast.Node) (ast.Node, error) {
|
||||||
function, err := ast.GetFunction(name)
|
function, err := ast.GetFunction(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rulesError("Unknown function \"%v\"", name)
|
return nil, fmt.Errorf("Unknown function \"%v\"", name)
|
||||||
}
|
}
|
||||||
functionCall, err := ast.NewFunctionCall(function, args)
|
functionCall, err := ast.NewFunctionCall(function, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rulesError(err.Error())
|
return nil, fmt.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
return functionCall, nil
|
return functionCall, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy []model.LabelName) (*ast.VectorAggregation, error) {
|
func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy []model.LabelName) (*ast.VectorAggregation, error) {
|
||||||
if vector.Type() != ast.VECTOR {
|
if vector.Type() != ast.VECTOR {
|
||||||
return nil, rulesError("Operand of %v aggregation must be of vector type", aggrTypeStr)
|
return nil, fmt.Errorf("Operand of %v aggregation must be of vector type", aggrTypeStr)
|
||||||
}
|
}
|
||||||
var aggrTypes = map[string]ast.AggrType{
|
var aggrTypes = map[string]ast.AggrType{
|
||||||
"SUM": ast.SUM,
|
"SUM": ast.SUM,
|
||||||
|
@ -84,7 +51,7 @@ func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy []model.L
|
||||||
}
|
}
|
||||||
aggrType, ok := aggrTypes[aggrTypeStr]
|
aggrType, ok := aggrTypes[aggrTypeStr]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, rulesError("Unknown aggregation type '%v'", aggrTypeStr)
|
return nil, fmt.Errorf("Unknown aggregation type '%v'", aggrTypeStr)
|
||||||
}
|
}
|
||||||
return ast.NewVectorAggregation(aggrType, vector.(ast.VectorNode), groupBy), nil
|
return ast.NewVectorAggregation(aggrType, vector.(ast.VectorNode), groupBy), nil
|
||||||
}
|
}
|
||||||
|
@ -107,11 +74,11 @@ func NewArithExpr(opTypeStr string, lhs ast.Node, rhs ast.Node) (ast.Node, error
|
||||||
}
|
}
|
||||||
opType, ok := opTypes[opTypeStr]
|
opType, ok := opTypes[opTypeStr]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, rulesError("Invalid binary operator \"%v\"", opTypeStr)
|
return nil, fmt.Errorf("Invalid binary operator \"%v\"", opTypeStr)
|
||||||
}
|
}
|
||||||
expr, err := ast.NewArithExpr(opType, lhs, rhs)
|
expr, err := ast.NewArithExpr(opType, lhs, rhs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, rulesError(err.Error())
|
return nil, fmt.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
return expr, nil
|
return expr, nil
|
||||||
}
|
}
|
||||||
|
@ -123,9 +90,9 @@ func NewMatrix(vector ast.Node, intervalStr string) (ast.MatrixNode, error) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, rulesError("Intervals are currently only supported for vector literals.")
|
return nil, fmt.Errorf("Intervals are currently only supported for vector literals.")
|
||||||
}
|
}
|
||||||
interval, err := stringToDuration(intervalStr)
|
interval, err := utility.StringToDuration(intervalStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,9 @@ AVG|SUM|MAX|MIN { yylval.str = yytext; return AGGR_OP }
|
||||||
{L}({L}|{D})+ { yylval.str = yytext; return IDENTIFIER }
|
{L}({L}|{D})+ { yylval.str = yytext; return IDENTIFIER }
|
||||||
|
|
||||||
\-?{D}+(\.{D}*)? { num, err := strconv.ParseFloat(yytext, 32);
|
\-?{D}+(\.{D}*)? { num, err := strconv.ParseFloat(yytext, 32);
|
||||||
if (err != nil) { rulesError("Invalid float %v", yytext) }
|
if (err != nil && err.(*strconv.NumError).Err == strconv.ErrSyntax) {
|
||||||
|
panic("Invalid float")
|
||||||
|
}
|
||||||
yylval.num = model.SampleValue(num)
|
yylval.num = model.SampleValue(num)
|
||||||
return NUMBER }
|
return NUMBER }
|
||||||
|
|
||||||
|
|
|
@ -436,8 +436,8 @@ var yyrules []yyrule = []yyrule{{regexp.MustCompile("[^\\n]"), nil, []yystartcon
|
||||||
}()
|
}()
|
||||||
{
|
{
|
||||||
num, err := strconv.ParseFloat(yytext, 32)
|
num, err := strconv.ParseFloat(yytext, 32)
|
||||||
if err != nil {
|
if err != nil && err.(*strconv.NumError).Err == strconv.ErrSyntax {
|
||||||
rulesError("Invalid float %v", yytext)
|
panic("Invalid float")
|
||||||
}
|
}
|
||||||
yylval.num = model.SampleValue(num)
|
yylval.num = model.SampleValue(num)
|
||||||
return yyactionreturn{NUMBER, yyRT_USER_RETURN}
|
return yyactionreturn{NUMBER, yyRT_USER_RETURN}
|
||||||
|
|
72
utility/strconv.go
Normal file
72
utility/strconv.go
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright 2013 Prometheus Team
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package utility
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var durationRE = regexp.MustCompile("^([0-9]+)([ywdhms]+)$")
|
||||||
|
|
||||||
|
func DurationToString(duration time.Duration) string {
|
||||||
|
seconds := int64(duration / time.Second)
|
||||||
|
factors := map[string]int64{
|
||||||
|
"y": 60 * 60 * 24 * 365,
|
||||||
|
"d": 60 * 60 * 24,
|
||||||
|
"h": 60 * 60,
|
||||||
|
"m": 60,
|
||||||
|
"s": 1,
|
||||||
|
}
|
||||||
|
unit := "s"
|
||||||
|
switch int64(0) {
|
||||||
|
case seconds % factors["y"]:
|
||||||
|
unit = "y"
|
||||||
|
case seconds % factors["d"]:
|
||||||
|
unit = "d"
|
||||||
|
case seconds % factors["h"]:
|
||||||
|
unit = "h"
|
||||||
|
case seconds % factors["m"]:
|
||||||
|
unit = "m"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%v%v", seconds/factors[unit], unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
func StringToDuration(durationStr string) (duration time.Duration, err error) {
|
||||||
|
matches := durationRE.FindStringSubmatch(durationStr)
|
||||||
|
if len(matches) != 3 {
|
||||||
|
err = fmt.Errorf("Not a valid duration string: '%v'", durationStr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
durationSeconds, _ := strconv.Atoi(matches[1])
|
||||||
|
duration = time.Duration(durationSeconds) * time.Second
|
||||||
|
unit := matches[2]
|
||||||
|
switch unit {
|
||||||
|
case "y":
|
||||||
|
duration *= 60 * 60 * 24 * 365
|
||||||
|
case "w":
|
||||||
|
duration *= 60 * 60 * 24 * 7
|
||||||
|
case "d":
|
||||||
|
duration *= 60 * 60 * 24
|
||||||
|
case "h":
|
||||||
|
duration *= 60 * 60
|
||||||
|
case "m":
|
||||||
|
duration *= 60
|
||||||
|
case "s":
|
||||||
|
duration *= 1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in a new issue