Skip to content

Commit

Permalink
Add Environment Variable options to flags managed in exporter-toolkit (
Browse files Browse the repository at this point in the history
…#607)

* add env var options to flags managed in exporter-toolkit
  • Loading branch information
oseoin authored Jan 25, 2024
1 parent c41546f commit aa81230
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 2 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,11 @@ usage: nginx-prometheus-exporter [<flags>]

Flags:
-h, --[no-]help Show context-sensitive help (also try --help-long and --help-man).
--[no-]web.systemd-socket Use systemd socket activation listeners instead
of port listeners (Linux only). ($SYSTEMD_SOCKET)
--web.listen-address=:9113 ...
Addresses on which to expose metrics and web interface. Repeatable for multiple addresses.
--web.config.file="" Path to configuration file that can enable TLS or authentication. See: https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md
Addresses on which to expose metrics and web interface. Repeatable for multiple addresses. ($LISTEN_ADDRESS)
--web.config.file="" Path to configuration file that can enable TLS or authentication. See: https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md ($CONFIG_FILE)
--web.telemetry-path="/metrics"
Path under which to expose metrics. ($TELEMETRY_PATH)
--[no-]nginx.plus Start the exporter for NGINX Plus. By default, the exporter is started for NGINX. ($NGINX_PLUS)
Expand Down
24 changes: 24 additions & 0 deletions exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ func main() {
flag.AddFlags(kingpin.CommandLine, promlogConfig)
kingpin.Version(version.Print(exporterName))
kingpin.HelpFlag.Short('h')

addMissingEnvironmentFlags(kingpin.CommandLine)

kingpin.Parse()
logger := promlog.New(promlogConfig)

Expand Down Expand Up @@ -281,3 +284,24 @@ func cloneRequest(req *http.Request) *http.Request {
}
return r
}

// addMissingEnvironmentFlags sets Envar on any flag which has
// the "web." prefix which doesn't already have an Envar set
func addMissingEnvironmentFlags(ka *kingpin.Application) {
for _, f := range ka.Model().FlagGroupModel.Flags {
if strings.HasPrefix(f.Name, "web.") && f.Envar == "" {
flag := ka.GetFlag(f.Name)
if flag != nil {
flag.Envar(convertFlagToEnvar(strings.TrimPrefix(f.Name, "web.")))
}
}
}
}

func convertFlagToEnvar(f string) string {
env := strings.ToUpper(f)
for _, s := range []string{"-", "."} {
env = strings.ReplaceAll(env, s, "_")
}
return env
}
61 changes: 61 additions & 0 deletions exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"reflect"
"testing"
"time"

"github.com/alecthomas/kingpin/v2"
"github.com/prometheus/exporter-toolkit/web/kingpinflag"
)

func TestParsePositiveDuration(t *testing.T) {
Expand Down Expand Up @@ -103,3 +106,61 @@ func TestParseUnixSocketAddress(t *testing.T) {
})
}
}

func TestAddMissingEnvironmentFlags(t *testing.T) {
expectedMatches := map[string]string{
"non-matching-flag": "",
"web.missing-env": "MISSING_ENV",
"web.has-env": "HAS_ENV_ALREADY",
"web.listen-address": "LISTEN_ADDRESS",
"web.config.file": "CONFIG_FILE",
}
kingpinflag.AddFlags(kingpin.CommandLine, ":9113")
kingpin.Flag("non-matching-flag", "").String()
kingpin.Flag("web.missing-env", "").String()
kingpin.Flag("web.has-env", "").Envar("HAS_ENV_ALREADY").String()
addMissingEnvironmentFlags(kingpin.CommandLine)

// using Envar() on a flag returned from GetFlag()
// adds an additional flag, which is processed correctly
// at runtime but means that we need to check for a match
// instead of checking the envar of each matching flag name
for k, v := range expectedMatches {
matched := false
for _, f := range kingpin.CommandLine.Model().FlagGroupModel.Flags {
if f.Name == k && f.Envar == v {
matched = true
}
}
if !matched {
t.Errorf("missing %s envar for %s", v, k)
}
}
}

func TestConvertFlagToEnvar(t *testing.T) {
cases := []struct {
input string
output string
}{
{
input: "dot.separate",
output: "DOT_SEPARATE",
},
{
input: "underscore_separate",
output: "UNDERSCORE_SEPARATE",
},
{
input: "mixed_separate_options",
output: "MIXED_SEPARATE_OPTIONS",
},
}

for _, c := range cases {
res := convertFlagToEnvar(c.input)
if res != c.output {
t.Errorf("expected %s to resolve to %s but got %s", c.input, c.output, res)
}
}
}

0 comments on commit aa81230

Please sign in to comment.