You've already forked prometheus-fail2ban-exporter
							
							implement new collector for textfile metrics
This commit is contained in:
		@@ -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
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
								
							
							
						
						
									
										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,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user