[英]c++ Static member function in logging class
出於學習目的,我正在做 static class 進行日志記錄。 我有 function “startLog”,它刪除任何同名文件並打開文件進行寫入。 而且我有功能“日志”,它可以將一些文本打印到文件中並且它可以工作。 但是,當從“startLog”調用此 function 時,不會寫入文件。
log.log 文件中的預期結果:
[信息] 2022-07-29 20:04:07.?????? | log.cpp:34: 無效 startLog (const std::string&) | 日志打開... log.log
[調試] 2022-07-29 20:04:07.465570 | main.cpp:15: int main(int, char**) | 測試1 - 開始
[調試] 2022-07-29 20:04:08.547214 | main.cpp:22: int main(int, char**) | 測試1 - 結束
但是在運行它之后,log.log 文件中只有這個:
[調試] 2022-07-29 20:04:07.465570 | main.cpp:15: int main(int, char**) | 測試1 - 開始
[調試] 2022-07-29 20:04:08.547214 | main.cpp:22: int main(int, char**) | 測試1 - 結束
#include "log.hpp"
#include <iostream>
int main(int, char*[])
{
std::string logFile {"log.log"};
Log::startLog (logFile);
Log::startLog ("log1.txt");
int testCycles {100'000};
Log::log ("TEST1 - START!", Log::DEBUG, logFile);
for (int i = 0; i < testCycles; ++i)
{
Log::log("TEST" + std::to_string(i), Log::INFO, "log1.txt");
}
Log::log ("TEST1 - END!", Log::DEBUG, logFile);
return EXIT_SUCCESS;
}
#ifndef LOG_HPP
#define LOG_HPP
#include <fstream>
#include <source_location>
#include <string>
#include <string_view>
class Log
{
public:
enum
{
INFO,
DEBUG,
WARNING,
ERROR,
FATAL,
};
static void log (std::string_view errorMsg, int severity = Log::INFO, const std::string& logFile = s_logFile,
const std::source_location location = std::source_location::current());
static void startLog (const std::string& logFile = "log.log");
static std::string getLogFile (){return s_logFile;};
static void setLogLevel (int logLevel);
private:
static inline std::string s_logFile;
static inline std::fstream s_outf {s_logFile, std::ios::app};
static inline std::string s_logMsg [] = {"[INFO]", "[DEBUG]", "[WARNING]","[ERROR]", "[FATAL]"};
static inline int s_logLevel = Log::INFO;
Log (){};
};
#endif // LOG_HPP_INCLUDED
#include "log.hpp"
#include "utilities.hpp"
#include <filesystem>
#include <fstream>
#include <iomanip>
#include <string_view>
void Log::log (std::string_view errorMsg, int severity, const std::string& logFile, const std::source_location location)
{
if (severity < Log::INFO) severity = Log::INFO;
else if (severity > Log::FATAL) severity = Log::FATAL;
if (severity < s_logLevel) return;
if (logFile != s_logFile)
{
s_outf.close();
s_outf.open (logFile, std::ios::app);
s_logFile = std::move (logFile);
}
s_outf
<< std::left << std::setw(10) << s_logMsg[severity]
<< Util::getTimeMillisec() << " | "
<< std::filesystem::path(location.file_name()).filename().string() << ":" << location.line() << ": " << location.function_name() << " | "
<< errorMsg <<'\n';
// should be optimized in C++23 using location.resource_file to get filename instead of using std::filesystem
}
void Log::startLog (const std::string& logFile)
{
s_logFile = logFile;
remove (s_logFile.c_str());
log ("Log opening ... " + s_logFile);
}
void Log::setLogLevel (int logLevel)
{
if (logLevel < 0) s_logLevel = 0;
else if (logLevel > Log::FATAL) s_logLevel = Log::FATAL;
else s_logLevel = logLevel;
}
注意:有實用程序.hpp 和實用程序.cpp 來獲取格式化時間點,它工作正常,所以我在這里不包含代碼。
Log::startLog
永遠不會導致日志文件被打開,因為s_logFile
設置為log
調用的默認參數。 最初也沒有打開文件,因為將空字符串傳遞給std::fstream
的構造函數不會導致文件被打開。
你可能想要類似的東西
class Log
{
...
static inline std::string s_logFile; // empty initially; will result in opening the file stream the first time a file name is passed to log
static inline std::fstream s_outf; // not opened initially as before (opening file "" fails)
...
};
void Log::startLog(const std::string& logFile)
{
remove(s_logFile.c_str());
log("Log opening ... " + s_logFile, Log::INFO, logFile);
}
此外,您應該聽聽編譯器警告:
在
s_logFile = std::move(logFile);
你正在移動一個 const 左值引用。 您應該簡單地使用復制賦值運算符。
您的代碼甚至可以編譯嗎? 您在 Main function 中的 testCycles 初始化中有一個奇怪的錯字。 可能循環被稱為零次。 此外 static 意味着您的成員變量 s_logFile 是全局的。 你用兩個不同的參數調用它兩次。 我不認為它會做,你的意圖。
最后:谷歌關於 ifstream/ofstream。 如果使用得當,就不需要調用 open/close。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.