C++ 日志模块打印

日志模块头文件

#pragma once

#define LOG_PRINT(printLev, format, ...) LogPrinter::LogPrint(printLev, __FILE__, __LINE__, format, __VA_ARGS__);

#define LOG_PRINT_INFO(format, ...) LogPrinter::LogPrint(PRINT_LEV_INFO, __FILE__, __LINE__, format, __VA_ARGS__);
#define LOG_PRINT_EVENT(format, ...) LogPrinter::LogPrint(PRINT_LEV_EVENT, __FILE__, __LINE__, format, __VA_ARGS__);
#define LOG_PRINT_ERROR(format, ...) LogPrinter::LogPrint(PRINT_LEV_ERROR, __FILE__, __LINE__, format, __VA_ARGS__);
#define LOG_PRINT_DEBUG(format, ...) LogPrinter::LogPrint(PRINT_LEV_DEBUG, __FILE__, __LINE__, format, __VA_ARGS__);

enum PRINT_LEV
{
    PRINT_LEV_DEBUG,
    PRINT_LEV_INFO,
    PRINT_LEV_EVENT,
    PRINT_LEV_ERROR,
    PRINT_LEV_UNKNOWN,
    PRINT_LEV_NUM
};

class LogPrinter
{
private:
    explicit LogPrinter();
    ~LogPrinter();

public:
    static void LogPrint(PRINT_LEV printLev, const char* filename, int lineNo, const char* format, ...);

private:
    class LogPrinterDef;
    static LogPrinterDef* _PrinterDef;
};

日志模块源文件

#include <stdio.h>
#include <string>
#include <stdarg.h>
#include <time.h>

#include "LogPrinter.h"

using namespace std;

#define RUN_LOG_FILENAME "RunLog.log"
#define LOG_FILE_MAX_SIZE (60 * 1024 * 1024)   // 单文件大小限制:60MB

class LogPrinter::LogPrinterDef
{
private:
    static const string m_printLevel[PRINT_LEV_NUM];

public:
    void prevInfoPrint(PRINT_LEV printLev, const char* fileName, int lineNo) {
        char buf[128];

        time_t now = time(0);
        tm ltm;
        localtime_s(&ltm, &now);

        sprintf_s(buf, "[%d/%02d/%02d %2d:%02d:%02d] [%s:%d] [%s]: ",
            ltm.tm_year + 1900, ltm.tm_mon + 1, ltm.tm_mday,
            ltm.tm_hour, ltm.tm_min, ltm.tm_sec,
            fileName, lineNo, m_printLevel[printLev].data());

        printf("%s", buf);

        FILE* fp;
        ::fopen_s(&fp, RUN_LOG_FILENAME, "a+");
        if (!fp) {
            return;
        }

        fwrite(buf, sizeof(char), strlen(buf), fp);
        fclose(fp);
    }

    int GetFileSize() {
        struct stat statbuf;
        stat(RUN_LOG_FILENAME, &statbuf);
        return statbuf.st_size;
    }

    void logFileSizeCtl() {
        if (GetFileSize() < LOG_FILE_MAX_SIZE)
            return;

        const char* newname = "RunLogBack.log";

        FILE* fp;
        fopen_s(&fp, newname, "r");
        if (fp != NULL) {
            fclose(fp);
            remove(newname);
        }
        rename(RUN_LOG_FILENAME, newname);
    }
};

LogPrinter::LogPrinterDef* LogPrinter::_PrinterDef = new LogPrinterDef;

const string LogPrinter::LogPrinterDef::m_printLevel[PRINT_LEV_NUM] = {
    "Debug",
    "Info",
    "Event",
    "Error",
    "Unknown",
};


LogPrinter::LogPrinter() {}

LogPrinter::~LogPrinter() { delete _PrinterDef; _PrinterDef = nullptr; }

/* 记录日志
* @param printLev  [日志信息等级]
* @param filename  [日志信息文件名]
* @param lineNo    [日志信息所在行]
* @param format    [日志信息列表格式]
*/
void __cdecl LogPrinter::LogPrint(PRINT_LEV printLev, const char* filename, int lineNo, const char* format, ...)    // __cdecl 是关键的返回值类型
{
    if (printLev < 0 || printLev >= PRINT_LEV_NUM)
        printLev = PRINT_LEV_UNKNOWN;

    _PrinterDef->logFileSizeCtl();

    string s_filiname;
    const char* temp = strrchr(filename, '\\');
    if (temp)
        s_filiname = temp + 1;
    else
        s_filiname = filename;
    _PrinterDef->prevInfoPrint(printLev, s_filiname.data(), lineNo);

    va_list args;
    va_start(args, format);
    vprintf(format, args);
    printf("\n");

    FILE* fp;
    ::fopen_s(&fp, RUN_LOG_FILENAME, "a+");
    if (!fp) {
        return;
    }
    vfprintf(fp, format, args);
    fwrite("\n", 1, 1, fp);
    fclose(fp);

    return;
}

调用方法:

int main()
{
	LOG_PRINT_INFO("要打印的字符串: %s, %s","Hello", "world");
	return 0;
}

运行截图:
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值