【发布时间】:2022-01-17 21:40:50
【问题描述】:
是否存在禁用记录器的每个代码行的现有方法取决于 log_level 而不用 ifndef 包围每个调用?
// 5 debug
// 4 info
// 3 warning
// 2 error
// 1 fatal
我的问题是,例如,即使将 log_level 设置为 3,也只会打印警告记录器和更少,但是我的记录器的每个函数的右值参数都非常耗时,例如:
Globals::LOGGER.logger_DEBUG("MyFunction", "rvalue is " + std::to_string(8));
即使使用log_level = 3,也会调用此函数,不会打印任何内容,但会创建 2 个临时字符串并分配字节。
我的目标是禁用每个 Globals::LOGGER.logger_xxxx 行取决于 log_level
我的记录器定义:
logger.hpp:
#pragma once
#include <string>
#include <iostream>
/**
* Class used to make logs
*/
class Logger
{
private:
int _Log_level;
public:
/**
* Contructor
* @param Log_level Level of log we want to print
* @param Name_Log_File Name of the log.txt
*/
Logger(int pLog_level = 4, const std::string &pName_Log_File = "cmd");
/**
* Destructor
*/
~Logger();
/**
* Logger printed when the Log_level is 5
* @param Class_function String that represent the class::function
* @param Message String that we want to print
*/
void logger_DEBUG(const std::string &pClass_function, const std::string &pMessage);
/**
* Logger printed when the Log_level is 4 and higher
* @param Message String that we want to print
*/
void logger_INFO(const std::string &pMessage);
/**
* Logger printed when the Log_level is 3 and higher
* @param Class_function String that represent the class::function
* @param Message String that we want to print
*/
void logger_WARNING(const std::string &pClass_function, const std::string &pMessage);
/**
* Logger printed when the Log_level is 2 and higher
* @param Class_function String that represent the class::function
* @param Message String that we want to print
*/
void logger_ERROR(const std::string &pClass_function, const std::string &pMessage);
/**
* Getter of the Log_level
*/
int get_Log_level();
/**
* Setter of the Log_level
* @param pLog_level
*/
void set_Log_level(const int &pLog_level);
private:
std::string date_time();
};
logger.cpp:
#include "Logger.hpp"
#include <filesystem>
#include <chrono>
#include <ctime>
Logger::Logger(int pLog_level, const std::string &pName_Log_File) : _Log_level(pLog_level)
{
std::cout << "LOGGER created" << std::endl;
if (pName_Log_File != "cmd")
{
std::filesystem::create_directory("LOG");
std::string output_file = "./LOG/" + pName_Log_File + ".txt";
std::freopen(const_cast<char *>(output_file.c_str()), "w", stdout);
}
}
Logger::~Logger()
{
}
void Logger::logger_DEBUG(const std::string &pClass_function, const std::string &pMessage)
{
if (this->_Log_level > 4)
{
std::cout << "[" << this->date_time() << "]"
<< " | [DEBUG] | [" << pClass_function << "] : " << pMessage << std::endl;
}
}
void Logger::logger_INFO(const std::string &pMessage)
{
if (this->_Log_level > 3)
{
std::cout << "[" << this->date_time() << "]"
<< " | [INFO] : " << pMessage << std::endl;
}
}
void Logger::logger_WARNING(const std::string &pClass_function, const std::string &pMessage)
{
if (this->_Log_level > 2)
{
std::cout << "[" << this->date_time() << "]"
<< " | [WARNING] | [" << pClass_function << "] : " << pMessage << std::endl;
}
}
void Logger::logger_ERROR(const std::string &pClass_function, const std::string &pMessage)
{
if (this->_Log_level > 1)
{
std::cout << "[" << this->date_time() << "]"
<< " | [ERROR] | [" << pClass_function << "] : " << pMessage << std::endl;
}
}
int Logger::get_Log_level()
{
return this->_Log_level;
}
void Logger::set_Log_level(const int &pLog_level)
{
this->_Log_level = pLog_level;
}
std::string Logger::date_time()
{
auto start = std::chrono::system_clock::now();
std::time_t time = std::chrono::system_clock::to_time_t(start);
auto res = std::string(std::ctime(&time));
res.pop_back();
return res;
}
为了更好地表达问题: 在我的应用程序 valgrind 中评论记录器的每一行:
total heap usage: 312,852 allocs, 312,852 frees, 7,055,259 bytes allocated
log_level 为 0,不打印,但调用函数,valgrind:
518,672 allocs, 518,672 frees, 23,963,961 bytes allocated
log_level 为 5,打印所有内容,valgrind:
total heap usage: 857,872 allocs, 857,872 frees, 30,917,557 bytes allocated
【问题讨论】:
-
我的代码使用这种模式:
if (log(log::warning)) log << log::warning("MyFunction") << "rvalue is " << rvalue << log::endl;这避免了在无路径旅行的情况下产生参数的开销。 (实际实现使用,ick ick,方便macros:WARN("MyFunction", "rvalue is " << rvalue);。) -
@Eljay 它似乎可以通过唯一检查 log_level 来阻止参数的构造,我可以承认它是一个比包围除
ifndef之外的所有内容更好的解决方案,谢谢
标签: c++ logging heap-memory valgrind allocation