C/C++格式化日志库实现代码

本文介绍了一个跨平台的日志记录函数,适用于Linux和Windows系统。该函数支持不同的日志级别,并能够记录日志的时间、文件名及行号等信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

头文件如下:



/*****************************************************/

/* 跨平台日志函数,Linux下与windows下亲测有效      */

/*****************************************************/

  

  

#ifndef _LOG_FORMAT_H_

#define _LOG_FORMAT_H_

  

// 日志等级

enum LogLevel { _LOG_TRACE, _LOG_INFO, _LOG_WARN, _LOG_ERROR, _LOG_FATAL };

void LogFormat(const char *pszFileName, const int nLine, LogLevel Level, const char *Format, ...);

  

/******************************************************/

/* 日志函数调用方法  _LOG(_LOG_FATAL, "%s", "sss"); */

/******************************************************/

#ifndef _LOG

#define _LOG(Level, Format, ...) LogFormat(__FILE__, __LINE__, Level, Format, ##__VA_ARGS__)

#endif

  

#endif // _LOG_FORMAT_H_

 源文件如下:



#include <string>

#include <stdio.h>

#include <stdarg.h>

#include <stdint.h>

  

#if defined __GNUC__ || defined LINUX

#include <sys/time.h>

#define MY_VA_LIST _G_va_list

#else

#include <windows.h>

#define MY_VA_LIST va_list

#endif

  

#include "LogFormat.h"

  

/*

*最终生成的日志字符串最大长度,要特别注意

*超过此长度程序会崩溃,用户可以自定义长度

*/

#define LOG_MAX 1024

  

/*

*时间长度,不需要修改

*/

#define FORMAT_TIME_SIZE 24

  

/*

*日志等级字符串,与头文件中定义的枚举必须一致

*/

static std::string g_LogLevel[] = { "TRACE","INFO","WARN","ERROR","FATAL" };

  

/*

*内存申请函数,用户可以自定义

*/

static char *NewBuf(const uint32_t unBufSize)

{

    return new char[unBufSize];

}

  

/*

*内存释放函数,必须与NewBuf对应

*/

static void DeleteBuf(char ** pszBuf)

{

    if (NULL != *pszBuf)

    {

        delete[] *pszBuf;

        *pszBuf = NULL;

    }

    *pszBuf = NULL;

}

  

/*

*获取当前时间字符串函数

*2018-08-08 08:08:08.888

*/

static char* GetTime()

{

    char *pszFormatTime = NewBuf(FORMAT_TIME_SIZE);

#if defined __GNUC__ || defined LINUX

    struct timeval tv;

    struct timezone tz;

    gettimeofday(&tv, &tz);

    struct tm *current_time = localtime(&tv.tv_sec);

    sprintf(pszFormatTime,

        "%04d-%02d-%02d %02d:%02d:%02d.%03d",

        current_time->tm_year + 1900,

        current_time->tm_mon + 1,

        current_time->tm_mday,

        current_time->tm_hour,

        current_time->tm_min,

        current_time->tm_sec,

        tv.tv_usec / 1000);

#else

    SYSTEMTIME sys_time;

    GetLocalTime(&sys_time);

#if _MSC_VER

    sprintf_s(pszFormatTime,

        FORMAT_TIME_SIZE,

        "%04d-%02d-%02d %02d:%02d:%02d.%03d",

        sys_time.wYear,

        sys_time.wMonth,

        sys_time.wDay,

        sys_time.wHour,

        sys_time.wMinute,

        sys_time.wSecond,

        sys_time.wMilliseconds);

#else

    sprintf(pszFormatTime,

        "%04d-%02d-%02d %02d:%02d:%02d.%03d",

        sys_time.wYear,

        sys_time.wMonth,

        sys_time.wDay,

        sys_time.wHour,

        sys_time.wMinute,

        sys_time.wSecond,

        sys_time.wMilliseconds);

#endif

#endif

    return pszFormatTime;

}

  

void LogFormat(const char *pszFileName, const int nLine, LogLevel Level, const char *Format, ...)

{

    int ret = 0;

    char *pszDescribeInfo = NewBuf(LOG_MAX);

  

    MY_VA_LIST ap;

    va_start(ap, Format);

#if defined __GNUC__ || defined LINUX

    ret = vsnprintf(pszDescribeInfo,

        LOG_MAX,

        Format,

        ap);

#else

#if _MSC_VER

    ret = _vsnprintf_s(pszDescribeInfo,

        LOG_MAX,

        _TRUNCATE,

        Format,

        ap);

#else

    ret = _vsnprintf(pszDescribeInfo,

        LOG_MAX,

        Format,

        ap);

#endif

#endif

    va_end(ap);

    if ((LOG_MAX <= ret) || (0 > ret))

    {

        DeleteBuf(&pszDescribeInfo);

        return;

    }

  

    // 组装日志,[时间][等级][文件名(行数)][自定义字符串]

    char *pszLog = NewBuf(LOG_MAX);

    char *pszTime = GetTime();

#if defined __GNUC__ || defined LINUX

    ret = sprintf(pszLog,

        "[%s][%s][%s(%d)][%s]",

        pszTime,

        g_LogLevel[Level].c_str(),

        pszFileName,

        nLine,

        pszDescribeInfo);

#else

#if _MSC_VER

    ret = sprintf_s(pszLog,

        LOG_MAX,

        "[%s][%s][%s(%d)][%s]",

        pszTime,

        g_LogLevel[Level].c_str(),

        pszFileName,

        nLine,

        pszDescribeInfo);

#else

    ret = sprintf(pszLog,

        "[%s][%s][%s(%d)][%s]",

        pszTime,

        g_LogLevel[Level].c_str(),

        pszFileName,

        nLine,

        pszDescribeInfo);

#endif

#endif

  

    // 日志默认输出到控制台,用户可以自行修改

    printf("%s\n", pszLog);

  

    DeleteBuf(&pszDescribeInfo);

    DeleteBuf(&pszLog);

    DeleteBuf(&pszTime);

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值