Use flags instead of config and remove attributes

This commit is contained in:
Johannes 'fish' Ziemke 2015-05-20 20:04:49 +02:00
parent 5b20dad9ad
commit 665b05eedc
23 changed files with 87 additions and 162 deletions

View file

@ -31,7 +31,6 @@ Which collectors are used is controlled by the `--collectors.enabled` flag.
Name | Description
---------|------------
attributes | Exposes attributes from the configuration file. Deprecated, use textfile module instead.
diskstats | Exposes disk I/O statistics from `/proc/diskstats`.
filesystem | Exposes filesystem statistics, such as disk space used.
loadavg | Exposes load average.

View file

@ -1,46 +0,0 @@
// +build !noattributes
package collector
import (
"github.com/golang/glog"
"github.com/prometheus/client_golang/prometheus"
)
type attributesCollector struct {
config Config
metric *prometheus.GaugeVec
}
func init() {
Factories["attributes"] = NewAttributesCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// labels from the config.
func NewAttributesCollector(config Config) (Collector, error) {
labelNames := []string{}
for l := range config.Attributes {
labelNames = append(labelNames, l)
}
return &attributesCollector{
config: config,
metric: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,
Name: "attributes",
Help: "The node_exporter attributes.",
},
labelNames,
),
}, nil
}
func (c *attributesCollector) Update(ch chan<- prometheus.Metric) (err error) {
glog.V(1).Info("Set node_attributes{%v}: 1", c.config.Attributes)
c.metric.Reset()
c.metric.With(c.config.Attributes).Set(1)
c.metric.Collect(ch)
return err
}

View file

@ -26,7 +26,7 @@ func init() {
// NewBondingCollector returns a newly allocated bondingCollector.
// It exposes the number of configured and active slave of linux bonding interfaces.
func NewBondingCollector(config Config) (Collector, error) {
func NewBondingCollector() (Collector, error) {
return &bondingCollector{
slaves: prometheus.NewGaugeVec(
prometheus.GaugeOpts{

View file

@ -7,7 +7,7 @@ import (
const Namespace = "node"
var Factories = make(map[string]func(Config) (Collector, error))
var Factories = make(map[string]func() (Collector, error))
// Interface a collector has to implement.
type Collector interface {
@ -20,8 +20,3 @@ type Collector interface {
// scraped. (However, for metric gathering that takes very long, it might
// actually be better to do them proactively before scraping to minimize scrape
// time.)
type Config struct {
Config map[string]string `json:"config"`
Attributes map[string]string `json:"attributes"`
}

View file

@ -26,7 +26,7 @@ var (
)
type diskstatsCollector struct {
config Config
ignoredDevicesPattern *regexp.Regexp
metrics []prometheus.Collector
}
@ -35,13 +35,12 @@ func init() {
Factories["diskstats"] = NewDiskstatsCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// disk device stats.
func NewDiskstatsCollector(config Config) (Collector, error) {
func NewDiskstatsCollector() (Collector, error) {
var diskLabelNames = []string{"device"}
return &diskstatsCollector{
config: config,
ignoredDevicesPattern: regexp.MustCompile(*ignoredDevices),
// Docs from https://www.kernel.org/doc/Documentation/iostats.txt
metrics: []prometheus.Collector{

View file

@ -25,7 +25,7 @@ var (
)
type filesystemCollector struct {
config Config
ignoredMountPointsPattern *regexp.Regexp
size, free, avail, files, filesFree *prometheus.GaugeVec
@ -35,13 +35,13 @@ func init() {
Factories["filesystem"] = NewFilesystemCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// network device filesystems.
func NewFilesystemCollector(config Config) (Collector, error) {
func NewFilesystemCollector() (Collector, error) {
var filesystemLabelNames = []string{"filesystem"}
return &filesystemCollector{
config: config,
ignoredMountPointsPattern: regexp.MustCompile(*ignoredMountPoints),
size: prometheus.NewGaugeVec(
prometheus.GaugeOpts{

View file

@ -25,7 +25,7 @@ const (
type gmondCollector struct {
metrics map[string]*prometheus.GaugeVec
config Config
}
func init() {
@ -34,10 +34,9 @@ func init() {
var illegalCharsRE = regexp.MustCompile(`[^a-zA-Z0-9_]`)
// Takes a config struct and prometheus registry and returns a new Collector scraping ganglia.
func NewGmondCollector(config Config) (Collector, error) {
// Takes a prometheus registry and returns a new Collector scraping ganglia.
func NewGmondCollector() (Collector, error) {
c := gmondCollector{
config: config,
metrics: map[string]*prometheus.GaugeVec{},
}

View file

@ -18,7 +18,7 @@ const (
)
type interruptsCollector struct {
config Config
metric *prometheus.CounterVec
}
@ -26,11 +26,11 @@ func init() {
Factories["interrupts"] = NewInterruptsCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// interrupts stats
func NewInterruptsCollector(config Config) (Collector, error) {
func NewInterruptsCollector() (Collector, error) {
return &interruptsCollector{
config: config,
metric: prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: Namespace,

View file

@ -3,6 +3,7 @@
package collector
import (
"flag"
"fmt"
"strconv"
@ -10,6 +11,10 @@ import (
"github.com/prometheus/procfs"
)
var (
ipvsProcfsMountPoint = flag.String("collector.ipvs.procfs", procfs.DefaultMountPoint, "procfs mountpoint.")
)
type ipvsCollector struct {
Collector
fs procfs.FS
@ -23,11 +28,11 @@ func init() {
// NewIPVSCollector sets up a new collector for IPVS metrics. It accepts the
// "procfs" config parameter to override the default proc location (/proc).
func NewIPVSCollector(config Config) (Collector, error) {
return newIPVSCollector(config)
func NewIPVSCollector() (Collector, error) {
return newIPVSCollector()
}
func newIPVSCollector(config Config) (*ipvsCollector, error) {
func newIPVSCollector() (*ipvsCollector, error) {
var (
ipvsBackendLabelNames = []string{
"local_address",
@ -37,23 +42,14 @@ func newIPVSCollector(config Config) (*ipvsCollector, error) {
"proto",
}
c ipvsCollector
subsystem string
err error
subsystem = "ipvs"
)
if p, ok := config.Config["procfs"]; !ok {
c.fs, err = procfs.NewFS(procfs.DefaultMountPoint)
} else {
c.fs, err = procfs.NewFS(p)
}
c.fs, err = procfs.NewFS(*ipvsProcfsMountPoint)
if err != nil {
return nil, err
}
if s, ok := config.Config["ipvs_subsystem"]; ok {
subsystem = s
} else {
subsystem = "ipvs"
}
c.connections = prometheus.NewCounter(
prometheus.CounterOpts{

View file

@ -1,6 +1,7 @@
package collector
import (
"flag"
"io/ioutil"
"net"
"net/http"
@ -106,7 +107,10 @@ var (
)
func TestIPVSCollector(t *testing.T) {
collector, err := newIPVSCollector(Config{Config: map[string]string{"procfs": "fixtures"}})
if err := flag.Set("collector.ipvs.procfs", "fixtures"); err != nil {
t.Fatal(err)
}
collector, err := newIPVSCollector()
if err != nil {
t.Fatal(err)
}
@ -165,7 +169,10 @@ func (c miniCollector) Describe(ch chan<- *prometheus.Desc) {
}
func TestIPVSCollectorResponse(t *testing.T) {
collector, err := NewIPVSCollector(Config{Config: map[string]string{"procfs": "fixtures"}})
if err := flag.Set("collector.ipvs.procfs", "fixtures"); err != nil {
t.Fatal(err)
}
collector, err := NewIPVSCollector()
if err != nil {
t.Fatal(err)
}
@ -183,6 +190,7 @@ func TestIPVSCollectorResponse(t *testing.T) {
wantLines := strings.Split(string(wantMetrics), "\n")
gotLines := strings.Split(string(rw.Body.String()), "\n")
gotLinesIdx := 0
t.Log(gotLines)
// Until the Prometheus Go client library offers better testability
// (https://github.com/prometheus/client_golang/issues/58), we simply compare

View file

@ -17,7 +17,7 @@ import (
const lastLoginSubsystem = "last_login"
type lastLoginCollector struct {
config Config
metric prometheus.Gauge
}
@ -25,11 +25,11 @@ func init() {
Factories["lastlogin"] = NewLastLoginCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// load, seconds since last login and a list of tags as specified by config.
func NewLastLoginCollector(config Config) (Collector, error) {
func NewLastLoginCollector() (Collector, error) {
return &lastLoginCollector{
config: config,
metric: prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: Namespace,
Subsystem: lastLoginSubsystem,

View file

@ -17,7 +17,7 @@ const (
)
type loadavgCollector struct {
config Config
metric prometheus.Gauge
}
@ -25,11 +25,11 @@ func init() {
Factories["loadavg"] = NewLoadavgCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// load, seconds since last login and a list of tags as specified by config.
func NewLoadavgCollector(config Config) (Collector, error) {
func NewLoadavgCollector() (Collector, error) {
return &loadavgCollector{
config: config,
metric: prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: Namespace,
Name: "load1",

View file

@ -4,6 +4,7 @@ package collector
import (
"bufio"
"flag"
"io"
"os/exec"
"strconv"
@ -17,9 +18,12 @@ const (
adapterHeaderSep = "================"
)
var (
megacliCommand = flag.String("collector.megacli.command", defaultMegaCli, "Command to run megacli.")
)
type megaCliCollector struct {
config Config
cli string
cli string
driveTemperature *prometheus.GaugeVec
driveCounters *prometheus.CounterVec
@ -30,17 +34,12 @@ func init() {
Factories["megacli"] = NewMegaCliCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// RAID status through megacli.
func NewMegaCliCollector(config Config) (Collector, error) {
cli := defaultMegaCli
if config.Config["megacli_command"] != "" {
cli = config.Config["megacli_command"]
}
func NewMegaCliCollector() (Collector, error) {
return &megaCliCollector{
config: config,
cli: cli,
cli: *megacliCommand,
driveTemperature: prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: Namespace,
Name: "megacli_drive_temperature_celsius",

View file

@ -21,7 +21,7 @@ const (
)
type meminfoCollector struct {
config Config
metrics map[string]prometheus.Gauge
}
@ -29,11 +29,10 @@ func init() {
Factories["meminfo"] = NewMeminfoCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// memory stats.
func NewMeminfoCollector(config Config) (Collector, error) {
func NewMeminfoCollector() (Collector, error) {
return &meminfoCollector{
config: config,
metrics: map[string]prometheus.Gauge{},
}, nil
}

View file

@ -19,7 +19,7 @@ const (
)
type netDevCollector struct {
config Config
metrics map[string]*prometheus.GaugeVec
}
@ -27,11 +27,10 @@ func init() {
Factories["netdev"] = NewNetDevCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// network device stats.
func NewNetDevCollector(config Config) (Collector, error) {
func NewNetDevCollector() (Collector, error) {
return &netDevCollector{
config: config,
metrics: map[string]*prometheus.GaugeVec{},
}, nil
}

View file

@ -19,7 +19,7 @@ const (
)
type netStatCollector struct {
config Config
metrics map[string]prometheus.Gauge
}
@ -27,11 +27,10 @@ func init() {
Factories["netstat"] = NewNetStatCollector
}
// NewNetStatCollector takes a config struct and returns
// NewNetStatCollector takes a returns
// a new Collector exposing network stats.
func NewNetStatCollector(config Config) (Collector, error) {
func NewNetStatCollector() (Collector, error) {
return &netStatCollector{
config: config,
metrics: map[string]prometheus.Gauge{},
}, nil
}

View file

@ -24,9 +24,9 @@ func init() {
Factories["ntp"] = NewNtpCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// the offset between ntp and the current system time.
func NewNtpCollector(config Config) (Collector, error) {
func NewNtpCollector() (Collector, error) {
if *ntpServer == "" {
return nil, fmt.Errorf("No NTP server specifies, see --ntpServer")
}

View file

@ -9,7 +9,7 @@ import (
)
type runitCollector struct {
config Config
state, stateDesired, stateNormal *prometheus.GaugeVec
}
@ -18,7 +18,7 @@ func init() {
Factories["runit"] = NewRunitCollector
}
func NewRunitCollector(config Config) (Collector, error) {
func NewRunitCollector() (Collector, error) {
var (
subsystem = "service"
constLabels = prometheus.Labels{"supervisor": "runit"}
@ -26,7 +26,7 @@ func NewRunitCollector(config Config) (Collector, error) {
)
return &runitCollector{
config: config,
state: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,

View file

@ -17,7 +17,7 @@ const (
)
type statCollector struct {
config Config
cpu *prometheus.CounterVec
intr prometheus.Counter
ctxt prometheus.Counter
@ -31,11 +31,11 @@ func init() {
Factories["stat"] = NewStatCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// network device stats.
func NewStatCollector(config Config) (Collector, error) {
func NewStatCollector() (Collector, error) {
return &statCollector{
config: config,
cpu: prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: Namespace,

View file

@ -35,7 +35,7 @@ const (
)
type tcpStatCollector struct {
config Config
metric *prometheus.GaugeVec
}
@ -43,11 +43,11 @@ func init() {
Factories["tcpstat"] = NewTCPStatCollector
}
// NewTCPStatCollector takes a config struct and returns
// NewTCPStatCollector takes a returns
// a new Collector exposing network stats.
func NewTCPStatCollector(config Config) (Collector, error) {
func NewTCPStatCollector() (Collector, error) {
return &tcpStatCollector{
config: config,
metric: prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: Namespace,

View file

@ -31,9 +31,9 @@ func init() {
Factories["textfile"] = NewTextFileCollector
}
// Takes a config struct and registers a
// Takes a registers a
// SetMetricFamilyInjectionHook.
func NewTextFileCollector(config Config) (Collector, error) {
func NewTextFileCollector() (Collector, error) {
if *textFileDirectory == "" {
// This collector is enabled by default, so do not fail if
// the flag is not passed.

View file

@ -10,7 +10,7 @@ import (
)
type timeCollector struct {
config Config
metric prometheus.Counter
}
@ -18,11 +18,11 @@ func init() {
Factories["time"] = NewTimeCollector
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// Takes a prometheus registry and returns a new Collector exposing
// the current system time in seconds since epoch.
func NewTimeCollector(config Config) (Collector, error) {
func NewTimeCollector() (Collector, error) {
return &timeCollector{
config: config,
metric: prometheus.NewCounter(prometheus.CounterOpts{
Namespace: Namespace,
Name: "time",

View file

@ -1,10 +1,8 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net/http"
_ "net/http/pprof"
"os"
@ -26,11 +24,10 @@ var (
// set at build time
Version = "0.0.0.dev"
configFile = flag.String("config.file", "", "Path to config file.")
memProfile = flag.String("debug.memprofile-file", "", "Write memory profile to this file upon receipt of SIGUSR1.")
listenAddress = flag.String("web.listen-address", ":9100", "Address on which to expose metrics and web interface.")
metricsPath = flag.String("web.telemetry-path", "/metrics", "Path under which to expose metrics.")
enabledCollectors = flag.String("collectors.enabled", "attributes,diskstats,filesystem,loadavg,meminfo,stat,textfile,time,netdev,netstat", "Comma-separated list of collectors to use.")
enabledCollectors = flag.String("collectors.enabled", "diskstats,filesystem,loadavg,meminfo,stat,textfile,time,netdev,netstat", "Comma-separated list of collectors to use.")
printCollectors = flag.Bool("collectors.print", false, "If true, print available collectors and exit.")
authUser = flag.String("auth.user", "", "Username for basic auth.")
authPass = flag.String("auth.pass", "", "Password for basic auth.")
@ -105,32 +102,14 @@ func Execute(name string, c collector.Collector, ch chan<- prometheus.Metric) {
scrapeDurations.WithLabelValues(name, result).Observe(duration.Seconds())
}
func getConfig(file string) (*collector.Config, error) {
config := &collector.Config{}
glog.Infof("Reading config %s", *configFile)
bytes, err := ioutil.ReadFile(*configFile)
if err != nil {
return nil, err
}
return config, json.Unmarshal(bytes, &config)
}
func loadCollectors(file string) (map[string]collector.Collector, error) {
func loadCollectors() (map[string]collector.Collector, error) {
collectors := map[string]collector.Collector{}
config := &collector.Config{}
if file != "" {
var err error
config, err = getConfig(file)
if err != nil {
return nil, fmt.Errorf("couldn't read config %s: %s", file, err)
}
}
for _, name := range strings.Split(*enabledCollectors, ",") {
fn, ok := collector.Factories[name]
if !ok {
return nil, fmt.Errorf("collector '%s' not available", name)
}
c, err := fn(*config)
c, err := fn()
if err != nil {
return nil, err
}
@ -154,9 +133,9 @@ func main() {
}
return
}
collectors, err := loadCollectors(*configFile)
collectors, err := loadCollectors()
if err != nil {
glog.Fatalf("Couldn't load config and collectors: %s", err)
glog.Fatalf("Couldn't load collectors: %s", err)
}
glog.Infof("Enabled collectors:")