Add statuspoller functionality

This first implementation intentionally ignores perfdata.
This commit is contained in:
Blerim Sheqa 2017-01-03 16:36:39 +01:00
parent 292049a1aa
commit 92fe7baaa2
7 changed files with 146 additions and 12 deletions

View File

@ -14,7 +14,7 @@ Example usage:
* Create dashboards in Kibana with metrics collected by Icinga 2 * Create dashboards in Kibana with metrics collected by Icinga 2
* Monitor notifications sent by Icinga 2 * Monitor notifications sent by Icinga 2
**StatusPoller:** The Icinga 2 API exports lots of information about the state **Statuspoller:** The Icinga 2 API exports lots of information about the state
of the Icinga daemon. These information can be polled periodically. of the Icinga daemon. These information can be polled periodically.
Example usage: Example usage:
@ -110,8 +110,12 @@ Example for the CheckResult type with the service matching the string pattern
filter: 'match("mysql*", event.service)' filter: 'match("mysql*", event.service)'
``` ```
### StatusPoller ### Statuspoller
StatusPoller is not implemented yet. These settings are specific to the statuspoller mode.
#### `interval`
Interval at which the status API is called. Set to `0` to disable polling.
Defaults to `60s`
## Run ## Run
To run Icingabeat with debugging output enabled, run: To run Icingabeat with debugging output enabled, run:

View File

@ -57,3 +57,7 @@ icingabeat:
# #
# To disable filtering set an empty string or comment out the filter option # To disable filtering set an empty string or comment out the filter option
filter: "" filter: ""
statuspoller:
# Interval at which the status API is called. Set to 0 to disable polling.
interval: 60s

View File

@ -34,16 +34,21 @@ func New(b *beat.Beat, cfg *common.Config) (beat.Beater, error) {
// Run Icingabeat // Run Icingabeat
func (bt *Icingabeat) Run(b *beat.Beat) error { func (bt *Icingabeat) Run(b *beat.Beat) error {
var eventstream *Eventstream
logp.Info("icingabeat is running! Hit CTRL-C to stop it.") logp.Info("icingabeat is running! Hit CTRL-C to stop it.")
bt.client = b.Publisher.Connect() bt.client = b.Publisher.Connect()
if len(bt.config.Eventstream.Types) > 0 { if len(bt.config.Eventstream.Types) > 0 {
var eventstream *Eventstream
eventstream = NewEventstream(bt, bt.config) eventstream = NewEventstream(bt, bt.config)
go eventstream.Run() go eventstream.Run()
} }
if bt.config.Statuspoller.Interval > 0 {
var statuspoller *Statuspoller
statuspoller = NewStatuspoller(bt, bt.config)
go statuspoller.Run()
}
for { for {
select { select {
case <-bt.done: case <-bt.done:

107
beater/statuspoller.go Normal file
View File

@ -0,0 +1,107 @@
package beater
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/url"
"strconv"
"time"
"github.com/icinga/icingabeat/config"
"github.com/elastic/beats/libbeat/common"
"github.com/elastic/beats/libbeat/logp"
)
// Statuspoller type
type Statuspoller struct {
icingabeat *Icingabeat
config config.Config
done chan struct{}
}
// NewStatuspoller ...
func NewStatuspoller(bt *Icingabeat, cfg config.Config) *Statuspoller {
statuspoller := &Statuspoller{
icingabeat: bt,
done: make(chan struct{}),
config: cfg,
}
return statuspoller
}
// Run evenstream receiver
func (sp *Statuspoller) Run() error {
host := sp.config.Host + ":" + strconv.Itoa(sp.config.Port)
var URL *url.URL
URL, err := url.Parse("https://" + host)
if err != nil {
logp.Info("Invalid request URL")
}
URL.Path += "/v1/status"
for {
ticker := time.NewTicker(sp.config.Statuspoller.Interval)
response, responseErr := requestURL(sp.icingabeat, "GET", URL)
var event common.MapStr
if responseErr == nil {
body, err := ioutil.ReadAll(response.Body)
if err != nil {
logp.Warn("Response body invalid: %v", err)
}
if err := json.Unmarshal(body, &event); err != nil {
logp.Info("Unmarshal problem %v", err)
if err == io.ErrUnexpectedEOF || err == io.EOF {
break
}
continue
}
for _, result := range event {
switch statustype := result.(type) {
case []interface{}:
for _, status := range statustype {
fmt.Println(status)
statusevent := common.MapStr{
"@timestamp": common.Time(time.Now()),
"type": "icingabeat.status",
}
for key, value := range status.(map[string]interface{}) {
if key != "perfdata" {
statusevent.Put(key, value)
}
}
sp.icingabeat.client.PublishEvent(statusevent)
logp.Info("Event sent")
}
}
}
} else {
logp.Info("Error connecting to API: %v", responseErr)
}
select {
case <-sp.done:
return nil
case <-ticker.C:
}
}
return nil
}
// Stop eventstream receiver
func (sp *Statuspoller) Stop() {
close(sp.done)
}

View File

@ -14,6 +14,7 @@ type Config struct {
RetryInterval time.Duration `config:"retry_interval"` RetryInterval time.Duration `config:"retry_interval"`
SkipSSLVerify bool `config:"skip_ssl_verify"` SkipSSLVerify bool `config:"skip_ssl_verify"`
Eventstream EventstreamConfig `config:"eventstream"` Eventstream EventstreamConfig `config:"eventstream"`
Statuspoller StatuspollerConfig `config:"statuspoller"`
} }
// EventstreamConfig optoins // EventstreamConfig optoins
@ -22,6 +23,11 @@ type EventstreamConfig struct {
Filter string `config:"filter"` Filter string `config:"filter"`
} }
// StatuspollerConfig options
type StatuspollerConfig struct {
Interval time.Duration `config:"interval"`
}
// DefaultConfig values // DefaultConfig values
var DefaultConfig = Config{ var DefaultConfig = Config{
RetryInterval: 1 * time.Second, RetryInterval: 1 * time.Second,

View File

@ -58,6 +58,10 @@ icingabeat:
# To disable filtering set an empty string or comment out the filter option # To disable filtering set an empty string or comment out the filter option
filter: "" filter: ""
statuspoller:
# Interval at which the status API is called. Set to 0 to disable polling.
interval: 60s
#================================ General ====================================== #================================ General ======================================
# The name of the shipper that publishes the network data. It can be used to group # The name of the shipper that publishes the network data. It can be used to group

View File

@ -58,6 +58,10 @@ icingabeat:
# To disable filtering set an empty string or comment out the filter option # To disable filtering set an empty string or comment out the filter option
filter: "" filter: ""
statuspoller:
# Interval at which the status API is called. Set to 0 to disable polling.
interval: 60s
#================================ General ===================================== #================================ General =====================================
# The name of the shipper that publishes the network data. It can be used to group # The name of the shipper that publishes the network data. It can be used to group