You've already forked nginx_exporter
mirror of
https://github.com/nginxinc/nginx-prometheus-exporter.git
synced 2025-08-08 05:02:04 +03:00
Add Environment Variable options to flags managed in exporter-toolkit (#607)
* add env var options to flags managed in exporter-toolkit
This commit is contained in:
@@ -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)
|
||||
|
24
exporter.go
24
exporter.go
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
@@ -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) {
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user