journal: add sd_journal_perror() to API

This commit is contained in:
Lennart Poettering 2012-07-31 16:09:01 +02:00
parent 4d9909c93e
commit 18c7ed186b
8 changed files with 140 additions and 6 deletions

View file

@ -557,6 +557,7 @@ MANPAGES_ALIAS = \
man/sd_journal_printv.3 \
man/sd_journal_send.3 \
man/sd_journal_sendv.3 \
man/sd_journal_perror.3 \
man/SD_JOURNAL_SUPPRESS_LOCATION.3 \
man/sd_journal_open_directory.3 \
man/sd_journal_close.3 \
@ -624,6 +625,7 @@ man/sd_id128_get_boot.3: man/sd_id128_get_machine.3
man/sd_journal_printv.3: man/sd_journal_print.3
man/sd_journal_send.3: man/sd_journal_print.3
man/sd_journal_sendv.3: man/sd_journal_print.3
man/sd_journal_perror.3: man/sd_journal_print.3
man/SD_JOURNAL_SUPPRESS_LOCATION.3: man/sd_journal_print.3
man/sd_journal_open_directory.3: man/sd_journal_open.3
man/sd_journal_close.3: man/sd_journal_open.3

View file

@ -89,7 +89,6 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\
-W \
-Wextra \
-Wno-inline \
-Wvla \
-Wundef \
-Wformat=2 \
-Wlogical-op \

View file

