Add initial support for YAML configuration files

Signed-off-by: Ben Reedy <breed808@breed808.com>
This commit is contained in:
Ben Reedy 2020-10-22 14:07:30 +10:00 committed by Ben Reedy
parent 6231eb43e8
commit 96aa2cf095
4 changed files with 110 additions and 2 deletions

82
config/config.go Normal file
View File

@ -0,0 +1,82 @@
// Copyright 2018 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"io/ioutil"
"os"
"github.com/prometheus/common/log"
"gopkg.in/alecthomas/kingpin.v2"
"gopkg.in/yaml.v2"
)
type getFlagger interface {
GetFlag(name string) *kingpin.FlagClause
}
// Resolver represents a configuration file resolver for kingpin.
type Resolver struct {
flags map[string]string
}
// NewResolver returns a Resolver structure.
func NewResolver(file string) (*Resolver, error) {
flags := map[string]string{}
log.Infof("Loading configuration file: %v", file)
if _, err := os.Stat(file); err != nil {
return nil, err
}
b, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
var m map[string]string
err = yaml.Unmarshal(b, &m)
if err != nil {
return nil, err
}
for k, v := range m {
if _, ok := flags[k]; !ok {
flags[k] = v
}
}
return &Resolver{flags: flags}, nil
}
func (c *Resolver) setDefault(v getFlagger) {
for name, value := range c.flags {
f := v.GetFlag(name)
if f != nil {
f.Default(value)
}
}
}
// Bind sets active flags with their default values from the configuration file(s).
func (c *Resolver) Bind(app *kingpin.Application, args []string) error {
// Parse the command line arguments to get the selected command.
pc, err := app.ParseContext(args)
if err != nil {
return err
}
c.setDefault(app)
if pc.SelectedCommand != nil {
c.setDefault(pc.SelectedCommand)
}
return nil
}

View File

@ -18,6 +18,7 @@ import (
"github.com/StackExchange/wmi"
"github.com/prometheus-community/windows_exporter/collector"
"github.com/prometheus-community/windows_exporter/config"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/log"
@ -269,7 +270,11 @@ func initWbem() {
func main() {
var (
app = kingpin.New("windows_exporter", "")
app = kingpin.New("windows_exporter", "")
configFile = app.Flag(
"config.file",
"YAML configuration file to use. Values set in this file will override flags.",
).Default(os.ExpandEnv("$ProgramFiles\\windows_exporter\\config.yml")).String()
listenAddress = app.Flag(
"telemetry.addr",
"host:port for exporter.",
@ -299,7 +304,26 @@ func main() {
log.AddFlags(app)
app.Version(version.Print("windows_exporter"))
app.HelpFlag.Short('h')
app.Parse(os.Args[1:])
// Load values from configuration file(s). Executable flags must first be parsed, in order
// to load the specified file(s).
_, err := app.Parse(os.Args[1:])
if err != nil {
log.Fatalf("%v\n", err)
}
resolver, err := config.NewResolver(*configFile)
if err != nil {
log.Fatalf("could not load config file: %v\n", err)
}
err = resolver.Bind(app, os.Args[1:])
if err != nil {
log.Fatalf("%v\n", err)
}
// Parse flags once more to include those discovered in configuration file(s).
_, err = app.Parse(os.Args[1:])
if err != nil {
log.Fatalf("%v\n", err)
}
if *printCollectors {
collectors := collector.Available()

1
go.mod
View File

@ -14,4 +14,5 @@ require (
github.com/prometheus/common v0.2.0
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/yaml.v2 v2.2.1
)

1
go.sum
View File

@ -69,4 +69,5 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=