mirror of
https://github.com/KjellKod/g3log.git
synced 2025-01-19 08:46:42 +01:00
Removing g2logmessage pimpl
This commit is contained in:
parent
43806018aa
commit
11235acbc9
@ -5,7 +5,6 @@
|
||||
* ============================================================================*/
|
||||
|
||||
#include "crashhandler.hpp"
|
||||
#include "g2log.hpp"
|
||||
#include "g2logmessage.hpp"
|
||||
#include "g2LogMessageBuilder.hpp"
|
||||
|
||||
@ -21,6 +20,7 @@
|
||||
#include <cxxabi.h>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
// Dump of stack,. then exit through g2log background worker
|
||||
@ -32,15 +32,13 @@ namespace {
|
||||
|
||||
std::ostringstream oss;
|
||||
oss << "Received fatal signal: " << g2::internal::signalName(signal_number);
|
||||
oss << "(" << signal_number << ")" << std::endl;
|
||||
oss << "\tPID: " << getpid() << std::endl;
|
||||
oss << "(" << signal_number << ")\tPID: " << getpid() << std::endl;
|
||||
oss << stackdump();
|
||||
|
||||
{ // Local scope, trigger send
|
||||
std::ostringstream fatal_stream;
|
||||
fatal_stream << oss.str() << std::endl;
|
||||
fatal_stream << "\n***** SIGNAL " << signalName(signal_number) << "(" << signal_number << ")" << std::endl;
|
||||
|
||||
fatal_stream << "\n***** SIGNAL " << signalName(signal_number) << "(" << signal_number << ")" << std::endl;
|
||||
g2::FatalMessageBuilder trigger(fatal_stream.str(), signal_number);
|
||||
} // message sent to g2LogWorker by FatalMessageBuilder
|
||||
// wait to die -- will be inside the FatalMessageBuilder
|
||||
@ -68,12 +66,13 @@ namespace g2 {
|
||||
// http://stackoverflow.com/questions/6878546/why-doesnt-parent-process-return-to-the-exact-location-after-handling-signal_number
|
||||
namespace internal {
|
||||
std::string stackdump() {
|
||||
std::ostringstream oss;
|
||||
const size_t max_dump_size = 50;
|
||||
void* dump[max_dump_size];
|
||||
size_t size = backtrace(dump, max_dump_size);
|
||||
char** messages = backtrace_symbols(dump, size); // overwrite sigaction with caller's address
|
||||
|
||||
// dump stack: skip first frame, since that is here
|
||||
std::ostringstream oss;
|
||||
for (size_t idx = 1; idx < size && messages != nullptr; ++idx) {
|
||||
char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;
|
||||
// find parantheses and +address offset surrounding mangled name
|
||||
@ -99,7 +98,7 @@ namespace g2 {
|
||||
char * real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
|
||||
// if demangling is successful, output the demangled function name
|
||||
if (status == 0) {
|
||||
oss << "\tstack dump [" << idx << "] " << messages[idx] << " : " << real_name << "+";
|
||||
oss << "\n\tstack dump [" << idx << "] " << messages[idx] << " : " << real_name << "+";
|
||||
oss << offset_begin << offset_end << std::endl;
|
||||
}// otherwise, output the mangled function name
|
||||
else {
|
||||
|
@ -7,10 +7,9 @@
|
||||
|
||||
//#include "g2log.hpp"
|
||||
#include "g2LogMessageBuilder.hpp"
|
||||
#include "g2logmessageimpl.hpp"
|
||||
#include "g2logmessage.hpp"
|
||||
#include "g2log.hpp"
|
||||
#include <csignal>
|
||||
|
||||
namespace {
|
||||
const int kMaxMessageSize = 2048;
|
||||
const std::string kTruncatedWarningText = "[...truncated...]";
|
||||
@ -20,26 +19,25 @@ namespace g2 {
|
||||
|
||||
LogMessageBuilder::LogMessageBuilder(const std::string& file, const int line,
|
||||
const std::string& function, const LEVELS& level)
|
||||
: _message(std::make_shared<LogMessageImpl>(file, line, function, level)) {
|
||||
: _message(file, line, function, level) {
|
||||
}
|
||||
|
||||
LogMessageBuilder::~LogMessageBuilder() {
|
||||
if (internal::wasFatal(_message->_level)) {
|
||||
FatalMessageBuilder trigger({_message, SIGABRT});
|
||||
if (_message.wasFatal()) {
|
||||
FatalMessageBuilder trigger(_message, SIGABRT);
|
||||
return; // FatalMessageBuilder will send to worker at scope exit
|
||||
}
|
||||
|
||||
LogMessage log_entry(_message);
|
||||
saveMessage(log_entry); // message saved to g2LogWorker
|
||||
saveMessage(_message); // message saved to g2LogWorker
|
||||
}
|
||||
|
||||
LogMessageBuilder& LogMessageBuilder::setExpression(const std::string& boolean_expression) {
|
||||
_message->_expression = boolean_expression;
|
||||
_message.setExpression(boolean_expression);
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::ostringstream& LogMessageBuilder::stream() {
|
||||
return _message->_stream;
|
||||
return _message.stream();
|
||||
}
|
||||
|
||||
void LogMessageBuilder::messageSave(const char *printf_like_message, ...) {
|
||||
@ -65,11 +63,11 @@ namespace g2 {
|
||||
/// FatalMessageBuilder
|
||||
|
||||
FatalMessageBuilder::FatalMessageBuilder(const std::string& exit_message, int signal_id)
|
||||
: _fatal_message(std::make_shared<LogMessageImpl>(exit_message)), _fatal_signal(signal_id)
|
||||
: _fatal_message{exit_message}, _fatal_signal{signal_id}
|
||||
{ }
|
||||
|
||||
|
||||
FatalMessageBuilder:: FatalMessageBuilder(const std::shared_ptr<LogMessageImpl>& details, int signal_id)
|
||||
FatalMessageBuilder:: FatalMessageBuilder(const LogMessage& details, int signal_id)
|
||||
: _fatal_message(details), _fatal_signal(signal_id)
|
||||
{}
|
||||
|
||||
@ -79,6 +77,7 @@ namespace g2 {
|
||||
// either we will stay here until the background worker has received the fatal
|
||||
// message, flushed the crash message to the sinks and exits with the same fatal signal
|
||||
//..... OR it's in unit-test mode then we throw a std::runtime_error (and never hit sleep)
|
||||
|
||||
FatalMessage msg(_fatal_message, _fatal_signal);
|
||||
fatalCall(msg);
|
||||
|
||||
|
@ -8,23 +8,21 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <cstdarg>
|
||||
#include "g2loglevels.hpp"
|
||||
|
||||
#include "g2loglevels.hpp"
|
||||
#include "g2logmessage.hpp"
|
||||
|
||||
namespace g2 {
|
||||
|
||||
struct LogMessageImpl;
|
||||
|
||||
// At RAII scope end this struct will trigger a FatalMessage sending
|
||||
struct FatalMessageBuilder {
|
||||
//explicit FatalMessageBuilder(const FatalMessage& exit_message);
|
||||
FatalMessageBuilder(const std::string& exit_message, int fatal_signal);
|
||||
FatalMessageBuilder(const std::shared_ptr<LogMessageImpl>& details, int signal_id);
|
||||
FatalMessageBuilder(const LogMessage& details, int signal_id);
|
||||
virtual ~FatalMessageBuilder();
|
||||
|
||||
std::shared_ptr<LogMessageImpl> _fatal_message;
|
||||
LogMessage _fatal_message;
|
||||
int _fatal_signal;
|
||||
};
|
||||
|
||||
@ -45,6 +43,6 @@ namespace g2 {
|
||||
__attribute__((format(printf, 2, 3))); // ref: http://www.codemaestro.com/reviews/18
|
||||
|
||||
private:
|
||||
std::shared_ptr<LogMessageImpl> _message;
|
||||
LogMessage _message;
|
||||
};
|
||||
} // g2
|
@ -35,7 +35,7 @@ FileSink::FileSink(const std::string& log_prefix, const std::string& log_directo
|
||||
addLogFileHeader();
|
||||
}
|
||||
FileSink::~FileSink() {
|
||||
std::string exit_msg{"\n\t\tg2log g2FileSink shutdown at: "};
|
||||
std::string exit_msg{"\ng2log g2FileSink shutdown at: "};
|
||||
exit_msg.append(localtime_formatted(systemtime_now(), internal::time_formatted));
|
||||
filestream() << exit_msg << std::flush;
|
||||
|
||||
|
@ -36,14 +36,25 @@ namespace g2 {
|
||||
template<typename Moveable>
|
||||
struct PretendToBeCopyable
|
||||
{
|
||||
explicit PretendToBeCopyable(Moveable&& m) : move_only_(std::move(m)) {}
|
||||
explicit PretendToBeCopyable(Moveable&& m) : _move_only(std::move(m)) {}
|
||||
|
||||
template<typename T> // universal copy constructor
|
||||
PretendToBeCopyable(T&& t): move_only_(std::move(t.move_only_)){}
|
||||
PretendToBeCopyable(PretendToBeCopyable const& t): _move_only(std::move(t._move_only)){}
|
||||
PretendToBeCopyable(PretendToBeCopyable&& t): _move_only(std::move(t._move_only)){}
|
||||
|
||||
void operator()() { move_only_(); } // execute
|
||||
PretendToBeCopyable& operator=(PretendToBeCopyable const& other) {
|
||||
_move_only=std::move(other._move_only);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PretendToBeCopyable& operator=(PretendToBeCopyable&& other) {
|
||||
_move_only=std::move(other._move_only);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void operator()() { _move_only(); } // execute
|
||||
private:
|
||||
mutable Moveable move_only_;
|
||||
mutable Moveable _move_only;
|
||||
};
|
||||
|
||||
|
||||
|
@ -21,19 +21,20 @@
|
||||
#include <mutex>
|
||||
#include <csignal>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
#include "std2_make_unique.hpp"
|
||||
#include "g2logworker.hpp"
|
||||
#include "crashhandler.hpp"
|
||||
#include "g2loglevels.hpp"
|
||||
#include "g2logmessageimpl.hpp"
|
||||
#include "g2logmessage.hpp"
|
||||
|
||||
namespace {
|
||||
std::once_flag g_initialize_flag;
|
||||
g2LogWorker* g_logger_instance = nullptr; // instantiated and OWNED somewhere else (main)
|
||||
std::mutex g_logging_init_mutex;
|
||||
|
||||
std::shared_ptr<g2::LogMessageImpl> g_first_unintialized_msg = {nullptr};
|
||||
bool g_uninitialized_call = false;
|
||||
std::unique_ptr<g2::LogMessage> g_first_unintialized_msg = {nullptr};
|
||||
std::once_flag g_set_first_uninitialized_flag;
|
||||
std::once_flag g_save_first_unintialized_flag;
|
||||
|
||||
@ -92,13 +93,13 @@ namespace g2 {
|
||||
* The first initialized log entry will also save the first uninitialized log message, if any
|
||||
* @param log_entry to save to logger
|
||||
*/
|
||||
void saveMessage(const g2::LogMessage& log_entry) {
|
||||
void saveMessage(const g2::LogMessage& incoming) {
|
||||
// Uninitialized messages are ignored but does not CHECK/crash the logger
|
||||
if (!internal::isLoggingInitialized()) {
|
||||
|
||||
LogMessage log_entry{incoming};
|
||||
std::call_once(g_set_first_uninitialized_flag, [&] {
|
||||
g_first_unintialized_msg = log_entry._pimpl;
|
||||
g_uninitialized_call = true;
|
||||
g_first_unintialized_msg = std2::make_unique<LogMessage>(log_entry);
|
||||
//g_uninitialized_call = true;
|
||||
std::string err = {"LOGGER NOT INITIALIZED:\n\t\t"};
|
||||
err.append(log_entry.message());
|
||||
auto& stream = log_entry.stream();
|
||||
@ -112,14 +113,14 @@ namespace g2 {
|
||||
// logger is initialized
|
||||
// Save the first uninitialized message, if any
|
||||
std::call_once(g_save_first_unintialized_flag, [] {
|
||||
if (g_uninitialized_call) {
|
||||
LogMessage error_msg{g_first_unintialized_msg};
|
||||
if (g_first_unintialized_msg) {
|
||||
LogMessage error_msg{*(g_first_unintialized_msg.get())};
|
||||
g_logger_instance->save(error_msg);
|
||||
g_first_unintialized_msg.reset();
|
||||
}
|
||||
});
|
||||
|
||||
g_logger_instance->save(log_entry);
|
||||
g_logger_instance->save(incoming);
|
||||
}
|
||||
|
||||
|
||||
@ -128,14 +129,14 @@ namespace g2 {
|
||||
* 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(const FatalMessage& message) {
|
||||
void fatalCallToLogger(const FatalMessage& message) {
|
||||
if (!isLoggingInitialized()) {
|
||||
std::ostringstream error;
|
||||
error << "FATAL CALL but logger is NOT initialized\n"
|
||||
<< "SIGNAL: " << g2::internal::signalName(message.signal_id_)
|
||||
<< "SIGNAL: " << g2::internal::signalName(message._signal_id)
|
||||
<< "\nMessage: \n" << message.toString() << std::flush;
|
||||
std::cerr << error << std::flush;
|
||||
internal::exitWithDefaultSignalHandler(message.signal_id_);
|
||||
internal::exitWithDefaultSignalHandler(message._signal_id);
|
||||
}
|
||||
|
||||
g_logger_instance->fatal(message);
|
||||
|
@ -21,10 +21,12 @@
|
||||
|
||||
#include <string>
|
||||
#include <cstdarg>
|
||||
#include <functional>
|
||||
|
||||
#include "g2loglevels.hpp"
|
||||
#include "g2LogMessageBuilder.hpp"
|
||||
|
||||
|
||||
class g2LogWorker;
|
||||
#if !(defined(__PRETTY_FUNCTION__))
|
||||
#define __PRETTY_FUNCTION__ __FUNCTION__
|
||||
|
@ -10,60 +10,67 @@
|
||||
* ********************************************* */
|
||||
|
||||
#include "g2logmessage.hpp"
|
||||
#include "g2logmessageimpl.hpp"
|
||||
#include "g2time.hpp"
|
||||
#include "crashhandler.hpp"
|
||||
#include <stdexcept> // exceptions
|
||||
#include "g2log.hpp"
|
||||
#include "g2time.hpp"
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
std::once_flag g_start_time_flag;
|
||||
g2::steady_time_point g_start_time;
|
||||
|
||||
long microsecondsCounter() {
|
||||
std::call_once(g_start_time_flag, []() { g_start_time = std::chrono::steady_clock::now(); });
|
||||
g2::steady_time_point now = std::chrono::steady_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(now - g_start_time).count();
|
||||
}
|
||||
|
||||
std::string splitFileName(const std::string& str) {
|
||||
size_t found;
|
||||
found = str.find_last_of("(/\\");
|
||||
return str.substr(found + 1);
|
||||
}
|
||||
} // anonymous
|
||||
|
||||
|
||||
|
||||
namespace g2 {
|
||||
|
||||
|
||||
std::string LogMessage::line() const {
|
||||
return std::to_string(_pimpl->_line);
|
||||
return std::to_string(_line);
|
||||
}
|
||||
|
||||
|
||||
std::string LogMessage::file() const {
|
||||
return _pimpl->_file;
|
||||
return _file;
|
||||
}
|
||||
|
||||
|
||||
std::string LogMessage::function() const {
|
||||
return _pimpl->_function;
|
||||
return _function;
|
||||
}
|
||||
|
||||
|
||||
std::string LogMessage::level() const {
|
||||
return _pimpl->_level.text;
|
||||
return _level.text;
|
||||
}
|
||||
|
||||
|
||||
std::string LogMessage::timestamp(const std::string & time_look) const {
|
||||
std::ostringstream oss;
|
||||
oss << localtime_formatted(_pimpl->_timestamp, time_look);
|
||||
oss << localtime_formatted(_timestamp, time_look);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
std::string LogMessage::microseconds() const {
|
||||
return std::to_string(_pimpl->_microseconds);
|
||||
return std::to_string(_microseconds);
|
||||
}
|
||||
|
||||
|
||||
std::string LogMessage::message() const {
|
||||
return _pimpl->_stream.str();
|
||||
return _stream.str();
|
||||
}
|
||||
|
||||
|
||||
std::string LogMessage::expression() const {
|
||||
return _pimpl->_expression;
|
||||
return _expression;
|
||||
}
|
||||
|
||||
|
||||
bool LogMessage::wasFatal() const {
|
||||
return internal::wasFatal(_pimpl->_level);
|
||||
return internal::wasFatal(_level);
|
||||
}
|
||||
|
||||
std::string LogMessage::toString() const {
|
||||
@ -80,7 +87,7 @@ namespace g2 {
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
if (internal::FATAL_SIGNAL.value == _pimpl->_level.value) {
|
||||
if (internal::FATAL_SIGNAL.value == _level.value) {
|
||||
oss.str(""); // clear any previous text and formatting
|
||||
oss << "\n" << timestamp() << "." << microseconds();
|
||||
oss << "\n\n***** FATAL SIGNAL RECEIVED ******* " << std::endl;
|
||||
@ -90,15 +97,15 @@ namespace g2 {
|
||||
|
||||
|
||||
// Not crash scenario but LOG or CONTRACT
|
||||
auto level_value = _pimpl->_level.value;
|
||||
auto level_value = _level.value;
|
||||
if (FATAL.value == level_value) {
|
||||
oss << "\n\t*******\tEXIT trigger caused by LOG(FATAL) entry: \n\t";
|
||||
oss << '"' << message() << '"';
|
||||
oss << "\n*******\tSTACKDUMP *******\n" << internal::stackdump();
|
||||
} else if (internal::CONTRACT.value == level_value) {
|
||||
oss << "\n\t *******\tEXIT trigger caused by broken Contract: CHECK(" << _pimpl->_expression << ")\n\t";
|
||||
oss << "\n\t *******\tEXIT trigger caused by broken Contract: CHECK(" << _expression << ")\n\t";
|
||||
oss << '"' << message() << '"';
|
||||
oss << "\n*******\tSTACKDUMP *******\n" << internal::stackdump()<< '"';
|
||||
oss << "\n*******\tSTACKDUMP *******\n" << internal::stackdump() << '"';
|
||||
} else {
|
||||
oss << "\n\t*******\tUNKNOWN Log Message Type\n" << '"' << message() << '"';
|
||||
}
|
||||
@ -108,21 +115,69 @@ namespace g2 {
|
||||
|
||||
|
||||
// is strictly not speaking const
|
||||
std::ostringstream& LogMessage::stream() const{
|
||||
return _pimpl->_stream;
|
||||
void LogMessage::setExpression(const std::string expression) {
|
||||
_expression = expression;
|
||||
}
|
||||
|
||||
std::ostringstream& LogMessage::stream(){
|
||||
return _stream;
|
||||
}
|
||||
|
||||
|
||||
LogMessage::LogMessage(const std::shared_ptr<LogMessageImpl>& details)
|
||||
: _pimpl(details) { }
|
||||
LogMessage::LogMessage(const std::string &file, const int line,
|
||||
const std::string& function, const LEVELS& level)
|
||||
: _timestamp(g2::systemtime_now())
|
||||
, _microseconds(microsecondsCounter())
|
||||
, _file(splitFileName(file)), _line(line), _function(function), _level(level) { }
|
||||
|
||||
|
||||
FatalMessage::FatalMessage(const std::shared_ptr<LogMessageImpl>& details, int signal_id)
|
||||
: LogMessage(details), signal_id_(signal_id) { }
|
||||
LogMessage::LogMessage(const std::string& fatalOsSignalCrashMessage)
|
||||
: LogMessage({""}, 0, {""}, internal::FATAL_SIGNAL) {
|
||||
_stream << fatalOsSignalCrashMessage;
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(const LogMessage& other)
|
||||
: _timestamp(other._timestamp)
|
||||
, _microseconds(other._microseconds)
|
||||
, _file(other._file)
|
||||
, _line(other._line)
|
||||
, _function(other._function)
|
||||
, _level(other._level)
|
||||
, _expression(other._expression)
|
||||
{
|
||||
_stream << other._stream.str();
|
||||
}
|
||||
|
||||
// LogMessage::LogMessage(LogMessage&& msg)
|
||||
// : _timestamp(other._timestamp)
|
||||
// , _microseconds(other._microseconds)
|
||||
// , _file(std::move(other._file))
|
||||
// , _line(other._line)
|
||||
// , _function(std::move(other._function))
|
||||
// , _level(other._level)
|
||||
// , _expression(other._expression)
|
||||
// , _stream(std::move(other._stream))
|
||||
// {
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
FatalMessage::FatalMessage(const LogMessage& details, int signal_id)
|
||||
: LogMessage(details), _signal_id(signal_id) { }
|
||||
|
||||
|
||||
|
||||
FatalMessage::FatalMessage(const FatalMessage& other)
|
||||
: LogMessage(other), _signal_id(other._signal_id) {}
|
||||
|
||||
|
||||
LogMessage FatalMessage::copyToLogMessage() const {
|
||||
return LogMessage(_pimpl);
|
||||
return LogMessage(*this);
|
||||
}
|
||||
|
||||
std::string FatalMessage::signal() const{
|
||||
return internal::signalName(_signal_id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // g2
|
||||
|
@ -14,20 +14,14 @@
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cstdarg>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
|
||||
#include "g2log.hpp"
|
||||
#include "g2loglevels.hpp"
|
||||
#include "g2time.hpp"
|
||||
//#include "g2logmessageimpl.hpp"
|
||||
|
||||
namespace g2 {
|
||||
struct LogMessageImpl;
|
||||
|
||||
struct LogMessage {
|
||||
mutable std::shared_ptr<LogMessageImpl> _pimpl;
|
||||
std::string file() const;
|
||||
std::string line() const;
|
||||
std::string function() const;
|
||||
@ -44,20 +38,43 @@ namespace g2 {
|
||||
std::string toString() const;
|
||||
|
||||
|
||||
std::ostringstream& stream() const;
|
||||
explicit LogMessage(const std::shared_ptr<LogMessageImpl>& details);
|
||||
std::ostringstream& stream();
|
||||
void setExpression(const std::string expression);
|
||||
|
||||
LogMessage(const std::string &file, const int line, const std::string& function, const LEVELS& level);
|
||||
explicit LogMessage(const std::string& fatalOsSignalCrashMessage);
|
||||
|
||||
LogMessage(const LogMessage&);
|
||||
//LogMessage(LogMessage&&);
|
||||
|
||||
~LogMessage() = default;
|
||||
|
||||
protected:
|
||||
const std::time_t _timestamp;
|
||||
const long _microseconds;
|
||||
const std::string _file;
|
||||
const int _line;
|
||||
const std::string _function;
|
||||
const LEVELS _level;
|
||||
|
||||
std::string _expression; // only with content for CHECK(...) calls
|
||||
mutable std::ostringstream _stream;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** Trigger for flushing the message queue and exiting the application
|
||||
* A thread that causes a FatalMessage will sleep forever until the
|
||||
* application has exited (after message flush) */
|
||||
struct FatalMessage : public LogMessage {
|
||||
FatalMessage(const std::shared_ptr<LogMessageImpl>& details, int signal_id);
|
||||
|
||||
FatalMessage(const LogMessage& details, int signal_id);
|
||||
FatalMessage(const FatalMessage&);
|
||||
~FatalMessage() = default;
|
||||
LogMessage copyToLogMessage() const;
|
||||
|
||||
int signal_id_;
|
||||
LogMessage copyToLogMessage() const;
|
||||
std::string signal() const;
|
||||
|
||||
const int _signal_id;
|
||||
};
|
||||
} // g2
|
||||
|
@ -1,39 +1,39 @@
|
||||
|
||||
|
||||
#include <g2logmessageimpl.hpp>
|
||||
#include <g2time.hpp>
|
||||
#include <mutex>
|
||||
|
||||
namespace {
|
||||
std::once_flag g_start_time_flag;
|
||||
g2::steady_time_point g_start_time;
|
||||
|
||||
long microsecondsCounter() {
|
||||
std::call_once(g_start_time_flag, []() { g_start_time = std::chrono::steady_clock::now(); });
|
||||
g2::steady_time_point now = std::chrono::steady_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(now - g_start_time).count();
|
||||
}
|
||||
|
||||
std::string splitFileName(const std::string& str) {
|
||||
size_t found;
|
||||
found = str.find_last_of("(/\\");
|
||||
return str.substr(found + 1);
|
||||
}
|
||||
} // anonymous
|
||||
|
||||
|
||||
namespace g2 {
|
||||
LogMessageImpl::LogMessageImpl(const std::string &file, const int line,
|
||||
const std::string& function, const LEVELS& level)
|
||||
: _timestamp(g2::systemtime_now())
|
||||
, _microseconds(microsecondsCounter())
|
||||
, _file(splitFileName(file)), _line(line), _function(function), _level(level) { }
|
||||
|
||||
|
||||
LogMessageImpl::LogMessageImpl(const std::string& fatalOsSignalCrashMessage)
|
||||
: LogMessageImpl({""}, 0, {""}, internal::FATAL_SIGNAL) {
|
||||
_stream << fatalOsSignalCrashMessage;
|
||||
}
|
||||
} // g2
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//#include <g2logmessageimpl.hpp>
|
||||
//#include <g2time.hpp>
|
||||
//#include <mutex>
|
||||
//
|
||||
//namespace {
|
||||
// std::once_flag g_start_time_flag;
|
||||
// g2::steady_time_point g_start_time;
|
||||
//
|
||||
// long microsecondsCounter() {
|
||||
// std::call_once(g_start_time_flag, []() { g_start_time = std::chrono::steady_clock::now(); });
|
||||
// g2::steady_time_point now = std::chrono::steady_clock::now();
|
||||
// return std::chrono::duration_cast<std::chrono::microseconds>(now - g_start_time).count();
|
||||
// }
|
||||
//
|
||||
// std::string splitFileName(const std::string& str) {
|
||||
// size_t found;
|
||||
// found = str.find_last_of("(/\\");
|
||||
// return str.substr(found + 1);
|
||||
// }
|
||||
//} // anonymous
|
||||
//
|
||||
//
|
||||
//namespace g2 {
|
||||
// LogMessageImpl::LogMessageImpl(const std::string &file, const int line,
|
||||
// const std::string& function, const LEVELS& level)
|
||||
// : _timestamp(g2::systemtime_now())
|
||||
// , _microseconds(microsecondsCounter())
|
||||
// , _file(splitFileName(file)), _line(line), _function(function), _level(level) { }
|
||||
//
|
||||
//
|
||||
// LogMessageImpl::LogMessageImpl(const std::string& fatalOsSignalCrashMessage)
|
||||
// : LogMessageImpl({""}, 0, {""}, internal::FATAL_SIGNAL) {
|
||||
// _stream << fatalOsSignalCrashMessage;
|
||||
// }
|
||||
//} // g2
|
||||
//
|
||||
//
|
||||
|
@ -1,40 +1,40 @@
|
||||
// -*- C++ -*-
|
||||
/*
|
||||
* File: g2logmessageimpl.hpp
|
||||
* Author: kjell
|
||||
*
|
||||
* Created on October 27, 2013, 9:14 PM
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <string>
|
||||
#include "g2loglevels.hpp"
|
||||
#include <ctime>
|
||||
#include <sstream>
|
||||
|
||||
namespace g2 {
|
||||
struct LogMessageImpl {
|
||||
|
||||
// LOG message constructor
|
||||
LogMessageImpl(const std::string &file, const int line,
|
||||
const std::string& function, const LEVELS& level);
|
||||
|
||||
// Fatal OS-Signal constructor
|
||||
explicit LogMessageImpl(const std::string& fatalOsSignalCrashMessage);
|
||||
|
||||
LogMessageImpl(const LogMessageImpl& copy) = default;
|
||||
~LogMessageImpl() = default;
|
||||
|
||||
const std::time_t _timestamp;
|
||||
const long _microseconds;
|
||||
const std::string _file;
|
||||
const int _line;
|
||||
const std::string _function;
|
||||
const LEVELS _level;
|
||||
|
||||
std::string _expression; // only with content for CHECK(...) calls
|
||||
std::ostringstream _stream;
|
||||
};
|
||||
}
|
||||
//// -*- C++ -*-
|
||||
///*
|
||||
// * File: g2logmessageimpl.hpp
|
||||
// * Author: kjell
|
||||
// *
|
||||
// * Created on October 27, 2013, 9:14 PM
|
||||
// */
|
||||
//
|
||||
//#pragma once
|
||||
//
|
||||
//
|
||||
//#include <string>
|
||||
//#include "g2loglevels.hpp"
|
||||
//#include <ctime>
|
||||
//#include <sstream>
|
||||
//
|
||||
//namespace g2 {
|
||||
//struct LogMessageImpl {
|
||||
//
|
||||
// // LOG message constructor
|
||||
// LogMessageImpl(const std::string &file, const int line,
|
||||
// const std::string& function, const LEVELS& level);
|
||||
//
|
||||
// // Fatal OS-Signal constructor
|
||||
// explicit LogMessageImpl(const std::string& fatalOsSignalCrashMessage);
|
||||
//
|
||||
// LogMessageImpl(const LogMessageImpl& copy) = default;
|
||||
// ~LogMessageImpl() = default;
|
||||
//
|
||||
// const std::time_t _timestamp;
|
||||
// const long _microseconds;
|
||||
// const std::string _file;
|
||||
// const int _line;
|
||||
// const std::string _function;
|
||||
// const LEVELS _level;
|
||||
//
|
||||
// std::string _expression; // only with content for CHECK(...) calls
|
||||
// std::ostringstream _stream;
|
||||
//};
|
||||
//}
|
||||
|
@ -47,12 +47,17 @@ struct g2LogWorkerImpl {
|
||||
}
|
||||
|
||||
void bgFatal(const FatalMessage& msg) {
|
||||
auto fatal_message = msg;
|
||||
fatal_message.stream() << "\nExiting after fatal event. Log flushed sucessfully to disk.\n";
|
||||
bgSave(fatal_message.copyToLogMessage());
|
||||
|
||||
FatalMessage fatal_message{msg};
|
||||
fatal_message.stream() << "\nExiting after fatal event (" << fatal_message.level()
|
||||
<<"). Exiting with signal: " << fatal_message.signal()
|
||||
<< "\nLog flushed sucessfully to disk\n\n";
|
||||
|
||||
|
||||
|
||||
std::cerr << fatal_message.message() << std::flush;
|
||||
_sinks.clear(); // flush all queues
|
||||
exitWithDefaultSignalHandler(fatal_message.signal_id_);
|
||||
|
||||
exitWithDefaultSignalHandler(fatal_message._signal_id);
|
||||
// should never reach this point
|
||||
perror("g2log exited after receiving FATAL trigger. Flush message status: ");
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "g2log.hpp"
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
|
||||
#include <iostream>
|
||||
namespace
|
||||
{
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "g2sinkwrapper.h"
|
||||
#include "g2sinkhandle.h"
|
||||
#include "g2logmessage.hpp"
|
||||
#include "g2logmessageimpl.hpp"
|
||||
|
||||
|
||||
using namespace std;
|
||||
@ -51,7 +50,7 @@ namespace g2 {
|
||||
|
||||
void bgSave(LogEntry msg) {
|
||||
for (auto& sink : _container) {
|
||||
g2::LogMessage message(std::make_shared<g2::LogMessageImpl>("test", 0, "test", DEBUG));
|
||||
g2::LogMessage message("test", 0, "test", DEBUG);
|
||||
message.stream() << msg;
|
||||
sink->send(message);
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <chrono>
|
||||
|
||||
#include "testing_helpers.h"
|
||||
#include "g2logmessageimpl.hpp"
|
||||
#include "g2logmessage.hpp"
|
||||
#include "g2logworker.hpp"
|
||||
|
||||
@ -23,7 +22,7 @@ TEST(Sink, OneSink) {
|
||||
EXPECT_FALSE(flag->load());
|
||||
EXPECT_TRUE(0 == count->load());
|
||||
//worker->save("this message should trigger an atomic increment at the sink");
|
||||
g2::LogMessage message(std::make_shared<g2::LogMessageImpl>("test", 0, "test", DEBUG));
|
||||
g2::LogMessage message("test", 0, "test", DEBUG);
|
||||
message.stream() << "this message should trigger an atomic increment at the sink";
|
||||
worker->save(message);
|
||||
}
|
||||
@ -59,7 +58,7 @@ TEST(ConceptSink, OneHundredSinks) {
|
||||
worker->addSink(std2::make_unique<ScopedSetTrue>(flag, count), &ScopedSetTrue::ReceiveMsg);
|
||||
}
|
||||
LOG(DEBUG) << "start message";
|
||||
g2::LogMessage message(std::make_shared<g2::LogMessageImpl>("test", 0, "test", DEBUG));
|
||||
g2::LogMessage message("test", 0, "test", DEBUG);
|
||||
auto& stream = message.stream();
|
||||
stream << "Hello to 100 receivers :)";
|
||||
worker->save(message);
|
||||
|
@ -34,7 +34,7 @@ namespace testing_helpers {
|
||||
|
||||
void mockFatalCall(const g2::FatalMessage& fatal_message) {
|
||||
g_mockFatal_message = fatal_message.toString();
|
||||
g_mockFatal_signal = fatal_message.signal_id_;
|
||||
g_mockFatal_signal = fatal_message._signal_id;
|
||||
g_mockFatalWasCalled = true;
|
||||
g2::internal::saveMessage(fatal_message.copyToLogMessage());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user