master
go 89 lines 1.76 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package monit
4
5 import (
6 "encoding/xml"
7 "errors"
8 "fmt"
9 "net/url"
10
11 "golang.org/x/net/html/charset"
12
13 "github.com/netdata/netdata/go/plugins/pkg/web"
14 )
15
16 var (
17 urlPathStatus = "/_status"
18 urlQueryStatus = url.Values{"format": {"xml"}, "level": {"full"}}.Encode()
19 )
20
21 func (c *Collector) collect() (map[string]int64, error) {
22 mx := make(map[string]int64)
23
24 if err := c.collectStatus(mx); err != nil {
25 return nil, err
26 }
27
28 return mx, nil
29 }
30
31 func (c *Collector) collectStatus(mx map[string]int64) error {
32 status, err := c.fetchStatus()
33 if err != nil {
34 return err
35 }
36
37 if status.Server == nil {
38 // not Monit
39 return errors.New("invalid Collector status response: missing server data")
40 }
41
42 mx["uptime"] = status.Server.Uptime
43
44 seen := make(map[string]bool)
45
46 for _, svc := range status.Services {
47 seen[svc.id()] = true
48
49 if _, ok := c.seenServices[svc.id()]; !ok {
50 c.seenServices[svc.id()] = svc
51 c.addServiceCheckCharts(svc, status.Server)
52 }
53
54 px := fmt.Sprintf("service_check_type_%s_name_%s_status_", svc.svcType(), svc.Name)
55
56 for _, v := range []string{"not_monitored", "ok", "initializing", "error"} {
57 mx[px+v] = 0
58 if svc.status() == v {
59 mx[px+v] = 1
60 }
61 }
62 }
63
64 for id, svc := range c.seenServices {
65 if !seen[id] {
66 delete(c.seenServices, id)
67 c.removeServiceCharts(svc)
68 }
69 }
70
71 return nil
72 }
73
74 func (c *Collector) fetchStatus() (*monitStatus, error) {
75 req, err := web.NewHTTPRequestWithPath(c.RequestConfig, urlPathStatus)
76 if err != nil {
77 return nil, err
78 }
79 req.URL.RawQuery = urlQueryStatus
80
81 var status monitStatus
82 if err := web.DoHTTP(c.httpClient).RequestXML(req, &status, func(d *xml.Decoder) {
83 d.CharsetReader = charset.NewReaderLabel
84 }); err != nil {
85 return nil, err
86 }
87
88 return &status, nil
89 }