ilogger.h File Reference
Description
Logger interface class that supports message logging. See Logging.
Code Example
ilogger.h
/***************************************************************************************************
* Copyright 2024 NVIDIA Corporation. All rights reserved.
**************************************************************************************************/
#ifndef MI_BASE_ILOGGER_H
#define MI_BASE_ILOGGER_H
#include <cstdarg>
#include <cstdio>
#include <ostream>
#include <sstream>
#include <string>
#include <mi/base/config.h>
#include <mi/base/enums.h>
#include <mi/base/handle.h>
#include <mi/base/iinterface.h>
#include <mi/base/interface_declare.h>
namespace mi {
namespace base {
namespace details {
// Tags may be combined.
enum Message_tag
{
TAG_NONE = 0u,
TAG_COMPATIBILITY = 1u << 0,
TAG_UNRECOVERABLE = 1u << 1,
TAG_API_INPUT = 1u << 2,
TAG_API_USAGE = 1u << 3,
TAG_VERSIONING = 1u << 4,
TAG_SYSTEM_RESOURCE = 1u << 5,
TAG_MEMORY = 1u << 6,
TAG_FILE = 1u << 7,
TAG_STATS = 1u << 8,
TAG_UNAVAILABLE = 1u << 9
};
} // namespace details
using namespace details;
struct Message_details
{
enum { HOST_ID_LOCAL = 0 };
enum {
DEVICE_ID_CPU = -1,
DEVICE_ID_UNKNOWN_CUDA = -2,
DEVICE_ID_ALL_CUDA = -3
};
Uint32
host_id;
Sint32
device_id;
Uint32
tags;
Uint32
message_id;
Message_details()
: host_id(HOST_ID_LOCAL)
, device_id(DEVICE_ID_CPU)
, tags(TAG_NONE)
, message_id(0u)
{}
Message_details(
const Uint32
host,
const Sint32
device,
const Uint32
tag,
const Uint32 id)
: host_id(host)
, device_id(device)
, tags(tag)
, message_id(id)
{}
bool is_device() const
{
return device_id != DEVICE_ID_CPU;
}
bool is_tagged(const Uint32 required_tags) const
{
return (this->tags & required_tags) == required_tags;
}
Message_details& host(const Uint32 id)
{
host_id = id;
return *this;
}
Message_details& device(const Sint32 id)
{
device_id = id;
return *this;
}
Message_details& tag(const Uint32 t)
{
tags = t;
return *this;
}
Message_details& tag(const Uint32 t, const Uint32
code)
{
tags = t;
message_id = code;
return *this;
}
Message_details& code(const Uint32 c)
{
message_id = c;
return *this;
}
};
class ILogger : public
Interface_declare<0x4afbf19a,0x5fb7,0x4422,0xae,0x4b,0x25,0x13,0x06,0x2c,0x30,0x5f>
{
public:
virtual void message(
Message_severity level, const char* module_category, const char* message)
#ifdef MI_NEURAYLIB_DEPRECATED_LOG
= 0;
#else
{
this->message(level,module_category,Message_details(),message);
}
#endif
virtual void message(
Message_severity level,
const char* module_category,
const Message_details&,
const char* message)
#ifdef MI_NEURAYLIB_DEPRECATED_LOG
{
this->message(level,module_category,message);
}
#else
= 0;
#endif
inline void printf(
Message_severity level, const char* module_category, const char* message, ...)
#ifdef MI_COMPILER_GCC
__attribute__((format(printf, 4, 5)))
#endif
{
va_list args;
va_start( args, message);
char buffer[1024];
#ifdef MI_COMPILER_MSC
vsnprintf_s( &buffer[0], sizeof( buffer), sizeof( buffer)-1, message, args);
#else
vsnprintf( buffer, sizeof( buffer), message, args);
#endif
this->message( level, module_category, Message_details(), buffer);
va_end( args);
}
inline void printf(
Message_severity level,
const char* module_category,
const Message_details& details,
const char* message,
...)
#ifdef MI_COMPILER_GCC
__attribute__((format(printf, 5, 6)))
#endif
{
va_list args;
va_start( args, message);
char buffer[1024];
#ifdef MI_COMPILER_MSC
vsnprintf_s( buffer, sizeof( buffer), sizeof( buffer)-1, message, args);
#else
vsnprintf( buffer, sizeof( buffer), message, args);
#endif
this->message( level, module_category, details, buffer);
va_end( args);
}
};
class Log_stream;
// A specialization of std::stringbuf to be used together with #mi::base::Log_stream.
//
// Its sync() method is overridden to send the contents of the string buffer to the logger, and an
// additional method #set_log_level() allows to specify the log level of the next message.
class Log_streambuf : public std::stringbuf
{
public:
// Constructor.
//
// \param stream The stream used with this string buffer. Used to flush the stream
// if the log level is changed.
// \param module_category The module and the category which specify the origin and the
// functional area of this message. See #mi::base::ILogger::message()
// for details.
// \param default_level The default log level. Used if no other log level is selected by
// one of the manipulators.
// \param default_details The default message details. Used if no other details are set.
Log_streambuf(
Log_stream& stream,
const std::string& module_category,
Message_severity default_level = MESSAGE_SEVERITY_INFO,
const Message_details& default_details = Message_details())
: std::stringbuf( std::ios::out),
m_stream( stream),
m_default_level( default_level),
m_default_details( default_details),
m_module_category( module_category),
m_details( default_details)
{
set_log_level( m_default_level);
}
// Destructor.
~Log_streambuf() throw()
{
}
// Flushes the string buffer if not empty, and sets the log level of the next message to the
// given log level.
void set_log_level( Message_severity level);
// Flushes the string buffer if not empty, and sets the log level of the next message to the
// given log level.
void set_details( const Message_details& details);
protected:
// Sends the contents of the string buffer to the logger, clears the string buffer, and resets
// the log level and details to their defaults.
int sync();
private:
Log_stream& m_stream;
Message_severity m_default_level;
Message_details m_default_details;
std::string m_module_category;
Message_severity m_level;
Message_details m_details;
};
class Log_stream : public std::ostream
{
public:
Log_stream(
ILogger* logger,
const char* module_category,
Message_severity default_level = MESSAGE_SEVERITY_INFO,
const Message_details& default_details = Message_details())
: std::ostream( 0),
m_buffer( *this, module_category ? module_category : "APP:MAIN",
default_level, default_details),
m_logger( logger, DUP_INTERFACE)
{
rdbuf( &m_buffer);
#if (__cplusplus >= 201402L)
this->pword( get_index()) = this;
#endif
}
Log_stream(
ILogger* logger,
const std::string& module_category,
Message_severity default_level = MESSAGE_SEVERITY_INFO,
const Message_details& default_details = Message_details())
: std::ostream( 0),
m_buffer( *this, module_category, default_level, default_details),
m_logger( logger, DUP_INTERFACE)
{
rdbuf( &m_buffer);
#if (__cplusplus >= 201402L)
this->pword( get_index()) = this;
#endif
}
~Log_stream() throw()
{
flush();
}
void set_log_level( Message_severity level) { m_buffer.set_log_level( level); }
void set_details( const Message_details& details) { m_buffer.set_details( details); }
#if (__cplusplus >= 201402L)
// Returns the unique index into the private storage of std::ios_base.
static int get_index()
{
// Static initialization is guaranteed to be thread-safe with C++11 and later. The method
// std::ios_base::xalloc() is guaranteed to be thread-safe with C++14 and later.
static const int s_index = std::ios_base::xalloc();
return s_index;
}
#endif
private:
friend class Log_streambuf;
Log_streambuf m_buffer;
mi::base::Handle< ILogger> m_logger;
// Primary customization point.
// Note that this function may be called from the destructor.
virtual void message(
Message_severity level,
const char* module_category,
const Message_details& details,
const char* message) const
{
m_logger->message( level, module_category, details, message);
}
};
inline void Log_streambuf::set_log_level( Message_severity level)
{
m_stream.flush();
m_level = level;
}
inline void Log_streambuf::set_details( const Message_details& details)
{
m_stream.flush();
m_details = details;
}
inline int Log_streambuf::sync()
{
std::stringbuf::sync();
const std::string& s = str();
if( !s.empty()) {
m_stream.message( m_level, m_module_category.c_str(), m_details, s.c_str());
str( "");
m_level = m_default_level;
m_details = m_default_details;
}
return 0;
}
template <typename C, typename T>
std::basic_ostream<C, T>& fatal( std::basic_ostream<C, T>& ostream)
{
#if (__cplusplus >= 201402L)
if( ostream.pword( Log_stream::get_index()) == &ostream)
#endif
static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_FATAL);
return ostream;
}
template <typename C, typename T>
std::basic_ostream<C, T>& error( std::basic_ostream<C, T>& ostream)
{
#if (__cplusplus >= 201402L)
if( ostream.pword( Log_stream::get_index()) == &ostream)
#endif
static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_ERROR);
return ostream;
}
template <typename C, typename T>
std::basic_ostream<C, T>& warning( std::basic_ostream<C, T>& ostream)
{
#if (__cplusplus >= 201402L)
if( ostream.pword( Log_stream::get_index()) == &ostream)
#endif
static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_WARNING);
return ostream;
}
template <typename C, typename T>
std::basic_ostream<C, T>& info( std::basic_ostream<C, T>& ostream)
{
#if (__cplusplus >= 201402L)
if( ostream.pword( Log_stream::get_index()) == &ostream)
#endif
static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_INFO);
return ostream;
}
template <typename C, typename T>
std::basic_ostream<C, T>& verbose( std::basic_ostream<C, T>& ostream)
{
#if (__cplusplus >= 201402L)
if( ostream.pword( Log_stream::get_index()) == &ostream)
#endif
static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_VERBOSE);
return ostream;
}
template <typename C, typename T>
std::basic_ostream<C, T>& debug( std::basic_ostream<C, T>& ostream)
{
#if (__cplusplus >= 201402L)
if( ostream.pword( Log_stream::get_index()) == &ostream)
#endif
static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_DEBUG);
return ostream;
}
template <typename C, typename T>
std::basic_ostream<C, T>& operator<<( std::basic_ostream<C, T>& ostream, const Message_details& md)
{
#if (__cplusplus >= 201402L)
if( ostream.pword( Log_stream::get_index()) == &ostream)
#endif
static_cast<Log_stream&>( ostream).set_details( md);
return ostream;
}
namespace msg {
using namespace details;
typedef Message_tag Tag;
typedef Message_details Details;
inline Details tag_details(const Uint32 tags)
{
return Details().tag(tags);
}
inline Details device_details(
const Sint32 device=Details::DEVICE_ID_UNKNOWN_CUDA,
const Uint32 tags=TAG_NONE)
{
return Details().tag(tags).device(device);
}
}
// end group mi_base_ilogger
} // namespace base
} // namespace mi
#endif // MI_BASE_ILOGGER_H
Namespaces
- namespace
- Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH. More...
- namespace
- Namespace for the Base API. More...
- namespace
- Namespace for details of the Base API. More...
- namespace mi::base::msg
Classes
- class
- The ILogger interface class supports logging of messages. More...
- class
- Adapts mi::base::ILogger to a standard streaming interface. More...
- struct
- Structured details to log messages. More...
Enumerations
- enum {TAG_NONE = 0u, TAG_COMPATIBILITY = 1u<<0, TAG_UNRECOVERABLE = 1u<<1, TAG_API_INPUT = 1u<<2, TAG_API_USAGE = 1u<<3, TAG_VERSIONING = 1u<<4, TAG_SYSTEM_RESOURCE = 1u<<5, TAG_MEMORY = 1u<<6, TAG_FILE = 1u<<7, TAG_STATS = 1u<<8, TAG_UNAVAILABLE = 1u<<9 }
- Tags which help categorize log messages. More...
Functions
- template< typename C, typename T> std::basic_ostream < C , T >& ( std::basic_ostream < C , T >& ostream)
- Manipulator for mi::base::Log_stream. More...
- template< typename C, typename T> std::basic_ostream < C , T >& ( std::basic_ostream < C , T >& ostream)
- Manipulator for mi::base::Log_stream. More...
- template< typename C, typename T> std::basic_ostream < C , T >& ( std::basic_ostream < C , T >& ostream)
- Manipulator for mi::base::Log_stream. More...
- template< typename C, typename T> std::basic_ostream < C , T >& ( std::basic_ostream < C , T >& ostream)
- Manipulator for mi::base::Log_stream. More...
- template< typename C, typename T> std::basic_ostream < C , T >& ( std::basic_ostream < C , T >& ostream, const Message_details& md)
- Manipulator for mi::base::Log_stream. More...
- template< typename C, typename T> std::basic_ostream < C , T >& ( std::basic_ostream < C , T >& ostream)
- Manipulator for mi::base::Log_stream. More...
- template< typename C, typename T> std::basic_ostream < C , T >& ( std::basic_ostream < C , T >& ostream)
- Manipulator for mi::base::Log_stream. More...