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