C++ C++;同时记录到控制台和日志文件
我有一个基类,例如“ProcessingThread”,它有几个派生。每个派生都有一个特定的名称,例如“派生1”、“派生2”。。。现在,对我来说,将格式化的输出输出到控制台似乎很有用,它可以打印如下内容:C++ C++;同时记录到控制台和日志文件,c++,logging,stream,C++,Logging,Stream,我有一个基类,例如“ProcessingThread”,它有几个派生。每个派生都有一个特定的名称,例如“派生1”、“派生2”。。。现在,对我来说,将格式化的输出输出到控制台似乎很有用,它可以打印如下内容: [DerivationOne]: Action X took place! [DerivationTwo]: Action Y took place! [DerivationTwo]: Action Z took place! 同时,它应该将每个内容写入特定于派生的日志文件。我想到了一个可以
[DerivationOne]: Action X took place!
[DerivationTwo]: Action Y took place!
[DerivationTwo]: Action Z took place!
同时,它应该将每个内容写入特定于派生的日志文件。我想到了一个可以用标准方式调用的类,例如“custom_out我认为这是一个很好的问题 实际上,在我看来,考虑两个不同的事情:
首先,我将使用一个简单的类,传递一个
std::ostream
引用和一个字符串(对于前缀,尽管这里可能不只是概括前缀)对于构造函数,然后重载operator这是我在评论中讨论的想法的入门工具包。您需要决定如何处理写入磁盘文件的错误-返回false、抛出异常或其他。我将其编辑为返回true/false。true表示无错误。正在进行中
#include <iostream>
#include <mutex>
#include <string>
#include <fstream>
#include <string_view>
#include <iomanip>
namespace dj {
inline bool print(std::ostream& out) {
return !!(out << std::endl);
}
template<typename T>
bool print(std::ostream& out, T&& value)
{
return !!(out << std::forward<T>(value) << std::endl);
}
template<typename First, typename ... Rest>
bool print(std::ostream& out, First&& first, Rest&& ... rest)
{
return !!(out << std::forward<First>(first)) && print(out, std::forward<Rest>(rest)...);
}
inline std::mutex logger_mtx;
class log_stream {
public:
log_stream(std::string_view str, std::ostream& ifile)
: name(str)
, file(ifile)
{
std::string s{ "[" };
name = s + name + "] ";
}
template <typename... Args>
bool operator() (Args&&... args) {
bool OK = print(file, std::forward<Args>(args)...);
{
std::lock_guard<std::mutex> lck(logger_mtx);
print(std::cout, name, std::forward<Args>(args)...);
if (!OK) {
print(std::cout, name, "-- Error writing to log file. --");
}
}
return OK;
}
private:
std::string name;
std::ostream& file;
};
}
int main()
{
std::ofstream outfile("DerivationOne.log.txt");
dj::log_stream log("DerivationOne", outfile);
std::ofstream outfile2; // ERROR. File not opened
dj::log_stream log2("DerivationTwo", outfile2);
log("Life. See ", 42, ", meaning of.");
bool OK =
log2("log", std::setw(4), 2.01, " That's all, folks. -", 30, '-');
std::cout << (OK ? "OK" : "So not OK") << std::endl;
}
#包括
#包括
#包括
#包括
#包括
#包括
命名空间dj{
内联bool打印(标准::ostream&out){
返回!!(在运算符上使用链接是否是一项要求?…函数将接受任意数量的参数,但它们将用逗号分隔,而不是@JiveDadson:我完全可以自由选择实现。所以当然,这也没问题。它最多应该简单明了,因为我想节省时间和精力通过实现它来增加复杂性。我不知道如何通过编写诸如loggerI之类的东西来处理动态数量的参数。我想我会尝试一下。这是您想到的一个例子吗?这个策略是否能够处理多个串联变量,如自定义输出多个流的事情当然是这样的。另一个是也是,但实现并没有那么简单。例如,您可以查找std::endl
(或'\n'
)然后,好吧,开始新的一行。考虑到这一点,我可能会坚持使用std::endl
来触发一个新的前缀,然后我甚至可以使用'\n'
进行多行输出。这也使得实现更加容易。非常感谢你!变量模板仅在C++17中可用?我目前正在C++11和prob中开发ably不会很快被选为17。但也许我可以通过某种方式改变它,以实现与C++11函数相同的效果…变量模板在C++11中首次亮相完美,你就是那个人!再次非常感谢!