file: fix collector producing no metrics, startup hang, and duplicate metric errors (#2371)

Signed-off-by: EisenbergD <dominik.eisenberg@beiersdorf.com>
Co-authored-by: EisenbergD <dominik.eisenberg@beiersdorf.com>
This commit is contained in:
Dominik Eisenberg
2026-04-01 12:52:22 +02:00
committed by GitHub
parent 43f83573ef
commit 612b29cfc9
3 changed files with 29 additions and 14 deletions

View File

@@ -17,20 +17,20 @@ See https://github.com/bmatcuk/doublestar#patterns for an extended description o
## Metrics ## Metrics
| Name | Description | Type | Labels | | Name | Description | Type | Labels |
|----------------------------------------|------------------------|-------|--------| |----------------------------------------|------------------------|-------|--------------------|
| `windows_file_mtime_timestamp_seconds` | File modification time | gauge | `file` | | `windows_file_mtime_timestamp_seconds` | File modification time | gauge | `file`, `pattern` |
| `windows_file_size_bytes` | File size | gauge | `file` | | `windows_file_size_bytes` | File size | gauge | `file`, `pattern` |
### Example metric ### Example metric
``` ```
# HELP windows_file_mtime_timestamp_seconds File modification time # HELP windows_file_mtime_timestamp_seconds File modification time
# TYPE windows_file_mtime_timestamp_seconds gauge # TYPE windows_file_mtime_timestamp_seconds gauge
windows_file_mtime_timestamp_seconds{file="C:\\Users\\admin\\Desktop\\Dashboard.lnk"} 1.726434517e+09 windows_file_mtime_timestamp_seconds{file="C:\\Users\\admin\\Desktop\\Dashboard.lnk",pattern="C:\\Users\\admin\\Desktop\\*.lnk"} 1.726434517e+09
# HELP windows_file_size_bytes File size # HELP windows_file_size_bytes File size
# TYPE windows_file_size_bytes gauge # TYPE windows_file_size_bytes gauge
windows_file_size_bytes{file="C:\\Users\\admin\\Desktop\\Dashboard.lnk"} 123 windows_file_size_bytes{file="C:\\Users\\admin\\Desktop\\Dashboard.lnk",pattern="C:\\Users\\admin\\Desktop\\*.lnk"} 123
``` ```
## Useful queries ## Useful queries

View File

@@ -74,12 +74,23 @@ func NewWithFlags(app *kingpin.Application) *Collector {
c := &Collector{ c := &Collector{
config: ConfigDefaults, config: ConfigDefaults,
} }
c.config.FilePatterns = make([]string, 0)
var filePatterns string
app.Flag( app.Flag(
"collector.file.file-patterns", "collector.file.file-patterns",
"Comma-separated list of file patterns. Each pattern is a glob pattern that can contain `*`, `?`, and `**` (recursive). See https://github.com/bmatcuk/doublestar#patterns", "Comma-separated list of file patterns. Each pattern is a glob pattern that can contain `*`, `?`, and `**` (recursive). See https://github.com/bmatcuk/doublestar#patterns",
).Default(strings.Join(ConfigDefaults.FilePatterns, ",")).StringsVar(&c.config.FilePatterns) ).Default(strings.Join(ConfigDefaults.FilePatterns, ",")).StringVar(&filePatterns)
app.Action(func(*kingpin.ParseContext) error {
for p := range strings.SplitSeq(filePatterns, ",") {
if p != "" {
c.config.FilePatterns = append(c.config.FilePatterns, p)
}
}
return nil
})
return c return c
} }
@@ -100,23 +111,24 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
c.fileMTime = prometheus.NewDesc( c.fileMTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "mtime_timestamp_seconds"), prometheus.BuildFQName(types.Namespace, Name, "mtime_timestamp_seconds"),
"File modification time", "File modification time",
[]string{"file"}, []string{"file", "pattern"},
nil, nil,
) )
c.fileSize = prometheus.NewDesc( c.fileSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "size_bytes"), prometheus.BuildFQName(types.Namespace, Name, "size_bytes"),
"File size", "File size",
[]string{"file"}, []string{"file", "pattern"},
nil, nil,
) )
for _, filePattern := range c.config.FilePatterns { for _, filePattern := range c.config.FilePatterns {
basePath, pattern := doublestar.SplitPattern(filePattern) if filePattern == "" {
continue
}
_, err := doublestar.Glob(os.DirFS(basePath), pattern, doublestar.WithFilesOnly()) if !doublestar.ValidatePattern(filepath.ToSlash(filePattern)) {
if err != nil { return fmt.Errorf("invalid glob pattern: %s", filePattern)
return fmt.Errorf("invalid glob pattern: %w", err)
} }
} }
@@ -170,6 +182,7 @@ func (c *Collector) collectGlobFilePath(ch chan<- prometheus.Metric, filePattern
prometheus.GaugeValue, prometheus.GaugeValue,
float64(fileInfo.ModTime().UTC().UnixMicro())/1e6, float64(fileInfo.ModTime().UTC().UnixMicro())/1e6,
filePath, filePath,
filePattern,
) )
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
@@ -177,6 +190,7 @@ func (c *Collector) collectGlobFilePath(ch chan<- prometheus.Metric, filePattern
prometheus.GaugeValue, prometheus.GaugeValue,
float64(fileInfo.Size()), float64(fileInfo.Size()),
filePath, filePath,
filePattern,
) )
return nil return nil

View File

@@ -134,6 +134,7 @@ var ConfigDefaults = Config{
DiskDrive: diskdrive.ConfigDefaults, DiskDrive: diskdrive.ConfigDefaults,
DNS: dns.ConfigDefaults, DNS: dns.ConfigDefaults,
Exchange: exchange.ConfigDefaults, Exchange: exchange.ConfigDefaults,
File: file.ConfigDefaults,
Fsrmquota: fsrmquota.ConfigDefaults, Fsrmquota: fsrmquota.ConfigDefaults,
GPU: gpu.ConfigDefaults, GPU: gpu.ConfigDefaults,
HyperV: hyperv.ConfigDefaults, HyperV: hyperv.ConfigDefaults,