c++ Как организовать бинарный лог (журнал)

Phoenix

Задался вопросом, как можно сделать бинарный лог с фиксированным количеством логгируемых структур, но чтобы новую структуру можно было удобно и быстро добавить при желании, не было дубливания кода, тем более в разных местах и удобно было пользоваться.
Пришёл к такому
 
 
enum class LogDataType : uint8_t
{
DiffRecv = 1,
DiffSend
};

struct LogHeader
{
timestamp_t moment;
LogDataType type;
int8_t body_size;
};

struct LogDiffRecv
{
static const LogDataType type = LogDataType::DiffRecv;
timestamp_t ts_stock;
timestamp_t ts_recv;
LogDiffRecv
{

}
LogDiffRecv(timestamp_t u_ts_stock, timestamp_t u_ts_recv):
ts_stock(u_ts_stock
ts_recv(u_ts_recv)
{
}
};

class BinaryLogger
{
std::string name_;

public:
void write(void *ptr, size_t size)
{

}

template <class T> void log(timestamp_t ts, T &&data)
{
LogHeader hdr;
hdr.type = data.type;
hdr.body_size = sizeof(T);
hdr.moment = ts;

this->writevoid*)&hdr, sizeof(hdr;
this->writevoid*)&data, sizeof(data;
}
};


logger_.log(123, LogDiffRecv(12345, 54321;

проблемы:
1. Ничто не мешает определить две структуры с одним LogDataType. Самое неприятное, что обнаружится это только при чтении, а запишется всё ок.
2. приходится определять конструктор, есть шанс забыть добавить туда какое-нибудь поле. Не так страшно, но всё равно лишние повторения.
3. Что если надо добавить/удалить поле в структуре? Тогда новые и старые структуры не будут читаться одновременно (by )
Можно как-нибудь избавиться от этих проблем, не создав новых?

istran

Вижу еще проблемы. Что если надо добавить/удалить поле в структуре? Что если структура не POD? Что если надо прочитать лог на машине с другой архитектурой/программой собраной другим компилятором?
Я бы не стал городить велосипеды, а использовал что-нибудь готовое. Например google-protobuf.

Phoenix

Да, добавил проблему.
За наводку спасибо - поизучаю

Garryss

Всё правильно тебе сказал — google-protobuf идеально подходит.
Однако, полагаю, что помимо механизма сериализации/десерализации одной записи, тебе потребуется механизм записи последовательности сериализованных записей. А вот тут всё зависит от требований: нужно ли сжатие на лету? если да, то сжатие по одной записи или группами (более эффективно)? захочешь ли ты иметь возможность произвольного доступа, напр. прочитать запись из середины лога? и т.п. Например, в хадупе (ява) есть SequenceFile — тебе нужно что-то похожее, но на плюсах.

tokuchu

Тебя не Леннартом звать, случаем?

Phoenix

Нет, кто это?
Оставить комментарий
Имя или ник:
Комментарий: