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 wakeup events
86 from the file descriptor returned by sd_journal_get_fd() are known to
87 be immediately triggered. On certain file systems where file change
88 events from the OS are not available (such as NFS) changes need to be
89 polled for repeatedly, and hence are detected only with a certain
90 latency. This call will return a positive value if the journal changes
91 are detected immediately and zero when they need to be polled for and
92 hence might be noticed only with a certain latency. Note that there is
93 usually no need to invoke this function directly as
94 sd_journal_get_timeout() on these file systems will ask for timeouts
95 explicitly anyway.
96
98 sd_journal_get_fd() returns a valid file descriptor on success or a
99 negative errno-style error code.
100
101 sd_journal_get_events() returns a combination of POLLIN, POLLOUT and
102 suchlike on success or a negative errno-style error code.
103
104 sd_journal_reliable_fd() returns a positive integer if the file
105 descriptor returned by sd_journal_get_fd() will generate wake-ups
106 immediately for all journal changes. Returns 0 if there might be a
107 latency involved.
108
109 sd_journal_process() and sd_journal_wait() return a negative
110 errno-style error code, or one of SD_JOURNAL_NOP, SD_JOURNAL_APPEND or
111 SD_JOURNAL_INVALIDATE on success:
112
113 · If SD_JOURNAL_NOP is returned, the journal did not change since the
114 last invocation.
115
116 · If SD_JOURNAL_APPEND is returned, new entries have been appended to
117 the end of the journal. In this case it is sufficient to simply
118 continue reading at the previous end location of the journal, to
119 read the newly added entries.
120
121 · If SD_JOURNAL_INVALIDATE, journal files were added to or removed
122 from the set of journal files watched (e.g. due to rotation or
123 vacuuming), and thus entries might have appeared or disappeared at
124 arbitrary places in the log stream, possibly before or after the
125 previous end of the log stream. If SD_JOURNAL_INVALIDATE is
126 returned, live-view UIs that want to reflect on screen the precise
127 state of the log data on disk should probably refresh their entire
128 display (relative to the cursor of the log entry on the top of the
129 screen). Programs only interested in a strictly sequential stream
130 of log data may treat SD_JOURNAL_INVALIDATE the same way as
131 SD_JOURNAL_APPEND, thus ignoring any changes to the log view
132 earlier than the old end of the log stream.
133
135 In general, sd_journal_get_fd(), sd_journal_get_events(), and
136 sd_journal_get_timeout() are not "async signal safe" in the meaning of
137 signal-safety(7). Nevertheless, only the first call to any of those
138 three functions performs unsafe operations, so subsequent calls are
139 safe.
140
141 sd_journal_process() and sd_journal_wait() are not safe.
142 sd_journal_reliable_fd() is safe.
143
145 All functions listed here are thread-agnostic and only a single
146 specific thread may operate on a given object during its entire
147 lifetime. It's safe to allocate multiple independent objects and use
148 each from a specific thread in parallel. However, it's not safe to
149 allocate such an object in one thread, and operate or free it from any
150 other, even if locking is used to ensure these threads don't operate on
151 it at the very same time.
152
153 These APIs are implemented as a shared library, which can be compiled
154 and linked to with the libsystemd pkg-config(1) file.
155
157 Iterating through the journal, in a live view tracking all changes:
158
159 #include <stdio.h>
160 #include <string.h>
161 #include <systemd/sd-journal.h>
162
163 int main(int argc, char *argv[]) {
164 int r;
165 sd_journal *j;
166 r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
167 if (r < 0) {
168 fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
169 return 1;
170 }
171 for (;;) {
172 const void *d;
173 size_t l;
174 r = sd_journal_next(j);
175 if (r < 0) {
176 fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
177 break;
178 }
179 if (r == 0) {
180 /* Reached the end, let's wait for changes, and try again */
181 r = sd_journal_wait(j, (uint64_t) -1);
182 if (r < 0) {
183 fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
184 break;
185 }
186 continue;
187 }
188 r = sd_journal_get_data(j, "MESSAGE", &d, &l);
189 if (r < 0) {
190 fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
191 continue;
192 }
193 printf("%.*s\n", (int) l, (const char*) d);
194 }
195 sd_journal_close(j);
196 return 0;
197 }
198
199 Waiting with poll() (this example lacks all error checking for the sake
200 of simplicity):
201
202 #include <poll.h>
203 #include <time.h>
204 #include <systemd/sd-journal.h>
205
206 int wait_for_changes(sd_journal *j) {
207 uint64_t t;
208 int msec;
209 struct pollfd pollfd;
210
211 sd_journal_get_timeout(j, &t);
212 if (t == (uint64_t) -1)
213 msec = -1;
214 else {
215 struct timespec ts;
216 uint64_t n;
217 clock_gettime(CLOCK_MONOTONIC, &ts);
218 n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
219 msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
220 }
221
222 pollfd.fd = sd_journal_get_fd(j);
223 pollfd.events = sd_journal_get_events(j);
224 poll(&pollfd, 1, msec);
225 return sd_journal_process(j);
226 }
227
229 systemd(1), sd-journal(3), sd_journal_open(3), sd_journal_next(3),
230 poll(2), clock_gettime(2)
231
232
233
234systemd 246 SD_JOURNAL_GET_FD(3)