1SD_JOURNAL_GET_FD(3) sd_journal_get_fd SD_JOURNAL_GET_FD(3)
2
3
4
6 sd_journal_get_fd, sd_journal_get_events, sd_journal_get_timeout,
7 sd_journal_process, sd_journal_wait, sd_journal_reliable_fd,
8 SD_JOURNAL_NOP, SD_JOURNAL_APPEND, SD_JOURNAL_INVALIDATE - Journal
9 change notification interface
10
12 #include <systemd/sd-journal.h>
13
14 int sd_journal_get_fd(sd_journal *j);
15
16 int sd_journal_get_events(sd_journal *j);
17
18 int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec);
19
20 int sd_journal_process(sd_journal *j);
21
22 int sd_journal_wait(sd_journal *j, uint64_t timeout_usec);
23
24 int sd_journal_reliable_fd(sd_journal *j);
25
27 sd_journal_get_fd() returns a file descriptor that may be
28 asynchronously polled in an external event loop and is signaled as soon
29 as the journal changes, because new entries or files were added,
30 rotation took place, or files have been deleted, and similar. The file
31 descriptor is suitable for usage in poll(2). Use
32 sd_journal_get_events() for an events mask to watch for. The call takes
33 one argument: the journal context object. Note that not all file
34 systems are capable of generating the necessary events for wakeups from
35 this file descriptor for changes to be noticed immediately. In
36 particular network files systems do not generate suitable file change
37 events in all cases. Cases like this can be detected with
38 sd_journal_reliable_fd(), below. sd_journal_get_timeout() will ensure
39 in these cases that wake-ups happen frequently enough for changes to be
40 noticed, although with a certain latency.
41
42 sd_journal_get_events() will return the poll() mask to wait for. This
43 function will return a combination of POLLIN and POLLOUT and similar to
44 fill into the ".events" field of struct pollfd.
45
46 sd_journal_get_timeout() will return a timeout value for usage in
47 poll(). This returns a value in microseconds since the epoch of
48 CLOCK_MONOTONIC for timing out poll() in timeout_usec. See
49 clock_gettime(2) for details about CLOCK_MONOTONIC. If there is no
50 timeout to wait for, this will fill in (uint64_t) -1 instead. Note that
51 poll() takes a relative timeout in milliseconds rather than an absolute
52 timeout in microseconds. To convert the absolute 'us' timeout into
53 relative 'ms', use code like the following:
54
55 uint64_t t;
56 int msec;
57 sd_journal_get_timeout(m, &t);
58 if (t == (uint64_t) -1)
59 msec = -1;
60 else {
61 struct timespec ts;
62 uint64_t n;
63 clock_gettime(CLOCK_MONOTONIC, &ts);
64 n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
65 msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
66 }
67
68 The code above does not do any error checking for brevity's sake. The
69 calculated msec integer can be passed directly as poll()'s timeout
70 parameter.
71
72 After each poll() wake-up sd_journal_process() needs to be called to
73 process events. This call will also indicate what kind of change has
74 been detected (see below; note that spurious wake-ups are possible).
75
76 A synchronous alternative for using sd_journal_get_fd(),
77 sd_journal_get_events(), sd_journal_get_timeout() and
78 sd_journal_process() is sd_journal_wait(). It will synchronously wait
79 until the journal gets changed. The maximum time this call sleeps may
80 be controlled with the timeout_usec parameter. Pass (uint64_t) -1 to
81 wait indefinitely. Internally this call simply combines
82 sd_journal_get_fd(), sd_journal_get_events(), sd_journal_get_timeout(),
83 poll() and sd_journal_process() into one.
84
85 sd_journal_reliable_fd() may be used to check whether the wake-up
86 events from the file descriptor returned by sd_journal_get_fd() are
87 known to be quickly triggered. On certain file systems where file
88 change events from the OS are not available (such as NFS) changes need
89 to be polled for repeatedly, and hence are detected only with a
90 considerable latency. This call will return a positive value if the
91 journal changes are detected quickly and zero when they need to be
92 polled for. Note that there is usually no need to invoke this function
93 directly as sd_journal_get_timeout() will request appropriate timeouts
94 anyway.
95
96 Note that all of the above change notification interfaces do not report
97 changes instantly. Latencies are introduced for multiple reasons: as
98 mentioned certain storage backends require time-based polling, in other
99 cases wake-ups are optimized by coalescing events, and the OS
100 introduces additional IO/CPU scheduling latencies.
101
103 sd_journal_get_fd() returns a valid file descriptor on success or a
104 negative errno-style error code.
105
106 sd_journal_get_events() returns a combination of POLLIN, POLLOUT and
107 suchlike on success or a negative errno-style error code.
108
109 sd_journal_reliable_fd() returns a positive integer if the file
110 descriptor returned by sd_journal_get_fd() will generate wake-ups
111 immediately for all journal changes. Returns 0 if there might be a
112 latency involved.
113
114 sd_journal_process() and sd_journal_wait() return a negative
115 errno-style error code, or one of SD_JOURNAL_NOP, SD_JOURNAL_APPEND or
116 SD_JOURNAL_INVALIDATE on success:
117
118 • If SD_JOURNAL_NOP is returned, the journal did not change since the
119 last invocation.
120
121 • If SD_JOURNAL_APPEND is returned, new entries have been appended to
122 the end of the journal. In this case it is sufficient to simply
123 continue reading at the previous end location of the journal, to
124 read the newly added entries.
125
126 • If SD_JOURNAL_INVALIDATE, journal files were added to or removed
127 from the set of journal files watched (e.g. due to rotation or
128 vacuuming), and thus entries might have appeared or disappeared at
129 arbitrary places in the log stream, possibly before or after the
130 previous end of the log stream. If SD_JOURNAL_INVALIDATE is
131 returned, live-view UIs that want to reflect on screen the precise
132 state of the log data on disk should probably refresh their entire
133 display (relative to the cursor of the log entry on the top of the
134 screen). Programs only interested in a strictly sequential stream
135 of log data may treat SD_JOURNAL_INVALIDATE the same way as
136 SD_JOURNAL_APPEND, thus ignoring any changes to the log view
137 earlier than the old end of the log stream.
138
140 In general, sd_journal_get_fd(), sd_journal_get_events(), and
141 sd_journal_get_timeout() are not "async signal safe" in the meaning of
142 signal-safety(7). Nevertheless, only the first call to any of those
143 three functions performs unsafe operations, so subsequent calls are
144 safe.
145
146 sd_journal_process() and sd_journal_wait() are not safe.
147 sd_journal_reliable_fd() is safe.
148
150 All functions listed here are thread-agnostic and only a single
151 specific thread may operate on a given object during its entire
152 lifetime. It's safe to allocate multiple independent objects and use
153 each from a specific thread in parallel. However, it's not safe to
154 allocate such an object in one thread, and operate or free it from any
155 other, even if locking is used to ensure these threads don't operate on
156 it at the very same time.
157
158 Functions described here are available as a shared library, which can
159 be compiled against and linked to with the libsystemd pkg-config(1)
160 file.
161
163 Iterating through the journal, in a live view tracking all changes:
164
165 /* SPDX-License-Identifier: MIT-0 */
166
167 #include <errno.h>
168 #include <stdio.h>
169 #include <systemd/sd-journal.h>
170
171 int main(int argc, char *argv[]) {
172 int r;
173 sd_journal *j;
174 r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
175 if (r < 0) {
176 errno = -r;
177 fprintf(stderr, "Failed to open journal: %m\n");
178 return 1;
179 }
180 for (;;) {
181 const void *d;
182 size_t l;
183 r = sd_journal_next(j);
184 if (r < 0) {
185 errno = -r;
186 fprintf(stderr, "Failed to iterate to next entry: %m\n");
187 break;
188 }
189 if (r == 0) {
190 /* Reached the end, let's wait for changes, and try again */
191 r = sd_journal_wait(j, (uint64_t) -1);
192 if (r < 0) {
193 errno = -r;
194 fprintf(stderr, "Failed to wait for changes: %m\n");
195 break;
196 }
197 continue;
198 }
199 r = sd_journal_get_data(j, "MESSAGE", &d, &l);
200 if (r < 0) {
201 errno = -r;
202 fprintf(stderr, "Failed to read message field: %m\n");
203 continue;
204 }
205 printf("%.*s\n", (int) l, (const char*) d);
206 }
207 sd_journal_close(j);
208 return 0;
209 }
210
211 Waiting with poll() (this example lacks all error checking for the sake
212 of simplicity):
213
214 /* SPDX-License-Identifier: MIT-0 */
215
216 #include <poll.h>
217 #include <time.h>
218 #include <systemd/sd-journal.h>
219
220 int wait_for_changes(sd_journal *j) {
221 uint64_t t;
222 int msec;
223 struct pollfd pollfd;
224
225 sd_journal_get_timeout(j, &t);
226 if (t == (uint64_t) -1)
227 msec = -1;
228 else {
229 struct timespec ts;
230 uint64_t n;
231 clock_gettime(CLOCK_MONOTONIC, &ts);
232 n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
233 msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
234 }
235
236 pollfd.fd = sd_journal_get_fd(j);
237 pollfd.events = sd_journal_get_events(j);
238 poll(&pollfd, 1, msec);
239 return sd_journal_process(j);
240 }
241
243 systemd(1), sd-journal(3), sd_journal_open(3), sd_journal_next(3),
244 poll(2), clock_gettime(2)
245
246
247
248systemd 254 SD_JOURNAL_GET_FD(3)