diff options
author | Christian Hoffmann <christian@hoffie.info> | 2019-04-18 17:47:04 +0200 |
---|---|---|
committer | Ben Kochie <superq@gmail.com> | 2019-04-18 17:47:04 +0200 |
commit | 36e3b2a923e551830b583ecd43c8f9a9726576cf (patch) | |
tree | d69bb389cf3ec9cdb074765a8c65423532aa33bf | |
parent | 5b4140e0bd3b56bc4b0be19908ab600d49c6c639 (diff) | |
download | prometheus_node_collector-36e3b2a923e551830b583ecd43c8f9a9726576cf.tar.bz2 prometheus_node_collector-36e3b2a923e551830b583ecd43c8f9a9726576cf.tar.xz prometheus_node_collector-36e3b2a923e551830b583ecd43c8f9a9726576cf.zip |
textfile: use opened file's mtime as timestamp (#1326)
Previously, the node_textfile_mtime_seconds metric was based on the
Fileinfo.ModTime() of the ioutil.ReadDir() return value. This is based
on lstat() and therefore has unintended consequences for symlinks
(modification time of the symlink instead of the symlink target is
returned). It is also racy as the lstat() is performed before reading
the file.
This commit changes the node_textfile_mtime_seconds metric to be based
on a fresh Stat() call on the open file. This eliminates the race and
works as expected for symlinks. Fixes #1324.
Signed-off-by: Christian Hoffmann <mail@hoffmann-christian.info>
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | collector/textfile.go | 10 |
2 files changed, 9 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index d86dbcf..08a9bf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
@@ -14,6 +14,7 @@ | |||
14 | ### Changes | 14 | ### Changes |
15 | 15 | ||
16 | * [BUGFIX] | 16 | * [BUGFIX] |
17 | * [BUGFIX] Fix node_textfile_mtime_seconds to work properly on symlinks #1326 | ||
17 | * [CHANGE] Renamed `interface` label to `device` in netclass collector #1224 | 18 | * [CHANGE] Renamed `interface` label to `device` in netclass collector #1224 |
18 | * [BUGFIX] Add fallback for missing /proc/1/mounts #1172 | 19 | * [BUGFIX] Add fallback for missing /proc/1/mounts #1172 |
19 | * [CHANGE] Add TCPSynRetrans to netstat default filter #1143 | 20 | * [CHANGE] Add TCPSynRetrans to netstat default filter #1143 |
diff --git a/collector/textfile.go b/collector/textfile.go index c80de98..52e88bb 100644 --- a/collector/textfile.go +++ b/collector/textfile.go | |||
@@ -204,9 +204,9 @@ func (c *textFileCollector) Update(ch chan<- prometheus.Metric) error { | |||
204 | error = 1.0 | 204 | error = 1.0 |
205 | continue | 205 | continue |
206 | } | 206 | } |
207 | defer file.Close() | ||
207 | var parser expfmt.TextParser | 208 | var parser expfmt.TextParser |
208 | parsedFamilies, err := parser.TextToMetricFamilies(file) | 209 | parsedFamilies, err := parser.TextToMetricFamilies(file) |
209 | file.Close() | ||
210 | if err != nil { | 210 | if err != nil { |
211 | log.Errorf("Error parsing %q: %v", path, err) | 211 | log.Errorf("Error parsing %q: %v", path, err) |
212 | error = 1.0 | 212 | error = 1.0 |
@@ -227,7 +227,13 @@ func (c *textFileCollector) Update(ch chan<- prometheus.Metric) error { | |||
227 | 227 | ||
228 | // Only set this once it has been parsed and validated, so that | 228 | // Only set this once it has been parsed and validated, so that |
229 | // a failure does not appear fresh. | 229 | // a failure does not appear fresh. |
230 | mtimes[f.Name()] = f.ModTime() | 230 | stat, err := file.Stat() |
231 | if err != nil { | ||
232 | log.Errorf("Error stat'ing %q: %v", path, err) | ||
233 | error = 1.0 | ||
234 | continue | ||
235 | } | ||
236 | mtimes[f.Name()] = stat.ModTime() | ||
231 | 237 | ||
232 | for _, mf := range parsedFamilies { | 238 | for _, mf := range parsedFamilies { |
233 | convertMetricFamily(mf, ch) | 239 | convertMetricFamily(mf, ch) |