If we take a long time to process log messages, and during that time
journal file rotation occurs, the journald client library will keep
those rotated files open until sd_journal_process() is called.
By periodically calling sd_journal_process() during the processing
loop we shrink the window of time a client instance has open file
descriptors for rotated (deleted) journal files.
This code is modelled after that of journalctl [1]; the above explanation
as well as the value of 1024 is taken from there.
[v2: fix CErr() argument]
[1] https://github.com/systemd/systemd/blob/dc16327c48d/src/journal/journalctl.c#L2676
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
(cherry picked from commit b73fb8fd5d521081c92b5c2cce334c21b2e0ff5f)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
... | ... |
@@ -113,6 +113,7 @@ import ( |
113 | 113 |
"github.com/coreos/go-systemd/journal" |
114 | 114 |
"github.com/docker/docker/api/types/backend" |
115 | 115 |
"github.com/docker/docker/daemon/logger" |
116 |
+ "github.com/sirupsen/logrus" |
|
116 | 117 |
) |
117 | 118 |
|
118 | 119 |
func (s *journald) Close() error { |
... | ... |
@@ -205,6 +206,16 @@ drain: |
205 | 205 |
}: |
206 | 206 |
shown++ |
207 | 207 |
} |
208 |
+ // Call sd_journal_process() periodically during the processing loop |
|
209 |
+ // to close any opened file descriptors for rotated (deleted) journal files. |
|
210 |
+ if shown%1024 == 0 { |
|
211 |
+ if ret := C.sd_journal_process(j); ret < 0 { |
|
212 |
+ // log a warning but ignore it for now |
|
213 |
+ logrus.WithField("container", s.vars["CONTAINER_ID_FULL"]). |
|
214 |
+ WithField("error", CErr(ret)). |
|
215 |
+ Warn("journald: error processing journal") |
|
216 |
+ } |
|
217 |
+ } |
|
208 | 218 |
} |
209 | 219 |
// If we're at the end of the journal, we're done (for now). |
210 | 220 |
if C.sd_journal_next(j) <= 0 { |