分享一个C++日志库,使用Win32接口编写,而且是线程安全的日志库。比较简单,只有2个文件,容易上手,使用起来也很简单

头文件

如下是日志库的头文件,接口看似很多,但是使用起来最常用的也就那么几个

  • WriteProgramLogNoMask:用来输出日志
  • InitProgramLogExByBuf:初始化日志库
  • CloseProgramLog:关闭日志输出,刷新内存到文件
#if !defined(__LOG_H__)
#define __LOG_H__ #if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000 #include <windows.h> /*使用方法
InitProgramLogExByBuf();
WriteProgramLogNoMask("%s %s", "aa", "bb"); // 输出 aa bb
CloseProgramLog();
*/ namespace RLBase { #ifdef __cplusplus
extern "C"
{
#endif // 参数定义同BaseInitProgramLog
XHBASE_API void DeleteProgramLog(LPCTSTR pProjectName = NULL, LPCTSTR pLogFilePath = NULL); // BaseInitProgramLog函数的参数定义
// DWORD dwMask的定义
#define BASE_LOG_MASK_ALL 0xFFFFFFFF // DWORD dwFlag的定义
#define BASE_LOG_DELETE_MASK 0x0000000F // 控制日志的大小
#define BASE_LOG_DELETE_NO 0x00000000 // 不自动删除日志文件,dwMaxLogFileSize/dwMaxReserveSize参数无任何意义
#define BASE_LOG_DELETE_INIT 0x00000001 // 在初始化的时候根据文件大小来删除日志文件
#define BASE_LOG_DELETE_CLOSE 0x00000002 // 在关闭的时候根据文件大小来删除日志文件
#define BASE_LOG_DELETE_WRITE 0x00000004 // 在写日志的时候根据文件大小来删除日志文件 #define BASE_LOG_RELEASE 0x80000000 // Release版本也输出日志,默认只有Debug版本输出日志
#define BASE_LOG_SAFE 0x40000000 // 日志文件是否加密
#define BASE_LOG_PROJECTNAME 0x20000000 // 日志文件是否显示项目名称
#define BASE_LOG_THREADID 0x10000000 // 显示线程ID
#define BASE_LOG_TIME 0x08000000 // 日志文件是否显示时间戳 #ifdef __BASE_LOG_RELEASE__
#define BASE_FLAG_INIT (BASE_LOG_DELETE_WRITE | BASE_LOG_RELEASE | BASE_LOG_PROJECTNAME | BASE_LOG_THREADID | BASE_LOG_TIME | BASE_LOG_SAFE)
#else
#define BASE_FLAG_INIT (BASE_LOG_DELETE_WRITE | BASE_LOG_RELEASE | BASE_LOG_PROJECTNAME | BASE_LOG_THREADID | BASE_LOG_TIME)
#endif #define __BASE_LOG_ENABLE__ #ifdef __BASE_LOG_ENABLE__ // DWORD dwMask 掩码,控制哪些日志需要真正写入
// DWORD dwFlag 标志位
// DWORD dwLogBufSize 日志缓冲区的大小,0为不使用缓冲,-1为使用默认缓冲大小(100K),其它为实际缓冲区的大小
// DWORD dwMaxLogFileSize 日志文件的最大尺寸(单位:KB),0代表不自动删除日志文件
// DWORD dwMaxReserveSize 日志文件的最大保留尺寸(单位:KB),0代表全部删除,不保留
// LPCTSTR pProjectName 项目名称,如果为NULL,取exe文件名
// LPCTSTR pLogFilePath 日志文件路径,可以为绝对路径和相对路径,如果为相对路径,前面添加exe所在的目录,如果为NULL,则为exe所在的目录+log\\+pProjectName.log
XHBASE_API void InitLog(const wchar_t* company, const wchar_t* product, const wchar_t* programName = NULL);
XHBASE_API void InitProgramLog(DWORD dwMask = BASE_LOG_MASK_ALL, DWORD dwFlag = BASE_FLAG_INIT, DWORD dwLogBufSize = -1, DWORD dwMaxLogFileSize = 0, DWORD dwMaxReserveSize = 0, LPCTSTR pProjectName = NULL, LPCTSTR pLogFilePath = NULL);
XHBASE_API void InitProgramLogEx(DWORD dwMask = BASE_LOG_MASK_ALL, LPCTSTR pProjectName = NULL, LPCTSTR pLogFilePath = NULL);
XHBASE_API void InitProgramLogExByBuf(DWORD dwMask = BASE_LOG_MASK_ALL, LPCTSTR pProjectName = NULL, LPCTSTR pLogFilePath = NULL); XHBASE_API void CloseProgramLog(); XHBASE_API void FlushProgramLog(); // 把缓存的日志写入文件 XHBASE_API void WriteProgramLogString(DWORD dwMask, LPCTSTR lpszLogText);
XHBASE_API void WriteProgramLogBin(DWORD dwMask, LPCTSTR lpszFront, LPCTSTR lpszBack, LPCTSTR lpszBuf, DWORD uBufLength);
XHBASE_API void WriteProgramLog(DWORD dwMask, LPCTSTR lpszFormat, ...);
XHBASE_API void WriteProgramLogNoMask(LPCTSTR lpszFormat, ...); #define WriteProgramLogStringNoMask(lpszLogText) WriteProgramLogString(BASE_LOG_MASK_ALL,lpszLogText)
#define WriteProgramLogBinNoMask(lpszFront,lpszBack,lpszBuf,nBufLength) WriteProgramLogBin(BASE_LOG_MASK_ALL,lpszFront,lpszBack,lpszBuf,nBufLength) #else // __BASE_LOG_ENABLE__ #define InitProgramLog __noop
#define InitProgramLogEx __noop
#define InitProgramLogExNoBuf __noop
#define CloseProgramLog() __noop
#define FlushProgramLog() __noop
#define WriteProgramLogString(dwMask,lpszLogText) __noop
#define WriteProgramLogBin(dwMask,lpszFront,lpszBack,lpszBuf,nBufLength) __noop
#define WriteProgramLog __noop
#define WriteProgramLogNoMask __noop #define WriteProgramLogStringNoMask(lpszLogText) __noop
#define WriteProgramLogBinNoMask(lpszFront,lpszBack,lpszBuf,nBufLength) __noop #endif // __BASE_LOG_ENABLE__ #ifdef __cplusplus
}
#endif //}}
} #endif // !defined(__BASE_PROGRAMLOG_H__)

