forked from cybozu-go/goma
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate.go
125 lines (110 loc) · 2.89 KB
/
create.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package goma
import (
"errors"
"fmt"
"time"
"github.com/cybozu-go/goma/actions"
"github.com/cybozu-go/goma/filters"
"github.com/cybozu-go/goma/monitor"
"github.com/cybozu-go/goma/probes"
)
const (
typeKey = "type"
defaultInterval = 60 * time.Second
defaultTimeout = 59 * time.Second
)
// Errors for goma.
var (
ErrBadName = errors.New("bad monitor name")
ErrNoType = errors.New("no type")
ErrInvalidType = errors.New("invalid type")
ErrInvalidRange = errors.New("invalid min/max range")
ErrNoKey = errors.New("no key")
)
// MonitorDefinition is a struct to load monitor definitions.
// TOML and JSON can be used.
type MonitorDefinition struct {
Name string `toml:"name" json:"name"`
Probe map[string]interface{} `toml:"probe" json:"probe"`
Filter map[string]interface{} `toml:"filter" json:"filter,omitempty"`
Actions []map[string]interface{} `toml:"actions" json:"actions"`
Interval int `toml:"interval" json:"interval,omitempty"`
Timeout int `toml:"timeout" json:"timeout,omitempty"`
Min float64 `toml:"min" json:"min,omitempty"`
Max float64 `toml:"max" json:"max,omitempty"`
}
func getType(m map[string]interface{}) (t string, err error) {
v, ok := m[typeKey]
if !ok {
err = ErrNoType
return
}
s, ok := v.(string)
if !ok {
err = ErrInvalidType
return
}
t = s
return
}
func getParams(m map[string]interface{}) map[string]interface{} {
nm := make(map[string]interface{})
for k, v := range m {
if k == typeKey {
continue
}
nm[k] = v
}
return nm
}
// CreateMonitor creates a monitor from MonitorDefinition.
func CreateMonitor(d *MonitorDefinition) (*monitor.Monitor, error) {
if len(d.Name) == 0 {
return nil, ErrBadName
}
t, err := getType(d.Probe)
if err != nil {
return nil, err
}
probe, err := probes.Construct(t, getParams(d.Probe))
if err != nil {
return nil, fmt.Errorf("%s: %v in probe", d.Name, err)
}
var filter filters.Filter
if d.Filter != nil {
t, err = getType(d.Filter)
if err != nil {
return nil, err
}
f, err := filters.Construct(t, getParams(d.Filter))
if err != nil {
return nil, fmt.Errorf("%s: %v in filter", d.Name, err)
}
filter = f
}
var actors []actions.Actor
for _, ad := range d.Actions {
t, err = getType(ad)
if err != nil {
return nil, err
}
a, err := actions.Construct(t, getParams(ad))
if err != nil {
return nil, fmt.Errorf("%s: %v in action %s", d.Name, err, t)
}
actors = append(actors, a)
}
interval := time.Duration(d.Interval) * time.Second
if interval == 0 {
interval = defaultInterval
}
timeout := time.Duration(d.Timeout) * time.Second
if timeout == 0 {
timeout = defaultTimeout
}
if d.Min > d.Max {
return nil, ErrInvalidRange
}
return monitor.NewMonitor(d.Name, probe, filter, actors,
interval, timeout, d.Min, d.Max), nil
}