mirror of
https://github.com/Dark98/threeSD.git
synced 2026-07-02 16:49:04 +00:00
Overhauls the logging system
Updated fmt to 8.0.0. This is now more compile-time, and outputs to stderr, file as well as a buffer.
This commit is contained in:
Vendored
+1
-1
Submodule externals/fmt updated: 7512a55aa3...a58c133821
@@ -25,6 +25,8 @@
|
||||
#endif
|
||||
#define CITRA_EXECUTABLE "citra-qt"
|
||||
|
||||
#define LOG_FILE "threeSD.log.txt"
|
||||
|
||||
// Subdirs in the User dir returned by GetUserPath(UserPath::UserDir)
|
||||
#define CONFIG_DIR "config"
|
||||
#define CACHE_DIR "cache"
|
||||
|
||||
@@ -3,9 +3,20 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#ifdef _WIN32
|
||||
#include <share.h> // For _SH_DENYWR
|
||||
#else
|
||||
#define _SH_DENYWR 0
|
||||
#endif
|
||||
|
||||
#include "common/common_paths.h"
|
||||
#include "common/file_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
|
||||
namespace Common::Logging {
|
||||
|
||||
std::uint64_t GetLoggingTime() {
|
||||
static auto time_origin = std::chrono::steady_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() -
|
||||
@@ -13,6 +24,38 @@ std::uint64_t GetLoggingTime() {
|
||||
.count();
|
||||
}
|
||||
|
||||
std::string StandardizeLogClass(const std::string& log_class) {
|
||||
return Common::ReplaceAll(log_class, "_", ".");
|
||||
// _SH_DENYWR allows read-only access for other programs. For non-Windows it's defined to 0.
|
||||
static FileUtil::IOFile g_log_file{LOG_FILE, "w", _SH_DENYWR};
|
||||
|
||||
static std::array<Entry, 3> g_error_buffer{};
|
||||
static int g_error_buffer_pos = 0;
|
||||
|
||||
void WriteLog(Entry entry) {
|
||||
// stderr
|
||||
fmt::print(stderr, entry.style, entry.message);
|
||||
|
||||
// log file
|
||||
g_log_file.WriteString(entry.message);
|
||||
if (entry.level >= Level::Error) {
|
||||
g_log_file.Flush(); // Do not flush the file too often
|
||||
}
|
||||
|
||||
// log buffer
|
||||
if (entry.level >= Level::Error) {
|
||||
g_error_buffer[g_error_buffer_pos] = std::move(entry);
|
||||
g_error_buffer_pos = (g_error_buffer_pos + 1) % g_error_buffer.size();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetLastErrors() {
|
||||
std::string output;
|
||||
for (std::size_t i = 0; i < g_error_buffer.size(); ++i) {
|
||||
const std::size_t pos = (g_error_buffer_pos + i) % g_error_buffer.size();
|
||||
if (g_error_buffer[pos].level != Level::Invalid) {
|
||||
output.append(g_error_buffer[pos].message);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace Common::Logging
|
||||
|
||||
+32
-20
@@ -12,37 +12,49 @@
|
||||
#include <fmt/color.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
std::uint64_t GetLoggingTime();
|
||||
std::string StandardizeLogClass(const std::string& log_class);
|
||||
namespace Common::Logging {
|
||||
|
||||
#define LOG_PRINT(log_class, level, text_style, file, line, func, format, ...) \
|
||||
{ \
|
||||
fmt::print(stderr, text_style, "[{:12.6f}] {} <{}> {}:{}:{}: " format "\n", \
|
||||
GetLoggingTime() / 1000000.0, StandardizeLogClass(log_class), level, file, \
|
||||
line, func __VA_OPT__(, ) __VA_ARGS__); \
|
||||
fflush(stderr); \
|
||||
}
|
||||
std::uint64_t GetLoggingTime();
|
||||
|
||||
enum Level { Invalid = 0, Trace, Debug, Info, Warning, Error, Critical };
|
||||
struct Entry {
|
||||
Level level;
|
||||
fmt::text_style style;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
void WriteLog(Entry entry);
|
||||
|
||||
// Returns up to 3 latest error messages
|
||||
std::string GetLastErrors();
|
||||
|
||||
} // namespace Common::Logging
|
||||
|
||||
#define HELPER_STR(line) #line
|
||||
#define HELPER_STR2(line) HELPER_STR(line)
|
||||
#define LOG_PRINT(log_class, level, text_style, format_str, ...) \
|
||||
Common::Logging::WriteLog( \
|
||||
Common::Logging::Entry{Common::Logging::Level::level, text_style, \
|
||||
fmt::format("[{:12.6f}] " log_class " <" #level "> " __FILE__ \
|
||||
":" HELPER_STR2(__LINE__) ":{}: " format_str "\n", \
|
||||
Common::Logging::GetLoggingTime() / 1000000.0, \
|
||||
__func__ __VA_OPT__(, ) __VA_ARGS__)});
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define LOG_TRACE(log_class, ...) \
|
||||
LOG_PRINT(#log_class, "Trace", fmt::fg(fmt::terminal_color::bright_black), __FILE__, __LINE__, \
|
||||
LOG_PRINT(#log_class, Trace, fmt::fg(fmt::terminal_color::bright_black), __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
#else
|
||||
#define LOG_TRACE(log_class, fmt, ...) (void(0))
|
||||
#endif
|
||||
|
||||
#define LOG_DEBUG(log_class, ...) \
|
||||
LOG_PRINT(#log_class, "Debug", fmt::fg(fmt::terminal_color::cyan), __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
LOG_PRINT(#log_class, Debug, fmt::fg(fmt::terminal_color::cyan), __VA_ARGS__)
|
||||
#define LOG_INFO(log_class, ...) \
|
||||
LOG_PRINT(#log_class, "Info", fmt::fg(fmt::terminal_color::white), __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
LOG_PRINT(#log_class, Info, fmt::fg(fmt::terminal_color::white), __VA_ARGS__)
|
||||
#define LOG_WARNING(log_class, ...) \
|
||||
LOG_PRINT(#log_class, "Warning", fmt::fg(fmt::terminal_color::bright_yellow), __FILE__, \
|
||||
__LINE__, __func__, __VA_ARGS__)
|
||||
LOG_PRINT(#log_class, Warning, fmt::fg(fmt::terminal_color::bright_yellow), __VA_ARGS__)
|
||||
#define LOG_ERROR(log_class, ...) \
|
||||
LOG_PRINT(#log_class, "Error", fmt::fg(fmt::terminal_color::bright_red), __FILE__, __LINE__, \
|
||||
__func__, __VA_ARGS__)
|
||||
LOG_PRINT(#log_class, Error, fmt::fg(fmt::terminal_color::bright_red), __VA_ARGS__)
|
||||
#define LOG_CRITICAL(log_class, ...) \
|
||||
LOG_PRINT(#log_class, "Critical", fmt::fg(fmt::terminal_color::bright_magenta), __FILE__, \
|
||||
__LINE__, __func__, __VA_ARGS__)
|
||||
LOG_PRINT(#log_class, Critical, fmt::fg(fmt::terminal_color::bright_magenta), __VA_ARGS__)
|
||||
|
||||
@@ -30,7 +30,7 @@ bool LoadTitleKeysBin(TitleKeysMap& out, const std::string& path) {
|
||||
}
|
||||
|
||||
if (file.Tell() != file.GetSize()) {
|
||||
LOG_ERROR(Core, "File {} has redundant data, may be corrupted");
|
||||
LOG_ERROR(Core, "File {} has redundant data, may be corrupted", path);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -437,8 +437,9 @@ std::shared_ptr<FileUtil::IOFile> SDMCImporter::OpenContent(const ContentSpecifi
|
||||
const auto format_str = (specifier.id >> 32) == 0x0004008c
|
||||
? "/title/{:08x}/{:08x}/content/00000000/{:08x}.app"
|
||||
: "/title/{:08x}/{:08x}/content/{:08x}.app";
|
||||
const auto path =
|
||||
fmt::format(format_str, (specifier.id >> 32), (specifier.id & 0xFFFFFFFF), content_id);
|
||||
const auto path = fmt::vformat(
|
||||
format_str,
|
||||
fmt::make_format_args((specifier.id >> 32), (specifier.id & 0xFFFFFFFF), content_id));
|
||||
return std::make_shared<SDMCFile>(config.sdmc_path, path, "rb");
|
||||
}
|
||||
}
|
||||
@@ -970,7 +971,8 @@ void SDMCImporter::ListExtdata(std::vector<ContentSpecifier>& out) const {
|
||||
}
|
||||
|
||||
const u64 id = std::stoull(virtual_name, nullptr, 16);
|
||||
const auto citra_path = fmt::format(citra_path_template, virtual_name);
|
||||
const auto citra_path =
|
||||
fmt::vformat(citra_path_template, fmt::make_format_args(virtual_name));
|
||||
out.push_back({type, (id_high << 32) | id, FileUtil::Exists(citra_path),
|
||||
FileUtil::GetDirectoryTreeSize(directory + virtual_name + "/")});
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user