C++ 小型记录器类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5028302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Small logger class
提问by herzl shemuelian
I am looking for a small lightweight logging system in c++. I have found some existing frameworks but I don't need all of their features at this point in time. I primarily am looking for a small system that can for example configure the log level output file. I am looking for an existing solution as I don't want to reinvent the wheel.
我正在寻找一个用 C++ 编写的小型轻量级日志系统。我找到了一些现有的框架,但目前我不需要它们的所有功能。我主要是在寻找一个可以配置日志级别输出文件的小型系统。我正在寻找现有的解决方案,因为我不想重新发明轮子。
回答by Pedro d'Aquino
I strongly recommend this simple logging system: http://www.drdobbs.com/cpp/201804215. It is composed of a single header file. I have successfully used it on Linux, Windows and Mac OS X.
我强烈推荐这个简单的日志系统:http: //www.drdobbs.com/cpp/201804215。它由单个头文件组成。我已经在 Linux、Windows 和 Mac OS X 上成功使用过它。
You write to the log like this:
您像这样写入日志:
FILE_LOG(logWARNING) << "Ops, variable x should be " << expectedX << "; is " << realX;
I really like the stream syntax. It is unobtrusive, typesafe and expressive. The logging framework automatically adds a \n
at the end of the line, plus date, time and indentation.
我真的很喜欢流语法。它不引人注目,类型安全且富有表现力。日志框架会自动\n
在行尾添加一个,加上日期、时间和缩进。
Configuring the logs is pretty easy:
配置日志非常简单:
FILELog::ReportingLevel() = logDEBUG3;
FILE* log_fd = fopen( "mylogfile.txt", "w" );
Output2FILE::Stream() = log_fd;
This framework is also easy to extend. At work, we have recently made some adaptations to it so that it now uses an std::ofstream
instead of a FILE*
. As a result, we are now able to add nice features such as encrypting the logs, by chaining the streams.
这个框架也很容易扩展。在工作中,我们最近对其进行了一些调整,以便它现在使用std::ofstream
代替FILE*
。因此,我们现在可以通过链接流来添加很好的功能,例如加密日志。
回答by lepe
For anyone wanting a simple solution, I recommend: easylogging++
对于任何想要简单解决方案的人,我推荐:easylogging++
Single header only C++ logging library. It is extremely light-weight, robust, fast performing, thread and type safe and consists of many built-in features. It provides ability to write logs in your own customized format. It also provide support for logging your classes, third-party libraries, STL and third-party containers etc.
This library has everything built-in to prevent usage of external libraries.
单头只有 C++ 日志库。它非常轻量、健壮、快速、线程和类型安全,并包含许多内置功能。它提供了以您自己的自定义格式写入日志的能力。它还支持记录您的类、第三方库、STL 和第三方容器等。
该库内置了所有内容,以防止使用外部库。
Simple example: (more advanced examples available on the link above).
简单示例:(上面链接中提供了更高级的示例)。
#include "easylogging++.h"
INITIALIZE_EASYLOGGINGPP
int main(int argv, char* argc[]) {
LOG(INFO) << "My first info log using default logger";
return 0;
}
Example output inside a class:
类中的示例输出:
2015-08-28 10:38:45,900 DEBUG [default] [user@localhost] [Config::Config(const string)] [src/Config.cpp:7] Reading config file: 'config.json'
2015-08-28 10:38:45,900 调试 [默认] [user@localhost] [Config::Config(const string)] [src/Config.cpp:7] 读取配置文件:'config.json'
I tried log4cpp and boost::log but they are not as easy as this one.
我尝试了 log4cpp 和 boost::log,但它们并不像这个那么容易。
EXTRA CONTENT: Minimal version - LOG header
额外内容:最小版本 - LOG 标头
I created a small code for even simpler applications based on easylogging but requires no initialization (be aware that it is probably not thread safe). Here is the code:
我为基于 easylogging 的更简单的应用程序创建了一个小代码,但不需要初始化(请注意它可能不是线程安全的)。这是代码:
/*
* File: Log.h
* Author: Alberto Lepe <[email protected]>
*
* Created on December 1, 2015, 6:00 PM
*/
#ifndef LOG_H
#define LOG_H
#include <iostream>
using namespace std;
enum typelog {
DEBUG,
INFO,
WARN,
ERROR
};
struct structlog {
bool headers = false;
typelog level = WARN;
};
extern structlog LOGCFG;
class LOG {
public:
LOG() {}
LOG(typelog type) {
msglevel = type;
if(LOGCFG.headers) {
operator << ("["+getLabel(type)+"]");
}
}
~LOG() {
if(opened) {
cout << endl;
}
opened = false;
}
template<class T>
LOG &operator<<(const T &msg) {
if(msglevel >= LOGCFG.level) {
cout << msg;
opened = true;
}
return *this;
}
private:
bool opened = false;
typelog msglevel = DEBUG;
inline string getLabel(typelog type) {
string label;
switch(type) {
case DEBUG: label = "DEBUG"; break;
case INFO: label = "INFO "; break;
case WARN: label = "WARN "; break;
case ERROR: label = "ERROR"; break;
}
return label;
}
};
#endif /* LOG_H */
Usage:
用法:
#include "Log.h"
int main(int argc, char** argv) {
//Config: -----(optional)----
structlog LOGCFG = {};
LOGCFG.headers = false;
LOGCFG.level = DEBUG;
//---------------------------
LOG(INFO) << "Main executed with " << (argc - 1) << " arguments";
}
This code print the message using "cout", but you can change it to use "cerr" or append a file, etc. I hope its useful to someone. (Note: I'm not C++ expert in any way, so this code may explode in extreme cases).
此代码使用“cout”打印消息,但您可以将其更改为使用“cerr”或附加文件等。我希望它对某人有用。(注意:我无论如何都不是 C++ 专家,所以这段代码在极端情况下可能会爆炸)。
回答by AbsolutelyFreeWeb
all of the mentioned loggers so far make use of macros for logging calls. To me, that is so ugly, I don't care about what performance boost that gives, I won't go near it.
到目前为止,所有提到的记录器都使用宏来记录调用。对我来说,这太丑了,我不在乎它会带来什么性能提升,我不会接近它。
https://github.com/gabime/spdlogis what I like. Clean syntax, handles all typical usages. Fast and small. e.g. for a file logger it is:
https://github.com/gabime/spdlog是我喜欢的。干净的语法,处理所有典型用法。又快又小。例如,对于文件记录器,它是:
auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic.txt");
my_logger->info("Some log message");
回答by Sergey Podobry
回答by Joris Timmermans
If you don't have size limitations on the project and you expect it to live a long time, I would suggest looking at Apache Log4cxx. It's not a small library, but it supports just about everything you ever wanted (including some things you didn't even knew you wanted) in logging, and it's portable.
如果您对项目没有大小限制,并且希望它能够存活很长时间,我建议您查看Apache Log4cxx。它不是一个小型库,但它支持您在日志记录中想要的几乎所有东西(包括一些您甚至不知道自己想要的东西),并且它是可移植的。
In any larger project sooner or later you'll want your logging solution to do more than a "small logger class", so indeed why reinvent the wheel.
在任何更大的项目中,您迟早会希望您的日志记录解决方案不仅仅是一个“小型记录器类”,所以为什么要重新发明轮子。
回答by rubenvb
This questionhas my attempt with some fanciness. It is completely Standard C++ and makes no platform assumptions whatsoever. It basically consists of a temporary object used like this:
这个问题让我有些幻想。它完全是标准 C++,不做任何平台假设。它基本上由一个像这样使用的临时对象组成:
Debug(5) << "This is level 5 debug info.\n";
I'm sure you can figure out how to specify different files and other stuff when you have the basic layout. I tried to keep the class structured so that in a release build, every form of Debug output is removed as good as possible.
我敢肯定,当您拥有基本布局时,您可以弄清楚如何指定不同的文件和其他内容。我试图保持类的结构,以便在发布版本中,尽可能好地删除每种形式的调试输出。
Mind you: if you specify a filename each time you construct it, and open the file and close it again, performance will suffer. In the case of multiple output files, it would certainly be best to have several static data members that open the different files when the program is run or if they are opened for the first time.
请注意:如果每次构造文件时都指定一个文件名,然后打开文件并再次关闭它,性能会受到影响。在多个输出文件的情况下,最好有几个静态数据成员在程序运行时或第一次打开不同的文件时打开不同的文件。
回答by Erik Aronesty
I, as well as many others, also answered this question with some code.
我和其他许多人一样,也用一些代码回答了这个问题。
This isn't really "ready" in all ways, but it could be easily modified:
这在所有方面都不是真正“准备好”,但可以轻松修改:
https://gist.github.com/earonesty/977b14c93358fe9b9ee674baac5d42d7
https://gist.github.com/earonesty/977b14c93358fe9b9ee674baac5d42d7
Features:
特征:
- writing to the log doesn't block on i/o
- similar macros to other solutions (
LOGE(blah << stream)
) - prefers discarding log entries to slowing down
- lazy flushing
- header only, very small, stl classes only
- tested on osx/win/nix
- time format is configurable
- 写入日志不会阻止 i/o
- 与其他解决方案类似的宏 (
LOGE(blah << stream)
) - 更喜欢丢弃日志条目而不是放慢速度
- 懒惰的冲洗
- 仅标头,非常小,仅 stl 类
- 在 osx/win/nix 上测试
- 时间格式可配置
Missing stuff:
缺少的东西:
- easy, flexible log formatting (predefining a macro would be fine)
- triggers have an interface but don't work yet
- microseconds aren't working yet
- 简单、灵活的日志格式(预定义宏就可以了)
- 触发器有一个接口,但还没有工作
- 微秒还没有工作
If anyone actually likes this solution in any way, lmk and I'll make a real repo out of it with tests, etc. It's pretty fast. Probably not as fast as speedlogger (a heavier feature complete library), but not sure.
如果有人真的以任何方式喜欢这个解决方案,lmk 和我会用它做一个真正的 repo,等等。它非常快。可能不如 speedlogger(一个更重的功能完整库)快,但不确定。
回答by asn100388
The above answers are all great.
上面的答案都很棒。
Doubt anyone will ever see this answer, but this is what I use https://github.com/asn10038/Cpp_Logger
怀疑任何人都会看到这个答案,但这就是我使用的 https://github.com/asn10038/Cpp_Logger
Easy to set up after a configuration of 4-5 variable names in the .h file, and implemented without non standard dependencies.
在 .h 文件中配置 4-5 个变量名称后易于设置,并且无需非标准依赖项即可实现。
Not header only but could be pretty easily.
不仅仅是标题,而且可能很容易。
Maybe this helps someone.
也许这对某人有帮助。
回答by Gary G.
An update to Dr. Dobb's "A Lightweight Logger for C++":There are actually a couple of loggers referred to in Dr. Dobb's. The first one Logging In C++which is listed in one of the answers. I tried to use this one but the source is no longer available on the Dr. Dobb's site.
Dobb 博士的“A Lightweight Logger for C++”的更新:Dobb 博士的文章中实际上提到了几个记录器。答案之一中列出的第一个登录 C++。我尝试使用这个,但 Dobb 博士的网站上不再提供该来源。
The second one that worked for me and that I recommend is A Lightweight Logger for C++by Filip Janiszewski working at Nokia Siemens Networks. At first I had some problems getting this code to run so as I was searching for solutions, I ran across an update by the original author at: GitHub: fjanisze/logger. I found this code to be easy to understand, modify, and to use. It is thread safe and works with Visual Studio with Windows.
第二个对我有用并且我推荐的是A Lightweight Logger for C++,作者是在诺基亚西门子通信工作的 Filip Janiszewski。起初,我在运行此代码时遇到了一些问题,因此在我寻找解决方案时,我遇到了原作者的更新:GitHub: fjanisze/logger。我发现这段代码易于理解、修改和使用。它是线程安全的,可与 Windows 的 Visual Studio 一起使用。
Another logger mentioned above is easylogging++. When I first tried this one it looked promising. But when I added threading and sockets2 under Windows, it crashed. I did have the defines set for threading and Sock2 but I still couldn't get it to work so I can't recommend this one. The source code is also very complex so I had no chance to modify and fix it within a reasonable amount of time.
上面提到的另一个记录器是easylogging++。当我第一次尝试这个时,它看起来很有希望。但是当我在 Windows 下添加 threading 和 sockets2 时,它崩溃了。我确实为线程和 Sock2 设置了定义,但我仍然无法让它工作,所以我不能推荐这个。源代码也非常复杂,所以我没有机会在合理的时间内修改和修复它。