@ -47,6 +47,7 @@
<refname>sd_journal_printv</refname>
<refname>sd_journal_send</refname>
<refname>sd_journal_sendv</refname>
<refname>sd_journal_perror</refname>
<refname>SD_JOURNAL_SUPPRESS_LOCATION</refname>
<refpurpose>Submit log entries to the journal</refpurpose>
</refnamediv>
@ -81,6 +82,11 @@
<paramdef>int <parameter>n</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_journal_perror</function></funcdef>
<paramdef>const char* <parameter>message</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
@ -150,6 +156,21 @@
particularly useful to submit binary objects to the
journal where that is necessary.</para>
<para><function>sd_journal_perror()</function> is a
similar to
<citerefentry><refentrytitle>perror</refentrytitle><manvolnum>3</manvolnum></citerefentry>
and writes a message to the journal that consists of
the passed string, suffixed with ": " and a human
readable representation of the current error code
stored in
<citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If
the message string is passed as NULL or empty string
only the error string representation will be written,
prefixed with nothing. An additional journal field
ERRNO= is included in the entry containing the numeric
error code formatted as decimal string. The log
priority used is <literal>LOG_ERR</literal> (3).</para>
<para>Note that <function>sd_journal_send()</function>
is a wrapper around
<function>sd_journal_sendv()</function> to make it
@ -191,8 +212,10 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(
<refsect1>
<title>Return Value</title>
<para>The four calls return 0 on success or a
negative errno-style error code.</para>
<para>The four calls return 0 on success or a negative
errno-style error code. The
<citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
variable itself is not altered.</para>
</refsect1>
<refsect1>
@ -217,6 +240,8 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid(
<citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_journal_stream_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>perror</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
</para>
</refsect1>

View file

@ -132,6 +132,19 @@
</listitem>
</varlistentry>
<varlistentry>
<term>ERRNO=</term>
<listitem>
<para>The low-level Unix error
number causing this entry, if
any. Contains the numeric
value of
<citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>
formatted as decimal
string.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>SYSLOG_FACILITY=</term>
<term>SYSLOG_IDENTIFIER=</term>

View file

@ -73,8 +73,11 @@ _public_ int sd_journal_print(int priority, const char *format, ...) {
}
_public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
char buffer[8 + LINE_MAX], p[11];
struct iovec iov[2];
/* FIXME: Instead of limiting things to LINE_MAX we could do a
C99 variable-length array on the stack here in a loop. */
char buffer[8 + LINE_MAX], p[11]; struct iovec iov[2];
if (priority < 0 || priority > 7)
return -EINVAL;
@ -340,6 +343,63 @@ finish:
return r;
}
static int fill_iovec_perror_and_send(const char *message, int skip, struct iovec iov[]) {
size_t n, k, r;
int saved_errno;
saved_errno = errno;
k = isempty(message) ? 0 : strlen(message) + 2;
n = 8 + k + 256 + 1;
for (;;) {
char buffer[n];
char* j;
errno = 0;
j = strerror_r(saved_errno, buffer + 8 + k, n - 8 - k);
if (errno == 0) {
char error[6 + 10 + 1]; /* for a 32bit value */
if (j != buffer + 8 + k)
memmove(buffer + 8 + k, j, strlen(j)+1);
memcpy(buffer, "MESSAGE=", 8);
if (k > 0) {
memcpy(buffer + 8, message, k - 2);
memcpy(buffer + 8 + k - 2, ": ", 2);
}
snprintf(error, sizeof(error), "ERRNO=%u", saved_errno);
char_array_0(error);
IOVEC_SET_STRING(iov[skip+0], "PRIORITY=3");
IOVEC_SET_STRING(iov[skip+1], buffer);
IOVEC_SET_STRING(iov[skip+2], error);
r = sd_journal_sendv(iov, skip + 3);
errno = saved_errno;
return r;
}
if (errno != ERANGE) {
r = -errno;
errno = saved_errno;
return r;
}
n *= 2;
}
}
_public_ int sd_journal_perror(const char *message) {
struct iovec iovec[3];
return fill_iovec_perror_and_send(message, 0, iovec);
}
_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) {
union sockaddr_union sa;
int fd;
@ -489,7 +549,11 @@ finish:
return r;
}
_public_ int sd_journal_sendv_with_location(const char *file, const char *line, const char *func, const struct iovec *iov, int n) {
_public_ int sd_journal_sendv_with_location(
const char *file, const char *line,
const char *func,
const struct iovec *iov, int n) {
struct iovec *niov;
char *f;
size_t fl;
@ -514,3 +578,24 @@ _public_ int sd_journal_sendv_with_location(const char *file, const char *line,
return sd_journal_sendv(niov, n);
}
_public_ int sd_journal_perror_with_location(
const char *file, const char *line,
const char *func,
const char *message) {
struct iovec iov[6];
size_t fl;
char *f;
fl = strlen(func);
f = alloca(fl + 10);
memcpy(f, "CODE_FUNC=", 10);
memcpy(f + 10, func, fl + 1);
IOVEC_SET_STRING(iov[0], file);
IOVEC_SET_STRING(iov[1], line);
IOVEC_SET_STRING(iov[2], f);
return fill_iovec_perror_and_send(message, 3, iov);
}

View file

@ -63,4 +63,6 @@ global:
sd_journal_wait;
sd_journal_open_directory;
sd_journal_add_disjunction;
sd_journal_perror;
sd_journal_perror_with_location;
} LIBSYSTEMD_JOURNAL_184;

View file

@ -32,5 +32,10 @@ int main(int argc, char *argv[]) {
"VALUE=%i", 7,
NULL);
errno = ENOENT;
sd_journal_perror("Foobar");
sd_journal_perror("");
return 0;
}

View file

@ -41,12 +41,14 @@ int sd_journal_print(int priority, const char *format, ...) __attribute__ ((form
int sd_journal_printv(int priority, const char *format, va_list ap);
int sd_journal_send(const char *format, ...) __attribute__((sentinel));
int sd_journal_sendv(const struct iovec *iov, int n);
int sd_journal_perror(const char *message);
/* Used by the macros below. Don't call this directly. */
int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap);
int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) __attribute__((sentinel));
int sd_journal_sendv_with_location(const char *file, const char *line, const char *func, const struct iovec *iov, int n);
int sd_journal_perror_with_location(const char *file, const char *line, const char *func, const char *message);
/* implicitly add code location to messages sent, if this is enabled */
#ifndef SD_JOURNAL_SUPPRESS_LOCATION
@ -58,6 +60,7 @@ int sd_journal_sendv_with_location(const char *file, const char *line, const cha
#define sd_journal_printv(priority, format, ap) sd_journal_printv_with_location(priority, "CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, format, ap)
#define sd_journal_send(...) sd_journal_send_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, __VA_ARGS__)
#define sd_journal_sendv(iovec, n) sd_journal_sendv_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, iovec, n)
#define sd_journal_perror(message) sd_journal_perror_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, message)
#endif