From 4f18bf35a8b13ee6a10b0af12587ba5f5284acb6 Mon Sep 17 00:00:00 2001 From: Hector Date: Sat, 6 Feb 2021 15:17:35 +0000 Subject: [PATCH] feat: add cli parameters for db path and metrics port (#4) Add support for configuring CLI parameters in the application using a new `cfg` package. The `cfg` package exports an `AppSettings` struct that contains the settings the application was run with. Update the application to use the new CLI parameters to set the db to open and the port to use for the metrics server. Add support for setting the app version during build. The app includes a `-version` flag to print the stored version data. --- cfg/cfg.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ db/db.go | 2 +- exporter.go | 49 ++++++++++++++++++++++++++++++++++--------------- 3 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 cfg/cfg.go diff --git a/cfg/cfg.go b/cfg/cfg.go new file mode 100644 index 0000000..e1ad5db --- /dev/null +++ b/cfg/cfg.go @@ -0,0 +1,48 @@ +package cfg + +import ( + "flag" + "fmt" + "os" +) + +const ( + minServerPort = 1000 + maxServerPort = 65535 +) + +type AppSettings struct { + VersionMode bool + MetricsPort int + Fail2BanDbPath string +} + +func Parse() *AppSettings { + appSettings := &AppSettings{} + flag.BoolVar(&appSettings.VersionMode, "version", false, "show version info and exit") + flag.IntVar(&appSettings.MetricsPort, "port", 9191, "port to use for the metrics server") + flag.StringVar(&appSettings.Fail2BanDbPath, "db", "", "path to the fail2ban sqlite database") + + flag.Parse() + appSettings.validateFlags() + return appSettings +} + +func (settings *AppSettings) validateFlags() { + var flagsValid = true + if !settings.VersionMode { + if settings.Fail2BanDbPath == "" { + fmt.Println("missing flag 'db'") + flagsValid = false + } + if settings.MetricsPort < minServerPort || settings.MetricsPort > maxServerPort { + fmt.Printf("invalid server port, must be within %d and %d (found %d)\n", + minServerPort, maxServerPort, settings.MetricsPort) + flagsValid = false + } + } + if !flagsValid { + flag.Usage() + os.Exit(1) + } +} diff --git a/db/db.go b/db/db.go index cd425c4..0d92edc 100644 --- a/db/db.go +++ b/db/db.go @@ -10,7 +10,7 @@ const queryBannedIpsPerJail = "SELECT j.name, (SELECT COUNT(1) FROM bans b WHERE type Fail2BanDB struct { DatabasePath string - sqliteDB *sql.DB + sqliteDB *sql.DB } func MustConnectToDb(databasePath string) *Fail2BanDB { diff --git a/exporter.go b/exporter.go index 19b2d7d..df968c0 100644 --- a/exporter.go +++ b/exporter.go @@ -1,7 +1,9 @@ package main import ( + "fail2ban-prometheus-exporter/cfg" fail2banDb "fail2ban-prometheus-exporter/db" + "fmt" _ "github.com/mattn/go-sqlite3" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -12,7 +14,11 @@ import ( const namespace = "fail2ban" var ( - db = fail2banDb.MustConnectToDb("fail2ban.sqlite3") + version = "dev" + commit = "none" + date = "unknown" + builtBy = "unknown" + metricUp = prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "up"), "Was the last fail2ban query successful.", @@ -31,6 +37,7 @@ var ( ) type Exporter struct { + db *fail2banDb.Fail2BanDB } func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { @@ -43,12 +50,12 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) { ch <- prometheus.MustNewConstMetric( metricUp, prometheus.GaugeValue, 1, ) - collectBadIpsPerJailMetrics(ch) - collectBannedIpsPerJailMetrics(ch) + e.collectBadIpsPerJailMetrics(ch) + e.collectBannedIpsPerJailMetrics(ch) } -func collectBadIpsPerJailMetrics(ch chan<- prometheus.Metric) { - jailNameToCountMap, err := db.CountBadIpsPerJail() +func (e *Exporter) collectBadIpsPerJailMetrics(ch chan<- prometheus.Metric) { + jailNameToCountMap, err := e.db.CountBadIpsPerJail() if err != nil { log.Print(err) } @@ -60,8 +67,8 @@ func collectBadIpsPerJailMetrics(ch chan<- prometheus.Metric) { } } -func collectBannedIpsPerJailMetrics(ch chan<- prometheus.Metric) { - jailNameToCountMap, err := db.CountBannedIpsPerJail() +func (e *Exporter) collectBannedIpsPerJailMetrics(ch chan<- prometheus.Metric) { + jailNameToCountMap, err := e.db.CountBannedIpsPerJail() if err != nil { log.Print(err) } @@ -73,12 +80,24 @@ func collectBannedIpsPerJailMetrics(ch chan<- prometheus.Metric) { } } -func main() { - log.Print("starting fail2ban exporter") - - exporter := &Exporter{} - prometheus.MustRegister(exporter) - - http.Handle("/metrics", promhttp.Handler()) - log.Fatal(http.ListenAndServe(":9101", nil)) +func printAppVersion() { + fmt.Println(version) + fmt.Printf(" build date: %s\r\n commit hash: %s\r\n built by: %s\r\n", date, commit, builtBy) +} + +func main() { + appSettings := cfg.Parse() + if appSettings.VersionMode { + printAppVersion() + } else { + log.Print("starting fail2ban exporter") + + exporter := &Exporter{ + db: fail2banDb.MustConnectToDb(appSettings.Fail2BanDbPath), + } + prometheus.MustRegister(exporter) + + http.Handle("/metrics", promhttp.Handler()) + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", appSettings.MetricsPort), nil)) + } }