使用方式也比较简单:

InitProgramLogExByBuf();
WriteProgramLogNoMask("%s %s", "aa", "bb"); // 输出 aa bb
CloseProgramLog();

喜欢的留下邮箱

如果您觉得文章不错,不妨给个打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!!

很重要--转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords

  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。


C++线程安全日志库-Win32接口实现的更多相关文章

  1. 自行实现的jar包中,日志库的适配实现

    ​ 日常情况下,我们自己都会自行实现一些基础的jar包,如dao包.service包或一些其他完成特定功能的jar包.如果没有一套调试日志信息,出现问题时想查找问题非常不方便.可能大多数小伙伴都会有自 ...

  2. 【原创】go语言学习(十七)接口应用实战--日志库

    目前 日志库需求分析 日志库接口设计 文件日志库开发 Console日志开发 日志使用以及测试 日志库需求分析 1.日志库需求分析 A. 程序运行是个黑盒B. 而日志是程序运行的外在表现C. 通过日志 ...

  3. 爆料喽!!!开源日志库Logger的剖析分析

    导读 Logger类提供了多种方法来处理日志活动.上一篇介绍了开源日志库Logger的使用,今天我主要来分析Logger实现的原理. 库的整体架构图 详细剖析 我们从使用的角度来对Logger库抽茧剥 ...

  4. 爆料喽!!!开源日志库Logger的使用秘籍

    日志对于开发来说是非常重要的,不管是调试数据查看.bug问题追踪定位.数据信息收集统计,日常工作运行维护等等,都大量的使用到.今天介绍著名开源日志库Logger的使用,库的地址:https://git ...

  5. C基础 多用户分级日志库 sclog

    引言 - sclog 总的设计思路 sclog在之前已经内置到simplec 简易c开发框架中一个日志库. 最近对其重新设计了一下. 减少了对外暴露的接口. 也是C开发中一个轮子. 比较简单, 非常适 ...

  6. 超轻量级、高性能C日志库--EasyLogger

    [ 声明:版权全部,欢迎转载.请勿用于商业用途. 联系信箱:armink.ztl@gmail.com] EasyLogger 1. 介绍 EasyLogger 是一款超轻量级(ROM<1.6K, ...

  7. C++第三方日志库Pantheios

    C++第三方日志库Pantheios Kagula 2012-1-11 简介 在项目实践中发现一个好的日志记录非常重要,你需要借助Logging才能跟踪软件中的错误.所以这里研究下第三方C++库Pan ...

  8. C++ 日志库 boost::log 以及 glog 的对比

    日志能方便地诊断程序原因.统计程序运行数据,是大型软件系统必不可少的组件之一.本文将从设计上和功能上对比 C++ 语言常见的两款日志库: boost::log 和 google-glog . 设计 b ...

  9. 新写的c++日志库:log4K

    网是开源的c/c++日志库也不少,但用起来总觉得不方便,于是动手写了一个C++日志框架Log4K. 测试代码: #include "log4k.h" #pragma comment ...

随机推荐

  1. 寻找DevExpress破解经历之旅

    众所周知DevExpress是收费的,但是破解版的也不少,近期公司需要做发票套打的功能让我找个打印工具,我寻思着DevExpress这个软件好像挺不错的,功能强大,看了下价格方面,好吧!2W多呢,市面 ...

  2. jenkins构建基于gradle的springboot项目CI采坑(采用jar方式部署)

    试了一堆插件,最后用的还是 publish over SSH jenkins基本配置不多说了,就是配置一下git仓储,配置一下gradle执行命令 clean bootRepackage 之后执行Se ...

  3. D3中的each() 以及svg defs元素 clipPath的使用

    each() 方法允许我们定制对选择集中DOM元素的处理行为: selection . each ( func ) 参数 func 是调用者定义的函数,在d3中被称为 访问器/accessor . d ...

  4. build.gradle使用gradle.property中定义的字段及乱码问题的解决

    gradle.property文件可以用来定义一些字段 而这些字段可以被build.gradle文件引用到 例如:给大家贴出来一个gradle.property文件 # Project-wide Gr ...

  5. 深入理解SpringBoot之自动装配

    SpringBoot的自动装配是拆箱即用的基础,也是微服务化的前提.其实它并不那么神秘,我在这之前已经写过最基本的实现了,大家可以参考这篇文章.这次主要的议题是,来看看它是怎么样实现的,我们透过源代码 ...

  6. TensorFlow-谷歌深度学习库 文件I/O Wrapper

    这篇文章主要介绍一下TensorFlow中相关的文件I/O操作,我们主要使tf.gfile来完成. Exists tf.gfile.Exists(filename) 用来判断一个路径是否存在,如果存在 ...

  7. urllib使用

    1.基本方法 urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=Fals ...

  8. .Net Core微服务系列--开篇

    记得原来有个项目是用wcf做的分布式,不仅横向根据业务拆分了,纵向把业务处理.数据访问等也拆分了成不同的服务,这个是当时公司的产品我也只是一个小小的开发人员所以就不做太多的评论,只是不得不吐槽下调试真 ...

  9. mysql事务隔离级别详解和实战

    A事务做了操作 没有提交 对B事务来说 就等于没做 获取的都是之前的数据 但是 在A事务中查询的话 查到的都是操作之后的数据 没有提交的数据只有自己看得到,并没有update到数据库. 查看InnoD ...

  10. HttpClient 专题

    HttpClient is a HTTP/1.1 compliant HTTP agent implementation based on HttpCore. It also provides reu ...