mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmalert: remove dependency on datasource pkg from config (#2905)
* vmalert: remove dependency on datasource pkg from config Signed-off-by: hagen1778 <roman@victoriametrics.com>
This commit is contained in:
parent
89890eab5d
commit
2914ce5ca5
13 changed files with 111 additions and 83 deletions
|
@ -20,7 +20,7 @@ import (
|
||||||
|
|
||||||
// AlertingRule is basic alert entity
|
// AlertingRule is basic alert entity
|
||||||
type AlertingRule struct {
|
type AlertingRule struct {
|
||||||
Type datasource.Type
|
Type config.Type
|
||||||
RuleID uint64
|
RuleID uint64
|
||||||
Name string
|
Name string
|
||||||
Expr string
|
Expr string
|
||||||
|
@ -72,7 +72,7 @@ func newAlertingRule(qb datasource.QuerierBuilder, group *Group, cfg config.Rule
|
||||||
GroupName: group.Name,
|
GroupName: group.Name,
|
||||||
EvalInterval: group.Interval,
|
EvalInterval: group.Interval,
|
||||||
q: qb.BuildWithParams(datasource.QuerierParams{
|
q: qb.BuildWithParams(datasource.QuerierParams{
|
||||||
DataSourceType: &group.Type,
|
DataSourceType: group.Type.String(),
|
||||||
EvaluationInterval: group.Interval,
|
EvaluationInterval: group.Interval,
|
||||||
QueryParams: group.Params,
|
QueryParams: group.Params,
|
||||||
Headers: group.Headers,
|
Headers: group.Headers,
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/datasource"
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/envtemplate"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/envtemplate"
|
||||||
|
@ -23,7 +22,7 @@ import (
|
||||||
// Group contains list of Rules grouped into
|
// Group contains list of Rules grouped into
|
||||||
// entity with one name and evaluation interval
|
// entity with one name and evaluation interval
|
||||||
type Group struct {
|
type Group struct {
|
||||||
Type datasource.Type `yaml:"type,omitempty"`
|
Type Type `yaml:"type,omitempty"`
|
||||||
File string
|
File string
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Interval *promutils.Duration `yaml:"interval,omitempty"`
|
Interval *promutils.Duration `yaml:"interval,omitempty"`
|
||||||
|
@ -39,7 +38,7 @@ type Group struct {
|
||||||
// Optional HTTP URL parameters added to each rule request
|
// Optional HTTP URL parameters added to each rule request
|
||||||
Params url.Values `yaml:"params"`
|
Params url.Values `yaml:"params"`
|
||||||
// Headers contains optional HTTP headers added to each rule request
|
// Headers contains optional HTTP headers added to each rule request
|
||||||
Headers []datasource.Header `yaml:"headers,omitempty"`
|
Headers []Header `yaml:"headers,omitempty"`
|
||||||
|
|
||||||
// Catches all undefined fields and must be empty after parsing.
|
// Catches all undefined fields and must be empty after parsing.
|
||||||
XXX map[string]interface{} `yaml:",inline"`
|
XXX map[string]interface{} `yaml:",inline"`
|
||||||
|
@ -57,7 +56,7 @@ func (g *Group) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
}
|
}
|
||||||
// change default value to prometheus datasource.
|
// change default value to prometheus datasource.
|
||||||
if g.Type.Get() == "" {
|
if g.Type.Get() == "" {
|
||||||
g.Type.Set(datasource.NewPrometheusType())
|
g.Type.Set(NewPrometheusType())
|
||||||
}
|
}
|
||||||
|
|
||||||
h := md5.New()
|
h := md5.New()
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
|
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/datasource"
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/templates"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/templates"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promutils"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promutils"
|
||||||
)
|
)
|
||||||
|
@ -224,7 +223,7 @@ func TestGroup_Validate(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: &Group{Name: "test thanos",
|
group: &Group{Name: "test thanos",
|
||||||
Type: datasource.NewRawType("thanos"),
|
Type: NewRawType("thanos"),
|
||||||
Rules: []Rule{
|
Rules: []Rule{
|
||||||
{Alert: "alert", Expr: "up == 1", Labels: map[string]string{
|
{Alert: "alert", Expr: "up == 1", Labels: map[string]string{
|
||||||
"description": "{{ value|query }}",
|
"description": "{{ value|query }}",
|
||||||
|
@ -236,7 +235,7 @@ func TestGroup_Validate(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: &Group{Name: "test graphite",
|
group: &Group{Name: "test graphite",
|
||||||
Type: datasource.NewGraphiteType(),
|
Type: NewGraphiteType(),
|
||||||
Rules: []Rule{
|
Rules: []Rule{
|
||||||
{Alert: "alert", Expr: "up == 1", Labels: map[string]string{
|
{Alert: "alert", Expr: "up == 1", Labels: map[string]string{
|
||||||
"description": "some-description",
|
"description": "some-description",
|
||||||
|
@ -248,7 +247,7 @@ func TestGroup_Validate(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
group: &Group{Name: "test prometheus",
|
group: &Group{Name: "test prometheus",
|
||||||
Type: datasource.NewPrometheusType(),
|
Type: NewPrometheusType(),
|
||||||
Rules: []Rule{
|
Rules: []Rule{
|
||||||
{Alert: "alert", Expr: "up == 1", Labels: map[string]string{
|
{Alert: "alert", Expr: "up == 1", Labels: map[string]string{
|
||||||
"description": "{{ value|query }}",
|
"description": "{{ value|query }}",
|
||||||
|
@ -261,7 +260,7 @@ func TestGroup_Validate(t *testing.T) {
|
||||||
{
|
{
|
||||||
group: &Group{
|
group: &Group{
|
||||||
Name: "test graphite inherit",
|
Name: "test graphite inherit",
|
||||||
Type: datasource.NewGraphiteType(),
|
Type: NewGraphiteType(),
|
||||||
Rules: []Rule{
|
Rules: []Rule{
|
||||||
{
|
{
|
||||||
Expr: "sumSeries(time('foo.bar',10))",
|
Expr: "sumSeries(time('foo.bar',10))",
|
||||||
|
@ -276,7 +275,7 @@ func TestGroup_Validate(t *testing.T) {
|
||||||
{
|
{
|
||||||
group: &Group{
|
group: &Group{
|
||||||
Name: "test graphite prometheus bad expr",
|
Name: "test graphite prometheus bad expr",
|
||||||
Type: datasource.NewGraphiteType(),
|
Type: NewGraphiteType(),
|
||||||
Rules: []Rule{
|
Rules: []Rule{
|
||||||
{
|
{
|
||||||
Expr: "sum(up == 0 ) by (host)",
|
Expr: "sum(up == 0 ) by (host)",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package datasource
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -10,45 +10,45 @@ import (
|
||||||
|
|
||||||
// Type represents data source type
|
// Type represents data source type
|
||||||
type Type struct {
|
type Type struct {
|
||||||
name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPrometheusType returns prometheus datasource type
|
// NewPrometheusType returns prometheus datasource type
|
||||||
func NewPrometheusType() Type {
|
func NewPrometheusType() Type {
|
||||||
return Type{
|
return Type{
|
||||||
name: "prometheus",
|
Name: "prometheus",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGraphiteType returns graphite datasource type
|
// NewGraphiteType returns graphite datasource type
|
||||||
func NewGraphiteType() Type {
|
func NewGraphiteType() Type {
|
||||||
return Type{
|
return Type{
|
||||||
name: "graphite",
|
Name: "graphite",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRawType returns datasource type from raw string
|
// NewRawType returns datasource type from raw string
|
||||||
// without validation.
|
// without validation.
|
||||||
func NewRawType(d string) Type {
|
func NewRawType(d string) Type {
|
||||||
return Type{name: d}
|
return Type{Name: d}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns datasource type
|
// Get returns datasource type
|
||||||
func (t *Type) Get() string {
|
func (t *Type) Get() string {
|
||||||
return t.name
|
return t.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set changes datasource type
|
// Set changes datasource type
|
||||||
func (t *Type) Set(d Type) {
|
func (t *Type) Set(d Type) {
|
||||||
t.name = d.name
|
t.Name = d.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements String interface with default value.
|
// String implements String interface with default value.
|
||||||
func (t Type) String() string {
|
func (t Type) String() string {
|
||||||
if t.name == "" {
|
if t.Name == "" {
|
||||||
return "prometheus"
|
return "prometheus"
|
||||||
}
|
}
|
||||||
return t.name
|
return t.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateExpr validates query expression with datasource ql.
|
// ValidateExpr validates query expression with datasource ql.
|
||||||
|
@ -63,7 +63,7 @@ func (t *Type) ValidateExpr(expr string) error {
|
||||||
return fmt.Errorf("bad prometheus expr: %q, err: %w", expr, err)
|
return fmt.Errorf("bad prometheus expr: %q, err: %w", expr, err)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown datasource type=%q", t.name)
|
return fmt.Errorf("unknown datasource type=%q", t.Name)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -82,13 +82,13 @@ func (t *Type) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown datasource type=%q, want %q or %q", s, "prometheus", "graphite")
|
return fmt.Errorf("unknown datasource type=%q, want %q or %q", s, "prometheus", "graphite")
|
||||||
}
|
}
|
||||||
t.name = s
|
t.Name = s
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalYAML implements the yaml.Unmarshaler interface.
|
// MarshalYAML implements the yaml.Unmarshaler interface.
|
||||||
func (t Type) MarshalYAML() (interface{}, error) {
|
func (t Type) MarshalYAML() (interface{}, error) {
|
||||||
return t.name, nil
|
return t.Name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header is a Key - Value struct for holding an HTTP header.
|
// Header is a Key - Value struct for holding an HTTP header.
|
|
@ -19,10 +19,10 @@ type QuerierBuilder interface {
|
||||||
|
|
||||||
// QuerierParams params for Querier.
|
// QuerierParams params for Querier.
|
||||||
type QuerierParams struct {
|
type QuerierParams struct {
|
||||||
DataSourceType *Type
|
DataSourceType string
|
||||||
EvaluationInterval time.Duration
|
EvaluationInterval time.Duration
|
||||||
QueryParams url.Values
|
QueryParams url.Values
|
||||||
Headers []Header
|
Headers map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metric is the basic entity which should be return by datasource
|
// Metric is the basic entity which should be return by datasource
|
||||||
|
|
|
@ -97,7 +97,7 @@ func Init(extraParams url.Values) (QuerierBuilder, error) {
|
||||||
appendTypePrefix: *appendTypePrefix,
|
appendTypePrefix: *appendTypePrefix,
|
||||||
lookBack: *lookBack,
|
lookBack: *lookBack,
|
||||||
queryStep: *queryStep,
|
queryStep: *queryStep,
|
||||||
dataSourceType: NewPrometheusType(),
|
dataSourceType: datasourcePrometheus,
|
||||||
extraParams: extraParams,
|
extraParams: extraParams,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,20 @@ import (
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type datasourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
datasourcePrometheus datasourceType = "prometheus"
|
||||||
|
datasourceGraphite datasourceType = "graphite"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toDatasourceType(s string) datasourceType {
|
||||||
|
if s == string(datasourceGraphite) {
|
||||||
|
return datasourceGraphite
|
||||||
|
}
|
||||||
|
return datasourcePrometheus
|
||||||
|
}
|
||||||
|
|
||||||
// VMStorage represents vmstorage entity with ability to read and write metrics
|
// VMStorage represents vmstorage entity with ability to read and write metrics
|
||||||
type VMStorage struct {
|
type VMStorage struct {
|
||||||
c *http.Client
|
c *http.Client
|
||||||
|
@ -21,10 +35,15 @@ type VMStorage struct {
|
||||||
lookBack time.Duration
|
lookBack time.Duration
|
||||||
queryStep time.Duration
|
queryStep time.Duration
|
||||||
|
|
||||||
dataSourceType Type
|
dataSourceType datasourceType
|
||||||
evaluationInterval time.Duration
|
evaluationInterval time.Duration
|
||||||
extraParams url.Values
|
extraParams url.Values
|
||||||
extraHeaders []Header
|
extraHeaders []keyValue
|
||||||
|
}
|
||||||
|
|
||||||
|
type keyValue struct {
|
||||||
|
key string
|
||||||
|
value string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone makes clone of VMStorage, shares http client.
|
// Clone makes clone of VMStorage, shares http client.
|
||||||
|
@ -42,12 +61,15 @@ func (s *VMStorage) Clone() *VMStorage {
|
||||||
|
|
||||||
// ApplyParams - changes given querier params.
|
// ApplyParams - changes given querier params.
|
||||||
func (s *VMStorage) ApplyParams(params QuerierParams) *VMStorage {
|
func (s *VMStorage) ApplyParams(params QuerierParams) *VMStorage {
|
||||||
if params.DataSourceType != nil {
|
s.dataSourceType = toDatasourceType(params.DataSourceType)
|
||||||
s.dataSourceType = *params.DataSourceType
|
|
||||||
}
|
|
||||||
s.evaluationInterval = params.EvaluationInterval
|
s.evaluationInterval = params.EvaluationInterval
|
||||||
s.extraParams = params.QueryParams
|
s.extraParams = params.QueryParams
|
||||||
s.extraHeaders = params.Headers
|
if params.Headers != nil {
|
||||||
|
for key, value := range params.Headers {
|
||||||
|
kv := keyValue{key: key, value: value}
|
||||||
|
s.extraHeaders = append(s.extraHeaders, kv)
|
||||||
|
}
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +87,7 @@ func NewVMStorage(baseURL string, authCfg *promauth.Config, lookBack time.Durati
|
||||||
appendTypePrefix: appendTypePrefix,
|
appendTypePrefix: appendTypePrefix,
|
||||||
lookBack: lookBack,
|
lookBack: lookBack,
|
||||||
queryStep: queryStep,
|
queryStep: queryStep,
|
||||||
dataSourceType: NewPrometheusType(),
|
dataSourceType: datasourcePrometheus,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,13 +98,13 @@ func (s *VMStorage) Query(ctx context.Context, query string, ts time.Time) ([]Me
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch s.dataSourceType.String() {
|
switch s.dataSourceType {
|
||||||
case "prometheus":
|
case "", datasourcePrometheus:
|
||||||
s.setPrometheusInstantReqParams(req, query, ts)
|
s.setPrometheusInstantReqParams(req, query, ts)
|
||||||
case "graphite":
|
case datasourceGraphite:
|
||||||
s.setGraphiteReqParams(req, query, ts)
|
s.setGraphiteReqParams(req, query, ts)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("engine not found: %q", s.dataSourceType.name)
|
return nil, fmt.Errorf("engine not found: %q", s.dataSourceType)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := s.do(ctx, req)
|
resp, err := s.do(ctx, req)
|
||||||
|
@ -94,7 +116,7 @@ func (s *VMStorage) Query(ctx context.Context, query string, ts time.Time) ([]Me
|
||||||
}()
|
}()
|
||||||
|
|
||||||
parseFn := parsePrometheusResponse
|
parseFn := parsePrometheusResponse
|
||||||
if s.dataSourceType.name != "prometheus" {
|
if s.dataSourceType != datasourcePrometheus {
|
||||||
parseFn = parseGraphiteResponse
|
parseFn = parseGraphiteResponse
|
||||||
}
|
}
|
||||||
return parseFn(req, resp)
|
return parseFn(req, resp)
|
||||||
|
@ -104,8 +126,8 @@ func (s *VMStorage) Query(ctx context.Context, query string, ts time.Time) ([]Me
|
||||||
// For Prometheus type see https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries
|
// For Prometheus type see https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries
|
||||||
// Graphite type isn't supported.
|
// Graphite type isn't supported.
|
||||||
func (s *VMStorage) QueryRange(ctx context.Context, query string, start, end time.Time) ([]Metric, error) {
|
func (s *VMStorage) QueryRange(ctx context.Context, query string, start, end time.Time) ([]Metric, error) {
|
||||||
if s.dataSourceType.name != "prometheus" {
|
if s.dataSourceType != datasourcePrometheus {
|
||||||
return nil, fmt.Errorf("%q is not supported for QueryRange", s.dataSourceType.name)
|
return nil, fmt.Errorf("%q is not supported for QueryRange", s.dataSourceType)
|
||||||
}
|
}
|
||||||
req, err := s.newRequestPOST()
|
req, err := s.newRequestPOST()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -151,7 +173,7 @@ func (s *VMStorage) newRequestPOST() (*http.Request, error) {
|
||||||
s.authCfg.SetHeaders(req, true)
|
s.authCfg.SetHeaders(req, true)
|
||||||
}
|
}
|
||||||
for _, h := range s.extraHeaders {
|
for _, h := range s.extraHeaders {
|
||||||
req.Header.Set(h.Key, h.Value)
|
req.Header.Set(h.key, h.value)
|
||||||
}
|
}
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,8 +89,8 @@ func TestVMInstantQuery(t *testing.T) {
|
||||||
}
|
}
|
||||||
s := NewVMStorage(srv.URL, authCfg, time.Minute, 0, false, srv.Client())
|
s := NewVMStorage(srv.URL, authCfg, time.Minute, 0, false, srv.Client())
|
||||||
|
|
||||||
p := NewPrometheusType()
|
p := datasourcePrometheus
|
||||||
pq := s.BuildWithParams(QuerierParams{DataSourceType: &p, EvaluationInterval: 15 * time.Second})
|
pq := s.BuildWithParams(QuerierParams{DataSourceType: string(p), EvaluationInterval: 15 * time.Second})
|
||||||
ts := time.Now()
|
ts := time.Now()
|
||||||
|
|
||||||
expErr := func(err string) {
|
expErr := func(err string) {
|
||||||
|
@ -146,8 +146,7 @@ func TestVMInstantQuery(t *testing.T) {
|
||||||
t.Fatalf("unexpected metric %+v want %+v", m, expected)
|
t.Fatalf("unexpected metric %+v want %+v", m, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
g := NewGraphiteType()
|
gq := s.BuildWithParams(QuerierParams{DataSourceType: string(datasourceGraphite)})
|
||||||
gq := s.BuildWithParams(QuerierParams{DataSourceType: &g})
|
|
||||||
|
|
||||||
m, err = gq.Query(ctx, queryRender, ts) // 8 - graphite
|
m, err = gq.Query(ctx, queryRender, ts) // 8 - graphite
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -212,8 +211,7 @@ func TestVMRangeQuery(t *testing.T) {
|
||||||
}
|
}
|
||||||
s := NewVMStorage(srv.URL, authCfg, time.Minute, 0, false, srv.Client())
|
s := NewVMStorage(srv.URL, authCfg, time.Minute, 0, false, srv.Client())
|
||||||
|
|
||||||
p := NewPrometheusType()
|
pq := s.BuildWithParams(QuerierParams{DataSourceType: string(datasourcePrometheus), EvaluationInterval: 15 * time.Second})
|
||||||
pq := s.BuildWithParams(QuerierParams{DataSourceType: &p, EvaluationInterval: 15 * time.Second})
|
|
||||||
|
|
||||||
_, err = pq.QueryRange(ctx, query, time.Now(), time.Time{})
|
_, err = pq.QueryRange(ctx, query, time.Now(), time.Time{})
|
||||||
expectError(t, err, "is missing")
|
expectError(t, err, "is missing")
|
||||||
|
@ -239,8 +237,7 @@ func TestVMRangeQuery(t *testing.T) {
|
||||||
t.Fatalf("unexpected metric %+v want %+v", m[0], expected)
|
t.Fatalf("unexpected metric %+v want %+v", m[0], expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
g := NewGraphiteType()
|
gq := s.BuildWithParams(QuerierParams{DataSourceType: string(datasourceGraphite)})
|
||||||
gq := s.BuildWithParams(QuerierParams{DataSourceType: &g})
|
|
||||||
|
|
||||||
_, err = gq.QueryRange(ctx, queryRender, start, end)
|
_, err = gq.QueryRange(ctx, queryRender, start, end)
|
||||||
expectError(t, err, "is not supported")
|
expectError(t, err, "is not supported")
|
||||||
|
@ -263,7 +260,7 @@ func TestRequestParams(t *testing.T) {
|
||||||
"prometheus path",
|
"prometheus path",
|
||||||
false,
|
false,
|
||||||
&VMStorage{
|
&VMStorage{
|
||||||
dataSourceType: NewPrometheusType(),
|
dataSourceType: datasourcePrometheus,
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
checkEqualString(t, "/api/v1/query", r.URL.Path)
|
checkEqualString(t, "/api/v1/query", r.URL.Path)
|
||||||
|
@ -273,7 +270,7 @@ func TestRequestParams(t *testing.T) {
|
||||||
"prometheus prefix",
|
"prometheus prefix",
|
||||||
false,
|
false,
|
||||||
&VMStorage{
|
&VMStorage{
|
||||||
dataSourceType: NewPrometheusType(),
|
dataSourceType: datasourcePrometheus,
|
||||||
appendTypePrefix: true,
|
appendTypePrefix: true,
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
|
@ -284,7 +281,7 @@ func TestRequestParams(t *testing.T) {
|
||||||
"prometheus range path",
|
"prometheus range path",
|
||||||
true,
|
true,
|
||||||
&VMStorage{
|
&VMStorage{
|
||||||
dataSourceType: NewPrometheusType(),
|
dataSourceType: datasourcePrometheus,
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
checkEqualString(t, "/api/v1/query_range", r.URL.Path)
|
checkEqualString(t, "/api/v1/query_range", r.URL.Path)
|
||||||
|
@ -294,7 +291,7 @@ func TestRequestParams(t *testing.T) {
|
||||||
"prometheus range prefix",
|
"prometheus range prefix",
|
||||||
true,
|
true,
|
||||||
&VMStorage{
|
&VMStorage{
|
||||||
dataSourceType: NewPrometheusType(),
|
dataSourceType: datasourcePrometheus,
|
||||||
appendTypePrefix: true,
|
appendTypePrefix: true,
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
|
@ -305,7 +302,7 @@ func TestRequestParams(t *testing.T) {
|
||||||
"graphite path",
|
"graphite path",
|
||||||
false,
|
false,
|
||||||
&VMStorage{
|
&VMStorage{
|
||||||
dataSourceType: NewGraphiteType(),
|
dataSourceType: datasourceGraphite,
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
checkEqualString(t, graphitePath, r.URL.Path)
|
checkEqualString(t, graphitePath, r.URL.Path)
|
||||||
|
@ -315,7 +312,7 @@ func TestRequestParams(t *testing.T) {
|
||||||
"graphite prefix",
|
"graphite prefix",
|
||||||
false,
|
false,
|
||||||
&VMStorage{
|
&VMStorage{
|
||||||
dataSourceType: NewGraphiteType(),
|
dataSourceType: datasourceGraphite,
|
||||||
appendTypePrefix: true,
|
appendTypePrefix: true,
|
||||||
},
|
},
|
||||||
func(t *testing.T, r *http.Request) {
|
func(t *testing.T, r *http.Request) {
|
||||||
|
@ -453,7 +450,7 @@ func TestRequestParams(t *testing.T) {
|
||||||
"graphite extra params",
|
"graphite extra params",
|
||||||
false,
|
false,
|
||||||
&VMStorage{
|
&VMStorage{
|
||||||
dataSourceType: NewGraphiteType(),
|
dataSourceType: datasourceGraphite,
|
||||||
extraParams: url.Values{
|
extraParams: url.Values{
|
||||||
"nocache": {"1"},
|
"nocache": {"1"},
|
||||||
"max_lookback": {"1h"},
|
"max_lookback": {"1h"},
|
||||||
|
@ -472,14 +469,14 @@ func TestRequestParams(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
switch tc.vm.dataSourceType.String() {
|
switch tc.vm.dataSourceType {
|
||||||
case "prometheus":
|
case "", datasourcePrometheus:
|
||||||
if tc.queryRange {
|
if tc.queryRange {
|
||||||
tc.vm.setPrometheusRangeReqParams(req, query, timestamp, timestamp)
|
tc.vm.setPrometheusRangeReqParams(req, query, timestamp, timestamp)
|
||||||
} else {
|
} else {
|
||||||
tc.vm.setPrometheusInstantReqParams(req, query, timestamp)
|
tc.vm.setPrometheusInstantReqParams(req, query, timestamp)
|
||||||
}
|
}
|
||||||
case "graphite":
|
case datasourceGraphite:
|
||||||
tc.vm.setGraphiteReqParams(req, query, timestamp)
|
tc.vm.setGraphiteReqParams(req, query, timestamp)
|
||||||
}
|
}
|
||||||
tc.checkFn(t, req)
|
tc.checkFn(t, req)
|
||||||
|
@ -530,9 +527,9 @@ func TestHeaders(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "custom extraHeaders",
|
name: "custom extraHeaders",
|
||||||
vmFn: func() *VMStorage {
|
vmFn: func() *VMStorage {
|
||||||
return &VMStorage{extraHeaders: []Header{
|
return &VMStorage{extraHeaders: []keyValue{
|
||||||
{Key: "Foo", Value: "bar"},
|
{key: "Foo", value: "bar"},
|
||||||
{Key: "Baz", Value: "qux"},
|
{key: "Baz", value: "qux"},
|
||||||
}}
|
}}
|
||||||
},
|
},
|
||||||
checkFn: func(t *testing.T, r *http.Request) {
|
checkFn: func(t *testing.T, r *http.Request) {
|
||||||
|
@ -551,8 +548,8 @@ func TestHeaders(t *testing.T) {
|
||||||
}
|
}
|
||||||
return &VMStorage{
|
return &VMStorage{
|
||||||
authCfg: cfg,
|
authCfg: cfg,
|
||||||
extraHeaders: []Header{
|
extraHeaders: []keyValue{
|
||||||
{Key: "Authorization", Value: "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="},
|
{key: "Authorization", value: "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="},
|
||||||
}}
|
}}
|
||||||
},
|
},
|
||||||
checkFn: func(t *testing.T, r *http.Request) {
|
checkFn: func(t *testing.T, r *http.Request) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ type Group struct {
|
||||||
Name string
|
Name string
|
||||||
File string
|
File string
|
||||||
Rules []Rule
|
Rules []Rule
|
||||||
Type datasource.Type
|
Type config.Type
|
||||||
Interval time.Duration
|
Interval time.Duration
|
||||||
Limit int
|
Limit int
|
||||||
Concurrency int
|
Concurrency int
|
||||||
|
@ -37,7 +37,7 @@ type Group struct {
|
||||||
|
|
||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
Params url.Values
|
Params url.Values
|
||||||
Headers []datasource.Header
|
Headers map[string]string
|
||||||
|
|
||||||
doneCh chan struct{}
|
doneCh chan struct{}
|
||||||
finishedCh chan struct{}
|
finishedCh chan struct{}
|
||||||
|
@ -97,7 +97,7 @@ func newGroup(cfg config.Group, qb datasource.QuerierBuilder, defaultInterval ti
|
||||||
Concurrency: cfg.Concurrency,
|
Concurrency: cfg.Concurrency,
|
||||||
Checksum: cfg.Checksum,
|
Checksum: cfg.Checksum,
|
||||||
Params: cfg.Params,
|
Params: cfg.Params,
|
||||||
Headers: cfg.Headers,
|
Headers: make(map[string]string),
|
||||||
Labels: cfg.Labels,
|
Labels: cfg.Labels,
|
||||||
|
|
||||||
doneCh: make(chan struct{}),
|
doneCh: make(chan struct{}),
|
||||||
|
@ -110,6 +110,9 @@ func newGroup(cfg config.Group, qb datasource.QuerierBuilder, defaultInterval ti
|
||||||
if g.Concurrency < 1 {
|
if g.Concurrency < 1 {
|
||||||
g.Concurrency = 1
|
g.Concurrency = 1
|
||||||
}
|
}
|
||||||
|
for _, h := range cfg.Headers {
|
||||||
|
g.Headers[h.Key] = h.Value
|
||||||
|
}
|
||||||
g.metrics = newGroupMetrics(g)
|
g.metrics = newGroupMetrics(g)
|
||||||
rules := make([]Rule, len(cfg.Rules))
|
rules := make([]Rule, len(cfg.Rules))
|
||||||
for i, r := range cfg.Rules {
|
for i, r := range cfg.Rules {
|
||||||
|
|
|
@ -200,13 +200,22 @@ func urlValuesToStrings(values url.Values) []string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func headersToStrings(headers []datasource.Header) []string {
|
func headersToStrings(headers map[string]string) []string {
|
||||||
if len(headers) < 1 {
|
if len(headers) < 1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var res []string
|
|
||||||
for _, h := range headers {
|
keys := make([]string, 0, len(headers))
|
||||||
res = append(res, fmt.Sprintf("%s: %s", h.Key, h.Value))
|
for k := range headers {
|
||||||
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
|
||||||
|
var res []string
|
||||||
|
for _, k := range keys {
|
||||||
|
v := headers[k]
|
||||||
|
res = append(res, fmt.Sprintf("%s: %s", k, v))
|
||||||
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/config"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/config"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/datasource"
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/remotewrite"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/remotewrite"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/templates"
|
"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/templates"
|
||||||
|
@ -132,7 +131,7 @@ func TestManagerUpdate(t *testing.T) {
|
||||||
{
|
{
|
||||||
File: "config/testdata/dir/rules1-good.rules",
|
File: "config/testdata/dir/rules1-good.rules",
|
||||||
Name: "duplicatedGroupDiffFiles",
|
Name: "duplicatedGroupDiffFiles",
|
||||||
Type: datasource.NewPrometheusType(),
|
Type: config.NewPrometheusType(),
|
||||||
Interval: defaultEvalInterval,
|
Interval: defaultEvalInterval,
|
||||||
Rules: []Rule{
|
Rules: []Rule{
|
||||||
&AlertingRule{
|
&AlertingRule{
|
||||||
|
@ -157,14 +156,14 @@ func TestManagerUpdate(t *testing.T) {
|
||||||
{
|
{
|
||||||
File: "config/testdata/rules/rules0-good.rules",
|
File: "config/testdata/rules/rules0-good.rules",
|
||||||
Name: "groupGorSingleAlert",
|
Name: "groupGorSingleAlert",
|
||||||
Type: datasource.NewPrometheusType(),
|
Type: config.NewPrometheusType(),
|
||||||
Rules: []Rule{VMRows},
|
Rules: []Rule{VMRows},
|
||||||
Interval: defaultEvalInterval,
|
Interval: defaultEvalInterval,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
File: "config/testdata/rules/rules0-good.rules",
|
File: "config/testdata/rules/rules0-good.rules",
|
||||||
Interval: defaultEvalInterval,
|
Interval: defaultEvalInterval,
|
||||||
Type: datasource.NewPrometheusType(),
|
Type: config.NewPrometheusType(),
|
||||||
Name: "TestGroup", Rules: []Rule{
|
Name: "TestGroup", Rules: []Rule{
|
||||||
Conns,
|
Conns,
|
||||||
ExampleAlertAlwaysFiring,
|
ExampleAlertAlwaysFiring,
|
||||||
|
@ -179,7 +178,7 @@ func TestManagerUpdate(t *testing.T) {
|
||||||
{
|
{
|
||||||
File: "config/testdata/rules/rules0-good.rules",
|
File: "config/testdata/rules/rules0-good.rules",
|
||||||
Name: "groupGorSingleAlert",
|
Name: "groupGorSingleAlert",
|
||||||
Type: datasource.NewPrometheusType(),
|
Type: config.NewPrometheusType(),
|
||||||
Interval: defaultEvalInterval,
|
Interval: defaultEvalInterval,
|
||||||
Rules: []Rule{VMRows},
|
Rules: []Rule{VMRows},
|
||||||
},
|
},
|
||||||
|
@ -187,7 +186,7 @@ func TestManagerUpdate(t *testing.T) {
|
||||||
File: "config/testdata/rules/rules0-good.rules",
|
File: "config/testdata/rules/rules0-good.rules",
|
||||||
Interval: defaultEvalInterval,
|
Interval: defaultEvalInterval,
|
||||||
Name: "TestGroup",
|
Name: "TestGroup",
|
||||||
Type: datasource.NewPrometheusType(),
|
Type: config.NewPrometheusType(),
|
||||||
Rules: []Rule{
|
Rules: []Rule{
|
||||||
Conns,
|
Conns,
|
||||||
ExampleAlertAlwaysFiring,
|
ExampleAlertAlwaysFiring,
|
||||||
|
@ -202,14 +201,14 @@ func TestManagerUpdate(t *testing.T) {
|
||||||
{
|
{
|
||||||
File: "config/testdata/rules/rules0-good.rules",
|
File: "config/testdata/rules/rules0-good.rules",
|
||||||
Name: "groupGorSingleAlert",
|
Name: "groupGorSingleAlert",
|
||||||
Type: datasource.NewPrometheusType(),
|
Type: config.NewPrometheusType(),
|
||||||
Interval: defaultEvalInterval,
|
Interval: defaultEvalInterval,
|
||||||
Rules: []Rule{VMRows},
|
Rules: []Rule{VMRows},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
File: "config/testdata/rules/rules0-good.rules",
|
File: "config/testdata/rules/rules0-good.rules",
|
||||||
Interval: defaultEvalInterval,
|
Interval: defaultEvalInterval,
|
||||||
Type: datasource.NewPrometheusType(),
|
Type: config.NewPrometheusType(),
|
||||||
Name: "TestGroup", Rules: []Rule{
|
Name: "TestGroup", Rules: []Rule{
|
||||||
Conns,
|
Conns,
|
||||||
ExampleAlertAlwaysFiring,
|
ExampleAlertAlwaysFiring,
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
// to evaluate configured Expression and
|
// to evaluate configured Expression and
|
||||||
// return TimeSeries as result.
|
// return TimeSeries as result.
|
||||||
type RecordingRule struct {
|
type RecordingRule struct {
|
||||||
Type datasource.Type
|
Type config.Type
|
||||||
RuleID uint64
|
RuleID uint64
|
||||||
Name string
|
Name string
|
||||||
Expr string
|
Expr string
|
||||||
|
@ -70,7 +70,7 @@ func newRecordingRule(qb datasource.QuerierBuilder, group *Group, cfg config.Rul
|
||||||
GroupID: group.ID(),
|
GroupID: group.ID(),
|
||||||
metrics: &recordingRuleMetrics{},
|
metrics: &recordingRuleMetrics{},
|
||||||
q: qb.BuildWithParams(datasource.QuerierParams{
|
q: qb.BuildWithParams(datasource.QuerierParams{
|
||||||
DataSourceType: &group.Type,
|
DataSourceType: group.Type.String(),
|
||||||
EvaluationInterval: group.Interval,
|
EvaluationInterval: group.Interval,
|
||||||
QueryParams: group.Params,
|
QueryParams: group.Params,
|
||||||
Headers: group.Headers,
|
Headers: group.Headers,
|
||||||
|
|
|
@ -27,6 +27,6 @@ func init() {
|
||||||
func Init() {
|
func Init() {
|
||||||
extraLabels := strings.Join(*pushExtraLabels, ",")
|
extraLabels := strings.Join(*pushExtraLabels, ",")
|
||||||
for _, pu := range *pushURL {
|
for _, pu := range *pushURL {
|
||||||
metrics.InitPushExt(pu, *pushInterval, extraLabels, appmetrics.WritePrometheusMetrics)
|
_ = metrics.InitPushExt(pu, *pushInterval, extraLabels, appmetrics.WritePrometheusMetrics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue