mirror of
https://github.com/ApfelTeeSaft/azahar.git
synced 2026-08-26 19:23:31 +00:00
log: Close file after stop and fallback to stderr
This commit is contained in:
@@ -51,6 +51,8 @@ public:
|
|||||||
virtual void EnableForStacktrace() = 0;
|
virtual void EnableForStacktrace() = 0;
|
||||||
|
|
||||||
virtual void Flush() = 0;
|
virtual void Flush() = 0;
|
||||||
|
|
||||||
|
virtual void Close() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,6 +74,10 @@ public:
|
|||||||
std::fflush(stderr);
|
std::fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Close() override {
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
void EnableForStacktrace() override {
|
void EnableForStacktrace() override {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
}
|
||||||
@@ -130,6 +136,11 @@ public:
|
|||||||
file->Flush();
|
file->Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Close() override {
|
||||||
|
file->Close();
|
||||||
|
enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
void EnableForStacktrace() override {
|
void EnableForStacktrace() override {
|
||||||
enabled = true;
|
enabled = true;
|
||||||
bytes_written = 0;
|
bytes_written = 0;
|
||||||
@@ -158,6 +169,8 @@ public:
|
|||||||
|
|
||||||
void Flush() override {}
|
void Flush() override {}
|
||||||
|
|
||||||
|
void Close() override {}
|
||||||
|
|
||||||
void EnableForStacktrace() override {}
|
void EnableForStacktrace() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -177,11 +190,14 @@ public:
|
|||||||
|
|
||||||
void Flush() override {}
|
void Flush() override {}
|
||||||
|
|
||||||
|
void Close() override {}
|
||||||
|
|
||||||
void EnableForStacktrace() override {}
|
void EnableForStacktrace() override {}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool initialization_in_progress_suppress_logging = true;
|
bool initialization_in_progress_suppress_logging = true;
|
||||||
|
bool logging_initialized = false;
|
||||||
|
|
||||||
#ifdef CITRA_LINUX_GCC_BACKTRACE
|
#ifdef CITRA_LINUX_GCC_BACKTRACE
|
||||||
[[noreturn]] void SleepForever() {
|
[[noreturn]] void SleepForever() {
|
||||||
@@ -216,6 +232,7 @@ public:
|
|||||||
instance = std::unique_ptr<Impl, decltype(&Deleter)>(
|
instance = std::unique_ptr<Impl, decltype(&Deleter)>(
|
||||||
new Impl(fmt::format("{}{}", log_dir, log_file), filter), Deleter);
|
new Impl(fmt::format("{}{}", log_dir, log_file), filter), Deleter);
|
||||||
initialization_in_progress_suppress_logging = false;
|
initialization_in_progress_suppress_logging = false;
|
||||||
|
logging_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Start() {
|
static void Start() {
|
||||||
@@ -258,8 +275,8 @@ public:
|
|||||||
if (!filter.CheckMessage(log_class, log_level)) {
|
if (!filter.CheckMessage(log_class, log_level)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Entry new_entry =
|
Entry new_entry = CreateEntry(log_class, log_level, filename, line_num, function,
|
||||||
CreateEntry(log_class, log_level, filename, line_num, function, std::move(message));
|
std::move(message), time_origin);
|
||||||
if (!regex_filter.empty() &&
|
if (!regex_filter.empty() &&
|
||||||
!boost::regex_search(FormatLogMessage(new_entry), regex_filter)) {
|
!boost::regex_search(FormatLogMessage(new_entry), regex_filter)) {
|
||||||
return;
|
return;
|
||||||
@@ -274,6 +291,24 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Entry CreateEntry(Class log_class, Level log_level, const char* filename,
|
||||||
|
unsigned int line_nr, const char* function, std::string&& message,
|
||||||
|
const std::chrono::steady_clock::time_point& time_origin) {
|
||||||
|
using std::chrono::duration_cast;
|
||||||
|
using std::chrono::microseconds;
|
||||||
|
using std::chrono::steady_clock;
|
||||||
|
|
||||||
|
return {
|
||||||
|
.timestamp = duration_cast<microseconds>(steady_clock::now() - time_origin),
|
||||||
|
.log_class = log_class,
|
||||||
|
.log_level = log_level,
|
||||||
|
.filename = filename,
|
||||||
|
.line_num = line_nr,
|
||||||
|
.function = function,
|
||||||
|
.message = std::move(message),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Impl(const std::string& file_backend_filename, const Filter& filter_)
|
Impl(const std::string& file_backend_filename, const Filter& filter_)
|
||||||
: filter{filter_}, file_backend{file_backend_filename} {
|
: filter{filter_}, file_backend{file_backend_filename} {
|
||||||
@@ -348,6 +383,8 @@ private:
|
|||||||
};
|
};
|
||||||
while (!stop_token.stop_requested()) {
|
while (!stop_token.stop_requested()) {
|
||||||
message_queue.PopWait(entry, stop_token);
|
message_queue.PopWait(entry, stop_token);
|
||||||
|
// Only write the log if something was actually popped (entry.filename != nullptr)
|
||||||
|
// (for example, when the stop token is signaled).
|
||||||
if (entry.filename != nullptr) {
|
if (entry.filename != nullptr) {
|
||||||
write_logs();
|
write_logs();
|
||||||
}
|
}
|
||||||
@@ -367,24 +404,10 @@ private:
|
|||||||
backend_thread.join();
|
backend_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
ForEachBackend([](Backend& backend) { backend.Flush(); });
|
ForEachBackend([](Backend& backend) {
|
||||||
}
|
backend.Flush();
|
||||||
|
backend.Close();
|
||||||
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
|
});
|
||||||
const char* function, std::string&& message) const {
|
|
||||||
using std::chrono::duration_cast;
|
|
||||||
using std::chrono::microseconds;
|
|
||||||
using std::chrono::steady_clock;
|
|
||||||
|
|
||||||
return {
|
|
||||||
.timestamp = duration_cast<microseconds>(steady_clock::now() - time_origin),
|
|
||||||
.log_class = log_class,
|
|
||||||
.log_level = log_level,
|
|
||||||
.filename = filename,
|
|
||||||
.line_num = line_nr,
|
|
||||||
.function = function,
|
|
||||||
.message = std::move(message),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForEachBackend(auto lambda) {
|
void ForEachBackend(auto lambda) {
|
||||||
@@ -485,9 +508,19 @@ void SetColorConsoleBackendEnabled(bool enabled) {
|
|||||||
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
|
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
|
||||||
unsigned int line_num, const char* function, fmt::string_view format,
|
unsigned int line_num, const char* function, fmt::string_view format,
|
||||||
const fmt::format_args& args) {
|
const fmt::format_args& args) {
|
||||||
if (!initialization_in_progress_suppress_logging) {
|
if (initialization_in_progress_suppress_logging) [[unlikely]] {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logging_initialized) [[likely]] {
|
||||||
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function,
|
Impl::Instance().PushEntry(log_class, log_level, filename, line_num, function,
|
||||||
fmt::vformat(format, args));
|
fmt::vformat(format, args));
|
||||||
|
} else {
|
||||||
|
// In the rare case that logging occurs before initialization, write the
|
||||||
|
// message to stderr to preserve useful debug information.
|
||||||
|
Entry new_entry = Impl::CreateEntry(log_class, log_level, filename, line_num, function,
|
||||||
|
fmt::vformat(format, args), {});
|
||||||
|
PrintMessage(new_entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace Common::Log
|
} // namespace Common::Log
|
||||||
|
|||||||
Reference in New Issue
Block a user