171 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
| package icinga2
 | |
| 
 | |
| import (
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"log"
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/influxdata/telegraf"
 | |
| 	"github.com/influxdata/telegraf/internal"
 | |
| 	"github.com/influxdata/telegraf/internal/tls"
 | |
| 	"github.com/influxdata/telegraf/plugins/inputs"
 | |
| )
 | |
| 
 | |
| type Icinga2 struct {
 | |
| 	Server          string
 | |
| 	ObjectType      string
 | |
| 	Username        string
 | |
| 	Password        string
 | |
| 	ResponseTimeout internal.Duration
 | |
| 	tls.ClientConfig
 | |
| 
 | |
| 	client *http.Client
 | |
| }
 | |
| 
 | |
| type Result struct {
 | |
| 	Results []Object `json:"results"`
 | |
| }
 | |
| 
 | |
| type Object struct {
 | |
| 	Attrs Attribute  `json:"attrs"`
 | |
| 	Name  string     `json:"name"`
 | |
| 	Joins struct{}   `json:"joins"`
 | |
| 	Meta  struct{}   `json:"meta"`
 | |
| 	Type  ObjectType `json:"type"`
 | |
| }
 | |
| 
 | |
| type Attribute struct {
 | |
| 	CheckCommand string `json:"check_command"`
 | |
| 	DisplayName  string `json:"display_name"`
 | |
| 	Name         string `json:"name"`
 | |
| 	State        int    `json:"state"`
 | |
| }
 | |
| 
 | |
| var levels = []string{"ok", "warning", "critical", "unknown"}
 | |
| 
 | |
| type ObjectType string
 | |
| 
 | |
| var sampleConfig = `
 | |
|   ## Required Icinga2 server address (default: "https://localhost:5665")
 | |
|   # server = "https://localhost:5665"
 | |
|   
 | |
|   ## Required Icinga2 object type ("services" or "hosts, default "services")
 | |
|   # object_type = "services"
 | |
| 
 | |
|   ## Credentials for basic HTTP authentication
 | |
|   # username = "admin"
 | |
|   # password = "admin"
 | |
| 
 | |
|   ## Maximum time to receive response.
 | |
|   # response_timeout = "5s"
 | |
| 
 | |
|   ## Optional TLS Config
 | |
|   # tls_ca = "/etc/telegraf/ca.pem"
 | |
|   # tls_cert = "/etc/telegraf/cert.pem"
 | |
|   # tls_key = "/etc/telegraf/key.pem"
 | |
|   ## Use TLS but skip chain & host verification
 | |
|   # insecure_skip_verify = true
 | |
|   `
 | |
| 
 | |
| func (i *Icinga2) Description() string {
 | |
| 	return "Gather Icinga2 status"
 | |
| }
 | |
| 
 | |
| func (i *Icinga2) SampleConfig() string {
 | |
| 	return sampleConfig
 | |
| }
 | |
| 
 | |
| func (i *Icinga2) GatherStatus(acc telegraf.Accumulator, checks []Object) {
 | |
| 	for _, check := range checks {
 | |
| 		fields := make(map[string]interface{})
 | |
| 		tags := make(map[string]string)
 | |
| 
 | |
| 		url, err := url.Parse(i.Server)
 | |
| 		if err != nil {
 | |
| 			log.Fatal(err)
 | |
| 		}
 | |
| 
 | |
| 		fields["name"] = check.Attrs.Name
 | |
| 		fields["state_code"] = check.Attrs.State
 | |
| 
 | |
| 		tags["display_name"] = check.Attrs.DisplayName
 | |
| 		tags["check_command"] = check.Attrs.CheckCommand
 | |
| 		tags["state"] = levels[check.Attrs.State]
 | |
| 		tags["source"] = url.Hostname()
 | |
| 		tags["scheme"] = url.Scheme
 | |
| 		tags["port"] = url.Port()
 | |
| 
 | |
| 		acc.AddFields(fmt.Sprintf("icinga2_%s", i.ObjectType), fields, tags)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (i *Icinga2) createHttpClient() (*http.Client, error) {
 | |
| 	tlsCfg, err := i.ClientConfig.TLSConfig()
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	client := &http.Client{
 | |
| 		Transport: &http.Transport{
 | |
| 			TLSClientConfig: tlsCfg,
 | |
| 		},
 | |
| 		Timeout: i.ResponseTimeout.Duration,
 | |
| 	}
 | |
| 
 | |
| 	return client, nil
 | |
| }
 | |
| 
 | |
| func (i *Icinga2) Gather(acc telegraf.Accumulator) error {
 | |
| 	if i.ResponseTimeout.Duration < time.Second {
 | |
| 		i.ResponseTimeout.Duration = time.Second * 5
 | |
| 	}
 | |
| 
 | |
| 	if i.client == nil {
 | |
| 		client, err := i.createHttpClient()
 | |
| 		if err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 		i.client = client
 | |
| 	}
 | |
| 
 | |
| 	url := fmt.Sprintf("%s/v1/objects/%s?attrs=name&attrs=display_name&attrs=state&attrs=check_command", i.Server, i.ObjectType)
 | |
| 
 | |
| 	req, err := http.NewRequest("GET", url, nil)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	if i.Username != "" {
 | |
| 		req.SetBasicAuth(i.Username, i.Password)
 | |
| 	}
 | |
| 
 | |
| 	resp, err := i.client.Do(req)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	defer resp.Body.Close()
 | |
| 
 | |
| 	result := Result{}
 | |
| 	json.NewDecoder(resp.Body).Decode(&result)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	i.GatherStatus(acc, result.Results)
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func init() {
 | |
| 	inputs.Add("icinga2", func() telegraf.Input {
 | |
| 		return &Icinga2{
 | |
| 			Server:     "https://localhost:5665",
 | |
| 			ObjectType: "services",
 | |
| 		}
 | |
| 	})
 | |
| }
 |