152#define FLOW_LOG_WARNING(ARG_stream_fragment) \ 
  153  FLOW_LOG_WITH_CHECKING(::flow::log::Sev::S_WARNING, ARG_stream_fragment) 
  167#define FLOW_LOG_FATAL(ARG_stream_fragment) \ 
  168  FLOW_LOG_WITH_CHECKING(::flow::log::Sev::S_FATAL, ARG_stream_fragment) 
  182#define FLOW_LOG_ERROR(ARG_stream_fragment) \ 
  183  FLOW_LOG_WITH_CHECKING(::flow::log::Sev::S_ERROR, ARG_stream_fragment) 
  197#define FLOW_LOG_INFO(ARG_stream_fragment) \ 
  198  FLOW_LOG_WITH_CHECKING(::flow::log::Sev::S_INFO, ARG_stream_fragment) 
  212#define FLOW_LOG_DEBUG(ARG_stream_fragment) \ 
  213  FLOW_LOG_WITH_CHECKING(::flow::log::Sev::S_DEBUG, ARG_stream_fragment) 
  227#define FLOW_LOG_TRACE(ARG_stream_fragment) \ 
  228  FLOW_LOG_WITH_CHECKING(::flow::log::Sev::S_TRACE, ARG_stream_fragment) 
  242#define FLOW_LOG_DATA(ARG_stream_fragment) \ 
  243  FLOW_LOG_WITH_CHECKING(::flow::log::Sev::S_DATA, ARG_stream_fragment) 
  264#define FLOW_LOG_WARNING_WITHOUT_CHECKING(ARG_stream_fragment) \ 
  265  FLOW_LOG_WITHOUT_CHECKING(::flow::log::Sev::S_WARNING, ARG_stream_fragment) 
  282#define FLOW_LOG_FATAL_WITHOUT_CHECKING(ARG_stream_fragment) \ 
  283  FLOW_LOG_WITHOUT_CHECKING(::flow::log::Sev::S_FATAL, ARG_stream_fragment) 
  300#define FLOW_LOG_ERROR_WITHOUT_CHECKING(ARG_stream_fragment) \ 
  301  FLOW_LOG_WITHOUT_CHECKING(::flow::log::Sev::S_ERROR, ARG_stream_fragment) 
  318#define FLOW_LOG_INFO_WITHOUT_CHECKING(ARG_stream_fragment) \ 
  319  FLOW_LOG_WITHOUT_CHECKING(::flow::log::Sev::S_INFO, ARG_stream_fragment) 
  336#define FLOW_LOG_DEBUG_WITHOUT_CHECKING(ARG_stream_fragment) \ 
  337  FLOW_LOG_WITHOUT_CHECKING(::flow::log::Sev::S_DEBUG, ARG_stream_fragment) 
  354#define FLOW_LOG_TRACE_WITHOUT_CHECKING(ARG_stream_fragment) \ 
  355  FLOW_LOG_WITHOUT_CHECKING(::flow::log::Sev::S_TRACE, ARG_stream_fragment) 
  372#define FLOW_LOG_DATA_WITHOUT_CHECKING(ARG_stream_fragment) \ 
  373  FLOW_LOG_WITHOUT_CHECKING(::flow::log::Sev::S_DATA, ARG_stream_fragment) 
  405#define FLOW_LOG_SET_CONTEXT(ARG_logger_ptr, ARG_component_payload) \ 
  406  FLOW_LOG_SET_LOGGER(ARG_logger_ptr); \ 
  407  FLOW_LOG_SET_COMPONENT(ARG_component_payload); 
  415#define FLOW_LOG_SET_LOGGER(ARG_logger_ptr) \ 
  417    const auto get_logger \ 
  418      = [logger_ptr_copy = static_cast<::flow::log::Logger*>(ARG_logger_ptr)] \ 
  419          () -> ::flow::log::Logger* { return logger_ptr_copy; } 
  451#define FLOW_LOG_SET_COMPONENT(ARG_component_payload) \ 
  453    const auto get_log_component = [component = ::flow::log::Component(ARG_component_payload)] \ 
  454                                     () -> const ::flow::log::Component & \ 
  489#define FLOW_LOG_WITH_CHECKING(ARG_sev, ARG_stream_fragment) \ 
  490  FLOW_UTIL_SEMICOLON_SAFE \ 
  492    ::flow::log::Logger const * const FLOW_LOG_W_CHK_logger = get_logger(); \ 
  493    if (FLOW_LOG_W_CHK_logger && FLOW_LOG_W_CHK_logger->should_log(ARG_sev, get_log_component())) \ 
  495      FLOW_LOG_WITHOUT_CHECKING(ARG_sev, ARG_stream_fragment); \ 
  532#define FLOW_LOG_WITHOUT_CHECKING(ARG_sev, ARG_stream_fragment) \ 
  533  FLOW_UTIL_SEMICOLON_SAFE \ 
  535    using ::flow::util::Thread_id; \ 
  536    using ::flow::log::Logger; \ 
  537    using ::flow::log::Component; \ 
  538    using ::flow::util::String_view; \ 
  539    using ::flow::util::get_last_path_segment; \ 
  540    using ::std::chrono::system_clock; \ 
  541    using ::std::string; \ 
  542    Logger* const FLOW_LOG_WO_CHK_logger = get_logger(); \ 
  543    if (!FLOW_LOG_WO_CHK_logger)  \ 
  550    auto const& FLOW_LOG_WO_CHK_time_stamp = system_clock::now(); \ 
  558    constexpr char const * FLOW_LOG_WO_CHK_file_ptr = __FILE__; \ 
  559    constexpr size_t FLOW_LOG_WO_CHK_file_sz = sizeof(__FILE__) - 1; \ 
  560    constexpr char const * FLOW_LOG_WO_CHK_func_ptr = __FUNCTION__; \ 
  561    constexpr size_t FLOW_LOG_WO_CHK_func_sz = sizeof(__FUNCTION__) - 1; \ 
  562    constexpr String_view FLOW_LOG_WO_CHK_full_file_str(FLOW_LOG_WO_CHK_file_ptr, FLOW_LOG_WO_CHK_file_sz); \ 
  564    constexpr String_view FLOW_LOG_WO_CHK_file_str = get_last_path_segment(FLOW_LOG_WO_CHK_full_file_str); \ 
  565    constexpr String_view FLOW_LOG_WO_CHK_func_str(FLOW_LOG_WO_CHK_func_ptr, FLOW_LOG_WO_CHK_func_sz); \ 
  566    const Component& FLOW_LOG_WO_CHK_component = get_log_component(); \ 
  567    string FLOW_LOG_WO_CHK_call_thread_nickname; \ 
  568    Thread_id FLOW_LOG_WO_CHK_call_thread_id; \ 
  569    Logger::set_thread_info(&FLOW_LOG_WO_CHK_call_thread_nickname, &FLOW_LOG_WO_CHK_call_thread_id); \ 
  570    FLOW_LOG_DO_LOG(FLOW_LOG_WO_CHK_logger, FLOW_LOG_WO_CHK_component, ARG_sev, FLOW_LOG_WO_CHK_file_str, __LINE__, \ 
  571                    FLOW_LOG_WO_CHK_func_str, FLOW_LOG_WO_CHK_time_stamp, FLOW_LOG_WO_CHK_call_thread_nickname, \ 
  572                    FLOW_LOG_WO_CHK_call_thread_id, ARG_stream_fragment); \ 
  683#define FLOW_LOG_DO_LOG(ARG_logger_ptr, \ 
  684                        ARG_component, ARG_sev, ARG_file_view, ARG_line, ARG_func_view, \ 
  685                        ARG_time_stamp, ARG_call_thread_nickname_str_moved, \ 
  686                        ARG_call_thread_id, ARG_stream_fragment) \ 
  687  FLOW_UTIL_SEMICOLON_SAFE \ 
  689    using ::flow::log::Thread_local_string_appender; \ 
  690    using ::flow::log::this_thread_sync_msg_metadata_ptr; \ 
  691    using ::flow::log::Logger; \ 
  692    using ::flow::log::Msg_metadata; \ 
  693    using ::flow::util::String_view; \ 
  694    using ::std::flush; \ 
  695    Logger* const FLOW_LOG_DO_LOG_logger = ARG_logger_ptr;  \ 
  705    auto& FLOW_LOG_DO_LOG_appender \ 
  706      = *(Thread_local_string_appender::get_this_thread_string_appender(*FLOW_LOG_DO_LOG_logger)); \ 
  707    auto& FLOW_LOG_DO_LOG_os = *(FLOW_LOG_DO_LOG_appender.fresh_appender_ostream()); \ 
  708    FLOW_LOG_DO_LOG_os << ARG_stream_fragment << flush; \ 
  710    Msg_metadata* FLOW_LOG_DO_LOG_msg_metadata_ptr; \ 
  711    if (FLOW_LOG_DO_LOG_logger->logs_asynchronously()) \ 
  714      (FLOW_LOG_DO_LOG_msg_metadata_ptr \ 
  715         = new Msg_metadata{ ARG_component, ARG_sev, ARG_file_view, ARG_line, ARG_func_view, \ 
  716                             ARG_time_stamp, std::move(ARG_call_thread_nickname_str_moved), ARG_call_thread_id }); \ 
  721      FLOW_LOG_DO_LOG_msg_metadata_ptr = this_thread_sync_msg_metadata_ptr.get(); \ 
  722      if (!FLOW_LOG_DO_LOG_msg_metadata_ptr) \ 
  724        this_thread_sync_msg_metadata_ptr.reset(FLOW_LOG_DO_LOG_msg_metadata_ptr = new Msg_metadata); \ 
  727      ((*FLOW_LOG_DO_LOG_msg_metadata_ptr) \ 
  728         = { ARG_component, ARG_sev, ARG_file_view, ARG_line, ARG_func_view, \ 
  729             ARG_time_stamp, std::move(ARG_call_thread_nickname_str_moved), ARG_call_thread_id }); \ 
  744    FLOW_LOG_DO_LOG_logger->do_log(FLOW_LOG_DO_LOG_msg_metadata_ptr, \ 
  745                                   String_view(FLOW_LOG_DO_LOG_appender.target_contents())); \ 
  868  template<
