void mockFatalCall(FatalMessagePtr fatal_message) { g_mockFatal_message = fatal_message.get()->toString(); g_mockFatal_signal = fatal_message.get()->_signal_id; g_mockFatalWasCalled = true; LogMessagePtr message{fatal_message.release()}; g3::internal::pushMessageToLogger(message); //fatal_message.copyToLogMessage()); }
void LogWorkerImpl::bgFatal(FatalMessagePtr msgPtr) { // this will be the last message. Only the active logworker can receive a FATAL call so it's // safe to shutdown logging now g2::internal::shutDownLogging(); std::string reason = msgPtr.get()->reason(); const auto level = msgPtr.get()->_level; const auto fatal_id = msgPtr.get()->_signal_id; std::unique_ptr<LogMessage> uniqueMsg(std::move(msgPtr.get())); uniqueMsg->write().append("\nExiting after fatal event (").append(uniqueMsg->level()); // Change output in case of a fatal signal (or windows exception) std::string exiting = {"Fatal type: "}; uniqueMsg->write().append("). ").append(exiting).append(" ").append(reason) .append("\nLog content flushed flushed sucessfully to sink\n\n"); std::cerr << uniqueMsg->message() << std::flush; for (auto& sink : _sinks) { LogMessage msg(*(uniqueMsg)); sink->send(LogMessageMover(std::move(msg))); } // This clear is absolutely necessary // All sinks are forced to receive the fatal message above before we continue _sinks.clear(); // flush all queues internal::exitWithDefaultSignalHandler(level, fatal_id); // should never reach this point perror("g2log exited after receiving FATAL trigger. Flush message status: "); }
/** Fatal call saved to logger. This will trigger SIGABRT or other fatal signal * to exit the program. After saving the fatal message the calling thread * will sleep forever (i.e. until the background thread catches up, saves the fatal * message and kills the software with the fatal signal. */ void fatalCallToLogger(FatalMessagePtr message) { if (!isLoggingInitialized()) { std::ostringstream error; error << "FATAL CALL but logger is NOT initialized\n" << "SIGNAL: " << message.get()->signal() << "\nMessage: \n" << message.get()->toString() << std::flush; std::cerr << error.str() << std::flush; internal::exitWithDefaultSignalHandler(message.get()->_signal_id); } g_logger_instance->fatal(message); while (true) { std::this_thread::sleep_for(std::chrono::seconds(1)); } }
/** Fatal call saved to logger. This will trigger SIGABRT or other fatal signal * to exit the program. After saving the fatal message the calling thread * will sleep forever (i.e. until the background thread catches up, saves the fatal * message and kills the software with the fatal signal. */ void pushFatalMessageToLogger(FatalMessagePtr message) { if (!isLoggingInitialized()) { std::ostringstream error; error << "FATAL CALL but logger is NOT initialized\n" << "CAUSE: " << message.get()->reason() << "\nMessage: \n" << message.get()->toString() << std::flush; std::cerr << error.str() << std::flush; internal::exitWithDefaultSignalHandler(message.get()->_level, message.get()->_signal_id); } g_logger_instance->fatal(message); while (shouldBlockForFatalHandling()) { std::this_thread::sleep_for(std::chrono::seconds(1)); } }