2020-09-21 17:17:34 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-06-26 15:17:35 +00:00
|
|
|
//
|
2020-09-21 17:17:34 +00:00
|
|
|
// EmulationStation Desktop Edition
|
2020-06-26 15:17:35 +00:00
|
|
|
// Log.cpp
|
|
|
|
//
|
2021-11-15 19:47:00 +00:00
|
|
|
// Log output.
|
2023-02-18 19:32:36 +00:00
|
|
|
// This class is thread safe.
|
2020-06-26 15:17:35 +00:00
|
|
|
//
|
|
|
|
|
2013-01-04 23:31:51 +00:00
|
|
|
#include "Log.h"
|
2021-11-15 22:45:17 +00:00
|
|
|
#include "utils/StringUtil.h"
|
2017-11-01 22:21:10 +00:00
|
|
|
|
2022-06-22 05:06:20 +00:00
|
|
|
LogLevel Log::getReportingLevel()
|
|
|
|
{
|
2022-06-23 21:20:48 +00:00
|
|
|
std::unique_lock<std::mutex> lock {sLogMutex};
|
2022-06-22 05:06:20 +00:00
|
|
|
return sReportingLevel;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Log::setReportingLevel(LogLevel level)
|
|
|
|
{
|
2022-06-23 21:20:48 +00:00
|
|
|
std::unique_lock<std::mutex> lock {sLogMutex};
|
2022-06-22 05:06:20 +00:00
|
|
|
sReportingLevel = level;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Log::getLogPath()
|
|
|
|
{
|
|
|
|
return Utils::FileSystem::getHomePath() + "/.emulationstation/es_log.txt";
|
|
|
|
}
|
|
|
|
|
2017-08-01 10:34:49 +00:00
|
|
|
void Log::init()
|
|
|
|
{
|
2020-07-10 16:32:23 +00:00
|
|
|
Utils::FileSystem::removeFile(getLogPath() + ".bak");
|
|
|
|
// Rename the previous log file.
|
|
|
|
Utils::FileSystem::renameFile(getLogPath(), getLogPath() + ".bak", true);
|
2020-06-26 15:17:35 +00:00
|
|
|
return;
|
2017-08-01 10:34:49 +00:00
|
|
|
}
|
|
|
|
|
2013-01-08 02:24:59 +00:00
|
|
|
void Log::open()
|
|
|
|
{
|
2022-06-23 21:20:48 +00:00
|
|
|
std::unique_lock<std::mutex> lock {sLogMutex};
|
2021-07-07 18:31:46 +00:00
|
|
|
#if defined(_WIN64)
|
2021-11-15 22:45:17 +00:00
|
|
|
sFile.open(Utils::String::stringToWideString(getLogPath()).c_str());
|
2021-07-07 18:31:46 +00:00
|
|
|
#else
|
2021-11-15 19:47:00 +00:00
|
|
|
sFile.open(getLogPath().c_str());
|
2021-07-07 18:31:46 +00:00
|
|
|
#endif
|
2013-01-08 02:24:59 +00:00
|
|
|
}
|
|
|
|
|
2022-06-23 21:20:48 +00:00
|
|
|
void Log::flush()
|
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> lock {sLogMutex};
|
|
|
|
sFile.flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Log::close()
|
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> lock {sLogMutex};
|
|
|
|
if (sFile.is_open())
|
|
|
|
sFile.close();
|
|
|
|
}
|
|
|
|
|
2013-01-04 23:31:51 +00:00
|
|
|
std::ostringstream& Log::get(LogLevel level)
|
|
|
|
{
|
2022-01-16 17:18:28 +00:00
|
|
|
time_t t {time(nullptr)};
|
2020-12-29 12:44:13 +00:00
|
|
|
struct tm tm;
|
2021-07-07 18:31:46 +00:00
|
|
|
#if defined(_WIN64)
|
2020-12-29 12:44:13 +00:00
|
|
|
// Of course Windows does not follow standards and puts the parameters the other way
|
|
|
|
// around compared to POSIX.
|
|
|
|
localtime_s(&tm, &t);
|
2021-07-07 18:31:46 +00:00
|
|
|
#else
|
2020-12-29 12:44:13 +00:00
|
|
|
localtime_r(&t, &tm);
|
2021-07-07 18:31:46 +00:00
|
|
|
#endif
|
2022-09-23 20:49:17 +00:00
|
|
|
std::unique_lock<std::mutex> lock {sLogMutex};
|
2021-11-15 19:47:00 +00:00
|
|
|
mOutStringStream << std::put_time(&tm, "%b %d %T ") << mLogLevelMap[level] << ":\t";
|
|
|
|
mMessageLevel = level;
|
2013-01-04 23:31:51 +00:00
|
|
|
|
2021-11-15 19:47:00 +00:00
|
|
|
return mOutStringStream;
|
2013-01-04 23:31:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Log::~Log()
|
|
|
|
{
|
2022-06-23 21:20:48 +00:00
|
|
|
std::unique_lock<std::mutex> lock {sLogMutex};
|
2023-01-28 12:36:22 +00:00
|
|
|
mOutStringStream << std::endl;
|
2022-06-23 21:20:48 +00:00
|
|
|
|
2021-11-15 19:47:00 +00:00
|
|
|
if (!sFile.is_open()) {
|
2020-07-10 16:32:23 +00:00
|
|
|
// Not open yet, print to stdout.
|
2021-07-07 18:31:46 +00:00
|
|
|
std::cerr << "Error: Tried to write to log file before it was open, "
|
|
|
|
"the following won't be logged:\n";
|
2021-11-15 19:47:00 +00:00
|
|
|
std::cerr << mOutStringStream.str();
|
2020-06-26 15:17:35 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-15 19:47:00 +00:00
|
|
|
sFile << mOutStringStream.str();
|
2020-06-26 15:17:35 +00:00
|
|
|
|
2021-11-15 19:47:00 +00:00
|
|
|
// If it's an error or the --debug flag has been set, then print to the console as well.
|
|
|
|
if (mMessageLevel == LogError || sReportingLevel >= LogDebug)
|
|
|
|
std::cerr << mOutStringStream.str();
|
2013-01-04 23:31:51 +00:00
|
|
|
}
|