/
godutch.go
188 lines (157 loc) · 4.87 KB
/
godutch.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package godutch
//
// GoDutch is the primary type on this software, acting on the integration
// position of network and local containers.
//
import (
gocache "github.com/patrickmn/go-cache"
"log"
"time"
)
//
// Holds the references of configuration, Panamax and NRPE service, linking
// those elements to work together.
//
type GoDutch struct {
// configuration object, for all assets
cfg *Config
// Panamax object, the container holder
p *Panamax
// cache instance, to dub as a shared object store
cache *gocache.Cache
// NRPE Service, listens to network and run checks
ns *NrpeService
// investigate cache for metrics and feed Carbon server
cs *CarbonService
// maximum threshold for running a check
lastRunThreshold int64
}
// Instantiates a new GoDutch, which will also spawn a new Panamax.
func NewGoDutch(cfg *Config) (*GoDutch, error) {
var cache *gocache.Cache
var p *Panamax
var g *GoDutch
var err error
cache = gocache.New(time.Minute, 20*time.Second)
if p, err = NewPanamax(cache); err != nil {
return nil, err
}
g = &GoDutch{
cfg: cfg,
p: p,
cache: cache,
ns: nil,
cs: nil,
lastRunThreshold: -1,
}
return g, nil
}
// Go through the configured containers and load (unless disabled).
func (g *GoDutch) LoadContainers() error {
var name string
var containerCfg *ContainerConfig
var err error
for name, containerCfg = range g.cfg.Container {
log.Printf("[GoDutch] Container: '%s'", name)
if !containerCfg.Enabled {
log.Printf("[GoDutch] Skipping, Container is disabled.")
continue
}
if err = g.p.Load(containerCfg); err != nil {
log.Printf("[GoDutch] Error loading container '%s'", name)
return err
}
}
return nil
}
// Loads all services listed on configuration files, skips when it's disabled
// and had specific loading mechanisms for each service. Return error.
func (g *GoDutch) LoadServices() error {
var serviceCfg *ServiceConfig
var name string
for name, serviceCfg = range g.cfg.Service {
log.Printf("[GoDutch] Service: '%s' (%s)", name, serviceCfg.Type)
if !serviceCfg.Enabled {
log.Printf("[GoDutch] Skipping '%s' (%s), Service is disabled.",
name, serviceCfg.Type)
continue
}
log.Printf("[GoDutch] DEBUG: name: '%s', lastRunThreshold: '%d'",
name, serviceCfg.LastRunThreshold)
// when last-run-threshold is found, saving the lowest item
if serviceCfg.LastRunThreshold > 0 {
if g.lastRunThreshold == -1 || g.lastRunThreshold > serviceCfg.LastRunThreshold {
log.Printf("[GoDutch] LastRunThreshold: from %ds to %ds'.",
g.lastRunThreshold, serviceCfg.LastRunThreshold)
g.lastRunThreshold = serviceCfg.LastRunThreshold
}
}
switch serviceCfg.Type {
case "nrpe":
log.Println("[GoDutch] Loading NRPE Service")
// initializing NRPE service and informing local Panamax instance,
// then the service is able to call for checks execution
g.ns = NewNrpeService(serviceCfg, g.p)
case "nsca":
log.Println("[GoDutch] Loading NSCA Service")
case "carbon":
log.Println("[GoDutch] Loading Carbon Relay Service")
// spawning a new Carbon Relay type of service, using local cache to
// dispatch metrics
g.cs = NewCarbonService(serviceCfg, g.cache)
case "sensu":
log.Println("[GoDutch] Loading Sensu Service")
default:
panic("[GoDutch] Service type is unkown: " + serviceCfg.Type)
}
}
return nil
}
// Wraps serve method on NRPE service.
func (g *GoDutch) Serve() {
if g.ns == nil {
panic("NRPE Service is not loaded, nothing to Serve.")
}
// nrpe service accepting connections
go g.ns.Serve()
// carbon relay inpecting cache and sending metrics
go g.cs.Serve()
// running check's that are delayed on shedule
go g.runDelayedChecks()
}
// Wraps stop call for the NRPE service and Panamax objects.
func (g *GoDutch) Stop() {
// nrpe service stop
g.ns.Stop()
// panamax (and it's containers) stop
g.p.Stop()
}
// Using Panamax data, loop through the checks that are delayed, executing them
// sequentially. This method is intended to run in background.
func (g *GoDutch) runDelayedChecks() {
var name string
var lastRun int64
var req *Request
var err error
if g.lastRunThreshold <= 0 {
log.Println("[GoDutch] lastRunThreshold is disabled, no auto-run.")
return
}
log.Printf("[GoDutch] Checks will run automatically after: %ds",
g.lastRunThreshold)
for {
time.Sleep(10 * time.Second)
log.Println("[GoDutch] Sleep done, looking for delayed checks.")
for name, lastRun = range g.p.ChecksRunReport(g.lastRunThreshold) {
log.Printf("[GoDutch] Executing '%s', last run at %ds ago (%ds threshold)",
name, lastRun, g.lastRunThreshold)
if req, err = NewRequest(name, []string{}); err != nil {
log.Fatalln("[GoDutch] Error on creating request to: '%s'", name)
}
if _, err = g.p.Execute(req); err != nil {
log.Println("[GoDutch] Error on execute: ", err)
}
}
}
}
/* EOF */