Add statuspoller functionality
This first implementation intentionally ignores perfdata.
This commit is contained in:
parent
292049a1aa
commit
92fe7baaa2
10
README.md
10
README.md
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -7,13 +7,14 @@ import "time"
|
||||||
|
|
||||||
// Config options
|
// Config options
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Host string `config:"host"`
|
Host string `config:"host"`
|
||||||
Port int `config:"port"`
|
Port int `config:"port"`
|
||||||
User string `config:"user"`
|
User string `config:"user"`
|
||||||
Password string `config:"password"`
|
Password string `config:"password"`
|
||||||
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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue