1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
package config
import (
"errors"
"flag"
"fmt"
"log"
"os"
"strconv"
"strings"
)
const (
defaultListenAddress = ":9301"
defaultWebConfigPath = ""
defaultListenPort = 9301
defaultMetricsPath = "/metrics"
defaultSquidHostname = "localhost"
defaultSquidPort = 3128
defaultExtractServiceTimes = true
defaultUseProxyHeader = false
)
const (
squidExporterListenKey = "SQUID_EXPORTER_LISTEN"
squidExporterWebConfigPathKey = "SQUID_EXPORTER_WEB_CONFIG_PATH"
squidExporterMetricsPathKey = "SQUID_EXPORTER_METRICS_PATH"
squidHostnameKey = "SQUID_HOSTNAME"
squidPortKey = "SQUID_PORT"
squidLoginKey = "SQUID_LOGIN"
squidPasswordKey = "SQUID_PASSWORD"
squidPidfile = "SQUID_PIDFILE"
squidExtractServiceTimes = "SQUID_EXTRACTSERVICETIMES"
squidUseProxyHeader = "SQUID_USE_PROXY_HEADER"
)
var (
VersionFlag *bool
)
type Labels struct {
Keys []string
Values []string
}
// Config configurations for exporter.
type Config struct {
ListenAddress string
WebConfigPath string
MetricPath string
Labels Labels
ExtractServiceTimes bool
SquidHostname string
SquidPort int
Login string
Password string
Pidfile string
UseProxyHeader bool
}
// NewConfig creates a new config object from command line args.
func NewConfig() *Config {
c := &Config{}
flag.StringVar(&c.ListenAddress, "listen",
loadEnvStringVar(squidExporterListenKey, defaultListenAddress), "Address and Port to bind exporter, in host:port format")
flag.StringVar(&c.WebConfigPath, "web.config.file", loadEnvStringVar(squidExporterWebConfigPathKey, defaultWebConfigPath),
"Path to configuration file that can enable TLS or authentication. See: https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md")
flag.StringVar(&c.MetricPath, "metrics-path",
loadEnvStringVar(squidExporterMetricsPathKey, defaultMetricsPath), "Metrics path to expose prometheus metrics")
flag.BoolVar(&c.ExtractServiceTimes, "extractservicetimes",
loadEnvBoolVar(squidExtractServiceTimes, defaultExtractServiceTimes), "Extract service times metrics")
flag.Var(&c.Labels, "label", "Custom metrics to attach to metrics, use -label multiple times for each additional label")
flag.StringVar(&c.SquidHostname, "squid-hostname",
loadEnvStringVar(squidHostnameKey, defaultSquidHostname), "Squid hostname")
flag.IntVar(&c.SquidPort, "squid-port",
loadEnvIntVar(squidPortKey, defaultSquidPort), "Squid port to read metrics")
flag.StringVar(&c.Login, "squid-login", loadEnvStringVar(squidLoginKey, ""), "Login to squid service")
flag.StringVar(&c.Password, "squid-password", loadEnvStringVar(squidPasswordKey, ""), "Password to squid service")
flag.StringVar(&c.Pidfile, "squid-pidfile", loadEnvStringVar(squidPidfile, ""), "Optional path to the squid PID file for additional metrics")
flag.BoolVar(&c.UseProxyHeader, "squid-use-proxy-header",
loadEnvBoolVar(squidUseProxyHeader, defaultUseProxyHeader), "Use proxy headers when fetching metrics")
VersionFlag = flag.Bool("version", false, "Print the version and exit")
flag.Parse()
return c
}
func loadEnvBoolVar(key string, def bool) bool {
val := os.Getenv(key)
if val == "" {
return def
}
switch strings.ToLower(val) {
case "true":
return true
case "false":
return false
default:
return def
}
}
func loadEnvStringVar(key, def string) string {
val := os.Getenv(key)
if val == "" {
return def
}
return val
}
func loadEnvIntVar(key string, def int) int {
valStr := os.Getenv(key)
if valStr != "" {
val, err := strconv.ParseInt(valStr, 0, 32)
if err == nil {
return int(val)
}
log.Printf("Error parsing %s='%s'. Integer value expected", key, valStr)
}
return def
}
func (l *Labels) String() string {
var lbls []string
for i := range l.Keys {
lbls = append(lbls, l.Keys[i]+"="+l.Values[i])
}
return strings.Join(lbls, ", ")
}
func (l *Labels) Set(value string) error {
args := strings.Split(value, "=")
if len(args) != 2 || len(args[1]) < 1 {
return errors.New("label must be in 'key=value' format")
}
for _, key := range l.Keys {
if key == args[0] {
return fmt.Errorf("labels must be distinct; found duplicate key %q", args[0])
}
}
l.Keys = append(l.Keys, args[0])
l.Values = append(l.Values, args[1])
return nil
}
|