-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ef2d44d
Showing
25 changed files
with
1,509 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, build with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 | ||
.glide/ | ||
|
||
# vim | ||
*.swp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
build: | ||
binary: jagozzi | ||
goos: | ||
- linux | ||
goarch: | ||
- amd64 | ||
archive: | ||
format: binary | ||
snapshot: | ||
name_template: "{{.Commit}}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
language: go | ||
|
||
go: | ||
- "1.10.x" | ||
|
||
after_script: | ||
- go get -v github.com/alecthomas/gometalinter/... | ||
- gometalinter --install | ||
- gometalinter | ||
|
||
after_success: | ||
- test -n "$TRAVIS_TAG" && curl -sL https://git.io/goreleaser | bash |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2018 Romain Beuque | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
all: | ||
go build -o jagozzi main.go utils.go instance.go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
jagozzi [![Build Status](https://travis-ci.org/rbeuque74/jagozzi.png?branch=master)](https://travis-ci.org/rbeuque74/jagozzi) [![GitHub release](https://img.shields.io/github/release/rbeuque74/jagozzi.svg)](https://github.com/rbeuque74/jagozzi/releases) | ||
============================== | ||
|
||
jagozzi is a light monitoring daemon for severals service in order to report results checks to a remote NSCA server. | ||
|
||
This program is a Golang clone of [sauna](https://github.com/NicolasLM/sauna) that will parse the same configuration file format. | ||
|
||
Services included | ||
----------------- | ||
|
||
- Supervisor | ||
- Command | ||
- Processes | ||
- HTTP | ||
- Marathon | ||
|
||
Installation | ||
------------ | ||
|
||
jagozzi can be installed using this command: | ||
|
||
``` | ||
go install github.com/rbeuque74/jagozzi | ||
``` | ||
|
||
License | ||
------- | ||
|
||
MIT, see [LICENSE](LICENSE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package config | ||
|
||
import ( | ||
"io/ioutil" | ||
|
||
"github.com/ghodss/yaml" | ||
) | ||
|
||
// Load is loading configuration from file and returns a jagozzi configuration | ||
func Load(configurationFile string) (*Configuration, error) { | ||
stream, err := ioutil.ReadFile(configurationFile) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
cfg := &Configuration{} | ||
if err = yaml.Unmarshal(stream, cfg); err != nil { | ||
return nil, err | ||
} | ||
|
||
return cfg, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package config | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
// Configuration is the jagozzi main configuration structure | ||
type Configuration struct { | ||
rawConfiguration | ||
// Periodicity is time span between two iterations of a check | ||
Periodicity time.Duration `json:"-"` | ||
} | ||
|
||
type rawConfiguration struct { | ||
RawPeriodicity int64 `json:"periodicity"` | ||
Hostname string `json:"hostname"` | ||
Consumers []ConsumerConfiguration `json:"consumers"` | ||
Plugins []PluginConfiguration `json:"plugins"` | ||
} | ||
|
||
// UnmarshalJSON explicits some variables from configuration file to proper Golang type | ||
func (cfg *Configuration) UnmarshalJSON(b []byte) error { | ||
raw := &rawConfiguration{} | ||
|
||
if err := UnmarshalConfig(b, raw); err != nil { | ||
return err | ||
} | ||
|
||
cfg.rawConfiguration = *raw | ||
cfg.Periodicity = time.Duration(raw.RawPeriodicity) * time.Second | ||
|
||
return nil | ||
} | ||
|
||
// ConsumerConfiguration is the configuration of a consumer | ||
type ConsumerConfiguration struct { | ||
rawConsumerConfiguration | ||
Timeout time.Duration `json:"-"` | ||
} | ||
|
||
type rawConsumerConfiguration struct { | ||
Type string `json:"type"` | ||
Server string `json:"server"` | ||
Port int64 `json:"port"` | ||
RawTimeout int64 `json:"timeout"` | ||
Encryption int64 `json:"encryption"` | ||
Key string `json:"key"` | ||
} | ||
|
||
// UnmarshalJSON explicits some variables from configuration file to proper Golang type | ||
func (cfg *ConsumerConfiguration) UnmarshalJSON(b []byte) error { | ||
raw := &rawConsumerConfiguration{} | ||
|
||
if err := UnmarshalConfig(b, raw); err != nil { | ||
return err | ||
} | ||
|
||
cfg.rawConsumerConfiguration = *raw | ||
cfg.Timeout = time.Duration(raw.RawTimeout) * time.Millisecond | ||
|
||
return nil | ||
} | ||
|
||
// PluginConfiguration represents the configuration of a plugin | ||
type PluginConfiguration struct { | ||
// Type is the name of the plugin that will run | ||
Type string `json:"type"` | ||
// Config is the custom configuration of the plugin | ||
Config interface{} `json:"config,omitempty"` | ||
// Checks is the list of all checks that plugin will run | ||
Checks []interface{} `json:"checks"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package config | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
) | ||
|
||
// UnmarshalConfig will decode a JSON structure while disallowing unknown fields, to prevent configuration file errors | ||
func UnmarshalConfig(b []byte, obj interface{}) error { | ||
if ok := json.Valid(b); !ok { | ||
return fmt.Errorf("json: not valid configuration") | ||
} | ||
|
||
reader := bytes.NewReader(b) | ||
dec := json.NewDecoder(reader) | ||
dec.DisallowUnknownFields() | ||
|
||
if err := dec.Decode(obj); err != nil && err != io.EOF { | ||
return err | ||
} | ||
|
||
if more := dec.More(); more { | ||
return fmt.Errorf("json: not valid configuration") | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package nsca | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/rbeuque74/jagozzi/config" | ||
"github.com/rbeuque74/jagozzi/plugins" | ||
log "github.com/sirupsen/logrus" | ||
"github.com/syncbak-git/nsca" | ||
) | ||
|
||
// Consumer is the representation of a NSCA consumer | ||
type Consumer struct { | ||
cfg config.ConsumerConfiguration | ||
messageChannel chan *nsca.Message | ||
exitChannel chan interface{} | ||
} | ||
|
||
// New generates a new NSCA Consumer instance | ||
func New(messageChannel chan *nsca.Message, exitChannel chan interface{}) Consumer { | ||
return Consumer{ | ||
messageChannel: messageChannel, | ||
exitChannel: exitChannel, | ||
} | ||
} | ||
|
||
// Send will produce a message to the specified consumer | ||
func (consumer Consumer) Send(ctx context.Context, result plugins.Result, hostname string, errorChannel chan error) { | ||
if consumer.messageChannel == nil { | ||
log.Warnf("consumer: message channel is empty") | ||
return | ||
} | ||
|
||
msg := nsca.Message{ | ||
State: int16(result.Status), | ||
Host: hostname, | ||
Service: result.Checker.ServiceName(), | ||
Message: result.Message, | ||
Status: errorChannel, | ||
} | ||
|
||
log.Debugf("consumer: send message %+v", msg) | ||
|
||
ch := consumer.messageChannel | ||
select { | ||
case ch <- &msg: | ||
return | ||
case <-ctx.Done(): | ||
log.Warnf("consumer: timeout to push message to consumer message channel: %s", ctx.Err()) | ||
return | ||
} | ||
} | ||
|
||
// Unload cleans all current operation/goroutine of consumer | ||
func (consumer Consumer) Unload() { | ||
if consumer.exitChannel == nil { | ||
return | ||
} | ||
|
||
log.Debugf("consumer: sent 'quit' information to receiver") | ||
consumer.exitChannel <- true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/rbeuque74/jagozzi/config" | ||
"github.com/rbeuque74/jagozzi/consumers/nsca" | ||
"github.com/rbeuque74/jagozzi/plugins" | ||
log "github.com/sirupsen/logrus" | ||
nscalib "github.com/syncbak-git/nsca" | ||
) | ||
|
||
// Jagozzi is an instance of jagozzi checker | ||
type Jagozzi struct { | ||
cfg config.Configuration | ||
checkers []plugins.Checker | ||
consumers []nsca.Consumer | ||
consumerErrorChannel chan error | ||
} | ||
|
||
// Load is loading configuration from file and returns a jagozzi configuration | ||
func Load(cfg config.Configuration) (*Jagozzi, error) { | ||
y := Jagozzi{ | ||
cfg: cfg, | ||
consumerErrorChannel: make(chan error), | ||
} | ||
|
||
// Consumers initialisation | ||
for _, consumer := range y.cfg.Consumers { | ||
if consumer.Type != "NSCA" { | ||
log.Warnf("config: found an unknown consumer type %q", consumer.Type) | ||
continue | ||
} | ||
if consumer.Port == 0 { | ||
// default nsca port | ||
consumer.Port = 5667 | ||
} | ||
serv := nscalib.ServerInfo{ | ||
Host: consumer.Server, | ||
Port: fmt.Sprintf("%d", consumer.Port), | ||
EncryptionMethod: int(consumer.Encryption), | ||
Password: consumer.Key, | ||
Timeout: consumer.Timeout, | ||
} | ||
|
||
exitChannel := make(chan interface{}) | ||
messagesChannel := make(chan *nscalib.Message) | ||
|
||
log.Infof("consumer: starting NSCA server to %s:%d", consumer.Server, consumer.Port) | ||
go nscalib.RunEndpoint(serv, exitChannel, messagesChannel) | ||
|
||
consumerInstance := nsca.New(messagesChannel, exitChannel) | ||
y.consumers = append(y.consumers, consumerInstance) | ||
} | ||
|
||
// Pluggins initialisation | ||
for _, plugin := range y.cfg.Plugins { | ||
for _, check := range plugin.Checks { | ||
checker, err := plugins.CreateChecker(plugin.Type, check, plugin.Config) | ||
if err != nil && err == plugins.UnknownCheckerTypeErr { | ||
log.WithField("type", plugin.Type).Warn(err) | ||
continue | ||
} else if err != nil { | ||
return nil, err | ||
} | ||
y.checkers = append(y.checkers, checker) | ||
} | ||
} | ||
|
||
return &y, nil | ||
} | ||
|
||
// Unload cleans all current operation/goroutine loaded by configuration and configuration childs | ||
func (y Jagozzi) Unload() { | ||
for _, consumer := range y.consumers { | ||
consumer.Unload() | ||
} | ||
} | ||
|
||
// SendConsumers will send a NSCA message to all consumers | ||
func (y Jagozzi) SendConsumers(ctx context.Context, result plugins.Result) { | ||
for _, consumer := range y.consumers { | ||
consumer.Send(ctx, result, y.cfg.Hostname, y.consumerErrorChannel) | ||
} | ||
} | ||
|
||
// Checkers returns the list of checkers | ||
func (y Jagozzi) Checkers() []plugins.Checker { | ||
return y.checkers | ||
} |
Oops, something went wrong.