自学内容网 自学内容网

一个c++的综合实例:log同步写入文件

1. 引言

功能

    通过一个API函数把log写入到文件中,分4个log level

目录
├── log
├── log.cpp
├── log.h
├── main.cpp
└── Makefile
 

2.代码 

文件:main.cpp

#include "log.h"

int main(int argc, char *argv[])
{
    Log::GetInstance().Init("./log");
    Log::GetInstance().WriteLog(ERROR,"error");
    Log::GetInstance().WriteLog(WARNING,"warning");
    Log::GetInstance().WriteLog(DEBUG,"debug");
    Log::GetInstance().WriteLog(INFO,"info");
}


文件:log.h

#ifndef LOG_H
#define LOG_H


#include <iostream>
#include <pthread.h>
#include <cstdio>

using namespace std;

typedef enum
{
    ERROR = 0,
    WARNING,
    DEBUG,
    INFO,
    LEVEL_MAX
}LogLevel_en;


typedef enum
{
    LOG_INIT_STATE,
    LOG_READY_STATE,
    LOG_INVALID_STATE
}LogState_en;


#define     LOG_NUM     255U

class Log
{
/*variable area */
private:
    char m_log_buf[LOG_NUM];
    pthread_mutex_t m_mutex;
    FILE *m_log_fd;
    LogState_en m_log_state;

/*function area */
public:
    static Log& GetInstance(void);
    void Init(const char *dir_file_name);
    void WriteLog(LogLevel_en log_level, const char* format, ...);

private:
    Log(void)
    {
        m_log_state = LOG_INVALID_STATE;
    };
    ~Log(void) = default;

};


#endif

文件:log.cpp 

#include "log.h"
#include <ctime>
#include <cstring>
#include <cstdarg>


Log& Log::GetInstance(void)
{
    static Log instance;
    return instance;
}

void Log::Init(const char *dir_file_name)
{
    if(nullptr != dir_file_name)
    {
        m_log_state = LOG_INIT_STATE;
        cout << dir_file_name << endl;
        m_log_fd = fopen(dir_file_name, "a");
    }
}


void Log::WriteLog(LogLevel_en log_level, const char* format, ...)
{
    /* Parameter check */
    if((LEVEL_MAX <= log_level) || (nullptr == format))
    {// parameter err
        return;
    }
    /* Log state check */
    if (LOG_INVALID_STATE == m_log_state)
    { // log state err
        return;
    }
    
    /* Set buffer log level string */
    char buffer_log_level[16] = {0};
    switch (log_level)
    {
        case ERROR:
            strcpy((char *)buffer_log_level, "[error]:");
            break;
        case WARNING:
            strcpy((char *)buffer_log_level, "[warning]:");
            break;
        case DEBUG:
            strcpy((char *)buffer_log_level, "[debug]:");
            break;
        case INFO:
            strcpy((char *)buffer_log_level, "[info]:");
            break;
        default:
            cout << "log level error" << endl;
            break;
    }

    /* Set time log string */
    time_t time_val = time(nullptr);
    struct tm *p_tm_val = localtime(&time_val);
    char buffer_time[48] = {0};
    snprintf(buffer_time, 48, "%.4d-%.2d-%.2d-%.2d-%.2d-%.2d:", 
        p_tm_val->tm_year + 1900,
        p_tm_val->tm_mon + 1,
        p_tm_val->tm_mday,
        p_tm_val->tm_hour,
        p_tm_val->tm_min,
        p_tm_val->tm_sec
    );

    /* Copy to m_buf */
    pthread_mutex_lock(&m_mutex);
    memset(m_log_buf, 0, sizeof(m_log_buf));
    u_int8_t log_len = strlen(buffer_log_level) + strlen(buffer_time) + 1;
    // cout << int(log_len) << endl;
    int n = snprintf(m_log_buf, log_len, "%s%s", buffer_log_level,buffer_time);
    if( 0 < n)
    {
        va_list variable_list;
        va_start(variable_list, format);
        int m = vsnprintf(m_log_buf + n, LOG_NUM - n - 1, format, variable_list);
        va_end(variable_list);
        if(0 < m)
        {
            cout << m_log_buf << endl;
        }
        else
        {
            cout << "vsnprintf err!" << endl;
        }
        m_log_buf[n + m] = '\n';
        m_log_buf[n + m + 1] = '\0';
        fputs((const char *)m_log_buf, m_log_fd);
    }
    else
    {
        cout << "snprintf err!" << endl;
    }
    pthread_mutex_unlock(&m_mutex);
}

 Makefile

# add target
TGT:= app

CUR_DIR := $(shell pwd)

# SRC := $(wildcard src/*.cpp)
SRC := $(wildcard *.cpp)
OBJ := $(patsubst %.cpp,%.o,$(SRC))

# cppflags setting
CPPFLAGS := -I.
CPPFLAGS += -pthread
CPPFLAGS += -I${CUR_DIR}/include

# cxxflags setting
CXXFLAGS := -Wall -O2


all:$(TGT)
@echo "make successfull[0]"

$(TGT): $(OBJ)
$(CXX) -std=c++11 $(CPPFLAGS) $(CXXFLAGS) $^ -o $@

%.o:%.cpp
$(CXX) -std=c++11 $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@

clean:
    ifneq ( ,$(wildcard $(OBJ)))
@rm $(OBJ)
    else
@echo "nothing to do for rm OBJ"
    endif
    ifneq ( ,$(wildcard $(TGT)))
@rm $(TGT) 
    else
@echo "nothing to do for rm TGT"
    endif

obj_clean:
    ifneq ( ,$(wildcard $(OBJ)))
@rm $(OBJ)
    else
@echo "nothing to do for rm OBJ"
    endif
.phony: obj_clean, clean, all

3. 结果

xuehy@ubuntu:~/code/01_comprehensive/log_demo$ make
g++ -std=c++11 -I. -pthread -I/mnt/code/01_comprehensive/log_demo/include -Wall -O2 -c log.cpp -o log.o
g++ -std=c++11 -I. -pthread -I/mnt/code/01_comprehensive/log_demo/include -Wall -O2 -c main.cpp -o main.o
g++ -std=c++11 -I. -pthread -I/mnt/code/01_comprehensive/log_demo/include -Wall -O2 log.o main.o -o app
make successfull[0]
xuehy@ubuntu:~/code/01_comprehensive/log_demo$ ./app 
./log
[error]:2024-06-29-11-33-03:error
[warning]:2024-06-29-11-33-03:warning
[debug]:2024-06-29-11-33-03:debug
[info]:2024-06-29-11-33-03:info
xuehy@ubuntu:~/code/01_comprehensive/log_demo$ cat log
[error]:2024-06-29-11-23-43:error
[warning]:2024-06-29-11-23-43:warning
[debug]:2024-06-29-11-23-43:debug
[info]:2024-06-29-11-23-43:info


原文地址:https://blog.csdn.net/weixin_42108533/article/details/140059892

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!