Add loading configuration from file.
This commit is contained in:
parent
3f9cc9e3e3
commit
24ac73af5d
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
all: generated/config.pb.go
|
||||
|
||||
generated/config.pb.go: config.proto
|
||||
protoc --go_out=generated/ config.proto
|
|
@ -0,0 +1,58 @@
|
|||
// 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 config
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"code.google.com/p/goprotobuf/proto"
|
||||
|
||||
pb "github.com/prometheus/alert_manager/config/generated"
|
||||
"github.com/prometheus/alert_manager/manager"
|
||||
)
|
||||
|
||||
// Config encapsulates the configuration of an Alert Manager instance. It wraps
|
||||
// the raw configuration protocol buffer to be able to add custom methods to
|
||||
// it.
|
||||
type Config struct {
|
||||
// The protobuf containing the actual configuration values.
|
||||
pb.AlertManagerConfig
|
||||
}
|
||||
|
||||
// String returns an ASCII serialization of the loaded configuration protobuf.
|
||||
func (c Config) String() string {
|
||||
return proto.MarshalTextString(&c.AlertManagerConfig)
|
||||
}
|
||||
|
||||
// Validate checks an entire parsed Config for the validity of its fields.
|
||||
func (c Config) Validate() error {
|
||||
// BUG: Nothing to do here for now.
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rules returns all the AggregationRules in a Config object.
|
||||
func (c Config) AggregationRules() manager.AggregationRules {
|
||||
rules := make(manager.AggregationRules, 0, len(c.AggregationRule))
|
||||
for _, r := range c.AggregationRule {
|
||||
filters := make(manager.Filters, 0, len(r.Filter))
|
||||
for _, filter := range r.Filter {
|
||||
filters = append(filters, manager.NewFilter(filter.GetNameRe(), filter.GetValueRe()))
|
||||
}
|
||||
rules = append(rules, &manager.AggregationRule{
|
||||
Filters: filters,
|
||||
RepeatRate: time.Duration(r.GetRepeatRate()) * time.Second,
|
||||
})
|
||||
}
|
||||
return rules
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// 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 io.prometheus.alert_manager;
|
||||
|
||||
// A regex-based label filter used in aggregations.
|
||||
message Filter {
|
||||
// The regex matching the label name.
|
||||
required string name_re = 1;
|
||||
// The regex matching the label value.
|
||||
required string value_re = 2;
|
||||
}
|
||||
|
||||
message AggregationRule {
|
||||
repeated Filter filter = 1;
|
||||
optional int32 repeat_rate = 2 [default = 7200];
|
||||
}
|
||||
|
||||
message AlertManagerConfig {
|
||||
repeated AggregationRule aggregation_rule = 1;
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
// 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 config
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var fixturesPath = "fixtures"
|
||||
|
||||
var configTests = []struct {
|
||||
inputFile string
|
||||
shouldFail bool
|
||||
errContains string
|
||||
}{
|
||||
{
|
||||
inputFile: "empty.conf.input",
|
||||
}, {
|
||||
inputFile: "sample.conf.input",
|
||||
}, {
|
||||
inputFile: "invalid_proto_format.conf.input",
|
||||
shouldFail: true,
|
||||
errContains: "unknown field name",
|
||||
},
|
||||
}
|
||||
|
||||
func TestConfigs(t *testing.T) {
|
||||
for i, configTest := range configTests {
|
||||
_, err := LoadFromFile(path.Join(fixturesPath, configTest.inputFile))
|
||||
|
||||
if err != nil {
|
||||
if !configTest.shouldFail {
|
||||
t.Fatalf("%d. Error parsing config %v: %v", i, configTest.inputFile, err)
|
||||
} else {
|
||||
if !strings.Contains(err.Error(), configTest.errContains) {
|
||||
t.Fatalf("%d. Expected error containing '%v', got: %v", i, configTest.errContains, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
aggregation_rule {
|
||||
filter {
|
||||
label_re: "service" // Unknown protobuf field name.
|
||||
value_re: "discovery"
|
||||
}
|
||||
filter {
|
||||
name_re: "zone"
|
||||
value_re: "aa"
|
||||
}
|
||||
repeat_rate: 3600
|
||||
}
|
||||
|
||||
aggregation_rule {
|
||||
filter {
|
||||
name_re: "service"
|
||||
value_re: "test"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
aggregation_rule {
|
||||
filter {
|
||||
name_re: "service"
|
||||
value_re: "discovery"
|
||||
}
|
||||
filter {
|
||||
name_re: "zone"
|
||||
value_re: "aa"
|
||||
}
|
||||
repeat_rate: 3600
|
||||
}
|
||||
|
||||
aggregation_rule {
|
||||
filter {
|
||||
name_re: "service"
|
||||
value_re: "test"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
// Code generated by protoc-gen-go.
|
||||
// source: config.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
package io_prometheus_alert_manager
|
||||
|
||||
import proto "code.google.com/p/goprotobuf/proto"
|
||||
import json "encoding/json"
|
||||
import math "math"
|
||||
|
||||
// Reference proto, json, and math imports to suppress error if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = &json.SyntaxError{}
|
||||
var _ = math.Inf
|
||||
|
||||
type Filter struct {
|
||||
NameRe *string `protobuf:"bytes,1,req,name=name_re" json:"name_re,omitempty"`
|
||||
ValueRe *string `protobuf:"bytes,2,req,name=value_re" json:"value_re,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Filter) Reset() { *m = Filter{} }
|
||||
func (m *Filter) String() string { return proto.CompactTextString(m) }
|
||||
func (*Filter) ProtoMessage() {}
|
||||
|
||||
func (m *Filter) GetNameRe() string {
|
||||
if m != nil && m.NameRe != nil {
|
||||
return *m.NameRe
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Filter) GetValueRe() string {
|
||||
if m != nil && m.ValueRe != nil {
|
||||
return *m.ValueRe
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AggregationRule struct {
|
||||
Filter []*Filter `protobuf:"bytes,1,rep,name=filter" json:"filter,omitempty"`
|
||||
RepeatRate *int32 `protobuf:"varint,2,opt,name=repeat_rate,def=7200" json:"repeat_rate,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AggregationRule) Reset() { *m = AggregationRule{} }
|
||||
func (m *AggregationRule) String() string { return proto.CompactTextString(m) }
|
||||
func (*AggregationRule) ProtoMessage() {}
|
||||
|
||||
const Default_AggregationRule_RepeatRate int32 = 7200
|
||||
|
||||
func (m *AggregationRule) GetFilter() []*Filter {
|
||||
if m != nil {
|
||||
return m.Filter
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AggregationRule) GetRepeatRate() int32 {
|
||||
if m != nil && m.RepeatRate != nil {
|
||||
return *m.RepeatRate
|
||||
}
|
||||
return Default_AggregationRule_RepeatRate
|
||||
}
|
||||
|
||||
type AlertManagerConfig struct {
|
||||
AggregationRule []*AggregationRule `protobuf:"bytes,1,rep,name=aggregation_rule" json:"aggregation_rule,omitempty"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AlertManagerConfig) Reset() { *m = AlertManagerConfig{} }
|
||||
func (m *AlertManagerConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*AlertManagerConfig) ProtoMessage() {}
|
||||
|
||||
func (m *AlertManagerConfig) GetAggregationRule() []*AggregationRule {
|
||||
if m != nil {
|
||||
return m.AggregationRule
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// 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 config
|
||||
|
||||
import (
|
||||
"code.google.com/p/goprotobuf/proto"
|
||||
|
||||
pb "github.com/prometheus/alert_manager/config/generated"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
func LoadFromString(configStr string) (Config, error) {
|
||||
configProto := pb.AlertManagerConfig{}
|
||||
if err := proto.UnmarshalText(configStr, &configProto); err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
config := Config{configProto}
|
||||
err := config.Validate()
|
||||
|
||||
return config, err
|
||||
}
|
||||
|
||||
func LoadFromFile(fileName string) (Config, error) {
|
||||
configStr, err := ioutil.ReadFile(fileName)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
return LoadFromString(string(configStr))
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// 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 config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadFromFile(t *testing.T) {
|
||||
_, err := LoadFromFile("file-does-not-exist.conf")
|
||||
if err == nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
26
main.go
26
main.go
|
@ -17,14 +17,24 @@ import (
|
|||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/prometheus/alert_manager/config"
|
||||
"github.com/prometheus/alert_manager/manager"
|
||||
"github.com/prometheus/alert_manager/web"
|
||||
"github.com/prometheus/alert_manager/web/api"
|
||||
)
|
||||
|
||||
var (
|
||||
configFile = flag.String("configFile", "alertmanager.conf", "Alert Manager configuration file name.")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
conf, err := config.LoadFromFile(*configFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading configuration from %s: %v", *configFile, err)
|
||||
}
|
||||
|
||||
suppressor := manager.NewSuppressor()
|
||||
defer suppressor.Close()
|
||||
|
||||
|
@ -50,21 +60,7 @@ func main() {
|
|||
}
|
||||
go webService.ServeForever()
|
||||
|
||||
// BEGIN EXAMPLE CODE - replace with config loading later.
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
rules := manager.AggregationRules{
|
||||
&manager.AggregationRule{
|
||||
Filters: manager.Filters{manager.NewFilter("service", "discovery")},
|
||||
},
|
||||
}
|
||||
|
||||
aggregator.SetRules(rules)
|
||||
|
||||
done <- true
|
||||
}()
|
||||
<-done
|
||||
// END EXAMPLE CODE
|
||||
aggregator.SetRules(conf.AggregationRules())
|
||||
|
||||
log.Println("Running summary dispatcher...")
|
||||
summarizer.Dispatch(suppressor)
|
||||
|
|
Loading…
Reference in New Issue