39#ifndef G_LOG_THREAD_LOCAL
40#define G_LOG_THREAD_LOCAL
64 G_EXCEPTION( LogFileError ,
tx(
"cannot open log file") )
65 G_EXCEPTION( EventLogError ,
tx(
"cannot access the system event log") )
78 enum class SyslogFacility
96 bool m_output_enabled {
false} ;
97 bool m_summary_info {
false} ;
98 bool m_verbose_info {
false} ;
99 bool m_more_verbose_info {
false} ;
100 bool m_debug {
false} ;
101 bool m_with_level {
false} ;
102 bool m_with_timestamp {
false} ;
103 bool m_with_context {
false} ;
104 bool m_strip {
false} ;
105 bool m_quiet_stderr {
false} ;
106 bool m_use_syslog {
false} ;
107 bool m_allow_bad_syslog {
false} ;
108 bool m_stdout {
false} ;
109 SyslogFacility m_facility {SyslogFacility::User} ;
110 Process::Umask::Mode m_umask {Process::Umask::Mode::NoChange} ;
113 Config & set_output_enabled(
bool value =
true ) noexcept ;
114 Config & set_summary_info(
bool value =
true ) noexcept ;
115 Config & set_verbose_info(
bool value =
true ) noexcept ;
116 Config & set_more_verbose_info(
bool value =
true ) noexcept ;
117 Config & set_debug(
bool value =
true ) noexcept ;
118 Config & set_with_level(
bool value =
true ) noexcept ;
119 Config & set_with_timestamp(
bool value =
true ) noexcept ;
120 Config & set_with_context(
bool value =
true ) noexcept ;
121 Config & set_strip(
bool value =
true ) noexcept ;
122 Config & set_quiet_stderr(
bool value =
true ) noexcept ;
123 Config & set_use_syslog(
bool value =
true ) noexcept ;
124 Config & set_allow_bad_syslog(
bool value =
true ) noexcept ;
125 Config & set_facility( SyslogFacility ) noexcept ;
126 Config & set_umask( Process::Umask::Mode ) noexcept ;
127 Config & set_stdout(
bool value =
true ) noexcept ;
132 static bool at( LogOutput::Severity ) noexcept ;
133 static bool atVerbose() noexcept ;
134 static bool atDebug() noexcept ;
135 static void context( std::string_view (*fn)(
void*) =
nullptr ,
void * fn_arg =
nullptr ) noexcept ;
136 static void * contextarg() noexcept ;
137 static LogStream start( LogOutput::Severity ,
const char * file ,
int line ) noexcept ;
138 static void output(
LogStream & ) noexcept ;
139 static int fd() noexcept ;
145 const Path & logfile = {} ) ;
184 Config
config() const noexcept ;
187 int fd() const noexcept ;
193 bool at( Severity ) const noexcept ;
196 void context(
std::string_view (*fn)(
void*) =
nullptr ,
void * fn_arg =
nullptr ) noexcept ;
205 LogStream
start( Severity , const
char * file ,
int line ) noexcept ;
210 void output( LogStream & ) noexcept ;
214 static
void assertion(
LogOutput * , const
char * file ,
int line ,
bool test , const
char * test_string ) ;
217 static
void assertion(
LogOutput * , const
char * file ,
int line ,
void * test , const
char * test_string ) ;
224 GDEF_NORETURN_LHS static
void assertionAbort() GDEF_NORETURN_RHS ;
227 static
void register_( const Path & exe ) ;
241 LogOutput( Private ,
const std::string & ,
const Config & ) ;
244 void open(
const Path & ,
bool ) ;
245 LogStream
start( Severity ) ;
246 void output( LogStream & ,
int ) ;
247 void osoutput(
int , Severity ,
char * , std::size_t ) ;
248 void oscleanup() const noexcept ;
250 bool updatePath( const Path & , Path & ) const ;
251 Path makePath( const Path & ) const ;
252 void appendTimeTo( LogStream & ) ;
253 static
std::string_view levelString( Severity ) noexcept ;
254 static const
char * basename( const
char * ) noexcept ;
257 struct Stream : public
std::ostream
259 explicit Stream( omembuf * buf ) :
std::ostream(buf) {}
260 void reset() { clear() ; seekp(0) ; }
264 friend struct Instance ;
265 static G_LOG_THREAD_LOCAL
LogOutput * m_instance ;
266 std::string m_exename ;
268 std::time_t m_time_s {0} ;
269 unsigned int m_time_us {0U} ;
270 std::array<char,17U> m_time_buffer {} ;
271 std::array<char,17U> m_time_change_buffer {} ;
272 static constexpr std::size_t m_rhs_margin = 7U ;
273 static constexpr std::size_t m_buffer_base_size = Limits<>::log + 40U ;
274 static constexpr std::size_t m_buffer_size = m_buffer_base_size + m_rhs_margin ;
275 std::vector<char> m_buffer ;
278 HANDLE m_handle {0} ;
282 unsigned int m_depth {0U} ;
283 Severity m_severity {Severity::Debug} ;
284 std::size_t m_start_pos {0U} ;
285 std::string_view (*m_context_fn)(
void *) {
nullptr} ;
286 void * m_context_fn_arg {
nullptr} ;
302 assertionFailure( instance , file , line , test_string ) ;
307inline G::LogOutput::Config & G::LogOutput::Config::set_output_enabled(
bool value )
noexcept { m_output_enabled = value ;
return *this ; }
308inline G::LogOutput::Config & G::LogOutput::Config::set_summary_info(
bool value )
noexcept { m_summary_info = value ;
return *this ; }
309inline G::LogOutput::Config & G::LogOutput::Config::set_verbose_info(
bool value )
noexcept { m_verbose_info = value ;
return *this ; }
310inline G::LogOutput::Config & G::LogOutput::Config::set_more_verbose_info(
bool value )
noexcept { m_more_verbose_info = value ;
return *this ; }
311inline G::LogOutput::Config & G::LogOutput::Config::set_debug(
bool value )
noexcept { m_debug = value ;
return *this ; }
312inline G::LogOutput::Config & G::LogOutput::Config::set_with_level(
bool value )
noexcept { m_with_level = value ;
return *this ; }
313inline G::LogOutput::Config & G::LogOutput::Config::set_with_timestamp(
bool value )
noexcept { m_with_timestamp = value ;
return *this ; }
314inline G::LogOutput::Config & G::LogOutput::Config::set_with_context(
bool value )
noexcept { m_with_context = value ;
return *this ; }
315inline G::LogOutput::Config & G::LogOutput::Config::set_strip(
bool value )
noexcept { m_strip = value ;
return *this ; }
316inline G::LogOutput::Config & G::LogOutput::Config::set_quiet_stderr(
bool value )
noexcept { m_quiet_stderr = value ;
return *this ; }
317inline G::LogOutput::Config & G::LogOutput::Config::set_use_syslog(
bool value )
noexcept { m_use_syslog = value ;
return *this ; }
318inline G::LogOutput::Config & G::LogOutput::Config::set_allow_bad_syslog(
bool value )
noexcept { m_allow_bad_syslog = value ;
return *this ; }
319inline G::LogOutput::Config & G::LogOutput::Config::set_facility( SyslogFacility facility )
noexcept { m_facility = facility ;
return *this ; }
320inline G::LogOutput::Config & G::LogOutput::Config::set_umask( Process::Umask::Mode umask )
noexcept { m_umask = umask ;
return *this ; }
321inline G::LogOutput::Config & G::LogOutput::Config::set_stdout(
bool value )
noexcept { m_stdout = value ;
return *this ; }
323inline bool G::LogOutput::Instance::at( LogOutput::Severity s )
noexcept {
return LogOutput::m_instance && LogOutput::m_instance->at( s ) ; }
324inline bool G::LogOutput::Instance::atVerbose() noexcept {
return LogOutput::m_instance && LogOutput::m_instance->at( LogOutput::Severity::InfoVerbose ) ; }
325inline bool G::LogOutput::Instance::atDebug() noexcept {
return LogOutput::m_instance && LogOutput::m_instance->at( LogOutput::Severity::Debug ) ; }
326inline void G::LogOutput::Instance::context( std::string_view (*fn)(
void*) ,
void * fn_arg )
noexcept {
if( LogOutput::m_instance ) LogOutput::m_instance->context( fn , fn_arg ) ; }
327inline void * G::LogOutput::Instance::contextarg() noexcept {
if( LogOutput::m_instance )
return LogOutput::m_instance->contextarg() ;
else return nullptr ; }
328inline G::LogStream G::LogOutput::Instance::start( LogOutput::Severity s ,
const char * file ,
int line )
noexcept {
if( LogOutput::m_instance )
return LogOutput::m_instance->start( s , file , line ) ;
else return LogStream(
nullptr ) ; }
329inline void G::LogOutput::Instance::output( LogStream & stream )
noexcept {
if( LogOutput::m_instance ) LogOutput::m_instance->output( stream ) ; }
330inline int G::LogOutput::Instance::fd() noexcept {
return LogOutput::m_instance ? LogOutput::m_instance->fd() : -1 ; }
331inline G::LogOutput::Config G::LogOutput::Instance::config() noexcept {
return LogOutput::m_instance ? LogOutput::m_instance->config() : LogOutput::Config() ; }
A static interface for daemonising the calling process.
Controls and implements low-level logging output, as used by G::Log.
LogStream start(Severity, const char *file, int line) noexcept
Returns an ostream for a new log line.
bool at(Severity) const noexcept
Returns true if logging should occur for the given severity level.
static GDEF_NORETURN_LHS void assertionAbort() GDEF_NORETURN_RHS
Aborts the program when an assertion has failed.
LogOutput(const std::string &exename, const Config &config, const Path &logfile={})
Constructor.
static void assertionFailure(LogOutput *, const char *file, int line, const char *test_string) noexcept
Reports an assertion failure.
void context(std::string_view(*fn)(void *)=nullptr, void *fn_arg=nullptr) noexcept
Sets a functor that is used to provide a context string for every log line, if configured.
static void register_(const Path &exe)
Registers the given executable as a source of logging.
Config config() const noexcept
Returns the current configuration.
void * contextarg() noexcept
Returns the functor argument as set by the last call to context().
void output(LogStream &) noexcept
Emits the current log line (see start()).
void configure(const Config &)
Updates the current configuration.
static LogOutput * instance() noexcept
Returns a pointer to the controlling LogOutput object.
int fd() const noexcept
Returns the output file descriptor.
static void assertion(LogOutput *, const char *file, int line, bool test, const char *test_string)
Performs an assertion check.
A Path object represents a file system path.
bool enabled() noexcept
Returns true if pop code is built in.
constexpr const char * tx(const char *p) noexcept
A briefer alternative to G::gettext_noop().
A configuration structure for G::LogOutput.
A set of convenience functions for calling LogOutput methods on LogOutput::instance().
A non-throwing copyable wrapper for std::ostream, used by G::LogOutput and associated logging macros.