implement new collector for textfile metrics
This commit is contained in:
parent
d81d494f19
commit
3384cc92e7
@ -46,8 +46,11 @@ func (settings *AppSettings) validateFlags() {
|
|||||||
minServerPort, maxServerPort, settings.MetricsPort)
|
minServerPort, maxServerPort, settings.MetricsPort)
|
||||||
flagsValid = false
|
flagsValid = false
|
||||||
}
|
}
|
||||||
|
if settings.FileCollectorPath != "" {
|
||||||
|
settings.FileCollectorEnabled = true
|
||||||
|
}
|
||||||
if settings.FileCollectorEnabled && settings.FileCollectorPath == "" {
|
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
|
flagsValid = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fail2ban-prometheus-exporter/cfg"
|
"fail2ban-prometheus-exporter/cfg"
|
||||||
"fail2ban-prometheus-exporter/export"
|
"fail2ban-prometheus-exporter/export"
|
||||||
|
"fail2ban-prometheus-exporter/textfile"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"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() {
|
func main() {
|
||||||
appSettings := cfg.Parse()
|
appSettings := cfg.Parse()
|
||||||
if appSettings.VersionMode {
|
if appSettings.VersionMode {
|
||||||
@ -55,8 +61,13 @@ func main() {
|
|||||||
exporter := export.NewExporter(appSettings, version)
|
exporter := export.NewExporter(appSettings, version)
|
||||||
prometheus.MustRegister(exporter)
|
prometheus.MustRegister(exporter)
|
||||||
|
|
||||||
|
textFileCollector := textfile.NewCollector(appSettings)
|
||||||
|
prometheus.MustRegister(textFileCollector)
|
||||||
|
|
||||||
http.HandleFunc("/", rootHtmlHandler)
|
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)
|
log.Printf("metrics available at '%s'", metricsPath)
|
||||||
|
|
||||||
svrErr := make(chan error)
|
svrErr := make(chan error)
|
||||||
|
36
src/textfile/collector.go
Normal file
36
src/textfile/collector.go
Normal 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
21
src/textfile/file.go
Normal 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
54
src/textfile/writer.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user