initial commit
This commit is contained in:
commit
9afe51eaf4
815 changed files with 333651 additions and 0 deletions
113
rcctl/rcctl.go
Normal file
113
rcctl/rcctl.go
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright (C) 2020 Marius Schellenberger
|
||||
|
||||
package rcctl
|
||||
|
||||
import (
|
||||
"github.com/go-kit/kit/log"
|
||||
"github.com/go-kit/kit/log/level"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
specialSvcs = map[string]struct{}{
|
||||
"accounting": struct{}{},
|
||||
"check_quotas": struct{}{},
|
||||
"ipsec": struct{}{},
|
||||
"library_aslr": struct{}{},
|
||||
"multicast": struct{}{},
|
||||
"pf": struct{}{},
|
||||
"spamd_black": struct{}{},
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
namespace = "rcctl"
|
||||
rcctl = "/usr/sbin/rcctl"
|
||||
statusOK = "(ok)"
|
||||
statusFailed = "(failed)"
|
||||
|
||||
serviceUpdateInterval = time.Second * 30
|
||||
)
|
||||
|
||||
type Collector struct {
|
||||
sync.RWMutex
|
||||
state *prometheus.Desc
|
||||
logger log.Logger
|
||||
|
||||
services []string
|
||||
}
|
||||
|
||||
// NewCollector returns a new Collector exposing rcctl statistics.
|
||||
func NewCollector(logger log.Logger) (*Collector, error) {
|
||||
c := &Collector{
|
||||
state: prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, "", "state"),
|
||||
"State of rcctl service.",
|
||||
[]string{"service"}, prometheus.Labels{"supervisor": "rcctl"},
|
||||
),
|
||||
logger: logger,
|
||||
}
|
||||
go c.getServices()
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *Collector) getServices() {
|
||||
for {
|
||||
var svcs []string
|
||||
cmd := exec.Command(rcctl, "ls", "on")
|
||||
on, err := cmd.Output()
|
||||
if err != nil {
|
||||
level.Debug(c.logger).Log("msg", "rcctl list services", "error", err)
|
||||
time.Sleep(serviceUpdateInterval)
|
||||
continue
|
||||
}
|
||||
for _, s := range strings.Split(string(on), "\n") {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := specialSvcs[s]; ok {
|
||||
continue
|
||||
}
|
||||
svcs = append(svcs, s)
|
||||
}
|
||||
c.Lock()
|
||||
c.services = svcs
|
||||
c.Unlock()
|
||||
time.Sleep(serviceUpdateInterval)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Collector) Collect(ch chan<- prometheus.Metric) {
|
||||
c.RLock()
|
||||
args := append([]string{"check"}, c.services...)
|
||||
c.RUnlock()
|
||||
cmd := exec.Command(rcctl, args...)
|
||||
states, err := cmd.Output()
|
||||
if err != nil {
|
||||
level.Debug(c.logger).Log("msg", "rcctl check services", "error", err)
|
||||
}
|
||||
for _, s := range strings.Split(string(states), "\n") {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
state := 0.0
|
||||
if strings.Contains(s, statusOK) {
|
||||
state = 1.0
|
||||
s = strings.TrimSuffix(s, statusOK)
|
||||
} else {
|
||||
s = strings.TrimSuffix(s, statusFailed)
|
||||
}
|
||||
level.Debug(c.logger).Log("msg", "Current status", "Service", s, "Status", state)
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.state, prometheus.GaugeValue, state, s)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Collector) Describe(desc chan<- *prometheus.Desc) {
|
||||
desc <- c.state
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue