Browse code

journald/read: avoid piling up open files

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>

Kir Kolyshkin authored on 2019/03/10 12:39:33
Showing 1 changed files
... ...
@@ -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 {