summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Herrmann <fherrmann@de.adit-jv.com>2020-01-10 16:03:07 +0100
committerSaya Sugiura <39760799+ssugiura@users.noreply.github.com>2020-07-06 10:04:07 +0900
commitc79ac621dbb7e774c90079ee1682857b4b0a2cfa (patch)
treebecb54377e60609fe71524940f88830043be1ee2
parentabb804937568b4fdf8e9c375b7ec2819c50f5eb9 (diff)
downloadDLT-daemon-c79ac621dbb7e774c90079ee1682857b4b0a2cfa.tar.gz
android logd forwarder
Signed-off-by: Felix Herrmann <fherrmann@de.adit-jv.com>
-rw-r--r--.gitignore4
-rw-r--r--Android.bp30
-rw-r--r--src/android/dlt-logd-converter.cpp236
-rw-r--r--src/android/dlt-logd-converter.rc4
-rw-r--r--src/daemon/dlt-daemon.rc4
5 files changed, 276 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 4178bd7..9268a3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,8 @@ include/dlt/dlt_version.h
.cproject
.settings
.idea/
+*~
+*.o
+*.out
+*.swp
cmake-build-debug/
diff --git a/Android.bp b/Android.bp
index b50115a..54ef69e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -52,11 +52,9 @@ cc_binary {
name: "dlt-daemon",
defaults: ["dlt_defaults"],
- /*
init_rc: [
"src/daemon/dlt-daemon.rc",
],
- */
local_include_dirs: [
"src/daemon",
@@ -151,4 +149,32 @@ cc_binary {
],
}
+cc_binary {
+
+ name: "dlt-logd-converter",
+ vendor: true,
+
+ srcs: [
+ "src/android/dlt-logd-converter.cpp",
+ ],
+ init_rc: [
+ "src/android/dlt-logd-converter.rc",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Wpedantic",
+ "-std=c++14",
+
+ ],
+ shared_libs: [
+ "libdlt",
+ "liblog",
+ ],
+ include_dirs: [
+ "system/core/include",
+ ],
+}
+
// vim: ft=python
diff --git a/src/android/dlt-logd-converter.cpp b/src/android/dlt-logd-converter.cpp
new file mode 100644
index 0000000..509ea81
--- /dev/null
+++ b/src/android/dlt-logd-converter.cpp
@@ -0,0 +1,236 @@
+/**
+ * @licence app begin@
+ * Copyright (C) 2019 Advanced Driver Information Technology.
+ * This code is developed by Advanced Driver Information Technology.
+ * Copyright of Advanced Driver Information Technology, Bosch and DENSO.
+ *
+ * DLT logd converter: Retrieve log entries from logd and forward them to DLT.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file: dlt-logd-convert
+ * For further information see http://www.genivi.org/.
+ * @licence end@
+ */
+#include <cerrno>
+#include <cstring>
+#include <cstdio>
+#include <cstdlib>
+#include <csignal>
+
+#include <log/log_read.h>
+#include <log/logprint.h>
+
+#include <dlt.h>
+
+DLT_DECLARE_CONTEXT(dlt_ctx_self)
+DLT_DECLARE_CONTEXT(dlt_ctx_main)
+DLT_DECLARE_CONTEXT(dlt_ctx_rdio)
+DLT_DECLARE_CONTEXT(dlt_ctx_evnt) /* Binary Buffer */
+DLT_DECLARE_CONTEXT(dlt_ctx_syst)
+DLT_DECLARE_CONTEXT(dlt_ctx_crsh) /* Binary Buffer */
+DLT_DECLARE_CONTEXT(dlt_ctx_stat) /* Binary Buffer */
+DLT_DECLARE_CONTEXT(dlt_ctx_secu) /* Binary Buffer */
+DLT_DECLARE_CONTEXT(dlt_ctx_krnl)
+
+volatile sig_atomic_t exit_parser_loop = false;
+
+static inline struct logger *init_logger(struct logger_list *logger_list, log_id_t log_id)
+{
+ struct logger *logger;
+ logger = android_logger_open(logger_list, log_id);
+ if (logger == nullptr) {
+ DLT_LOG(dlt_ctx_self, DLT_LOG_WARN, DLT_STRING("could not open logd buffer id="), DLT_INT64(log_id));
+ }
+ return logger;
+}
+
+static struct logger_list *init_logger_list(bool skip_binary_buffers)
+{
+ struct logger_list *logger_list;
+ logger_list = android_logger_list_alloc(ANDROID_LOG_RDONLY, 0, 0);
+ if (logger_list == nullptr) {
+ DLT_LOG(dlt_ctx_self, DLT_LOG_FATAL, DLT_STRING("could not allocate logger list"));
+ return nullptr;
+ }
+
+ /**
+ * logd buffer types are defined in:
+ * system/core/include/log/android/log.h
+ */
+ init_logger(logger_list, LOG_ID_MAIN);
+ init_logger(logger_list, LOG_ID_RADIO);
+ init_logger(logger_list, LOG_ID_SYSTEM);
+ init_logger(logger_list, LOG_ID_KERNEL);
+
+ if (!skip_binary_buffers) {
+ init_logger(logger_list, LOG_ID_CRASH);
+ init_logger(logger_list, LOG_ID_EVENTS);
+ init_logger(logger_list, LOG_ID_STATS);
+ init_logger(logger_list, LOG_ID_SECURITY);
+ }
+
+ return logger_list;
+}
+
+static DltContext *get_log_context_from_log_msg(struct log_msg *log_msg)
+{
+ switch (log_msg->id()) {
+ case LOG_ID_MAIN:
+ return &dlt_ctx_main;
+ case LOG_ID_RADIO:
+ return &dlt_ctx_rdio;
+ case LOG_ID_EVENTS:
+ return &dlt_ctx_evnt;
+ case LOG_ID_SYSTEM:
+ return &dlt_ctx_syst;
+ case LOG_ID_CRASH:
+ return &dlt_ctx_crsh;
+ case LOG_ID_STATS:
+ return &dlt_ctx_stat;
+ case LOG_ID_SECURITY:
+ return &dlt_ctx_secu;
+ case LOG_ID_KERNEL:
+ return &dlt_ctx_krnl;
+ default:
+ return &dlt_ctx_self;
+ }
+}
+
+static uint32_t get_timestamp_from_log_msg(struct log_msg *log_msg)
+{
+ /* in 0.1 ms = 100 us */
+ return (uint32_t)log_msg->entry.sec * 10000 + (uint32_t)log_msg->entry.nsec / 100000;
+}
+
+static DltLogLevelType get_log_level_from_log_msg(struct log_msg *log_msg)
+{
+ android_LogPriority priority = static_cast<android_LogPriority>(log_msg->buf[0]);
+ switch (priority) {
+ case ANDROID_LOG_VERBOSE:
+ return DLT_LOG_VERBOSE;
+ case ANDROID_LOG_DEBUG:
+ return DLT_LOG_DEBUG;
+ case ANDROID_LOG_INFO:
+ return DLT_LOG_INFO;
+ case ANDROID_LOG_WARN:
+ return DLT_LOG_WARN;
+ case ANDROID_LOG_ERROR:
+ return DLT_LOG_ERROR;
+ case ANDROID_LOG_FATAL:
+ return DLT_LOG_FATAL;
+ case ANDROID_LOG_SILENT:
+ return DLT_LOG_OFF;
+ case ANDROID_LOG_UNKNOWN:
+ case ANDROID_LOG_DEFAULT:
+ default:
+ return DLT_LOG_DEFAULT;
+ }
+}
+
+void signal_handler(int signal)
+{
+ (void) signal;
+ if (signal == SIGTERM) {
+ exit_parser_loop = true;
+ }
+}
+
+static int logd_parser_loop(struct logger_list *logger_list)
+{
+ struct log_msg log_msg;
+ int ret;
+
+ DLT_LOG(dlt_ctx_self, DLT_LOG_VERBOSE, DLT_STRING("Entering parsing loop"));
+
+ while (!exit_parser_loop) {
+ ret = android_logger_list_read(logger_list, &log_msg);
+ if (ret == -EAGAIN || ret == -EINTR) {
+ if (exit_parser_loop == true) {
+ break;
+ }
+ continue;
+ } else if (ret == -EINVAL || ret == -ENOMEM || ret == -ENODEV || ret == -EIO) {
+ DLT_LOG(dlt_ctx_self, DLT_LOG_FATAL, DLT_STRING("Could not cannot retrieve logs, permanent error="), DLT_INT32(ret));
+ return ret;
+ } else if (ret <= 0) {
+ DLT_LOG(dlt_ctx_self, DLT_LOG_ERROR, DLT_STRING("android_logger_list_read unexpected return="), DLT_INT32(ret));
+ return ret;
+ }
+
+ DltContext *ctx = nullptr;
+ ctx = get_log_context_from_log_msg(&log_msg);
+
+ DltLogLevelType log_level;
+ log_level = get_log_level_from_log_msg(&log_msg);
+
+ /* Look into system/core/liblog/logprint.c for buffer format */
+ auto tag = log_msg.msg()+1;
+ auto message = tag+strlen(tag)+1;
+
+ uint32_t ts;
+ ts = get_timestamp_from_log_msg(&log_msg);
+
+ /* Binary buffers are not supported by DLT_STRING DLT_RAW would need the message length */
+ DLT_LOG_TS(*ctx, log_level, ts,
+ DLT_STRING(tag),
+ DLT_INT32(log_msg.entry.pid),
+ DLT_UINT32(log_msg.entry.tid),
+ DLT_STRING(message));
+ }
+
+ DLT_LOG(dlt_ctx_self, DLT_LOG_VERBOSE, DLT_STRING("Exited parsing loop"));
+
+ return EXIT_SUCCESS;
+}
+
+int main(int argc, char *argv[])
+{
+ (void) argc;
+ (void) argv;
+
+ DLT_REGISTER_APP("LOGD", "logd -> dlt adapter");
+ DLT_REGISTER_CONTEXT(dlt_ctx_self, "LOGF", "logd retriever");
+ DLT_REGISTER_CONTEXT(dlt_ctx_main, "MAIN", "logd type: main");
+ DLT_REGISTER_CONTEXT(dlt_ctx_rdio, "RDIO", "logd type: rdio");
+ DLT_REGISTER_CONTEXT(dlt_ctx_evnt, "EVNT", "logd type: evnt");
+ DLT_REGISTER_CONTEXT(dlt_ctx_syst, "SYST", "logd type: syst");
+ DLT_REGISTER_CONTEXT(dlt_ctx_crsh, "CRSH", "logd type: crsh");
+ DLT_REGISTER_CONTEXT(dlt_ctx_stat, "STAT", "logd type: stat");
+ DLT_REGISTER_CONTEXT(dlt_ctx_secu, "SECU", "logd type: secu");
+ DLT_REGISTER_CONTEXT(dlt_ctx_krnl, "KRNL", "logd type: krnl");
+
+ struct sigaction act;
+ act.sa_handler = signal_handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ sigaction(SIGTERM, &act, 0);
+
+ struct logger_list *logger_list;
+ /* Binary buffers are currently not supported */
+ logger_list = init_logger_list(true);
+ if (logger_list == nullptr)
+ return EXIT_FAILURE;
+
+ int ret;
+ ret = logd_parser_loop(logger_list); /* Main loop */
+
+ android_logger_list_free(logger_list);
+
+ DLT_UNREGISTER_CONTEXT(dlt_ctx_krnl);
+ DLT_UNREGISTER_CONTEXT(dlt_ctx_secu);
+ DLT_UNREGISTER_CONTEXT(dlt_ctx_stat);
+ DLT_UNREGISTER_CONTEXT(dlt_ctx_crsh);
+ DLT_UNREGISTER_CONTEXT(dlt_ctx_syst);
+ DLT_UNREGISTER_CONTEXT(dlt_ctx_evnt);
+ DLT_UNREGISTER_CONTEXT(dlt_ctx_rdio);
+ DLT_UNREGISTER_CONTEXT(dlt_ctx_main);
+ DLT_UNREGISTER_CONTEXT(dlt_ctx_self);
+
+ DLT_UNREGISTER_APP_FLUSH_BUFFERED_LOGS();
+
+ return ret;
+}
diff --git a/src/android/dlt-logd-converter.rc b/src/android/dlt-logd-converter.rc
new file mode 100644
index 0000000..7e8b0c6
--- /dev/null
+++ b/src/android/dlt-logd-converter.rc
@@ -0,0 +1,4 @@
+service dlt-logd-converter /vendor/bin/dlt-logd-converter
+ class late_start
+ user system
+ group system
diff --git a/src/daemon/dlt-daemon.rc b/src/daemon/dlt-daemon.rc
new file mode 100644
index 0000000..7a7bc0e
--- /dev/null
+++ b/src/daemon/dlt-daemon.rc
@@ -0,0 +1,4 @@
+service dlt-daemon /vendor/bin/dlt-daemon
+ class late_start
+ user root
+ group root