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>
1290 private boost::noncopyable
1464 bool also_set_os_name =
true);
1644 template<
typename Component_payload>
1728template<
typename Payload>
1735template<
typename Payload>
1742template<
typename Payload>
1745 static_assert(std::is_enum_v<Payload>,
"Payload type must be an enum.");
1746 static_assert(std::is_same_v<typename std::underlying_type_t<Payload>,
enum_raw_t>,
1747 "Payload enum underlying type must equal enum_raw_t.");
1757template<
typename Component_payload>
1760 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...
std::type_index payload_type_index() const
Convenience accessor that returns std::type_index(payload_type()), which can be used most excellently...
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.