|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <cassert>
 | 
					
						
							|  |  |  | #include <pthread.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <cstdint>
 | 
					
						
							|  |  |  | #include <cstdio>
 | 
					
						
							|  |  |  | #include <memory>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <capnp/serialize.h>
 | 
					
						
							|  |  |  | #include <kj/array.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #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<capnp::byte> 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<RawFile> log, q_log;
 | 
					
						
							|  |  |  | } LoggerHandle;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct LoggerState {
 | 
					
						
							|  |  |  |   pthread_mutex_t lock;
 | 
					
						
							|  |  |  |   int part;
 | 
					
						
							|  |  |  |   kj::Array<capnp::word> init_data;
 | 
					
						
							|  |  |  |   std::string route_name;
 | 
					
						
							|  |  |  |   char log_name[64];
 | 
					
						
							|  |  |  |   bool has_qlog;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   LoggerHandle handles[LOGGER_MAX_HANDLES];
 | 
					
						
							|  |  |  |   LoggerHandle* cur_handle;
 | 
					
						
							|  |  |  | } LoggerState;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | kj::Array<capnp::word> 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);
 |