diff --git a/selfdrive/loggerd/bootlog.cc b/selfdrive/loggerd/bootlog.cc index 0da38728..e15d84c5 100644 --- a/selfdrive/loggerd/bootlog.cc +++ b/selfdrive/loggerd/bootlog.cc @@ -1,37 +1,60 @@ #include #include +#include + +#include #include "common/swaglog.h" #include "common/util.h" -#include "logger.h" #include "messaging.hpp" +#include "logger.h" int main(int argc, char** argv) { - LoggerState logger; - logger_init(&logger, "bootlog", false); + char filename[64] = {'\0'}; - char segment_path[4096]; - int err = logger_next(&logger, LOG_ROOT.c_str(), segment_path, sizeof(segment_path), nullptr); - assert(err == 0); - LOGW("bootlog to %s", segment_path); + time_t rawtime = time(NULL); + struct tm timeinfo; - MessageBuilder msg; - auto boot = msg.initEvent().initBoot(); + localtime_r(&rawtime, &timeinfo); + strftime(filename, sizeof(filename), + "%Y-%m-%d--%H-%M-%S.bz2", &timeinfo); - boot.setWallTimeNanos(nanos_since_epoch()); + std::string path = LOG_ROOT + "/boot/" + std::string(filename); + LOGW("bootlog to %s", path.c_str()); - std::string lastKmsg = util::read_file("/sys/fs/pstore/console-ramoops"); - boot.setLastKmsg(capnp::Data::Reader((const kj::byte*)lastKmsg.data(), lastKmsg.size())); + MessageBuilder boot_msg; + logger_build_boot(boot_msg); - std::string lastPmsg = util::read_file("/sys/fs/pstore/pmsg-ramoops-0"); - boot.setLastPmsg(capnp::Data::Reader((const kj::byte*)lastPmsg.data(), lastPmsg.size())); + MessageBuilder init_msg; + logger_build_init_data(init_msg); - std::string launchLog = util::read_file("/tmp/launch_log"); - boot.setLaunchLog(capnp::Text::Reader(launchLog.data(), launchLog.size())); - auto bytes = msg.toBytes(); - logger_log(&logger, bytes.begin(), bytes.size(), false); + // Open bootlog + int r = logger_mkpath((char*)path.c_str()); + assert(r == 0); - logger_close(&logger); + FILE * file = fopen(path.c_str(), "wb"); + assert(file != nullptr); + + // Open as bz2 + int bzerror; + BZFILE* bz_file = BZ2_bzWriteOpen(&bzerror, file, 9, 0, 30); + assert(bzerror == BZ_OK); + + // Write initdata + auto bytes = init_msg.toBytes(); + BZ2_bzWrite(&bzerror, bz_file, bytes.begin(), bytes.size()); + assert(bzerror == BZ_OK); + + // Write bootlog + bytes = boot_msg.toBytes(); + BZ2_bzWrite(&bzerror, bz_file, bytes.begin(), bytes.size()); + assert(bzerror == BZ_OK); + + // Close bz2 and file + BZ2_bzWriteClose(&bzerror, bz_file, 0, NULL, NULL); + assert(bzerror == BZ_OK); + + fclose(file); return 0; } diff --git a/selfdrive/loggerd/config.py b/selfdrive/loggerd/config.py index f859e8cb..3f82b9f8 100644 --- a/selfdrive/loggerd/config.py +++ b/selfdrive/loggerd/config.py @@ -1,8 +1,11 @@ import os +from pathlib import Path +from selfdrive.hardware import PC if os.environ.get('LOGGERD_ROOT', False): ROOT = os.environ['LOGGERD_ROOT'] - print("Custom loggerd root: ", ROOT) +elif PC: + ROOT = os.path.join(str(Path.home()), ".comma", "media", "0", "realdata") else: ROOT = '/data/media/0/realdata/' diff --git a/selfdrive/loggerd/logger.cc b/selfdrive/loggerd/logger.cc index a4e35426..a6f22326 100644 --- a/selfdrive/loggerd/logger.cc +++ b/selfdrive/loggerd/logger.cc @@ -35,7 +35,7 @@ void append_property(const char* key, const char* value, void *cookie) { properties->push_back(std::make_pair(std::string(key), std::string(value))); } -static int mkpath(char* file_path) { +int logger_mkpath(char* file_path) { assert(file_path && *file_path); char* p; for (p=strchr(file_path+1, '/'); p; p=strchr(p+1, '/')) { @@ -52,9 +52,22 @@ static int mkpath(char* file_path) { } // ***** log metadata ***** +void logger_build_boot(MessageBuilder &msg) { + auto boot = msg.initEvent().initBoot(); -void log_init_data(LoggerState *s) { - MessageBuilder msg; + boot.setWallTimeNanos(nanos_since_epoch()); + + std::string lastKmsg = util::read_file("/sys/fs/pstore/console-ramoops"); + boot.setLastKmsg(capnp::Data::Reader((const kj::byte*)lastKmsg.data(), lastKmsg.size())); + + std::string lastPmsg = util::read_file("/sys/fs/pstore/pmsg-ramoops-0"); + boot.setLastPmsg(capnp::Data::Reader((const kj::byte*)lastPmsg.data(), lastPmsg.size())); + + std::string launchLog = util::read_file("/tmp/launch_log"); + boot.setLaunchLog(capnp::Text::Reader(launchLog.data(), launchLog.size())); +} + +void logger_build_init_data(MessageBuilder &msg) { auto init = msg.initEvent().initInitData(); if (util::file_exists("/EON")) { @@ -119,7 +132,11 @@ void log_init_data(LoggerState *s) { i++; } } +} +void log_init_data(LoggerState *s) { + MessageBuilder msg; + logger_build_init_data(msg); auto bytes = msg.toBytes(); logger_log(s, bytes.begin(), bytes.size(), s->has_qlog); } @@ -174,7 +191,7 @@ static LoggerHandle* logger_open(LoggerState *s, const char* root_path) { snprintf(h->qlog_path, sizeof(h->qlog_path), "%s/qlog.bz2", h->segment_path); snprintf(h->lock_path, sizeof(h->lock_path), "%s.lock", h->log_path); - err = mkpath(h->log_path); + err = logger_mkpath(h->log_path); if (err) return NULL; FILE* lock_file = fopen(h->lock_path, "wb"); diff --git a/selfdrive/loggerd/logger.h b/selfdrive/loggerd/logger.h index d845d197..fc05513e 100644 --- a/selfdrive/loggerd/logger.h +++ b/selfdrive/loggerd/logger.h @@ -40,6 +40,9 @@ typedef struct LoggerState { LoggerHandle* cur_handle; } LoggerState; +int logger_mkpath(char* file_path); +void logger_build_boot(MessageBuilder &msg); +void logger_build_init_data(MessageBuilder &msg); void logger_init(LoggerState *s, const char* log_name, bool has_qlog); int logger_next(LoggerState *s, const char* root_path, char* out_segment_path, size_t out_segment_path_len, diff --git a/selfdrive/loggerd/tests/test_loggerd.py b/selfdrive/loggerd/tests/test_loggerd.py index 6389c1d7..c7d1e6ad 100755 --- a/selfdrive/loggerd/tests/test_loggerd.py +++ b/selfdrive/loggerd/tests/test_loggerd.py @@ -45,15 +45,23 @@ class TestLoggerd(unittest.TestCase): return path return None + def _get_log_fn(self, x): + for p in x.split(' '): + path = Path(p.strip()) + if path.is_file(): + return path + return None + def _gen_bootlog(self): with Timeout(5): out = subprocess.check_output("./bootlog", cwd=os.path.join(BASEDIR, "selfdrive/loggerd"), encoding='utf-8') + log_fn = self._get_log_fn(out) + # check existence - d = self._get_log_dir(out) - path = Path(os.path.join(d, "bootlog.bz2")) - assert path.is_file(), "failed to create bootlog file" - return path + assert log_fn is not None + + return log_fn def _check_init_data(self, msgs): msg = msgs[0] @@ -131,11 +139,9 @@ class TestLoggerd(unittest.TestCase): lr = list(LogReader(str(bootlog_path))) # check length - assert len(lr) == 4 # boot + initData + 2x sentinel - - # check initData and sentinel + assert len(lr) == 2 # boot + initData + self._check_init_data(lr) - self._check_sentinel(lr, True) # check msgs bootlog_msgs = [m for m in lr if m.which() == 'boot'] diff --git a/selfdrive/loggerd/uploader.py b/selfdrive/loggerd/uploader.py index 1e84cbd0..15376761 100644 --- a/selfdrive/loggerd/uploader.py +++ b/selfdrive/loggerd/uploader.py @@ -58,7 +58,7 @@ class Uploader(): self.last_resp = None self.last_exc = None - self.immediate_folders = ["crash/"] + self.immediate_folders = ["crash/", "boot/"] self.immediate_priority = {"qlog.bz2": 0, "qcamera.ts": 1} self.high_priority = {"rlog.bz2": 0, "fcamera.hevc": 1, "dcamera.hevc": 2, "ecamera.hevc": 3}