C++日志记录器
大家好!我是大聪明-PLUS!

日志库
这个项目是一个用 C++ 编写的简单而灵活的日志库。该库支持多种日志级别、消息格式化以及将日志写入不同流的功能。
主要特点
-
支持不同的日志级别:
DEBUG,,,。INFOWARNERROR -
可自定义日志格式。
-
支持在多个数据流中进行日志记录,并防止数据竞争。
-
将日志记录到不同的输出流(
std::cout文件等)。 -
可以使用全局日志记录器。
安装
-
克隆仓库:
git clone <https://github.com/Fallet666/logger.git> -
进入项目目录并使用 CMake 进行构建:
cd logger mkdir build cd build cmake .. make
基本概念
-
日志记录器:主要的日志记录类。创建此类的实例以将日志记录到指定的流中。
-
全局日志记录器:一个单例实例
Logger,可在整个项目中默认使用。
日志记录功能
该项目提供了多种用于写入不同严重级别的日志的功能。这些功能允许根据日志的严重级别灵活控制消息输出。日志分为四个级别:
-
DEBUG— 用于调试信息。 -
INFO— 用于一般信息消息。 -
WARN— 用于警告。 -
ERROR— 用于需要注意的错误。
基本功能
LOG_MESSAGE(Logger& logger, LogLevel level, const std::string& message)
记录指定级别的消息。此函数通用,可用于记录任何级别的消息。
使用示例:
Logger::Logger log("Logger");
LOG_MESSAGE(log, Logger::DEBUG, "I'm MESSAGE");
各级别的简化功能
这些函数旨在简化特定级别的日志记录调用:
-
logDebug(Logger& logger, const std::string& message)
记录一条级别为DEBUG.
使用示例:
logDebug(log, "This is a debug message");
-
logInfo(Logger& logger, const std::string& message)
记录一条级别为INFO.
使用示例:
logInfo(log, "This is an info message");
-
logWarn(Logger& logger, const std::string& message)
记录一条级别为WARN.
使用示例:
logWarn(log, "This is a warning message");
-
logError(Logger& logger, const std::string& message)
记录一条级别为ERROR.
使用示例:
logError(log, "This is an error message");
全局日志记录功能
该项目还提供了使用 globalLogger 的全局日志记录功能。这些功能允许您记录消息,而无需创建和管理自己的日志记录器实例。
与基本功能类似,还有以下全局日志记录功能:
-
logMessageGlobal(LogLevel level, const std::string& message) -
logDebugGlobal(const std::string& message) -
logInfoGlobal(const std::string& message) -
logWarnGlobal(const std::string& message) -
logErrorGlobal(const std::string& message)
日志级别
您可以使用设置日志级别Cmake,这样就会显示不低于指定级别的日志。例如,如果您将级别设置为,则会显示级别为 100和Warn100 的日志。WarnError
使用示例:
set(DEFAULT_LOG_LEVEL DEBUG)
add_compile_definitions(GLOBAL_LOG_LEVEL=${DEFAULT_LOG_LEVEL})
笔记
每个日志记录函数都会使用FILE和LINE宏自动添加有关调用该日志的文件和行的信息。这使得在代码中追踪日志来源变得更加容易。
格式化日志
默认格式:
格式字符串:“%L: %T [%N]: %M\n”
示例输出:
DEBUG: 12:34:56 [MyLogger]: This is a debug message
高级格式设置
可以使用格式字符串自定义日志。默认情况下,格式字符串可以包含以下组件:
-
%L — 日志级别(DEBUG、INFO、WARN、ERROR)。
-
%T — 以 HH:MM:SS 格式记录日志条目时间。
-
%N — 日志记录器名称。
-
%M — 日志消息。
-
%t — 写入日志的线程 ID。
-
%S — 调用该日志的文件名。
-
%# — 调用该日志的文件行号。
这些规范可以按任意顺序组合和排列,以自定义日志格式,从而满足项目的需要。
格式字符串指定如下:
Logger::Logger log("custom formating");
log.setFormatString("%L: %T [%N]: %M (%S: %#)\n");
在对数中使用颜色
该项目包含对控制台日志输出进行颜色编码的功能,以便轻松区分不同级别的消息。如果日志记录器的输出流配置为启用颜色编码,则会自动应用颜色std::cout。
配色方案
-
DEBUG— 白色 (\033[37m)。 -
INFO— 绿色(\033[32m)。 -
WARN— 黄色(\033[33m)。 -
ERROR— 红色 (\033[31m)。
日志记录时,终端会显示颜色,这使得识别消息的重要性变得更加容易。
禁用颜色
如果使用不同的输出流(例如,将日志写入文件),则颜色会自动禁用。
多线程应用程序中的日志记录
该项目支持多线程日志记录。这意味着多个线程可以同时写入日志,而不会出现数据损坏或竞态条件。
流同步
为了确保线程安全,Logger 类使用互斥锁(mutex std::mutex)。每次调用日志记录函数或修改日志记录字段时,线程都会被阻塞,直到操作完成。这可以防止并发访问共享资源(例如输出流或日志记录设置),从而确保日志数据的正确性和完整性。
多线程日志记录示例:
Logger::Logger log("MultiThreadLogger");
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i) {
threads.emplace_back([&log, i] {
logInfo(log, "Message from thread " + std::to_string(i));
});
}
for (auto &t : threads) {
t.join();
}
此示例创建了 10 个线程,每个线程都会写入一条包含其线程 ID 的日志消息。使用互斥锁可确保所有消息都能正确写入,避免混淆。
多线程日志记录的特性
-
线程安全:在日志记录器中使用互斥锁可确保一次只执行一个操作——要么写入消息,要么更改日志记录器字段(例如,更改输出流或日志格式)。
-
性能:尽管日志记录器会阻塞进程,但其设计旨在最大限度地减少对性能的影响。然而,当日志数量庞大或系统负载较高时,可能会出现延迟。
-
输出到不同的流:日志记录器允许您为不同的实例使用不同的输出流,这对于按类别或来源分离日志非常有用。
将日志记录到不同的输出流
该项目为日志记录器提供了灵活的输出流配置。这意味着您可以将日志定向到任何支持该接口的流std::ostream,包括标准输出(std::cout)、文件、字符串流(std::ostringstream),甚至是自定义流。
设置输出流
创建日志记录器实例时,您可以指定日志的写入位置。默认情况下,日志会写入到 `/ std::coutetc/logger ...
std::ofstream file("log.txt");
Logger::Logger log("FileLogger", file);
在这个例子中,日志将被写入 log.txt 文件。
更改输出流
您还可以使用以下方法在程序运行时更改日志记录器输出流setOutStream:
Logger::Logger log("Logger");
log.setOutStream(std::cerr);
使用不同输出流的示例:
std::ofstream file("output.log");
std::ostringstream oss;
Logger::Logger logToFile("FileLogger", file);
Logger::Logger logToStringStream("StringStreamLogger", oss);
Logger::Logger logToConsole("ConsoleLogger");
logInfo(logToFile, "This log goes to a file");
logWarn(logToStringStream, "This log goes to a string stream");
logError(logToConsole, "This log goes to the console");
file.close();
更多推荐
所有评论(0)