71 // LogHandle(logging) log; 72 // if (log.is_debug()) { 73 // ... 74 // log.debug("result = %d", result).trace(" tracing info"); 75 // obj->print_on(log.debug_stream()); 76 // } 77 // 78 #define LogHandle(...) Log<LOG_TAGS(__VA_ARGS__)> 79 80 template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG, 81 LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG> 82 class Log VALUE_OBJ_CLASS_SPEC { 83 private: 84 static const size_t LogBufferSize = 512; 85 public: 86 // Make sure no more than the maximum number of tags have been given. 87 // The GuardTag allows this to be detected if/when it happens. If the GuardTag 88 // is not __NO_TAG, the number of tags given exceeds the maximum allowed. 89 STATIC_ASSERT(GuardTag == LogTag::__NO_TAG); // Number of logging tags exceeds maximum supported! 90 91 static bool is_level(LogLevelType level) { 92 return LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().is_level(level); 93 } 94 95 template <LogLevelType Level> 96 ATTRIBUTE_PRINTF(1, 2) 97 static void write(const char* fmt, ...) { 98 va_list args; 99 va_start(args, fmt); 100 vwrite<Level>(fmt, args); 101 va_end(args); 102 }; 103 104 template <LogLevelType Level> 105 ATTRIBUTE_PRINTF(1, 0) 106 static void vwrite(const char* fmt, va_list args) { 107 char buf[LogBufferSize]; 108 size_t prefix_len = LogPrefix<T0, T1, T2, T3, T4>::prefix(buf, sizeof(buf)); 109 // Check that string fits in buffer; resize buffer if necessary 110 int ret = os::log_vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args); | 71 // LogHandle(logging) log; 72 // if (log.is_debug()) { 73 // ... 74 // log.debug("result = %d", result).trace(" tracing info"); 75 // obj->print_on(log.debug_stream()); 76 // } 77 // 78 #define LogHandle(...) Log<LOG_TAGS(__VA_ARGS__)> 79 80 template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG, 81 LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG> 82 class Log VALUE_OBJ_CLASS_SPEC { 83 private: 84 static const size_t LogBufferSize = 512; 85 public: 86 // Make sure no more than the maximum number of tags have been given. 87 // The GuardTag allows this to be detected if/when it happens. If the GuardTag 88 // is not __NO_TAG, the number of tags given exceeds the maximum allowed. 89 STATIC_ASSERT(GuardTag == LogTag::__NO_TAG); // Number of logging tags exceeds maximum supported! 90 91 Log() {} 92 93 static bool is_level(LogLevelType level) { 94 return LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().is_level(level); 95 } 96 97 template <LogLevelType Level> 98 ATTRIBUTE_PRINTF(1, 2) 99 static void write(const char* fmt, ...) { 100 va_list args; 101 va_start(args, fmt); 102 vwrite<Level>(fmt, args); 103 va_end(args); 104 }; 105 106 template <LogLevelType Level> 107 ATTRIBUTE_PRINTF(1, 0) 108 static void vwrite(const char* fmt, va_list args) { 109 char buf[LogBufferSize]; 110 size_t prefix_len = LogPrefix<T0, T1, T2, T3, T4>::prefix(buf, sizeof(buf)); 111 // Check that string fits in buffer; resize buffer if necessary 112 int ret = os::log_vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args); |