firehol/netdata

View on GitHub
src/go/plugin/go.d/modules/monit/collect.go

Summary

Maintainability
A
0 mins
Test Coverage
// SPDX-License-Identifier: GPL-3.0-or-later

package monit

import (
    "encoding/xml"
    "errors"
    "fmt"
    "net/url"

    "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/web"

    "golang.org/x/net/html/charset"
)

var (
    urlPathStatus  = "/_status"
    urlQueryStatus = url.Values{"format": {"xml"}, "level": {"full"}}.Encode()
)

func (m *Monit) collect() (map[string]int64, error) {
    mx := make(map[string]int64)

    if err := m.collectStatus(mx); err != nil {
        return nil, err
    }

    return mx, nil
}

func (m *Monit) collectStatus(mx map[string]int64) error {
    status, err := m.fetchStatus()
    if err != nil {
        return err
    }

    if status.Server == nil {
        // not Monit
        return errors.New("invalid Monit status response: missing server data")
    }

    mx["uptime"] = status.Server.Uptime

    seen := make(map[string]bool)

    for _, svc := range status.Services {
        seen[svc.id()] = true

        if _, ok := m.seenServices[svc.id()]; !ok {
            m.seenServices[svc.id()] = svc
            m.addServiceCheckCharts(svc, status.Server)
        }

        px := fmt.Sprintf("service_check_type_%s_name_%s_status_", svc.svcType(), svc.Name)

        for _, v := range []string{"not_monitored", "ok", "initializing", "error"} {
            mx[px+v] = 0
            if svc.status() == v {
                mx[px+v] = 1
            }
        }
    }

    for id, svc := range m.seenServices {
        if !seen[id] {
            delete(m.seenServices, id)
            m.removeServiceCharts(svc)
        }
    }

    return nil
}

func (m *Monit) fetchStatus() (*monitStatus, error) {
    req, err := web.NewHTTPRequestWithPath(m.RequestConfig, urlPathStatus)
    if err != nil {
        return nil, err
    }
    req.URL.RawQuery = urlQueryStatus

    var status monitStatus
    if err := web.DoHTTP(m.httpClient).RequestXML(req, &status, func(d *xml.Decoder) {
        d.CharsetReader = charset.NewReaderLabel
    }); err != nil {
        return nil, err
    }

    return &status, nil
}