diff --git a/README.md b/README.md index eb60169..2795f9b 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This exporter collects metrics from a running fail2ban instance. Once the exporter is running, metrics are available at `localhost:9191/metrics`. -(The default port is `9191` but can be modified with the `--port` flag) +(The default port is `9191` but can be modified with the `--web.listen-address` flag) The exporter communicates with the fail2ban server over its socket. This allows the data collected by the exporter to always align with the output of the `fail2ban-client`. @@ -38,22 +38,21 @@ See the [releases page](https://gitlab.com/hectorjsmith/fail2ban-prometheus-expo **CLI Usage** ``` $ fail2ban-prometheus-exporter -h -usage: exporter [] +usage: fail2ban-prometheus-exporter [] Flags: - -h, --help Show context-sensitive help (also try --help-long and --help-man). - --version show version info and exit - --port=9191 port to use for the metrics server - --web.listen-address="0.0.0.0" - address to use for the metrics server - --socket="" path to the fail2ban server socket - --collector.textfile enable the textfile collector - --collector.textfile.directory="" - directory to read text files with metrics from - --web.basic-auth.username="" - username to use to protect endpoints with basic auth - --web.basic-auth.password="" - password to use to protect endpoints with basic auth + -h, --help Show context-sensitive help (also try --help-long and --help-man). + -v, --version show version info and exit + --collector.f2b.socket="/var/run/fail2ban/fail2ban.sock" + path to the fail2ban server socket + --collector.textfile.directory="" + directory to read text files with metrics from + --web.listen-address=":9191" + address to use for the metrics server + --web.basic-auth.username="" + username to use to protect endpoints with basic auth + --web.basic-auth.password="" + password to use to protect endpoints with basic auth ``` **Environment variables** @@ -62,9 +61,7 @@ The tool can also be configured using environment variables. Each CLI parameter ``` F2B_COLLECTOR_SOCKET -F2B_COLLECTOR_TEXT F2B_COLLECTOR_TEXT_PATH -F2B_WEB_PORT F2B_WEB_LISTEN_ADDRESS F2B_WEB_BASICAUTH_USER F2B_WEB_BASICAUTH_PASS @@ -73,7 +70,7 @@ F2B_WEB_BASICAUTH_PASS **Example** ``` -fail2ban-prometheus-exporter --socket /var/run/fail2ban/fail2ban.sock --port 9191 +fail2ban-prometheus-exporter --collector.f2b.socket=/var/run/fail2ban/fail2ban.sock --web.listen-address=":9191" ``` Note that the exporter will need read access to the fail2ban socket. @@ -232,9 +229,7 @@ Status for the jail: sshd|- Filter For more flexibility the exporter also allows exporting metrics collected from a text file. -To enable textfile metrics: -1. Enable the collector with `--collector.textfile=true` -2. Provide the directory to read files from with the `--collector.textfile.directory` flag +To enable textfile metrics provide the directory to read files from with the `--collector.textfile.directory` flag. Metrics collected from these files will be exposed directly alongside the other metrics without any additional processing. This means that it is the responsibility of the file creator to ensure the format is correct. @@ -252,8 +247,8 @@ textfile_error{path="file.prom"} 0 **Running in Docker** To collect textfile metrics inside a docker container, a couple of things need to be done: -1. Mount the folder with the metrics -2. Set the relevant environment variables +1. Mount the folder with the metrics files +2. Set the `F2B_COLLECTOR_TEXT_PATH` environment variable *For example:* ``` @@ -261,7 +256,6 @@ docker run -d \ --name "fail2ban-exporter" \ -v /var/run/fail2ban:/var/run/fail2ban:ro \ -v /path/to/metrics:/app/metrics/:ro \ - -e F2B_COLLECTOR_TEXT=true \ -e F2B_COLLECTOR_TEXT_PATH=/app/metrics \ -p "9191:9191" \ registry.gitlab.com/hectorjsmith/fail2ban-prometheus-exporter:latest diff --git a/src/cfg/cfg.go b/src/cfg/cfg.go index 2f584a3..842e12a 100644 --- a/src/cfg/cfg.go +++ b/src/cfg/cfg.go @@ -7,25 +7,19 @@ import ( ) const ( - minServerPort = 1000 - maxServerPort = 65535 - socketEnvName = "F2B_COLLECTOR_SOCKET" - fileCollectorEnabledEnvName = "F2B_COLLECTOR_TEXT" - fileCollectorPathEnvName = "F2B_COLLECTOR_TEXT_PATH" - portEnvName = "F2B_WEB_PORT" - addressEnvName = "F2B_WEB_LISTEN_ADDRESS" - basicAuthUserEnvName = "F2B_WEB_BASICAUTH_USER" - basicAuthPassEnvName = "F2B_WEB_BASICAUTH_PASS" + socketEnvName = "F2B_COLLECTOR_SOCKET" + fileCollectorPathEnvName = "F2B_COLLECTOR_TEXT_PATH" + addressEnvName = "F2B_WEB_LISTEN_ADDRESS" + basicAuthUserEnvName = "F2B_WEB_BASICAUTH_USER" + basicAuthPassEnvName = "F2B_WEB_BASICAUTH_PASS" ) type AppSettings struct { - VersionMode bool - MetricsAddress string - MetricsPort int - Fail2BanSocketPath string - FileCollectorPath string - FileCollectorEnabled bool - BasicAuthProvider *hashedBasicAuth + VersionMode bool + MetricsAddress string + Fail2BanSocketPath string + FileCollectorPath string + BasicAuthProvider *hashedBasicAuth } func init() { @@ -42,31 +36,22 @@ func Parse() *AppSettings { func readParamsFromCli(settings *AppSettings) { versionMode := kingpin. Flag("version", "show version info and exit"). + Short('v'). Default("false"). Bool() socketPath := kingpin. - Flag("socket", "path to the fail2ban server socket"). + Flag("collector.f2b.socket", "path to the fail2ban server socket"). Default("/var/run/fail2ban/fail2ban.sock"). Envar(socketEnvName). String() - fileCollectorEnabled := kingpin. - Flag("collector.textfile", "enable the textfile collector"). - Default("false"). - Envar(fileCollectorEnabledEnvName). - Bool() fileCollectorPath := kingpin. Flag("collector.textfile.directory", "directory to read text files with metrics from"). Default(""). Envar(fileCollectorPathEnvName). String() - port := kingpin. - Flag("port", "port to use for the metrics server"). - Default("9191"). - Envar(portEnvName). - Int() address := kingpin. Flag("web.listen-address", "address to use for the metrics server"). - Default("0.0.0.0"). + Default(":9191"). Envar(addressEnvName). String() rawBasicAuthUsername := kingpin. @@ -83,10 +68,8 @@ func readParamsFromCli(settings *AppSettings) { kingpin.Parse() settings.VersionMode = *versionMode - settings.MetricsPort = *port settings.MetricsAddress = *address settings.Fail2BanSocketPath = *socketPath - settings.FileCollectorEnabled = *fileCollectorEnabled settings.FileCollectorPath = *fileCollectorPath settings.setBasicAuthValues(*rawBasicAuthUsername, *rawBasicAuthPassword) } @@ -102,13 +85,8 @@ func (settings *AppSettings) validateFlags() { fmt.Println("error: fail2ban socket path must not be blank") flagsValid = false } - if settings.MetricsPort < minServerPort || settings.MetricsPort > maxServerPort { - fmt.Printf("error: invalid server port, must be within %d and %d (found %d)\n", - minServerPort, maxServerPort, settings.MetricsPort) - flagsValid = false - } - if settings.FileCollectorEnabled && settings.FileCollectorPath == "" { - fmt.Println("error: file collector directory path must not be empty if collector enabled") + if settings.MetricsAddress == "" { + fmt.Println("error: invalid server address, must not be blank") flagsValid = false } if (len(settings.BasicAuthProvider.username) > 0) != (len(settings.BasicAuthProvider.password) > 0) { diff --git a/src/collector/textfile/collector.go b/src/collector/textfile/collector.go index d5b3a71..0acc5a2 100644 --- a/src/collector/textfile/collector.go +++ b/src/collector/textfile/collector.go @@ -20,7 +20,7 @@ type fileData struct { func NewCollector(appSettings *cfg.AppSettings) *Collector { collector := &Collector{ - enabled: appSettings.FileCollectorEnabled, + enabled: appSettings.FileCollectorPath != "", folderPath: appSettings.FileCollectorPath, fileMap: make(map[string]*fileData), } diff --git a/src/exporter.go b/src/exporter.go index adf4518..ff357d2 100644 --- a/src/exporter.go +++ b/src/exporter.go @@ -54,9 +54,8 @@ func main() { if appSettings.VersionMode { printAppVersion() } else { - addr := fmt.Sprintf("%s:%d", appSettings.MetricsAddress, appSettings.MetricsPort) log.Printf("fail2ban exporter version %s", version) - log.Printf("starting server at %s", addr) + log.Printf("starting server at %s", appSettings.MetricsAddress) f2bCollector := f2b.NewExporter(appSettings, version) prometheus.MustRegister(f2bCollector) @@ -78,7 +77,7 @@ func main() { svrErr := make(chan error) go func() { - svrErr <- http.ListenAndServe(addr, nil) + svrErr <- http.ListenAndServe(appSettings.MetricsAddress, nil) }() log.Print("ready")