From d81d494f19bd26fbfe3004d3a647cb4eb4c0ab9c Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Mon, 11 Oct 2021 21:04:37 +0100 Subject: [PATCH 01/12] add cli options to enable the textfile collector --- src/cfg/cfg.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cfg/cfg.go b/src/cfg/cfg.go index 1b4ce49..b9c4f3e 100644 --- a/src/cfg/cfg.go +++ b/src/cfg/cfg.go @@ -16,6 +16,8 @@ type AppSettings struct { MetricsPort int Fail2BanDbPath string Fail2BanSocketPath string + FileCollectorPath string + FileCollectorEnabled bool } func Parse() *AppSettings { @@ -24,6 +26,8 @@ func Parse() *AppSettings { 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") flag.Parse() appSettings.validateFlags() @@ -42,6 +46,10 @@ func (settings *AppSettings) validateFlags() { minServerPort, maxServerPort, settings.MetricsPort) flagsValid = false } + if settings.FileCollectorEnabled && settings.FileCollectorPath == "" { + fmt.Printf("file collector directory must not be empty if collector enabled\n") + flagsValid = false + } } if !flagsValid { flag.Usage() From 3384cc92e796dfa77b99208a0ab6c990169c307e Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Mon, 11 Oct 2021 21:42:52 +0100 Subject: [PATCH 02/12] implement new collector for textfile metrics --- src/cfg/cfg.go | 5 +++- src/exporter.go | 13 +++++++++- src/textfile/collector.go | 36 ++++++++++++++++++++++++++ src/textfile/file.go | 21 +++++++++++++++ src/textfile/writer.go | 54 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 src/textfile/collector.go create mode 100644 src/textfile/file.go create mode 100644 src/textfile/writer.go diff --git a/src/cfg/cfg.go b/src/cfg/cfg.go index b9c4f3e..457a9b3 100644 --- a/src/cfg/cfg.go +++ b/src/cfg/cfg.go @@ -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 } } diff --git a/src/exporter.go b/src/exporter.go index b06ca2c..00fb395 100644 --- a/src/exporter.go +++ b/src/exporter.go @@ -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) diff --git a/src/textfile/collector.go b/src/textfile/collector.go new file mode 100644 index 0000000..1bcea12 --- /dev/null +++ b/src/textfile/collector.go @@ -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) + } +} diff --git a/src/textfile/file.go b/src/textfile/file.go new file mode 100644 index 0000000..8e587e2 --- /dev/null +++ b/src/textfile/file.go @@ -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, + ) + } +} diff --git a/src/textfile/writer.go b/src/textfile/writer.go new file mode 100644 index 0000000..7e49ce8 --- /dev/null +++ b/src/textfile/writer.go @@ -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, + } +} From 52468bb63ed3721e1ee8d4a1bd9c07ad540429f4 Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Mon, 11 Oct 2021 21:59:56 +0100 Subject: [PATCH 03/12] disable collector correctly --- src/cfg/cfg.go | 3 --- src/textfile/writer.go | 4 ++++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cfg/cfg.go b/src/cfg/cfg.go index 457a9b3..894c901 100644 --- a/src/cfg/cfg.go +++ b/src/cfg/cfg.go @@ -46,9 +46,6 @@ 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 path must not be empty if collector enabled\n") flagsValid = false diff --git a/src/textfile/writer.go b/src/textfile/writer.go index 7e49ce8..129df6a 100644 --- a/src/textfile/writer.go +++ b/src/textfile/writer.go @@ -9,6 +9,10 @@ import ( ) func (c *Collector) WriteTextFileMetrics(w http.ResponseWriter, r *http.Request) { + if !c.enabled { + return + } + files, err := ioutil.ReadDir(c.folderPath) if err != nil { c.appendErrorForPath(c.folderPath) From bb813d312df7ff3f16a08ea32e19e2b6c3b5de81 Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Tue, 12 Oct 2021 19:31:02 +0100 Subject: [PATCH 04/12] update docker entrypoint to support textfile exporter --- docker/run.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docker/run.sh b/docker/run.sh index 0739997..add11e4 100644 --- a/docker/run.sh +++ b/docker/run.sh @@ -5,6 +5,8 @@ db_path=/app/fail2ban.sqlite3 socket_path=/var/run/fail2ban/fail2ban.sock +textfile_dir=/app/textfile/ +textfile_enabled=false # Blank out the file paths if they do not exist - a hacky way to only use these files if they were mounted into the container. if [ ! -f "$db_path" ]; then @@ -13,9 +15,14 @@ fi if [ ! -S "$socket_path" ]; then socket_path="" fi +if [ -d $textfile_dir ]; then + textfile_enabled=true +fi # Start the exporter (use exec to support graceful shutdown) # Inspired by: https://akomljen.com/stopping-docker-containers-gracefully/ exec /app/fail2ban-prometheus-exporter \ -db "$db_path" \ - -socket "$socket_path" + -socket "$socket_path" \ + -collector.textfile=$textfile_enabled \ + -collector.textfile.directory="$textfile_dir" From 3302da1c920133dc0d62fa876be68173d7701a61 Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Tue, 12 Oct 2021 20:36:32 +0100 Subject: [PATCH 05/12] collect file contents before exporting metrics --- src/textfile/collector.go | 9 +++++--- src/textfile/file.go | 40 ++++++++++++++++++++++++++++++++--- src/textfile/writer.go | 44 +++++---------------------------------- 3 files changed, 48 insertions(+), 45 deletions(-) diff --git a/src/textfile/collector.go b/src/textfile/collector.go index 1bcea12..178d828 100644 --- a/src/textfile/collector.go +++ b/src/textfile/collector.go @@ -8,18 +8,20 @@ import ( type Collector struct { enabled bool folderPath string - fileMap map[string]fileMetrics + fileMap map[string]*fileData } -type fileMetrics struct { +type fileData struct { readErrors int + fileName string + fileContents []byte } func NewCollector(appSettings *cfg.AppSettings) *Collector { return &Collector{ enabled: appSettings.FileCollectorEnabled, folderPath: appSettings.FileCollectorPath, - fileMap: make(map[string]fileMetrics), + fileMap: make(map[string]*fileData), } } @@ -31,6 +33,7 @@ func (c *Collector) Describe(ch chan<- *prometheus.Desc) { func (c *Collector) Collect(ch chan<- prometheus.Metric) { if c.enabled { + c.collectFileContents() c.collectFileErrors(ch) } } diff --git a/src/textfile/file.go b/src/textfile/file.go index 8e587e2..1bdd378 100644 --- a/src/textfile/file.go +++ b/src/textfile/file.go @@ -1,6 +1,12 @@ package textfile -import "github.com/prometheus/client_golang/prometheus" +import ( + "github.com/prometheus/client_golang/prometheus" + "io/ioutil" + "log" + "path/filepath" + "strings" +) const namespace = "textfile" @@ -12,10 +18,38 @@ var ( ) ) +func (c *Collector) collectFileContents() { + files, err := ioutil.ReadDir(c.folderPath) + if err != nil { + 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.fileMap[fileName] = &fileData{ + readErrors: 0, + fileName: fileName, + } + + 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) + } + + c.fileMap[fileName].fileContents = content + } +} + func (c *Collector) collectFileErrors(ch chan<- prometheus.Metric) { - for fileName, metrics := range c.fileMap { + for _, f := range c.fileMap { ch <- prometheus.MustNewConstMetric( - metricReadError, prometheus.GaugeValue, float64(metrics.readErrors), fileName, + metricReadError, prometheus.GaugeValue, float64(f.readErrors), f.fileName, ) } } diff --git a/src/textfile/writer.go b/src/textfile/writer.go index 129df6a..9c6b13f 100644 --- a/src/textfile/writer.go +++ b/src/textfile/writer.go @@ -1,11 +1,8 @@ package textfile import ( - "io/ioutil" "log" "net/http" - "path/filepath" - "strings" ) func (c *Collector) WriteTextFileMetrics(w http.ResponseWriter, r *http.Request) { @@ -13,46 +10,15 @@ func (c *Collector) WriteTextFileMetrics(w http.ResponseWriter, r *http.Request) return } - 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) + for _, f := range c.fileMap { + _, err := w.Write(f.fileContents) 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) + c.appendErrorForPath(f.fileName) + log.Printf("error writing file contents to response writer '%s': %v", f.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, - } + c.fileMap[path].readErrors++ } From 3e56339c71e3c91ea4064e5ca4d77658ebf8e09d Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Tue, 12 Oct 2021 20:39:18 +0100 Subject: [PATCH 06/12] move function --- src/textfile/collector.go | 4 ++++ src/textfile/writer.go | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/textfile/collector.go b/src/textfile/collector.go index 178d828..863225b 100644 --- a/src/textfile/collector.go +++ b/src/textfile/collector.go @@ -37,3 +37,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric) { c.collectFileErrors(ch) } } + +func (c *Collector) appendErrorForPath(path string) { + c.fileMap[path].readErrors++ +} diff --git a/src/textfile/writer.go b/src/textfile/writer.go index 9c6b13f..8b76b84 100644 --- a/src/textfile/writer.go +++ b/src/textfile/writer.go @@ -19,6 +19,3 @@ func (c *Collector) WriteTextFileMetrics(w http.ResponseWriter, r *http.Request) } } -func (c *Collector) appendErrorForPath(path string) { - c.fileMap[path].readErrors++ -} From ac3681edb1e1f0c4ce908fa31bee1318b03a0a11 Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Tue, 12 Oct 2021 20:45:09 +0100 Subject: [PATCH 07/12] go fmt --- src/cfg/cfg.go | 10 +++++----- src/textfile/collector.go | 8 ++++---- src/textfile/file.go | 4 ++-- src/textfile/writer.go | 1 - 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/cfg/cfg.go b/src/cfg/cfg.go index 894c901..2e3a6c4 100644 --- a/src/cfg/cfg.go +++ b/src/cfg/cfg.go @@ -12,11 +12,11 @@ const ( ) type AppSettings struct { - VersionMode bool - MetricsPort int - Fail2BanDbPath string - Fail2BanSocketPath string - FileCollectorPath string + VersionMode bool + MetricsPort int + Fail2BanDbPath string + Fail2BanSocketPath string + FileCollectorPath string FileCollectorEnabled bool } diff --git a/src/textfile/collector.go b/src/textfile/collector.go index 863225b..5796eee 100644 --- a/src/textfile/collector.go +++ b/src/textfile/collector.go @@ -6,14 +6,14 @@ import ( ) type Collector struct { - enabled bool + enabled bool folderPath string - fileMap map[string]*fileData + fileMap map[string]*fileData } type fileData struct { - readErrors int - fileName string + readErrors int + fileName string fileContents []byte } diff --git a/src/textfile/file.go b/src/textfile/file.go index 1bdd378..d96d2e2 100644 --- a/src/textfile/file.go +++ b/src/textfile/file.go @@ -31,8 +31,8 @@ func (c *Collector) collectFileContents() { continue } c.fileMap[fileName] = &fileData{ - readErrors: 0, - fileName: fileName, + readErrors: 0, + fileName: fileName, } fullPath := filepath.Join(c.folderPath, file.Name()) diff --git a/src/textfile/writer.go b/src/textfile/writer.go index 8b76b84..3bc3e63 100644 --- a/src/textfile/writer.go +++ b/src/textfile/writer.go @@ -18,4 +18,3 @@ func (c *Collector) WriteTextFileMetrics(w http.ResponseWriter, r *http.Request) } } } - From 172746eb71c67685fcf85883bcc76b6e499bdcce Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Tue, 12 Oct 2021 20:53:27 +0100 Subject: [PATCH 08/12] log textfile directory on startup --- src/textfile/collector.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/textfile/collector.go b/src/textfile/collector.go index 5796eee..00582db 100644 --- a/src/textfile/collector.go +++ b/src/textfile/collector.go @@ -3,6 +3,7 @@ package textfile import ( "fail2ban-prometheus-exporter/cfg" "github.com/prometheus/client_golang/prometheus" + "log" ) type Collector struct { @@ -18,11 +19,15 @@ type fileData struct { } func NewCollector(appSettings *cfg.AppSettings) *Collector { - return &Collector{ + collector := &Collector{ enabled: appSettings.FileCollectorEnabled, folderPath: appSettings.FileCollectorPath, fileMap: make(map[string]*fileData), } + if collector.enabled { + log.Printf("collector.textfile directory: %s", collector.folderPath) + } + return collector } func (c *Collector) Describe(ch chan<- *prometheus.Desc) { From eedd7e607448c2253a5b22e34b9ae3010aceac15 Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Tue, 12 Oct 2021 20:59:30 +0100 Subject: [PATCH 09/12] use variable instead of function --- src/textfile/file.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textfile/file.go b/src/textfile/file.go index d96d2e2..0388e3f 100644 --- a/src/textfile/file.go +++ b/src/textfile/file.go @@ -35,7 +35,7 @@ func (c *Collector) collectFileContents() { fileName: fileName, } - fullPath := filepath.Join(c.folderPath, file.Name()) + fullPath := filepath.Join(c.folderPath, fileName) content, err := ioutil.ReadFile(fullPath) if err != nil { c.appendErrorForPath(fileName) From c30c860724be7dbf7edaba08ae1273afa54ec3d5 Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Tue, 12 Oct 2021 21:22:18 +0100 Subject: [PATCH 10/12] update readme --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index 8c0c592..c3d06c8 100644 --- a/README.md +++ b/README.md @@ -240,3 +240,24 @@ fail2ban_errors{type="db"} 0 # TYPE fail2ban_up gauge fail2ban_up 1 ``` + +### 4.3. Textfile Metrics + +For more flexibility the exporter also allows exporting metrics collected from a text file. + +To enable textfile metrics: +1. Enable the collector with `-collector.textfile=true` +2. Provide the directory to read files from with the `-collector.textfile.directory` flag + +Metrics collected from these files will be exposed directly alongside the other metrics without any additional processing. +This means that it is the responsibility of the file creator to ensure the format is correct. + +By exporting textfile metrics, an extra metric is also exported with an error count for each file: + +``` +# HELP textfile_error Checks for errors while reading text files +# TYPE textfile_error gauge +textfile_error{path="file.prom"} 0 +``` + +**NOTE:** Only files ending with `.prom` will be considered. From 8afaf2e92dcb0a75d5b1eea4bbe53ad3cd15cdff Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Tue, 12 Oct 2021 21:23:31 +0100 Subject: [PATCH 11/12] add new cli params to readme --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index c3d06c8..7cd339a 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,10 @@ $ fail2ban-prometheus-exporter -h path to the fail2ban server socket -version show version info and exit + -collector.textfile + enable the textfile collector + -collector.textfile.directory string + directory to read text files with metrics from ``` **Example** From e8296a644d4b05c7f5907abd0b49d7f557289a87 Mon Sep 17 00:00:00 2001 From: Hector <dev@hsmith.org> Date: Tue, 12 Oct 2021 21:28:19 +0100 Subject: [PATCH 12/12] support metric files with uppercase extension --- README.md | 6 +++--- src/textfile/file.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7cd339a..6667d7b 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ $ fail2ban-prometheus-exporter -h path to the fail2ban server socket -version show version info and exit - -collector.textfile + -collector.textfile enable the textfile collector -collector.textfile.directory string directory to read text files with metrics from @@ -256,7 +256,7 @@ To enable textfile metrics: Metrics collected from these files will be exposed directly alongside the other metrics without any additional processing. This means that it is the responsibility of the file creator to ensure the format is correct. -By exporting textfile metrics, an extra metric is also exported with an error count for each file: +By exporting textfile metrics an extra metric is also exported with an error count for each file: ``` # HELP textfile_error Checks for errors while reading text files @@ -264,4 +264,4 @@ By exporting textfile metrics, an extra metric is also exported with an error co textfile_error{path="file.prom"} 0 ``` -**NOTE:** Only files ending with `.prom` will be considered. +**NOTE:** Any file not ending with `.prom` will be ignored. diff --git a/src/textfile/file.go b/src/textfile/file.go index 0388e3f..7ed5de7 100644 --- a/src/textfile/file.go +++ b/src/textfile/file.go @@ -27,7 +27,7 @@ func (c *Collector) collectFileContents() { for _, file := range files { fileName := file.Name() - if !strings.HasSuffix(fileName, ".prom") { + if !strings.HasSuffix(strings.ToLower(fileName), ".prom") { continue } c.fileMap[fileName] = &fileData{