/** ========================================================================== * 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes * with no warranties. This code is yours to share, use and modify with no * strings attached and no restrictions or obligations. * * For more information see g3log/LICENSE or refer refer to http://unlicense.org * ============================================================================*/ #pragma once #include "g3log/loglevels.hpp" #include "g3log/time.hpp" #include "g3log/moveoncopy.hpp" #include "g3log/crashhandler.hpp" #include <string> #include <sstream> #include <thread> #include <memory> namespace g3 { /** LogMessage contains all the data collected from the LOG(...) call. * If the sink receives a std::string it will be the std::string toString()... function * that will format the data into a string * * For sinks that receive a LogMessage they can either use the toString() function, or use * the helper functions or even the public raw data to format the saved log message any * desired way. */ struct LogMessage { std::string file_path() const { return _file_path; } std::string file() const { return _file; } std::string line() const { return std::to_string(_line); } std::string function() const { return _function; } std::string level() const { return _level.text; } /// use a different format string to get a different look on the time. // default look is Y/M/D H:M:S std::string timestamp(const std::string& time_format = {internal::date_formatted + " " + internal::time_formatted}) const; std::string message() const { return _message; } std::string& write() const { return _message; } std::string expression() const { return _expression; } bool wasFatal() const { return internal::wasFatal(_level); } std::string threadID() const; std::string toString() const; void setExpression(const std::string expression) { _expression = expression; } LogMessage& operator=(LogMessage other); LogMessage(const std::string& file, const int line, const std::string& function, const LEVELS& level); explicit LogMessage(const std::string& fatalOsSignalCrashMessage); LogMessage(const LogMessage& other); LogMessage(LogMessage&& other); virtual ~LogMessage() {} // // Complete access to the raw data in case the helper functions above // are not enough. // timespec _timestamp; std::thread::id _call_thread_id; std::string _file; std::string _file_path; int _line; std::string _function; LEVELS _level; std::string _expression; // only with content for CHECK(...) calls mutable std::string _message; friend void swap(LogMessage& first, LogMessage& second) { using std::swap; swap(first._timestamp, second._timestamp); swap(first._call_thread_id, second._call_thread_id); swap(first._file, second._file); swap(first._line, second._line); swap(first._function, second._function); swap(first._level, second._level); swap(first._expression, second._expression); swap(first._message, second._message); } }; /** 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 LogMessage& details, g3::SignalType signal_id); FatalMessage(const FatalMessage&); virtual ~FatalMessage() {} LogMessage copyToLogMessage() const; std::string reason() const; const SignalType _signal_id; }; typedef MoveOnCopy<std::unique_ptr<FatalMessage>> FatalMessagePtr; typedef MoveOnCopy<std::unique_ptr<LogMessage>> LogMessagePtr; typedef MoveOnCopy<LogMessage> LogMessageMover; } // g3