diff --git a/system/logcatd/SConscript b/system/logcatd/SConscript new file mode 100644 index 0000000..6bd7c6f --- /dev/null +++ b/system/logcatd/SConscript @@ -0,0 +1,3 @@ +Import('env', 'cereal', 'messaging', 'common') + +env.Program('logcatd', 'logcatd_systemd.cc', LIBS=[cereal, messaging, common, 'zmq', 'capnp', 'kj', 'systemd', 'json11']) diff --git a/system/logcatd/logcatd b/system/logcatd/logcatd deleted file mode 100755 index 56804f5..0000000 Binary files a/system/logcatd/logcatd and /dev/null differ diff --git a/system/logcatd/logcatd_systemd.cc b/system/logcatd/logcatd_systemd.cc new file mode 100644 index 0000000..54b3782 --- /dev/null +++ b/system/logcatd/logcatd_systemd.cc @@ -0,0 +1,75 @@ +#include + +#include +#include +#include +#include + +#include "third_party/json11/json11.hpp" + +#include "cereal/messaging/messaging.h" +#include "common/timing.h" +#include "common/util.h" + +ExitHandler do_exit; +int main(int argc, char *argv[]) { + + PubMaster pm({"androidLog"}); + + sd_journal *journal; + int err = sd_journal_open(&journal, 0); + assert(err >= 0); + err = sd_journal_get_fd(journal); // needed so sd_journal_wait() works properly if files rotate + assert(err >= 0); + err = sd_journal_seek_tail(journal); + assert(err >= 0); + + // workaround for bug https://github.com/systemd/systemd/issues/9934 + // call sd_journal_previous_skip after sd_journal_seek_tail (like journalctl -f does) to makes things work. + sd_journal_previous_skip(journal, 1); + + while (!do_exit) { + err = sd_journal_next(journal); + assert(err >= 0); + + // Wait for new message if we didn't receive anything + if (err == 0) { + err = sd_journal_wait(journal, 1000 * 1000); + assert(err >= 0); + continue; // Try again + } + + uint64_t timestamp = 0; + err = sd_journal_get_realtime_usec(journal, ×tamp); + assert(err >= 0); + + const void *data; + size_t length; + std::map kv; + + SD_JOURNAL_FOREACH_DATA(journal, data, length) { + std::string str((char*)data, length); + + // Split "KEY=VALUE"" on "=" and put in map + std::size_t found = str.find("="); + if (found != std::string::npos) { + kv[str.substr(0, found)] = str.substr(found + 1, std::string::npos); + } + } + + MessageBuilder msg; + + // Build message + auto androidEntry = msg.initEvent().initAndroidLog(); + androidEntry.setTs(timestamp); + androidEntry.setMessage(json11::Json(kv).dump()); + if (kv.count("_PID")) androidEntry.setPid(std::atoi(kv["_PID"].c_str())); + if (kv.count("PRIORITY")) androidEntry.setPriority(std::atoi(kv["PRIORITY"].c_str())); + if (kv.count("SYSLOG_IDENTIFIER")) androidEntry.setTag(kv["SYSLOG_IDENTIFIER"]); + + pm.send("androidLog", msg); + } + + sd_journal_close(journal); + return 0; +}