typename Payload>
 
  905  template<
typename Payload>
 
  931  template<
typename Payload>
 
 1283  private boost::noncopyable 
 
 1457                                              bool also_set_os_name = 
true);
 
 1637  template<
typename Component_payload>
 
 1721template<
typename Payload>
 
 1728template<
typename Payload>
 
 1735template<
typename Payload>
 
 1738  static_assert(std::is_enum_v<Payload>, 
"Payload type must be an enum.");
 
 1739  static_assert(std::is_same_v<typename std::underlying_type_t<Payload>, 
enum_raw_t>,
 
 1740                "Payload enum underlying type must equal enum_raw_t.");
 
 1750template<
typename Component_payload>
 
 1753  m_component(component_payload)
 
A light-weight class, each object storing a component payload encoding an enum value from enum type o...
Component & operator=(const Component &src)
Overwrites *this with a copy of src.
unsigned int enum_raw_t
The type Payload must be enum class Payload : enum_raw_t: an enum type encoded via this integer type.
Component(Component &&src_moved)
Constructs *this equal to src_moved.
std::type_info const  * m_payload_type_or_null
The typeid() of the Payload passed to the 1-arg constructor; if 0-arg ctor was used (empty() is true)...
const std::type_info & payload_type() const
Returns typeid(Payload), where Payload was the template param used when calling the originating one-a...
bool empty() const
Returns true if *this is as if default-constructed (a null Component); false if as if constructed via...
enum_raw_t m_payload_enum_raw_value
The internally stored integer representation of the enum value passed to the 1-arg constructor; meani...
Component(const Component &src)
Copies the source Component into *this.
Payload payload() const
Returns reference to immutable payload stored in *this; undefined behavior if empty() == true.
Component & operator=(Component &&src_moved)
Makes *this equal to src_moved.
enum_raw_t payload_enum_raw_value() const
Returns the numeric value of the enum payload stored by this Component, originating in the one-arg co...
Component()
Constructs a Component that stores no payload; meaning an unspecified-component Component that return...
Convenience class that simply stores a Logger and/or Component passed into a constructor; and returns...
Log_context(const Log_context &src)
Copy constructor that stores equal Logger* and Component values as the source.
Log_context & operator=(const Log_context &src)
Assignment operator that behaves similarly to the copy constructor.
const Component & get_log_component() const
Returns reference to the stored Component object, particularly as many FLOW_LOG_*() macros expect.
void swap(Log_context &other)
Swaps Logger pointers and Component objects held by *this and other.
Component m_component
The held Component object. Making the object non-const to allow operator=() to work.
Log_context(Logger *logger=0)
Constructs Log_context by storing the given pointer to a Logger and a null Component.
Logger * m_logger
The held Logger pointer. Making the pointer itself non-const to allow operator=() to work.
Logger * get_logger() const
Returns the stored Logger pointer, particularly as many FLOW_LOG_*() macros expect.
Interface that the user should implement, passing the implementing Logger into logging classes (Flow'...
static void set_thread_info(std::string *call_thread_nickname, flow::util::Thread_id *call_thread_id)
Same as set_thread_info_in_msg_metadata() but targets the given two variables as opposed to a Msg_met...
static void set_thread_info_in_msg_metadata(Msg_metadata *msg_metadata)
Loads msg_metadata->m_call_thread_nickname (if set) or else msg_metadata->m_call_thread_id,...
static boost::thread_specific_ptr< std::string > s_this_thread_nickname_ptr
Thread-local storage for each thread's logged name (null pointer, which is default,...
static void this_thread_set_logged_nickname(util::String_view thread_nickname=util::String_view(), Logger *logger_ptr=0, bool also_set_os_name=true)
Sets or unsets the current thread's logging-worthy string name; optionally sets the OS thread name (s...
virtual void do_log(Msg_metadata *metadata, util::String_view msg)=0
Given a message and its severity, logs that message and possibly severity WITHOUT checking whether it...
static std::ostream & this_thread_logged_name_os_manip(std::ostream &os)
ostream manipulator function that, if output via operator<< to an ostream, will cause the current thr...
virtual bool should_log(Sev sev, const Component &component) const =0
Given attributes of a hypothetical message that would be logged, return true if that message should b...
std::ostream * this_thread_ostream() const
Returns the stream dedicated to the executing thread and this Logger, so that the caller can apply st...
virtual bool logs_asynchronously() const =0
Must return true if do_log() at least sometimes logs the given message and metadata (e....
An empty interface, consisting of nothing but a default virtual destructor, intended as a boiler-plat...
Each object of this class stores (at construction) and returns (on demand) a numeric ID unique from a...
Flow module providing logging functionality.
Sev
Enumeration containing one of several message severity levels, ordered from highest to lowest.
Thread::id Thread_id
Short-hand for an OS-provided ID of a util::Thread.
Basic_string_view< char > String_view
Commonly used char-based Basic_string_view. See its doc header.