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_getttime(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's
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 one of
110 SD_JOURNAL_NOP, SD_JOURNAL_APPEND or SD_JOURNAL_INVALIDATE on success
111 or a negative errno-style error code. If SD_JOURNAL_NOP is returned,
112 the journal did not change since the last invocation. If
113 SD_JOURNAL_APPEND is returned, new entries have been appended to the
114 end of the journal. If SD_JOURNAL_INVALIDATE, journal files were added
115 or removed (possibly due to rotation). In the latter event, live-view
116 UIs should probably refresh their entire display, while in the case of
117 SD_JOURNAL_APPEND, it is sufficient to simply continue reading at the
118 previous end of the journal.
119
121 The sd_journal_get_fd(), sd_journal_get_events(),
122 sd_journal_reliable_fd(), sd_journal_process() and sd_journal_wait()
123 interfaces are available as a shared library, which can be compiled and
124 linked to with the libsystemd pkg-config(1) file.
125
127 Iterating through the journal, in a live view tracking all changes:
128
129 #include <stdio.h>
130 #include <string.h>
131 #include <systemd/sd-journal.h>
132
133 int main(int argc, char *argv[]) {
134 int r;
135 sd_journal *j;
136 r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
137 if (r < 0) {
138 fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
139 return 1;
140 }
141 for (;;) {
142 const void *d;
143 size_t l;
144 r = sd_journal_next(j);
145 if (r < 0) {
146 fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
147 break;
148 }
149 if (r == 0) {
150 /* Reached the end, let's wait for changes, and try again */
151 r = sd_journal_wait(j, (uint64_t) -1);
152 if (r < 0) {
153 fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
154 break;
155 }
156 continue;
157 }
158 r = sd_journal_get_data(j, "MESSAGE", &d, &l);
159 if (r < 0) {
160 fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
161 continue;
162 }
163 printf("%.*s\n", (int) l, (const char*) d);
164 }
165 sd_journal_close(j);
166 return 0;
167 }
168
169 Waiting with poll() (this example lacks all error checking for the sake
170 of simplicity):
171
172 #include <poll.h>
173 #include <systemd/sd-journal.h>
174
175 int wait_for_changes(sd_journal *j) {
176 struct pollfd pollfd;
177 int msec;
178
179 sd_journal_get_timeout(m, &t);
180 if (t == (uint64_t) -1)
181 msec = -1;
182 else {
183 struct timespec ts;
184 uint64_t n;
185 clock_getttime(CLOCK_MONOTONIC, &ts);
186 n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
187 msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
188 }
189
190 pollfd.fd = sd_journal_get_fd(j);
191 pollfd.events = sd_journal_get_events(j);
192 poll(&pollfd, 1, msec);
193 return sd_journal_process(j);
194 }
195
197 systemd(1), sd-journal(3), sd_journal_open(3), sd_journal_next(3),
198 poll(2), clock_gettime(2)
199
200
201
202systemd 219 SD_JOURNAL_GET_FD(3)