#pragma once #include #include #include #include #include #include #include #include #include "cereal/messaging/messaging.h" #include "common/util.h" #include "common/swaglog.h" #include "system/hardware/hw.h" const std::string LOG_ROOT = Path::log_root(); #define LOGGER_MAX_HANDLES 16 class RawFile { public: RawFile(const char* path) { file = util::safe_fopen(path, "wb"); assert(file != nullptr); } ~RawFile() { util::safe_fflush(file); int err = fclose(file); assert(err == 0); } inline void write(void* data, size_t size) { int written = util::safe_fwrite(data, 1, size, file); assert(written == size); } inline void write(kj::ArrayPtr array) { write(array.begin(), array.size()); } private: FILE* file = nullptr; }; typedef cereal::Sentinel::SentinelType SentinelType; typedef struct LoggerHandle { pthread_mutex_t lock; SentinelType end_sentinel_type; int exit_signal; int refcnt; char segment_path[4096]; char log_path[4096]; char qlog_path[4096]; char lock_path[4096]; std::unique_ptr log, q_log; } LoggerHandle; typedef struct LoggerState { pthread_mutex_t lock; int part; kj::Array init_data; std::string route_name; char log_name[64]; bool has_qlog; LoggerHandle handles[LOGGER_MAX_HANDLES]; LoggerHandle* cur_handle; } LoggerState; kj::Array logger_build_init_data(); std::string logger_get_route_name(); void logger_init(LoggerState *s, bool has_qlog); int logger_next(LoggerState *s, const char* root_path, char* out_segment_path, size_t out_segment_path_len, int* out_part); LoggerHandle* logger_get_handle(LoggerState *s); void logger_close(LoggerState *s, ExitHandler *exit_handler=nullptr); void logger_log(LoggerState *s, uint8_t* data, size_t data_size, bool in_qlog); void lh_log(LoggerHandle* h, uint8_t* data, size_t data_size, bool in_qlog); void lh_close(LoggerHandle* h);