Skip to content

Commit

Permalink
textfile: Allow specifiying multiple directory globs. (#3135)
Browse files Browse the repository at this point in the history
We already support reading from multiple directories though only using globs. Now we can specify them outright.

Example use case is exporting both static info on a RO FS generated during image building and traditional uses of textfiles (e.g. for R/W service metrics files) without scripting a file copy.

* keep flag name for compatibility
* clarify flag help text
* add test case (replicating the glob one)

Signed-off-by: eduarrrd <[email protected]>
  • Loading branch information
eduarrrd authored Sep 30, 2024
1 parent b5ce6bc commit 11f93d3
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 43 deletions.
22 changes: 13 additions & 9 deletions collector/textfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import (
)

var (
textFileDirectory = kingpin.Flag("collector.textfile.directory", "Directory to read text files with metrics from.").Default("").String()
mtimeDesc = prometheus.NewDesc(
textFileDirectories = kingpin.Flag("collector.textfile.directory", "Directory to read text files with metrics from, supports glob matching. (repeatable)").Default("").Strings()
mtimeDesc = prometheus.NewDesc(
"node_textfile_mtime_seconds",
"Unixtime mtime of textfiles successfully read.",
[]string{"file"},
Expand All @@ -42,7 +42,7 @@ var (
)

type textFileCollector struct {
path string
paths []string
// Only set for testing to get predictable output.
mtime *float64
logger *slog.Logger
Expand All @@ -56,7 +56,7 @@ func init() {
// in the given textfile directory.
func NewTextFileCollector(logger *slog.Logger) (Collector, error) {
c := &textFileCollector{
path: *textFileDirectory,
paths: *textFileDirectories,
logger: logger,
}
return c, nil
Expand Down Expand Up @@ -194,11 +194,15 @@ func (c *textFileCollector) Update(ch chan<- prometheus.Metric) error {
metricsNamesToFiles := map[string][]string{}
metricsNamesToHelpTexts := map[string][2]string{}

paths, err := filepath.Glob(c.path)
if err != nil || len(paths) == 0 {
// not glob or not accessible path either way assume single
// directory and let os.ReadDir handle it
paths = []string{c.path}
paths := []string{}
for _, glob := range c.paths {
ps, err := filepath.Glob(glob)
if err != nil || len(ps) == 0 {
// not glob or not accessible path either way assume single
// directory and let os.ReadDir handle it
ps = []string{glob}
}
paths = append(paths, ps...)
}

mtimes := make(map[string]time.Time)
Expand Down
75 changes: 41 additions & 34 deletions collector/textfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,75 +52,82 @@ func (a collectorAdapter) Collect(ch chan<- prometheus.Metric) {

func TestTextfileCollector(t *testing.T) {
tests := []struct {
path string
out string
paths []string
out string
}{
{
path: "fixtures/textfile/no_metric_files",
out: "fixtures/textfile/no_metric_files.out",
paths: []string{"fixtures/textfile/no_metric_files"},
out: "fixtures/textfile/no_metric_files.out",
},
{
path: "fixtures/textfile/two_metric_files",
out: "fixtures/textfile/two_metric_files.out",
paths: []string{"fixtures/textfile/two_metric_files"},
out: "fixtures/textfile/two_metric_files.out",
},
{
path: "fixtures/textfile/nonexistent_path",
out: "fixtures/textfile/nonexistent_path.out",
paths: []string{"fixtures/textfile/nonexistent_path"},
out: "fixtures/textfile/nonexistent_path.out",
},
{
path: "fixtures/textfile/client_side_timestamp",
out: "fixtures/textfile/client_side_timestamp.out",
paths: []string{"fixtures/textfile/client_side_timestamp"},
out: "fixtures/textfile/client_side_timestamp.out",
},
{
path: "fixtures/textfile/different_metric_types",
out: "fixtures/textfile/different_metric_types.out",
paths: []string{"fixtures/textfile/different_metric_types"},
out: "fixtures/textfile/different_metric_types.out",
},
{
path: "fixtures/textfile/inconsistent_metrics",
out: "fixtures/textfile/inconsistent_metrics.out",
paths: []string{"fixtures/textfile/inconsistent_metrics"},
out: "fixtures/textfile/inconsistent_metrics.out",
},
{
path: "fixtures/textfile/histogram",
out: "fixtures/textfile/histogram.out",
paths: []string{"fixtures/textfile/histogram"},
out: "fixtures/textfile/histogram.out",
},
{
path: "fixtures/textfile/histogram_extra_dimension",
out: "fixtures/textfile/histogram_extra_dimension.out",
paths: []string{"fixtures/textfile/histogram_extra_dimension"},
out: "fixtures/textfile/histogram_extra_dimension.out",
},
{
path: "fixtures/textfile/summary",
out: "fixtures/textfile/summary.out",
paths: []string{"fixtures/textfile/summary"},
out: "fixtures/textfile/summary.out",
},
{
path: "fixtures/textfile/summary_extra_dimension",
out: "fixtures/textfile/summary_extra_dimension.out",
paths: []string{"fixtures/textfile/summary_extra_dimension"},
out: "fixtures/textfile/summary_extra_dimension.out",
},
{
path: "fixtures/textfile/*_extra_dimension",
out: "fixtures/textfile/glob_extra_dimension.out",
paths: []string{
"fixtures/textfile/histogram_extra_dimension",
"fixtures/textfile/summary_extra_dimension",
},
out: "fixtures/textfile/glob_extra_dimension.out",
},
{
path: "fixtures/textfile/metrics_merge_empty_help",
out: "fixtures/textfile/metrics_merge_empty_help.out",
paths: []string{"fixtures/textfile/*_extra_dimension"},
out: "fixtures/textfile/glob_extra_dimension.out",
},
{
path: "fixtures/textfile/metrics_merge_no_help",
out: "fixtures/textfile/metrics_merge_no_help.out",
paths: []string{"fixtures/textfile/metrics_merge_empty_help"},
out: "fixtures/textfile/metrics_merge_empty_help.out",
},
{
path: "fixtures/textfile/metrics_merge_same_help",
out: "fixtures/textfile/metrics_merge_same_help.out",
paths: []string{"fixtures/textfile/metrics_merge_no_help"},
out: "fixtures/textfile/metrics_merge_no_help.out",
},
{
path: "fixtures/textfile/metrics_merge_different_help",
out: "fixtures/textfile/metrics_merge_different_help.out",
paths: []string{"fixtures/textfile/metrics_merge_same_help"},
out: "fixtures/textfile/metrics_merge_same_help.out",
},
{
paths: []string{"fixtures/textfile/metrics_merge_different_help"},
out: "fixtures/textfile/metrics_merge_different_help.out",
},
}

for i, test := range tests {
mtime := 1.0
c := &textFileCollector{
path: test.path,
paths: test.paths,
mtime: &mtime,
logger: slog.New(slog.NewTextHandler(io.Discard, nil)),
}
Expand All @@ -146,7 +153,7 @@ func TestTextfileCollector(t *testing.T) {
}

if string(want) != got {
t.Fatalf("%d.%q want:\n\n%s\n\ngot:\n\n%s", i, test.path, string(want), got)
t.Fatalf("%d.%q want:\n\n%s\n\ngot:\n\n%s", i, test.paths, string(want), got)
}
}
}

0 comments on commit 11f93d3

Please sign in to comment.