Math API nvidia_logo_transpbg.gif Up
ilogger.h
Go to the documentation of this file.
1/***************************************************************************************************
2 * Copyright 2023 NVIDIA Corporation. All rights reserved.
3 **************************************************************************************************/
8
9#ifndef MI_BASE_ILOGGER_H
10#define MI_BASE_ILOGGER_H
11
12#include <cstdarg>
13#include <cstdio>
14#include <ostream>
15#include <sstream>
16#include <string>
17
18#include <mi/base/config.h>
19#include <mi/base/enums.h>
20#include <mi/base/handle.h>
21#include <mi/base/iinterface.h>
23
24namespace mi {
25
26namespace base {
27
39namespace details {
40
43// Tags may be combined.
45{
46 TAG_NONE = 0u,
49 TAG_API_INPUT = 1u << 2,
50 TAG_API_USAGE = 1u << 3,
51 TAG_VERSIONING = 1u << 4,
53 TAG_MEMORY = 1u << 6,
54 TAG_FILE = 1u << 7,
55 TAG_STATS = 1u << 8,
56 TAG_UNAVAILABLE = 1u << 9
57};
58
59} // namespace details
60
61using namespace details;
62
71{
72 enum { HOST_ID_LOCAL = 0 };
73 enum {
74 DEVICE_ID_CPU = -1,
75 DEVICE_ID_UNKNOWN_CUDA = -2,
76 DEVICE_ID_ALL_CUDA = -3
77 };
78
85
88
93
96
98 : host_id(HOST_ID_LOCAL)
99 , device_id(DEVICE_ID_CPU)
100 , tags(TAG_NONE)
101 , message_id(0u)
102 {}
103
105 const Uint32 host,
106 const Sint32 device,
107 const Uint32 tag,
108 const Uint32 id)
109 : host_id(host)
111 , tags(tag)
112 , message_id(id)
113 {}
114
116 bool is_device() const
117 {
118 return device_id != DEVICE_ID_CPU;
119 }
120
122 bool is_tagged(const Uint32 required_tags) const
123 {
124 return (this->tags & required_tags) == required_tags;
125 }
126
129 {
130 host_id = id;
131 return *this;
132 }
133
136 {
137 device_id = id;
138 return *this;
139 }
140
143 {
144 tags = t;
145 return *this;
146 }
147
150 {
151 tags = t;
153 return *this;
154 }
155
158 {
159 message_id = c;
160 return *this;
161 }
162};
163
164
192class ILogger : public
193 Interface_declare<0x4afbf19a,0x5fb7,0x4422,0xae,0x4b,0x25,0x13,0x06,0x2c,0x30,0x5f>
194{
195public:
215 virtual void message(
216 Message_severity level, const char* module_category, const char* message)
217#ifdef MI_NEURAYLIB_DEPRECATED_LOG
218 = 0;
219#else
220 {
221 this->message(level,module_category,Message_details(),message);
222 }
223#endif
224
229 virtual void message(
230 Message_severity level,
231 const char* module_category,
232 const Message_details&,
233 const char* message)
234#ifdef MI_NEURAYLIB_DEPRECATED_LOG
235 {
236 this->message(level,module_category,message);
237 }
238#else
239 = 0;
240#endif
241
263 inline void printf(
264 Message_severity level, const char* module_category, const char* message, ...)
265#ifdef MI_COMPILER_GCC
266 __attribute__((format(printf, 4, 5)))
267#endif
268 {
269 va_list args;
270 va_start( args, message);
271 char buffer[1024];
272#ifdef MI_COMPILER_MSC
273 vsnprintf_s( &buffer[0], sizeof( buffer), sizeof( buffer)-1, message, args);
274#else
275 vsnprintf( buffer, sizeof( buffer), message, args);
276#endif
277 this->message( level, module_category, Message_details(), buffer);
278 va_end( args);
279 }
280
285 inline void printf(
286 Message_severity level,
287 const char* module_category,
288 const Message_details& details,
289 const char* message,
290 ...)
291#ifdef MI_COMPILER_GCC
292 __attribute__((format(printf, 5, 6)))
293#endif
294 {
295 va_list args;
296 va_start( args, message);
297 char buffer[1024];
298#ifdef MI_COMPILER_MSC
299 vsnprintf_s( buffer, sizeof( buffer), sizeof( buffer)-1, message, args);
300#else
301 vsnprintf( buffer, sizeof( buffer), message, args);
302#endif
303 this->message( level, module_category, details, buffer);
304 va_end( args);
305 }
306};
307
308
309class Log_stream;
310
311
312// A specialization of std::stringbuf to be used together with #mi::base::Log_stream.
313//
314// Its sync() method is overridden to send the contents of the string buffer to the logger, and an
315// additional method #set_log_level() allows to specify the log level of the next message.
316class Log_streambuf : public std::stringbuf
317{
318public:
319 // Constructor.
320 //
321 // \param stream The stream used with this string buffer. Used to flush the stream
322 // if the log level is changed.
323 // \param module_category The module and the category which specify the origin and the
324 // functional area of this message. See #mi::base::ILogger::message()
325 // for details.
326 // \param default_level The default log level. Used if no other log level is selected by
327 // one of the manipulators.
328 // \param default_details The default message details. Used if no other details are set.
329 Log_streambuf(
330 Log_stream& stream,
331 const std::string& module_category,
333 const Message_details& default_details = Message_details())
334 : std::stringbuf( std::ios::out),
335 m_stream( stream),
336 m_default_level( default_level),
337 m_default_details( default_details),
338 m_module_category( module_category),
339 m_details( default_details)
340 {
341 set_log_level( m_default_level);
342 }
343
344 // Destructor.
345 ~Log_streambuf() throw()
346 {
347 }
348
349 // Flushes the string buffer if not empty, and sets the log level of the next message to the
350 // given log level.
351 void set_log_level( Message_severity level);
352
353 // Flushes the string buffer if not empty, and sets the log level of the next message to the
354 // given log level.
355 void set_details( const Message_details& details);
356
357protected:
358
359 // Sends the contents of the string buffer to the logger, clears the string buffer, and resets
360 // the log level and details to their defaults.
361 int sync();
362
363private:
364
365 Log_stream& m_stream;
366 Message_severity m_default_level;
367 Message_details m_default_details;
368 std::string m_module_category;
369 Message_severity m_level;
370 Message_details m_details;
371};
372
389class Log_stream : public std::ostream
390{
391public:
402 ILogger* logger,
403 const char* module_category,
405 const Message_details& default_details = Message_details())
406 : std::ostream( 0),
407 m_buffer( *this, module_category ? module_category : "APP:MAIN",
408 default_level, default_details),
409 m_logger( logger, DUP_INTERFACE)
410 {
411 rdbuf( &m_buffer);
412#if (__cplusplus >= 201402L)
413 this->pword( get_index()) = this;
414#endif
415 }
416
427 ILogger* logger,
428 const std::string& module_category,
430 const Message_details& default_details = Message_details())
431 : std::ostream( 0),
432 m_buffer( *this, module_category, default_level, default_details),
433 m_logger( logger, DUP_INTERFACE)
434 {
435 rdbuf( &m_buffer);
436#if (__cplusplus >= 201402L)
437 this->pword( get_index()) = this;
438#endif
439 }
440
444 ~Log_stream() throw()
445 {
446 flush();
447 }
448
451 void set_log_level( Message_severity level) { m_buffer.set_log_level( level); }
452
454 void set_details( const Message_details& details) { m_buffer.set_details( details); }
455
456#if (__cplusplus >= 201402L)
457 // Returns the unique index into the private storage of std::ios_base.
458 static int get_index()
459 {
460 // Static initialization is guaranteed to be thread-safe with C++11 and later. The method
461 // std::ios_base::xalloc() is guaranteed to be thread-safe with C++14 and later.
462 static const int s_index = std::ios_base::xalloc();
463 return s_index;
464 }
465#endif
466
467private:
468 friend class Log_streambuf;
469
470 Log_streambuf m_buffer;
472
473 // Primary customization point.
474 // Note that this function may be called from the destructor.
475 virtual void message(
476 Message_severity level,
477 const char* module_category,
478 const Message_details& details,
479 const char* message) const
480 {
481 m_logger->message( level, module_category, details, message);
482 }
483};
484
485
486
487inline void Log_streambuf::set_log_level( Message_severity level)
488{
489 m_stream.flush();
490 m_level = level;
491}
492
493inline void Log_streambuf::set_details( const Message_details& details)
494{
495 m_stream.flush();
496 m_details = details;
497}
498
499inline int Log_streambuf::sync()
500{
501 std::stringbuf::sync();
502 const std::string& s = str();
503 if( !s.empty()) {
504 m_stream.message( m_level, m_module_category.c_str(), m_details, s.c_str());
505 str( "");
506 m_level = m_default_level;
507 m_details = m_default_details;
508 }
509 return 0;
510}
511
512
522template <typename C, typename T>
523std::basic_ostream<C, T>& fatal( std::basic_ostream<C, T>& ostream)
524{
525#if (__cplusplus >= 201402L)
526 if( ostream.pword( Log_stream::get_index()) == &ostream)
527#endif
528 static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_FATAL);
529 return ostream;
530}
531
541template <typename C, typename T>
542std::basic_ostream<C, T>& error( std::basic_ostream<C, T>& ostream)
543{
544#if (__cplusplus >= 201402L)
545 if( ostream.pword( Log_stream::get_index()) == &ostream)
546#endif
547 static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_ERROR);
548 return ostream;
549}
550
560template <typename C, typename T>
561std::basic_ostream<C, T>& warning( std::basic_ostream<C, T>& ostream)
562{
563#if (__cplusplus >= 201402L)
564 if( ostream.pword( Log_stream::get_index()) == &ostream)
565#endif
566 static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_WARNING);
567 return ostream;
568}
569
579template <typename C, typename T>
580std::basic_ostream<C, T>& info( std::basic_ostream<C, T>& ostream)
581{
582#if (__cplusplus >= 201402L)
583 if( ostream.pword( Log_stream::get_index()) == &ostream)
584#endif
585 static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_INFO);
586 return ostream;
587}
588
598template <typename C, typename T>
599std::basic_ostream<C, T>& verbose( std::basic_ostream<C, T>& ostream)
600{
601#if (__cplusplus >= 201402L)
602 if( ostream.pword( Log_stream::get_index()) == &ostream)
603#endif
604 static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_VERBOSE);
605 return ostream;
606}
607
617template <typename C, typename T>
618std::basic_ostream<C, T>& debug( std::basic_ostream<C, T>& ostream)
619{
620#if (__cplusplus >= 201402L)
621 if( ostream.pword( Log_stream::get_index()) == &ostream)
622#endif
623 static_cast<Log_stream&>( ostream).set_log_level( base::MESSAGE_SEVERITY_DEBUG);
624 return ostream;
625}
626
635template <typename C, typename T>
636std::basic_ostream<C, T>& operator<<( std::basic_ostream<C, T>& ostream, const Message_details& md)
637{
638#if (__cplusplus >= 201402L)
639 if( ostream.pword( Log_stream::get_index()) == &ostream)
640#endif
641 static_cast<Log_stream&>( ostream).set_details( md);
642 return ostream;
643}
644
645
646namespace msg {
647
648using namespace details;
649typedef Message_tag Tag;
650typedef Message_details Details;
651
652inline Details tag_details(const Uint32 tags)
653{
654 return Details().tag(tags);
655}
656
657inline Details device_details(
658 const Sint32 device=Details::DEVICE_ID_UNKNOWN_CUDA,
659 const Uint32 tags=TAG_NONE)
660{
661 return Details().tag(tags).device(device);
662}
663
664}
665 // end group mi_base_ilogger
667
668} // namespace base
669
670} // namespace mi
671
672#endif // MI_BASE_ILOGGER_H
Handle class template for interfaces, automatizing the lifetime control via reference counting.
Definition: handle.h:113
The ILogger interface class supports logging of messages.
Definition: ilogger.h:194
Mixin class template for deriving new interface declarations.
Definition: interface_declare.h:43
Adapts mi::base::ILogger to a standard streaming interface.
Definition: ilogger.h:390
Configuration of the Base API.
Basic enums.
static const Dup_interface DUP_INTERFACE
Symbolic constant to trigger a special constructor in the Handle class.
Definition: handle.h:37
bool is_device() const
Checks if this event pertains to a CUDA device or the CPU.
Definition: ilogger.h:116
std::basic_ostream<C, T> & operator<<(std::basic_ostream<C, T> &ostream, const Message_details &md)
Manipulator for mi::base::Log_stream.
Definition: ilogger.h:636
Uint32 host_id
The cluster ID of the host on which the message originated.
Definition: ilogger.h:84
Sint32 device_id
DEVICE_ID_XXX or a CUDA device ID.
Definition: ilogger.h:87
std::basic_ostream<C, T> & fatal(std::basic_ostream<C, T> &ostream)
Manipulator for mi::base::Log_stream.
Definition: ilogger.h:523
Message_severity
Constants for possible message severities.
Definition: enums.h:31
std::basic_ostream<C, T> & warning(std::basic_ostream<C, T> &ostream)
Manipulator for mi::base::Log_stream.
Definition: ilogger.h:561
Message_details & device(const Sint32 id)
Named constructor.
Definition: ilogger.h:135
Log_stream(ILogger *logger, const std::string &module_category, Message_severity default_level=MESSAGE_SEVERITY_INFO, const Message_details &default_details=Message_details())
Constructor.
Definition: ilogger.h:426
Uint32 message_id
An additional message identifier.
Definition: ilogger.h:95
std::basic_ostream<C, T> & verbose(std::basic_ostream<C, T> &ostream)
Manipulator for mi::base::Log_stream.
Definition: ilogger.h:599
Message_details & tag(const Uint32 t)
Named constructor.
Definition: ilogger.h:142
void printf(Message_severity level, const char *module_category, const Message_details &details, const char *message,...) __attribute__((format(printf
Emits a message to the application's log.
virtual void message(Message_severity level, const char *module_category, const Message_details &, const char *message)=0
Emits a message to the application's log.
Message_details & code(const Uint32 c)
Named constructor.
Definition: ilogger.h:157
bool is_tagged(const Uint32 required_tags) const
Checks if all required_tags are present.
Definition: ilogger.h:122
void printf(Message_severity level, const char *module_category, const char *message,...) __attribute__((format(printf
Emits a message to the application's log.
void set_log_level(Message_severity level)
Flushes the buffer if not empty, and sets the log level of the next message to the given log level.
Definition: ilogger.h:451
Uint32 tags
A set of tags.
Definition: ilogger.h:92
std::basic_ostream<C, T> & info(std::basic_ostream<C, T> &ostream)
Manipulator for mi::base::Log_stream.
Definition: ilogger.h:580
std::basic_ostream<C, T> & debug(std::basic_ostream<C, T> &ostream)
Manipulator for mi::base::Log_stream.
Definition: ilogger.h:618
std::basic_ostream<C, T> & error(std::basic_ostream<C, T> &ostream)
Manipulator for mi::base::Log_stream.
Definition: ilogger.h:542
Message_tag
Tags which help categorize log messages.
Definition: ilogger.h:45
Message_details & host(const Uint32 id)
Named constructor.
Definition: ilogger.h:128
Message_details & tag(const Uint32 t, const Uint32 code)
Named constructor.
Definition: ilogger.h:149
void set_details(const Message_details &details)
Flushes the buffer if not empty, and sets the message details of the next message.
Definition: ilogger.h:454
Log_stream(ILogger *logger, const char *module_category, Message_severity default_level=MESSAGE_SEVERITY_INFO, const Message_details &default_details=Message_details())
Constructor.
Definition: ilogger.h:401
virtual void message(Message_severity level, const char *module_category, const char *message)
Emits a message to the application's log.
Definition: ilogger.h:215
~Log_stream()
Destructor.
Definition: ilogger.h:444
@ MESSAGE_SEVERITY_FATAL
A fatal error has occurred.
Definition: enums.h:33
@ MESSAGE_SEVERITY_DEBUG
This is debug message.
Definition: enums.h:43
@ MESSAGE_SEVERITY_WARNING
A warning has occurred.
Definition: enums.h:37
@ MESSAGE_SEVERITY_INFO
This is a normal operational message.
Definition: enums.h:39
@ MESSAGE_SEVERITY_VERBOSE
This is a more verbose message.
Definition: enums.h:41
@ MESSAGE_SEVERITY_ERROR
An error has occurred.
Definition: enums.h:35
@ TAG_COMPATIBILITY
hardware or library compatibility
Definition: ilogger.h:47
@ TAG_FILE
File not found, etc.
Definition: ilogger.h:54
@ TAG_STATS
e.g. timing, memory usage
Definition: ilogger.h:55
@ TAG_API_USAGE
e.g. wrong order of operations
Definition: ilogger.h:50
@ TAG_UNAVAILABLE
device or resource not available; possibly temporary
Definition: ilogger.h:56
@ TAG_UNRECOVERABLE
unrecoverable issue, e.g. fatal CUDA errors
Definition: ilogger.h:48
@ TAG_MEMORY
memory resource
Definition: ilogger.h:53
@ TAG_SYSTEM_RESOURCE
non-memory, e.g. device assignment, disk space, ...
Definition: ilogger.h:52
@ TAG_NONE
no tags
Definition: ilogger.h:46
@ TAG_API_INPUT
e.g. invalid value
Definition: ilogger.h:49
@ TAG_VERSIONING
e.g. library version info, mismatch
Definition: ilogger.h:51
unsigned int Uint32
32-bit unsigned integer.
Definition: types.h:49
signed int Sint32
32-bit signed integer.
Definition: types.h:46
Smart-pointer handle class for interfaces, const and non-const version.
The basic extensible interface.
Mixin class template for deriving new interface declarations.
Common namespace for APIs of NVIDIA Advanced Rendering Center GmbH.
Definition: math.h:22
Structured details to log messages.
Definition: ilogger.h:71