armink / EasyLogger

An ultra-lightweight(ROM<1.6K, RAM<0.3k), high-performance C/C++ log library. | 一款超轻量级(ROM<1.6K, RAM<0.3k)、高性能的 C/C++ 日志库
MIT License
3.77k stars 1.17k forks source link

异步输出如何保证输出日志的完整? #161

Open Zeedff opened 1 week ago

Zeedff commented 1 week ago

例如我将日志存储在一个10K环形缓冲区内,每次取5K的数据输出,但是会出现数据截取5K数据最后一条Log不完整改怎么解决?

void elog_async_restore_data(size_t size){
    uint32_t recoveryCount = 0;
    recoveryCount = last_read_index;
    recoveryCount =  (recoveryCount < size) ? recoveryCount : size;
    read_index += (last_read_index - recoveryCount);
    while(read_index >= ELOG_ASYNC_OUTPUT_BUF_SIZE)
    {
        read_index -= ELOG_ASYNC_OUTPUT_BUF_SIZE;
    }

    last_read_index = 0;
}
size_t elog_async_get_logchunk(char *log, size_t size) {
    size_t used = 0;
    /* lock output */
    elog_output_lock();
    used = elog_async_get_buf_used();
    /* no log */
    if (!used || !size || last_read_index) {
        size = 0;
        goto __exit;
    }
    /* less log */
    if (used < size) {
        size = 0;
        buf_is_empty = true;
    }
    else
    {
        memcpy(log,log_buf + read_index,size);
        read_index = (read_index + size) > OUTPUT_BUF_SIZE ?  OUTPUT_BUF_SIZE : read_index + size;  
    }
    last_read_index = size;
    buf_is_full = false;
__exit:
    /* lock output */
    elog_output_unlock();
    return size;
}
size_t When_Close_get_logchunk(char *log, size_t size) {
    size_t used = 0;
    size_t bytes_to_copy = 0;

    used = elog_async_get_buf_used();

    if (!used) {
        return 0;
    }

    bytes_to_copy = (used < size) ? used : size;

    if (read_index + bytes_to_copy <= OUTPUT_BUF_SIZE) 
    {
        memcpy(log, log_buf + read_index, bytes_to_copy);
    } 
    else 
    {

        size_t first_part_size = OUTPUT_BUF_SIZE - read_index;
        memcpy(log, log_buf + read_index, OUTPUT_BUF_SIZE - read_index);
        memcpy(log + first_part_size, log_buf, bytes_to_copy - first_part_size);
    }

    read_index += bytes_to_copy;

    if (read_index >= OUTPUT_BUF_SIZE) {
        read_index -= OUTPUT_BUF_SIZE;
    }

    last_read_index = read_index;

    if (used == bytes_to_copy) {
        buf_is_empty = true;
    }
    return bytes_to_copy;
}
switch (msg.instruction)
{
        case 1: //Open
        {
            get_log_size = elog_async_get_logchunk(log_Writebuf,LOG_CHUNK_SIZE);
            if(get_log_size>=LOG_CHUNK_SIZE)
            {
//                      uint16_t strLen = strlen(log_Writebuf);
//                      if(strLen > LOG_CHUNK_SIZE) strLen = LOG_CHUNK_SIZE;
                Log_Write(FileName, log_Writebuf, LOG_CHUNK_SIZE,NULL);
                elog_async_restore_data(LOG_CHUNK_SIZE);
                memset(log_Writebuf,0,LOG_CHUNK_SIZE);
                get_log_size = 0;                           
            }
            break;
        }
        case 0: //Close
        {
            get_log_size = When_Close_get_logchunk(log_Writebuf_WhenClose, ELOG_LINE_BUF_SIZE);
            uint16_t strLen = strlen(log_Writebuf);
            if (strLen > LOG_CHUNK_SIZE) strLen = LOG_CHUNK_SIZE;
            //
            Log_Write(FileName, log_Writebuf_WhenClose, strLen,1);

            elog_async_restore_data(LOG_CHUNK_SIZE);
            memset(log_Writebuf, 0, sizeof(log_Writebuf));              
            Send_Control(2,NULL);       //4:
            break;
        }
    }
}
ancientwaiting commented 1 week ago

Got your email, thank you!Will reply you asap