From 874f68e0d4b9fca76f30a9ac62a80eb36aad00d0 Mon Sep 17 00:00:00 2001 From: Maciej Slodczyk Date: Fri, 9 Feb 2018 14:09:28 +0100 Subject: [PATCH] add monotonic send timestamp when using android backend feature is experimental and can be enabled/disabled with autoconf's configure script command line option Change-Id: I99b35d704789df343cfd051f7984c36d8b602709 Signed-off-by: Maciej Slodczyk --- configure.ac | 8 ++++++++ include/queued_entry.h | 12 ++++++++++++ src/libdlog/log_android.c | 21 +++++++++++++++++++-- src/shared/queued_entry.c | 34 +++++++++++++++++++++++++++++++--- 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index d16022f..eae8fe0 100644 --- a/configure.ac +++ b/configure.ac @@ -51,6 +51,14 @@ AC_ARG_ENABLE([server-group], AC_DEFINE_UNQUOTED([DLOG_SERVER_GROUP], "$dlog_server_group") AC_SUBST([DLOG_SERVER_GROUP], "$dlog_server_group") +AC_ARG_ENABLE([android-monotonic], + AS_HELP_STRING([--enable-android-monotonic], [use monotonic send timestamp with log message when using android backend (EXPERIMENTAL)]), + [android_monotonic=true], + [android_monotonic=false]) +if test x$android_monotonic = xtrue; then + AC_DEFINE_UNQUOTED([USE_ANDROID_MONOTONIC]) +fi + # output files AC_SUBST([datadir]) AC_SUBST([libexecdir]) diff --git a/include/queued_entry.h b/include/queued_entry.h index d80f3d2..e44ca30 100644 --- a/include/queued_entry.h +++ b/include/queued_entry.h @@ -65,6 +65,18 @@ struct android_logger_entry { char msg[]; }; +#ifdef USE_ANDROID_MONOTONIC + +#define ANDROID_LOGGER_FOOTER_MAGIC 0xa1379841 + +struct android_logger_footer { + uint32_t sec_sent_mono; /* time sent, seconds, monotonic */ + uint32_t nsec_sent_mono; /* time sent, nanoseconds, monotonic */ + uint32_t magic; /* arbitrary magic number, encode other info here (e.g. version number) in future versions, last field of structure no matter real version is */ +}; + +#endif /* USE_ANDROID_MONOTONIC */ + struct pipe_logger_entry { /* same meanings as above */ uint16_t len; diff --git a/src/libdlog/log_android.c b/src/libdlog/log_android.c index be1f5d9..8ff4cc7 100644 --- a/src/libdlog/log_android.c +++ b/src/libdlog/log_android.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -23,7 +24,6 @@ static int __write_to_log_android(log_id_t log_id, log_priority prio, const char { ssize_t ret; int log_fd; - struct iovec vec[3]; if (log_id > LOG_ID_INVALID && log_id < LOG_ID_MAX) log_fd = log_fds[log_id]; @@ -39,6 +39,23 @@ static int __write_to_log_android(log_id_t log_id, log_priority prio, const char if (!msg) return DLOG_ERROR_INVALID_PARAMETER; +#ifdef USE_ANDROID_MONOTONIC + struct iovec vec[4]; + + struct timespec ts; + struct android_logger_footer alf; + + clock_gettime(CLOCK_MONOTONIC, &ts); + alf.magic = ANDROID_LOGGER_FOOTER_MAGIC; + alf.sec_sent_mono = ts.tv_sec; + alf.nsec_sent_mono = ts.tv_nsec; + + vec[3].iov_base = (void *) &alf; + vec[3].iov_len = sizeof alf; +#else + struct iovec vec[3]; +#endif /* USE_ANDROID_MONOTONIC */ + vec[0].iov_base = (unsigned char *) &prio; vec[0].iov_len = 1; vec[1].iov_base = (void *) tag; @@ -46,7 +63,7 @@ static int __write_to_log_android(log_id_t log_id, log_priority prio, const char vec[2].iov_base = (void *) msg; vec[2].iov_len = strlen(msg) + 1; - ret = writev(log_fd, vec, 3); + ret = writev(log_fd, vec, NELEMS(vec)); if (ret < 0) ret = -errno; // LCOV_EXCL_LINE diff --git a/src/shared/queued_entry.c b/src/shared/queued_entry.c index b1890b1..e32dcc2 100644 --- a/src/shared/queued_entry.c +++ b/src/shared/queued_entry.c @@ -177,6 +177,27 @@ int parse_kmsg_message(char *buffer, struct logger_entry_with_msg *lem, int buff memmove(le->msg, xle->msg + 1, payload_size); \ } +#ifdef USE_ANDROID_MONOTONIC +static void parse_android_logger_footer(struct android_logger_entry *ale, struct logger_entry *le, size_t *payload_size) +{ + assert(ale); + assert(le); + assert(payload_size); + + struct android_logger_footer *alf; + if (*payload_size <= sizeof *alf) + return; + + alf = ale->msg + *payload_size - sizeof *alf; + if (alf->magic != ANDROID_LOGGER_FOOTER_MAGIC) + return; + + *payload_size -= sizeof *alf; + le->sec_sent_mono = alf->sec_sent_mono; + le->nsec_sent_mono = alf->nsec_sent_mono; +} +#endif + /** * @brief Parse AL message * @details Parses an Android Logger message into DLog's internal format @@ -187,13 +208,20 @@ int parse_kmsg_message(char *buffer, struct logger_entry_with_msg *lem, int buff void parse_androidlogger_message(struct android_logger_entry *ale, struct logger_entry *le, size_t dgram_size) { size_t payload_size = dgram_size - sizeof *ale; - assert(payload_size <= LOG_MAX_PAYLOAD_SIZE); + assert(payload_size > 0); + + le->sec_sent_mono = 0; + le->nsec_sent_mono = 0; +#ifdef USE_ANDROID_MONOTONIC + /* there may be android_logger_footer at the end of payload, right after log message, + * but only if the message has been prepared and sent by libdlog, + * not directly from shell script via /dev file */ + parse_android_logger_footer(ale, le, &payload_size); +#endif SHARED_PROCESS_MESSAGE(ale); le->sec_sent_real = ale->sec_sent; le->nsec_sent_real = ale->nsec_sent; - le->sec_sent_mono = 0; - le->nsec_sent_mono = 0; le->default_send_ts_type = LOGGER_ENTRY_REALTIME; } -- 2.7.4