remove: database-based metrics

Remove all database-based metrics from the metrics endpoint.
Remove all code related to pulling metrics from the fail2ban database.
Remove all configuration variables related to the fail2ban database.
The CLI parameter for the database path was not removed to avoid breaking
compatibility.
This commit is contained in:
Hector 2021-10-15 17:57:09 +01:00
parent 025347b7ca
commit 39ec8633d5
5 changed files with 28 additions and 245 deletions

View File

@ -14,7 +14,6 @@ const (
type AppSettings struct {
VersionMode bool
MetricsPort int
Fail2BanDbPath string
Fail2BanSocketPath string
FileCollectorPath string
FileCollectorEnabled bool
@ -24,11 +23,13 @@ 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 (deprecated)")
flag.StringVar(&appSettings.Fail2BanSocketPath, "socket", "", "path to the fail2ban server socket")
flag.BoolVar(&appSettings.FileCollectorEnabled, "collector.textfile", false, "enable the textfile collector")
flag.StringVar(&appSettings.FileCollectorPath, "collector.textfile.directory", "", "directory to read text files with metrics from")
// deprecated: to be removed in next version
_ = flag.String("db", "", "path to the fail2ban sqlite database (removed)")
flag.Parse()
appSettings.validateFlags()
return appSettings
@ -37,8 +38,8 @@ func Parse() *AppSettings {
func (settings *AppSettings) validateFlags() {
var flagsValid = true
if !settings.VersionMode {
if settings.Fail2BanDbPath == "" && settings.Fail2BanSocketPath == "" {
fmt.Println("at least one of the following flags must be provided: 'db', 'socket'")
if settings.Fail2BanSocketPath == "" {
fmt.Println("fail2ban socket path must not be blank")
flagsValid = false
}
if settings.MetricsPort < minServerPort || settings.MetricsPort > maxServerPort {

View File

@ -2,14 +2,12 @@ package f2b
import (
"fail2ban-prometheus-exporter/cfg"
fail2banDb "fail2ban-prometheus-exporter/db"
"fail2ban-prometheus-exporter/socket"
"github.com/prometheus/client_golang/prometheus"
"log"
)
type Collector struct {
db *fail2banDb.Fail2BanDB
socketPath string
exporterVersion string
lastError error
@ -19,65 +17,39 @@ type Collector struct {
}
func NewExporter(appSettings *cfg.AppSettings, exporterVersion string) *Collector {
colector := &Collector{
return &Collector{
socketPath: appSettings.Fail2BanSocketPath,
exporterVersion: exporterVersion,
lastError: nil,
dbErrorCount: 0,
socketConnectionErrorCount: 0,
socketRequestErrorCount: 0,
}
if appSettings.Fail2BanDbPath != "" {
log.Print("database-based metrics have been deprecated and will be removed in a future release")
colector.db = fail2banDb.MustConnectToDb(appSettings.Fail2BanDbPath)
}
if appSettings.Fail2BanSocketPath != "" {
colector.socketPath = appSettings.Fail2BanSocketPath
}
return colector
}
func (c *Collector) Describe(ch chan<- *prometheus.Desc) {
if c.db != nil {
ch <- deprecatedMetricUp
ch <- deprecatedMetricBadIpsPerJail
ch <- deprecatedMetricBannedIpsPerJail
ch <- deprecatedMetricEnabledJails
ch <- deprecatedMetricErrorCount
}
if c.socketPath != "" {
ch <- metricServerUp
ch <- metricJailCount
ch <- metricJailFailedCurrent
ch <- metricJailFailedTotal
ch <- metricJailBannedCurrent
ch <- metricJailBannedTotal
}
ch <- metricServerUp
ch <- metricJailCount
ch <- metricJailFailedCurrent
ch <- metricJailFailedTotal
ch <- metricJailBannedCurrent
ch <- metricJailBannedTotal
ch <- metricErrorCount
}
func (c *Collector) Collect(ch chan<- prometheus.Metric) {
if c.db != nil {
c.collectDeprecatedBadIpsPerJailMetrics(ch)
c.collectDeprecatedBannedIpsPerJailMetrics(ch)
c.collectDeprecatedEnabledJailMetrics(ch)
c.collectDeprecatedUpMetric(ch)
c.collectDeprecatedErrorCountMetric(ch)
}
if c.socketPath != "" {
s, err := socket.ConnectToSocket(c.socketPath)
if err != nil {
log.Printf("error opening socket: %v", err)
c.socketConnectionErrorCount++
} else {
defer s.Close()
}
c.collectServerUpMetric(ch, s)
if err == nil && s != nil {
c.collectJailMetrics(ch, s)
}
c.collectVersionMetric(ch, s)
s, err := socket.ConnectToSocket(c.socketPath)
if err != nil {
log.Printf("error opening socket: %v", err)
c.socketConnectionErrorCount++
} else {
c.collectVersionMetric(ch, nil)
defer s.Close()
}
c.collectServerUpMetric(ch, s)
if err == nil && s != nil {
c.collectJailMetrics(ch, s)
c.collectVersionMetric(ch, s)
}
c.collectErrorCountMetric(ch)
}

View File

@ -1,102 +0,0 @@
package f2b
import (
"github.com/prometheus/client_golang/prometheus"
"log"
)
const (
deprecatedNamespace = "fail2ban"
)
var (
deprecatedMetricUp = prometheus.NewDesc(
prometheus.BuildFQName(deprecatedNamespace, "", "up"),
"(Deprecated) Was the last fail2ban query successful.",
nil, nil,
)
deprecatedMetricBannedIpsPerJail = prometheus.NewDesc(
prometheus.BuildFQName(deprecatedNamespace, "", "banned_ips"),
"(Deprecated) Number of banned IPs stored in the database (per jail).",
[]string{"jail"}, nil,
)
deprecatedMetricBadIpsPerJail = prometheus.NewDesc(
prometheus.BuildFQName(deprecatedNamespace, "", "bad_ips"),
"(Deprecated) Number of bad IPs stored in the database (per jail).",
[]string{"jail"}, nil,
)
deprecatedMetricEnabledJails = prometheus.NewDesc(
prometheus.BuildFQName(deprecatedNamespace, "", "enabled_jails"),
"(Deprecated) Enabled jails.",
[]string{"jail"}, nil,
)
deprecatedMetricErrorCount = prometheus.NewDesc(
prometheus.BuildFQName(deprecatedNamespace, "", "errors"),
"(Deprecated) Number of errors found since startup.",
[]string{"type"}, nil,
)
)
func (c *Collector) collectDeprecatedUpMetric(ch chan<- prometheus.Metric) {
var upMetricValue float64 = 1
if c.lastError != nil {
upMetricValue = 0
}
ch <- prometheus.MustNewConstMetric(
deprecatedMetricUp, prometheus.GaugeValue, upMetricValue,
)
}
func (c *Collector) collectDeprecatedErrorCountMetric(ch chan<- prometheus.Metric) {
ch <- prometheus.MustNewConstMetric(
deprecatedMetricErrorCount, prometheus.CounterValue, float64(c.dbErrorCount), "db",
)
}
func (c *Collector) collectDeprecatedBadIpsPerJailMetrics(ch chan<- prometheus.Metric) {
jailNameToCountMap, err := c.db.CountBadIpsPerJail()
c.lastError = err
if err != nil {
c.dbErrorCount++
log.Print(err)
}
for jailName, count := range jailNameToCountMap {
ch <- prometheus.MustNewConstMetric(
deprecatedMetricBadIpsPerJail, prometheus.GaugeValue, float64(count), jailName,
)
}
}
func (c *Collector) collectDeprecatedBannedIpsPerJailMetrics(ch chan<- prometheus.Metric) {
jailNameToCountMap, err := c.db.CountBannedIpsPerJail()
c.lastError = err
if err != nil {
c.dbErrorCount++
log.Print(err)
}
for jailName, count := range jailNameToCountMap {
ch <- prometheus.MustNewConstMetric(
deprecatedMetricBannedIpsPerJail, prometheus.GaugeValue, float64(count), jailName,
)
}
}
func (c *Collector) collectDeprecatedEnabledJailMetrics(ch chan<- prometheus.Metric) {
jailNameToEnabledMap, err := c.db.JailNameToEnabledValue()
c.lastError = err
if err != nil {
c.dbErrorCount++
log.Print(err)
}
for jailName, count := range jailNameToEnabledMap {
ch <- prometheus.MustNewConstMetric(
deprecatedMetricEnabledJails, prometheus.GaugeValue, float64(count), jailName,
)
}
}

View File

@ -170,14 +170,10 @@ func (c *Collector) collectJailConfigMetrics(ch chan<- prometheus.Metric, s *soc
}
func (c *Collector) collectVersionMetric(ch chan<- prometheus.Metric, s *socket.Fail2BanSocket) {
var err error
var fail2banVersion = ""
if s != nil {
fail2banVersion, err = s.GetServerVersion()
if err != nil {
c.socketRequestErrorCount++
log.Printf("failed to get fail2ban server version: %v", err)
}
fail2banVersion, err := s.GetServerVersion()
if err != nil {
c.socketRequestErrorCount++
log.Printf("failed to get fail2ban server version: %v", err)
}
ch <- prometheus.MustNewConstMetric(

View File

@ -1,84 +0,0 @@
package db
import (
"database/sql"
"log"
"os"
)
const queryBadIpsPerJail = "SELECT j.name, (SELECT COUNT(1) FROM bips b WHERE j.name = b.jail) FROM jails j"
const queryBannedIpsPerJail = "SELECT j.name, (SELECT COUNT(1) FROM bans b WHERE j.name = b.jail AND b.timeofban + b.bantime >= strftime('%s','now') + 0) FROM jails j"
const queryJailNameToEnabled = "SELECT j.name, j.enabled FROM jails j"
type Fail2BanDB struct {
DatabasePath string
sqliteDB *sql.DB
}
func MustConnectToDb(databasePath string) *Fail2BanDB {
if _, err := os.Stat(databasePath); os.IsNotExist(err) {
log.Fatalf("database path does not exist: %v", err)
}
db, err := sql.Open("sqlite3", databasePath)
if err != nil {
log.Fatal(err)
}
return &Fail2BanDB{
DatabasePath: databasePath,
sqliteDB: db,
}
}
func (db *Fail2BanDB) CountBannedIpsPerJail() (map[string]int, error) {
return db.RunJailNameToCountQuery(queryBannedIpsPerJail)
}
func (db *Fail2BanDB) CountBadIpsPerJail() (map[string]int, error) {
return db.RunJailNameToCountQuery(queryBadIpsPerJail)
}
func (db *Fail2BanDB) JailNameToEnabledValue() (map[string]int, error) {
return db.RunJailNameToCountQuery(queryJailNameToEnabled)
}
func (db *Fail2BanDB) RunJailNameToCountQuery(query string) (map[string]int, error) {
stmt, err := db.sqliteDB.Prepare(query)
defer db.mustCloseStatement(stmt)
if err != nil {
return nil, err
}
jailNameToCountMap := map[string]int{}
rows, err := stmt.Query()
if err != nil {
return nil, err
}
if rows == nil {
return jailNameToCountMap, nil
}
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) {
if stmt != nil {
err := stmt.Close()
if err != nil {
log.Fatal(err)
}
}
}