implement new collector for textfile metrics

This commit is contained in:
Hector 2021-10-11 21:42:52 +01:00
parent d81d494f19
commit 3384cc92e7
5 changed files with 127 additions and 2 deletions

View File

@ -46,8 +46,11 @@ func (settings *AppSettings) validateFlags() {
minServerPort, maxServerPort, settings.MetricsPort)
flagsValid = false
}
if settings.FileCollectorPath != "" {
settings.FileCollectorEnabled = true
}
if settings.FileCollectorEnabled && settings.FileCollectorPath == "" {
fmt.Printf("file collector directory must not be empty if collector enabled\n")
fmt.Printf("file collector directory path must not be empty if collector enabled\n")
flagsValid = false
}
}

View File

@ -3,6 +3,7 @@ package main
import (
"fail2ban-prometheus-exporter/cfg"
"fail2ban-prometheus-exporter/export"
"fail2ban-prometheus-exporter/textfile"
"fmt"
"log"
"net/http"
@ -43,6 +44,11 @@ func rootHtmlHandler(w http.ResponseWriter, r *http.Request) {
}
}
func metricHandler(w http.ResponseWriter, r *http.Request, collector *textfile.Collector) {
promhttp.Handler().ServeHTTP(w, r)
collector.WriteTextFileMetrics(w, r)
}
func main() {
appSettings := cfg.Parse()
if appSettings.VersionMode {
@ -55,8 +61,13 @@ func main() {
exporter := export.NewExporter(appSettings, version)
prometheus.MustRegister(exporter)
textFileCollector := textfile.NewCollector(appSettings)
prometheus.MustRegister(textFileCollector)
http.HandleFunc("/", rootHtmlHandler)
http.Handle(metricsPath, promhttp.Handler())
http.HandleFunc(metricsPath, func(w http.ResponseWriter, r *http.Request) {
metricHandler(w, r, textFileCollector)
})
log.Printf("metrics available at '%s'", metricsPath)
svrErr := make(chan error)

36
src/textfile/collector.go Normal file
View File

@ -0,0 +1,36 @@
package textfile
import (
"fail2ban-prometheus-exporter/cfg"
"github.com/prometheus/client_golang/prometheus"
)
type Collector struct {
enabled bool
folderPath string
fileMap map[string]fileMetrics
}
type fileMetrics struct {
readErrors int
}
func NewCollector(appSettings *cfg.AppSettings) *Collector {
return &Collector{
enabled: appSettings.FileCollectorEnabled,
folderPath: appSettings.FileCollectorPath,
fileMap: make(map[string]fileMetrics),
}
}
func (c *Collector) Describe(ch chan<- *prometheus.Desc) {
if c.enabled {
ch <- metricReadError
}
}
func (c *Collector) Collect(ch chan<- prometheus.Metric) {
if c.enabled {
c.collectFileErrors(ch)
}
}

21
src/textfile/file.go Normal file
View File

@ -0,0 +1,21 @@
package textfile
import "github.com/prometheus/client_golang/prometheus"
const namespace = "textfile"
var (
metricReadError = prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "error"),
"Checks for errors while reading text files",
[]string{"path"}, nil,
)
)
func (c *Collector) collectFileErrors(ch chan<- prometheus.Metric) {
for fileName, metrics := range c.fileMap {
ch <- prometheus.MustNewConstMetric(
metricReadError, prometheus.GaugeValue, float64(metrics.readErrors), fileName,
)
}
}

54
src/textfile/writer.go Normal file
View File

@ -0,0 +1,54 @@
package textfile
import (
"io/ioutil"
"log"
"net/http"
"path/filepath"
"strings"
)
func (c *Collector) WriteTextFileMetrics(w http.ResponseWriter, r *http.Request) {
files, err := ioutil.ReadDir(c.folderPath)
if err != nil {
c.appendErrorForPath(c.folderPath)
log.Printf("error reading directory '%s': %v", c.folderPath, err)
return
}
for _, file := range files {
fileName := file.Name()
if !strings.HasSuffix(fileName, ".prom") {
continue
}
c.setErrorCountForPath(fileName, 0)
fullPath := filepath.Join(c.folderPath, file.Name())
content, err := ioutil.ReadFile(fullPath)
if err != nil {
c.appendErrorForPath(fileName)
log.Printf("error reading contents of file '%s': %v", fileName, err)
}
_, err = w.Write(content)
if err != nil {
c.appendErrorForPath(fileName)
log.Printf("error writing file contents to response writer '%s': %v", fileName, err)
}
}
}
func (c *Collector) appendErrorForPath(path string) {
if _, ok := c.fileMap[path]; !ok {
c.setErrorCountForPath(path, 1)
} else {
c.setErrorCountForPath(path, c.fileMap[path].readErrors + 1)
}
}
func (c *Collector) setErrorCountForPath(path string, count int) {
c.fileMap[path] = fileMetrics{
readErrors: count,
}
}