diff --git a/db/db.go b/db/db.go index 86a29fe..f7146df 100644 --- a/db/db.go +++ b/db/db.go @@ -3,10 +3,9 @@ package db import ( "database/sql" "log" - "strconv" ) -const queryCountTotalBadIps = "SELECT COUNT(1) FROM bips" +const queryBadIpsPerJail = "SELECT jail, COUNT(1) FROM bips GROUP BY jail" type Fail2BanDB struct { DatabasePath string @@ -24,22 +23,37 @@ func MustConnectToDb(databasePath string) *Fail2BanDB { } } -func (db *Fail2BanDB) CountTotalBadIps() (int, error) { - stmt, err := db.sqliteDB.Prepare(queryCountTotalBadIps) +func (db *Fail2BanDB) CountBadIpsPerJail() (map[string]int, error) { + stmt, err := db.sqliteDB.Prepare(queryBadIpsPerJail) defer db.mustCloseStatement(stmt) if err != nil { - return -1, err + return nil, err } - result := "" - err = stmt.QueryRow().Scan(&result) - + jailNameToCountMap := map[string]int{} + rows, err := stmt.Query() if err != nil { - return -1, err + return nil, err + } + if rows == nil { + return jailNameToCountMap, nil } - return strconv.Atoi(result) + for rows.Next() { + if rows.Err() != nil { + return nil, err + } + jailName := "" + count := 0 + err = rows.Scan(&jailName, &count) + if err != nil { + return nil, err + } + + jailNameToCountMap[jailName] = count + } + return jailNameToCountMap, nil } func (db *Fail2BanDB) mustCloseStatement(stmt *sql.Stmt) { diff --git a/exporter.go b/exporter.go index 6cf2221..0fa3803 100644 --- a/exporter.go +++ b/exporter.go @@ -18,10 +18,10 @@ var ( "Was the last fail2ban query successful.", nil, nil, ) - metricBadIpTotal = prometheus.NewDesc( - prometheus.BuildFQName(namespace, "", "badip_total"), - "Total number of bad IPs stored in the database.", - nil, nil, + metricBadIpsPerJail = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "bad_ips"), + "Number of bad IPs stored in the database (per jail).", + []string{"jail"}, nil, ) ) @@ -30,22 +30,27 @@ type Exporter struct { func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { ch <- metricUp - ch <- metricBadIpTotal + ch <- metricBadIpsPerJail } func (e *Exporter) Collect(ch chan<- prometheus.Metric) { ch <- prometheus.MustNewConstMetric( metricUp, prometheus.GaugeValue, 1, ) - ch <- *collectTotalBadIpMetric() + collectBadIpsPerJailMetrics(ch) } -func collectTotalBadIpMetric() *prometheus.Metric { - count, _ := db.CountTotalBadIps() - metric := prometheus.MustNewConstMetric( - metricBadIpTotal, prometheus.GaugeValue, float64(count), - ) - return &metric +func collectBadIpsPerJailMetrics(ch chan<- prometheus.Metric) { + jailNameToCountMap, err := db.CountBadIpsPerJail() + if err != nil { + log.Print(err) + } + + for jailName, count := range jailNameToCountMap { + ch <- prometheus.MustNewConstMetric( + metricBadIpsPerJail, prometheus.GaugeValue, float64(count), jailName, + ) + } } func main() {