mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 21:09:42 +00:00
Merge branch 'tests_log' into 'master'
Support custom log level in tests See merge request OpenMW/openmw!4179
This commit is contained in:
commit
3ffd6a7ae9
18 changed files with 200 additions and 184 deletions
|
@ -121,14 +121,14 @@ namespace
|
|||
|
||||
if (variables.find("help") != variables.end())
|
||||
{
|
||||
getRawStdout() << desc << std::endl;
|
||||
Debug::getRawStdout() << desc << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Files::ConfigurationManager config;
|
||||
config.readConfiguration(variables, desc);
|
||||
|
||||
setupLogging(config.getLogPath(), applicationName);
|
||||
Debug::setupLogging(config.getLogPath(), applicationName);
|
||||
|
||||
const std::string encoding(variables["encoding"].as<std::string>());
|
||||
Log(Debug::Info) << ToUTF8::encodingUsingMessage(encoding);
|
||||
|
@ -202,5 +202,5 @@ namespace
|
|||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
return wrapApplication(runBulletObjectTool, argc, argv, applicationName);
|
||||
return Debug::wrapApplication(runBulletObjectTool, argc, argv, applicationName);
|
||||
}
|
||||
|
|
|
@ -458,10 +458,14 @@ CUSTOM, PLAYER: useInterface.lua
|
|||
callback.call(1.5, 2.5);
|
||||
EXPECT_EQ(internal::GetCapturedStdout(), "1.5\t2.5\n");
|
||||
|
||||
const Debug::Level level = std::exchange(Log::sMinDebugLevel, Debug::All);
|
||||
|
||||
testing::internal::CaptureStdout();
|
||||
callback.mHiddenData[LuaUtil::ScriptsContainer::sScriptIdKey] = sol::nil;
|
||||
callback.call(1.5, 2.5);
|
||||
EXPECT_EQ(internal::GetCapturedStdout(), "Ignored callback to the removed script some_script.lua\n");
|
||||
|
||||
Log::sMinDebugLevel = level;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ namespace
|
|||
sol::protected_function mNew;
|
||||
LuaUiContentTest()
|
||||
{
|
||||
mLuaState.addInternalLibSearchPath("resources/lua_libs");
|
||||
mLuaState.addInternalLibSearchPath(
|
||||
std::filesystem::path{ OPENMW_PROJECT_SOURCE_DIR } / "components" / "lua_ui");
|
||||
mNew = LuaUi::loadContentConstructor(&mLuaState);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <components/debug/debugging.hpp>
|
||||
#include <components/misc/strings/conversion.hpp>
|
||||
#include <components/settings/parser.hpp>
|
||||
#include <components/settings/values.hpp>
|
||||
|
||||
#include "components/misc/strings/conversion.hpp"
|
||||
#include "components/settings/parser.hpp"
|
||||
#include "components/settings/values.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Log::sMinDebugLevel = Debug::getDebugLevel();
|
||||
|
||||
const std::filesystem::path settingsDefaultPath = std::filesystem::path{ OPENMW_PROJECT_SOURCE_DIR } / "files"
|
||||
/ Misc::StringUtils::stringToU8String("settings-default.cfg");
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ int runLauncher(int argc, char* argv[])
|
|||
configurationManager.addCommonOptions(description);
|
||||
configurationManager.readConfiguration(variables, description, true);
|
||||
|
||||
setupLogging(configurationManager.getLogPath(), "Launcher");
|
||||
Debug::setupLogging(configurationManager.getLogPath(), "Launcher");
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -66,5 +66,5 @@ int runLauncher(int argc, char* argv[])
|
|||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
return wrapApplication(runLauncher, argc, argv, "Launcher");
|
||||
return Debug::wrapApplication(runLauncher, argc, argv, "Launcher");
|
||||
}
|
||||
|
|
|
@ -140,14 +140,14 @@ namespace NavMeshTool
|
|||
|
||||
if (variables.find("help") != variables.end())
|
||||
{
|
||||
getRawStdout() << desc << std::endl;
|
||||
Debug::getRawStdout() << desc << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Files::ConfigurationManager config;
|
||||
config.readConfiguration(variables, desc);
|
||||
|
||||
setupLogging(config.getLogPath(), applicationName);
|
||||
Debug::setupLogging(config.getLogPath(), applicationName);
|
||||
|
||||
const std::string encoding(variables["encoding"].as<std::string>());
|
||||
Log(Debug::Info) << ToUTF8::encodingUsingMessage(encoding);
|
||||
|
@ -260,5 +260,5 @@ namespace NavMeshTool
|
|||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
return wrapApplication(NavMeshTool::runNavMeshTool, argc, argv, NavMeshTool::applicationName);
|
||||
return Debug::wrapApplication(NavMeshTool::runNavMeshTool, argc, argv, NavMeshTool::applicationName);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace NavMeshTool
|
|||
void serializeToStderr(const T& value)
|
||||
{
|
||||
const std::vector<std::byte> data = serialize(value);
|
||||
getLockedRawStderr()->write(
|
||||
Debug::getLockedRawStderr()->write(
|
||||
reinterpret_cast<const char*>(data.data()), static_cast<std::streamsize>(data.size()));
|
||||
}
|
||||
|
||||
|
|
|
@ -219,7 +219,8 @@ namespace NavMeshTool
|
|||
void serializeToStderr(const T& value)
|
||||
{
|
||||
const std::vector<std::byte> data = serialize(value);
|
||||
getRawStderr().write(reinterpret_cast<const char*>(data.data()), static_cast<std::streamsize>(data.size()));
|
||||
Debug::getRawStderr().write(
|
||||
reinterpret_cast<const char*>(data.data()), static_cast<std::streamsize>(data.size()));
|
||||
}
|
||||
|
||||
std::string makeAddObjectErrorMessage(
|
||||
|
|
|
@ -139,7 +139,7 @@ boost::program_options::variables_map CS::Editor::readConfiguration()
|
|||
|
||||
mCfgMgr.readConfiguration(variables, desc, false);
|
||||
Settings::Manager::load(mCfgMgr, true);
|
||||
setupLogging(mCfgMgr.getLogPath(), "OpenMW-CS");
|
||||
Debug::setupLogging(mCfgMgr.getLogPath(), "OpenMW-CS");
|
||||
|
||||
return variables;
|
||||
}
|
||||
|
|
|
@ -78,5 +78,5 @@ int runApplication(int argc, char* argv[])
|
|||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
return wrapApplication(&runApplication, argc, argv, "OpenMW-CS");
|
||||
return Debug::wrapApplication(&runApplication, argc, argv, "OpenMW-CS");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#include <components/debug/debugging.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
Log::sMinDebugLevel = Debug::getDebugLevel();
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
|
|
@ -53,19 +53,19 @@ bool parseOptions(int argc, char** argv, OMW::Engine& engine, Files::Configurati
|
|||
|
||||
if (variables.count("help"))
|
||||
{
|
||||
getRawStdout() << desc << std::endl;
|
||||
Debug::getRawStdout() << desc << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (variables.count("version"))
|
||||
{
|
||||
getRawStdout() << Version::getOpenmwVersionDescription() << std::endl;
|
||||
Debug::getRawStdout() << Version::getOpenmwVersionDescription() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
cfgMgr.readConfiguration(variables, desc);
|
||||
|
||||
setupLogging(cfgMgr.getLogPath(), "OpenMW");
|
||||
Debug::setupLogging(cfgMgr.getLogPath(), "OpenMW");
|
||||
Log(Debug::Info) << Version::getOpenmwVersionDescription();
|
||||
|
||||
Settings::Manager::load(cfgMgr);
|
||||
|
@ -245,7 +245,7 @@ extern "C" int SDL_main(int argc, char** argv)
|
|||
int main(int argc, char** argv)
|
||||
#endif
|
||||
{
|
||||
return wrapApplication(&runApplication, argc, argv, "OpenMW");
|
||||
return Debug::wrapApplication(&runApplication, argc, argv, "OpenMW");
|
||||
}
|
||||
|
||||
// Platform specific for Windows when there is no console built into the executable.
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
#include <components/debug/debugging.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
Log::sMinDebugLevel = Debug::getDebugLevel();
|
||||
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include "debugging.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <deque>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -109,22 +109,19 @@ namespace Debug
|
|||
class DebugOutputBase : public boost::iostreams::sink
|
||||
{
|
||||
public:
|
||||
DebugOutputBase()
|
||||
{
|
||||
if (CurrentDebugLevel == NoLevel)
|
||||
fillCurrentDebugLevel();
|
||||
}
|
||||
|
||||
virtual std::streamsize write(const char* str, std::streamsize size)
|
||||
{
|
||||
if (size <= 0)
|
||||
return size;
|
||||
std::string_view msg{ str, size_t(size) };
|
||||
std::string_view msg{ str, static_cast<size_t>(size) };
|
||||
|
||||
// Skip debug level marker
|
||||
Level level = getLevelMarker(str);
|
||||
if (level != NoLevel)
|
||||
Level level = All;
|
||||
if (Log::sWriteLevel)
|
||||
{
|
||||
level = getLevelMarker(msg[0]);
|
||||
msg = msg.substr(1);
|
||||
}
|
||||
|
||||
char prefix[32];
|
||||
std::size_t prefixSize;
|
||||
|
@ -165,37 +162,11 @@ namespace Debug
|
|||
virtual ~DebugOutputBase() = default;
|
||||
|
||||
protected:
|
||||
static Level getLevelMarker(const char* str)
|
||||
static Level getLevelMarker(char marker)
|
||||
{
|
||||
if (unsigned(*str) <= unsigned(Marker))
|
||||
{
|
||||
return Level(*str);
|
||||
}
|
||||
|
||||
return NoLevel;
|
||||
}
|
||||
|
||||
static void fillCurrentDebugLevel()
|
||||
{
|
||||
const char* env = getenv("OPENMW_DEBUG_LEVEL");
|
||||
if (env)
|
||||
{
|
||||
std::string value(env);
|
||||
if (value == "ERROR")
|
||||
CurrentDebugLevel = Error;
|
||||
else if (value == "WARNING")
|
||||
CurrentDebugLevel = Warning;
|
||||
else if (value == "INFO")
|
||||
CurrentDebugLevel = Info;
|
||||
else if (value == "VERBOSE")
|
||||
CurrentDebugLevel = Verbose;
|
||||
else if (value == "DEBUG")
|
||||
CurrentDebugLevel = Debug;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentDebugLevel = Verbose;
|
||||
if (0 <= marker && static_cast<unsigned>(marker) < static_cast<unsigned>(All))
|
||||
return static_cast<Level>(marker);
|
||||
return All;
|
||||
}
|
||||
|
||||
virtual std::streamsize writeImpl(const char* str, std::streamsize size, Level debugLevel)
|
||||
|
@ -229,7 +200,7 @@ namespace Debug
|
|||
Level mLevel;
|
||||
};
|
||||
|
||||
std::vector<Record> globalBuffer;
|
||||
std::deque<Record> globalBuffer;
|
||||
|
||||
Color getColor(Level level)
|
||||
{
|
||||
|
@ -245,7 +216,7 @@ namespace Debug
|
|||
return DarkGray;
|
||||
case Debug:
|
||||
return DarkGray;
|
||||
case NoLevel:
|
||||
case All:
|
||||
return Reset;
|
||||
}
|
||||
return Reset;
|
||||
|
@ -314,18 +285,22 @@ namespace Debug
|
|||
class Buffer
|
||||
{
|
||||
public:
|
||||
explicit Buffer(std::vector<Record>& buffer)
|
||||
: mBuffer(buffer)
|
||||
explicit Buffer(std::size_t capacity, std::deque<Record>& buffer)
|
||||
: mCapacity(capacity)
|
||||
, mBuffer(buffer)
|
||||
{
|
||||
}
|
||||
|
||||
void write(const char* str, std::streamsize size, Level debugLevel)
|
||||
{
|
||||
while (mBuffer.size() >= mCapacity)
|
||||
mBuffer.pop_front();
|
||||
mBuffer.push_back(Record{ std::string(str, size), debugLevel });
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Record>& mBuffer;
|
||||
std::size_t mCapacity;
|
||||
std::deque<Record>& mBuffer;
|
||||
};
|
||||
|
||||
template <class First, class Second>
|
||||
|
@ -352,131 +327,157 @@ namespace Debug
|
|||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static std::unique_ptr<std::ostream> rawStdout = nullptr;
|
||||
static std::unique_ptr<std::ostream> rawStderr = nullptr;
|
||||
static std::unique_ptr<std::mutex> rawStderrMutex = nullptr;
|
||||
static std::ofstream logfile;
|
||||
static std::unique_ptr<std::ostream> rawStdout = nullptr;
|
||||
static std::unique_ptr<std::ostream> rawStderr = nullptr;
|
||||
static std::unique_ptr<std::mutex> rawStderrMutex = nullptr;
|
||||
static std::ofstream logfile;
|
||||
|
||||
#if defined(_WIN32) && defined(_DEBUG)
|
||||
static boost::iostreams::stream_buffer<Debug::DebugOutput> sb;
|
||||
static boost::iostreams::stream_buffer<DebugOutput> sb;
|
||||
#else
|
||||
static boost::iostreams::stream_buffer<Debug::Tee<Debug::Identity, Debug::Coloured>> standardOut;
|
||||
static boost::iostreams::stream_buffer<Debug::Tee<Debug::Identity, Debug::Coloured>> standardErr;
|
||||
static boost::iostreams::stream_buffer<Debug::Tee<Debug::Buffer, Debug::Coloured>> bufferedOut;
|
||||
static boost::iostreams::stream_buffer<Debug::Tee<Debug::Buffer, Debug::Coloured>> bufferedErr;
|
||||
static boost::iostreams::stream_buffer<Tee<Identity, Coloured>> standardOut;
|
||||
static boost::iostreams::stream_buffer<Tee<Identity, Coloured>> standardErr;
|
||||
static boost::iostreams::stream_buffer<Tee<Buffer, Coloured>> bufferedOut;
|
||||
static boost::iostreams::stream_buffer<Tee<Buffer, Coloured>> bufferedErr;
|
||||
#endif
|
||||
|
||||
std::ostream& getRawStdout()
|
||||
{
|
||||
return rawStdout ? *rawStdout : std::cout;
|
||||
}
|
||||
std::ostream& getRawStdout()
|
||||
{
|
||||
return rawStdout ? *rawStdout : std::cout;
|
||||
}
|
||||
|
||||
std::ostream& getRawStderr()
|
||||
{
|
||||
return rawStderr ? *rawStderr : std::cerr;
|
||||
}
|
||||
std::ostream& getRawStderr()
|
||||
{
|
||||
return rawStderr ? *rawStderr : std::cerr;
|
||||
}
|
||||
|
||||
Misc::Locked<std::ostream&> getLockedRawStderr()
|
||||
{
|
||||
return Misc::Locked<std::ostream&>(*rawStderrMutex, getRawStderr());
|
||||
}
|
||||
Misc::Locked<std::ostream&> getLockedRawStderr()
|
||||
{
|
||||
return Misc::Locked<std::ostream&>(*rawStderrMutex, getRawStderr());
|
||||
}
|
||||
|
||||
Level getDebugLevel()
|
||||
{
|
||||
if (const char* env = getenv("OPENMW_DEBUG_LEVEL"))
|
||||
{
|
||||
const std::string_view value(env);
|
||||
if (value == "ERROR")
|
||||
return Error;
|
||||
if (value == "WARNING")
|
||||
return Warning;
|
||||
if (value == "INFO")
|
||||
return Info;
|
||||
if (value == "VERBOSE")
|
||||
return Verbose;
|
||||
if (value == "DEBUG")
|
||||
return Debug;
|
||||
}
|
||||
|
||||
return Verbose;
|
||||
}
|
||||
|
||||
void setupLogging(const std::filesystem::path& logDir, std::string_view appName)
|
||||
{
|
||||
Log::sMinDebugLevel = getDebugLevel();
|
||||
Log::sWriteLevel = true;
|
||||
|
||||
// Redirect cout and cerr to the log file
|
||||
void setupLogging(const std::filesystem::path& logDir, std::string_view appName, std::ios_base::openmode mode)
|
||||
{
|
||||
#if !(defined(_WIN32) && defined(_DEBUG))
|
||||
const std::string logName = Misc::StringUtils::lowerCase(appName) + ".log";
|
||||
logfile.open(logDir / logName, mode);
|
||||
const std::string logName = Misc::StringUtils::lowerCase(appName) + ".log";
|
||||
logfile.open(logDir / logName, std::ios::out);
|
||||
|
||||
Debug::Identity log(logfile);
|
||||
Identity log(logfile);
|
||||
|
||||
for (const Debug::Record& v : Debug::globalBuffer)
|
||||
log.write(v.mValue.data(), v.mValue.size(), v.mLevel);
|
||||
for (const Record& v : globalBuffer)
|
||||
log.write(v.mValue.data(), v.mValue.size(), v.mLevel);
|
||||
|
||||
Debug::globalBuffer.clear();
|
||||
globalBuffer.clear();
|
||||
|
||||
standardOut.open(Debug::Tee(log, Debug::Coloured(*rawStdout)));
|
||||
standardErr.open(Debug::Tee(log, Debug::Coloured(*rawStderr)));
|
||||
standardOut.open(Tee(log, Coloured(*rawStdout)));
|
||||
standardErr.open(Tee(log, Coloured(*rawStderr)));
|
||||
|
||||
std::cout.rdbuf(&standardOut);
|
||||
std::cerr.rdbuf(&standardErr);
|
||||
std::cout.rdbuf(&standardOut);
|
||||
std::cerr.rdbuf(&standardErr);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
if (Crash::CrashCatcher::instance())
|
||||
{
|
||||
Crash::CrashCatcher::instance()->updateDumpPath(logDir);
|
||||
if (Crash::CrashCatcher::instance())
|
||||
{
|
||||
Crash::CrashCatcher::instance()->updateDumpPath(logDir);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int wrapApplication(int (*innerApplication)(int argc, char* argv[]), int argc, char* argv[], std::string_view appName)
|
||||
{
|
||||
int wrapApplication(
|
||||
int (*innerApplication)(int argc, char* argv[]), int argc, char* argv[], std::string_view appName)
|
||||
{
|
||||
#if defined _WIN32
|
||||
(void)Debug::attachParentConsole();
|
||||
(void)attachParentConsole();
|
||||
#endif
|
||||
rawStdout = std::make_unique<std::ostream>(std::cout.rdbuf());
|
||||
rawStderr = std::make_unique<std::ostream>(std::cerr.rdbuf());
|
||||
rawStderrMutex = std::make_unique<std::mutex>();
|
||||
rawStdout = std::make_unique<std::ostream>(std::cout.rdbuf());
|
||||
rawStderr = std::make_unique<std::ostream>(std::cerr.rdbuf());
|
||||
rawStderrMutex = std::make_unique<std::mutex>();
|
||||
|
||||
#if defined(_WIN32) && defined(_DEBUG)
|
||||
// Redirect cout and cerr to VS debug output when running in debug mode
|
||||
sb.open(Debug::DebugOutput());
|
||||
std::cout.rdbuf(&sb);
|
||||
std::cerr.rdbuf(&sb);
|
||||
// Redirect cout and cerr to VS debug output when running in debug mode
|
||||
sb.open(DebugOutput());
|
||||
std::cout.rdbuf(&sb);
|
||||
std::cerr.rdbuf(&sb);
|
||||
#else
|
||||
bufferedOut.open(Debug::Tee(Debug::Buffer(Debug::globalBuffer), Debug::Coloured(*rawStdout)));
|
||||
bufferedErr.open(Debug::Tee(Debug::Buffer(Debug::globalBuffer), Debug::Coloured(*rawStderr)));
|
||||
constexpr std::size_t bufferCapacity = 1024;
|
||||
|
||||
std::cout.rdbuf(&bufferedOut);
|
||||
std::cerr.rdbuf(&bufferedErr);
|
||||
bufferedOut.open(Tee(Buffer(bufferCapacity, globalBuffer), Coloured(*rawStdout)));
|
||||
bufferedErr.open(Tee(Buffer(bufferCapacity, globalBuffer), Coloured(*rawStderr)));
|
||||
|
||||
std::cout.rdbuf(&bufferedOut);
|
||||
std::cerr.rdbuf(&bufferedErr);
|
||||
#endif
|
||||
|
||||
int ret = 0;
|
||||
try
|
||||
{
|
||||
if (const auto env = std::getenv("OPENMW_DISABLE_CRASH_CATCHER");
|
||||
env == nullptr || Misc::StringUtils::toNumeric<int>(env, 0) == 0)
|
||||
int ret = 0;
|
||||
try
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
const std::string crashDumpName = Misc::StringUtils::lowerCase(appName) + "-crash.dmp";
|
||||
const std::string freezeDumpName = Misc::StringUtils::lowerCase(appName) + "-freeze.dmp";
|
||||
std::filesystem::path dumpDirectory = std::filesystem::temp_directory_path();
|
||||
PWSTR userProfile = nullptr;
|
||||
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &userProfile)))
|
||||
if (const auto env = std::getenv("OPENMW_DISABLE_CRASH_CATCHER");
|
||||
env == nullptr || Misc::StringUtils::toNumeric<int>(env, 0) == 0)
|
||||
{
|
||||
dumpDirectory = userProfile;
|
||||
}
|
||||
CoTaskMemFree(userProfile);
|
||||
Crash::CrashCatcher crashy(argc, argv, dumpDirectory, crashDumpName, freezeDumpName);
|
||||
#if defined(_WIN32)
|
||||
const std::string crashDumpName = Misc::StringUtils::lowerCase(appName) + "-crash.dmp";
|
||||
const std::string freezeDumpName = Misc::StringUtils::lowerCase(appName) + "-freeze.dmp";
|
||||
std::filesystem::path dumpDirectory = std::filesystem::temp_directory_path();
|
||||
PWSTR userProfile = nullptr;
|
||||
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &userProfile)))
|
||||
{
|
||||
dumpDirectory = userProfile;
|
||||
}
|
||||
CoTaskMemFree(userProfile);
|
||||
Crash::CrashCatcher crashy(argc, argv, dumpDirectory, crashDumpName, freezeDumpName);
|
||||
#else
|
||||
const std::string crashLogName = Misc::StringUtils::lowerCase(appName) + "-crash.log";
|
||||
// install the crash handler as soon as possible.
|
||||
crashCatcherInstall(argc, argv, std::filesystem::temp_directory_path() / crashLogName);
|
||||
const std::string crashLogName = Misc::StringUtils::lowerCase(appName) + "-crash.log";
|
||||
// install the crash handler as soon as possible.
|
||||
crashCatcherInstall(argc, argv, std::filesystem::temp_directory_path() / crashLogName);
|
||||
#endif
|
||||
ret = innerApplication(argc, argv);
|
||||
ret = innerApplication(argc, argv);
|
||||
}
|
||||
else
|
||||
ret = innerApplication(argc, argv);
|
||||
}
|
||||
else
|
||||
ret = innerApplication(argc, argv);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
#if (defined(__APPLE__) || defined(__linux) || defined(__unix) || defined(__posix))
|
||||
if (!isatty(fileno(stdin)))
|
||||
if (!isatty(fileno(stdin)))
|
||||
#endif
|
||||
SDL_ShowSimpleMessageBox(0, (std::string(appName) + ": Fatal error").c_str(), e.what(), nullptr);
|
||||
SDL_ShowSimpleMessageBox(0, (std::string(appName) + ": Fatal error").c_str(), e.what(), nullptr);
|
||||
|
||||
Log(Debug::Error) << "Fatal error: " << e.what();
|
||||
Log(Debug::Error) << "Fatal error: " << e.what();
|
||||
|
||||
ret = 1;
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
// Restore cout and cerr
|
||||
std::cout.rdbuf(rawStdout->rdbuf());
|
||||
std::cerr.rdbuf(rawStderr->rdbuf());
|
||||
|
||||
Log::sMinDebugLevel = All;
|
||||
Log::sWriteLevel = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Restore cout and cerr
|
||||
std::cout.rdbuf(rawStdout->rdbuf());
|
||||
std::cerr.rdbuf(rawStderr->rdbuf());
|
||||
Debug::CurrentDebugLevel = Debug::NoLevel;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -26,18 +26,21 @@ namespace Debug
|
|||
|
||||
using LogListener = std::function<void(Debug::Level, std::string_view prefix, std::string_view msg)>;
|
||||
void setLogListener(LogListener);
|
||||
|
||||
// Can be used to print messages without timestamps
|
||||
std::ostream& getRawStdout();
|
||||
|
||||
std::ostream& getRawStderr();
|
||||
|
||||
Misc::Locked<std::ostream&> getLockedRawStderr();
|
||||
|
||||
Level getDebugLevel();
|
||||
|
||||
// Redirect cout and cerr to the log file
|
||||
void setupLogging(const std::filesystem::path& logDir, std::string_view appName);
|
||||
|
||||
int wrapApplication(
|
||||
int (*innerApplication)(int argc, char* argv[]), int argc, char* argv[], std::string_view appName);
|
||||
}
|
||||
|
||||
// Can be used to print messages without timestamps
|
||||
std::ostream& getRawStdout();
|
||||
|
||||
std::ostream& getRawStderr();
|
||||
|
||||
Misc::Locked<std::ostream&> getLockedRawStderr();
|
||||
|
||||
void setupLogging(
|
||||
const std::filesystem::path& logDir, std::string_view appName, std::ios_base::openmode mode = std::ios::out);
|
||||
|
||||
int wrapApplication(int (*innerApplication)(int argc, char* argv[]), int argc, char* argv[], std::string_view appName);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,15 +5,13 @@
|
|||
#include <components/files/conversion.hpp>
|
||||
#include <components/misc/strings/conversion.hpp>
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
Level CurrentDebugLevel = Level::NoLevel;
|
||||
}
|
||||
|
||||
static std::mutex sLock;
|
||||
|
||||
Debug::Level Log::sMinDebugLevel = Debug::All;
|
||||
bool Log::sWriteLevel = false;
|
||||
|
||||
Log::Log(Debug::Level level)
|
||||
: mShouldLog(level <= Debug::CurrentDebugLevel)
|
||||
: mShouldLog(level <= sMinDebugLevel)
|
||||
{
|
||||
// No need to hold the lock if there will be no logging anyway
|
||||
if (!mShouldLog)
|
||||
|
@ -22,9 +20,7 @@ Log::Log(Debug::Level level)
|
|||
// Locks a global lock while the object is alive
|
||||
sLock.lock();
|
||||
|
||||
// If the app has no logging system enabled, log level is not specified.
|
||||
// Show all messages without marker - we just use the plain cout in this case.
|
||||
if (Debug::CurrentDebugLevel == Debug::NoLevel)
|
||||
if (!sWriteLevel)
|
||||
return;
|
||||
|
||||
std::cout << static_cast<unsigned char>(level);
|
||||
|
|
|
@ -6,24 +6,23 @@
|
|||
|
||||
namespace Debug
|
||||
{
|
||||
enum Level
|
||||
enum Level : unsigned
|
||||
{
|
||||
Error = 1,
|
||||
Warning = 2,
|
||||
Info = 3,
|
||||
Verbose = 4,
|
||||
Debug = 5,
|
||||
Marker = Debug,
|
||||
|
||||
NoLevel = 6 // Do not filter messages in this case
|
||||
All = 6,
|
||||
};
|
||||
|
||||
extern Level CurrentDebugLevel;
|
||||
}
|
||||
|
||||
class Log
|
||||
{
|
||||
public:
|
||||
static Debug::Level sMinDebugLevel;
|
||||
static bool sWriteLevel;
|
||||
|
||||
explicit Log(Debug::Level level);
|
||||
~Log();
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace osgMyGUI
|
|||
|
||||
MyGUI::LogLevel LogFacility::getCurrentLogLevel() const
|
||||
{
|
||||
switch (Debug::CurrentDebugLevel)
|
||||
switch (Log::sMinDebugLevel)
|
||||
{
|
||||
case Debug::Error:
|
||||
return MyGUI::LogLevel::Error;
|
||||
|
|
Loading…
Reference in a new issue