6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24 #ifndef SHARE_VM_LOGGING_LOG_HPP
25 #define SHARE_VM_LOGGING_LOG_HPP
26 #include "logging/logLevel.hpp"
27 #include "logging/logPrefix.hpp"
28 #include "logging/logTagSet.hpp"
29 #include "logging/logTag.hpp"
30 #include "utilities/debug.hpp"
31 #include "utilities/ostream.hpp"
32
33 //
34 // Logging macros
35 //
36 // Usage:
37 // log_<level>(<comma separated log tags>)(<printf-style log arguments>);
38 // e.g.
39 // log_debug(logging)("message %d", i);
40 //
41 // Note that these macros will not evaluate the arguments unless the logging is enabled.
42 //
43 #define log_error(...) (!log_is_enabled(Error, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Error>
44 #define log_warning(...) (!log_is_enabled(Warning, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Warning>
45 #define log_info(...) (!log_is_enabled(Info, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Info>
46 #define log_debug(...) (!log_is_enabled(Debug, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Debug>
47 #define log_trace(...) (!log_is_enabled(Trace, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Trace>
48 #ifndef PRODUCT
49 #define log_develop(...) (!log_is_enabled(Develop, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Develop>
56 #define log_is_enabled(level, ...) (Log<LOG_TAGS(__VA_ARGS__)>::is_level(LogLevel::level))
57
58 //
59 // Log class for more advanced logging scenarios.
60 // Has printf-style member functions for each log level (trace(), debug(), etc).
61 //
62 // Also has outputStream compatible API for the different log-levels.
63 // The streams are resource allocated when requested and are accessed through
64 // calls to <level>_stream() functions (trace_stream(), debug_stream(), etc).
65 //
66 // Example usage:
67 // LogHandle(logging) log;
68 // if (log.is_debug()) {
69 // ...
70 // log.debug("result = %d", result).trace(" tracing info");
71 // obj->print_on(log.debug_stream());
72 // }
73 //
74 #define LogHandle(...) Log<LOG_TAGS(__VA_ARGS__)>
75
76 template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG, LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
77 class Log {
78 private:
79 static const size_t LogBufferSize = 512;
80 public:
81 // Make sure no more than the maximum number of tags have been given.
82 // The GuardTag allows this to be detected if/when it happens. If the GuardTag
83 // is not __NO_TAG, the number of tags given exceeds the maximum allowed.
84 STATIC_ASSERT(GuardTag == LogTag::__NO_TAG); // Number of logging tags exceeds maximum supported!
85
86 static bool is_level(LogLevelType level) {
87 return LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().is_level(level);
88 }
89
90 template <LogLevelType Level>
91 static void write(const char* fmt, ...) ATTRIBUTE_PRINTF(1, 2);
92
93 template <LogLevelType Level>
94 static void vwrite(const char* fmt, va_list args) ATTRIBUTE_PRINTF(1, 0);
95
96 #define LOG_LEVEL(level, name) ATTRIBUTE_PRINTF(2, 0) \
97 Log& v##name(const char* fmt, va_list args) { \
98 vwrite<LogLevel::level>(fmt, args); \
99 return *this; \
100 } \
101 Log& name(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3) { \
102 va_list args; \
103 va_start(args, fmt); \
104 vwrite<LogLevel::level>(fmt, args); \
105 va_end(args); \
106 return *this; \
107 } \
108 static bool is_##name() { \
109 return is_level(LogLevel::level); \
110 } \
111 static outputStream* name##_stream() { \
112 return new logStream(write<LogLevel::level>); \
113 }
114 LOG_LEVEL_LIST
115 #undef LOG_LEVEL
116 };
117
118 template <LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
119 template <LogLevelType Level>
120 void Log<T0, T1, T2, T3, T4, GuardTag>::write(const char* fmt, ...) {
121 va_list args;
122 va_start(args, fmt);
123 vwrite<Level>(fmt, args);
124 va_end(args);
125 }
126
127 template <LogTagType T0, LogTagType T1, LogTagType T2, LogTagType T3, LogTagType T4, LogTagType GuardTag>
128 template <LogLevelType Level>
129 void Log<T0, T1, T2, T3, T4, GuardTag>::vwrite(const char* fmt, va_list args) {
130 char buf[LogBufferSize];
131 size_t prefix_len = LogPrefix<T0, T1, T2, T3, T4>::prefix(buf, sizeof(buf));
132 int ret = vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
133 assert(ret >= 0 && (size_t)ret < sizeof(buf), "Log message too long");
134 LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().log(Level, buf);
135 }
136
137 #endif
|
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24 #ifndef SHARE_VM_LOGGING_LOG_HPP
25 #define SHARE_VM_LOGGING_LOG_HPP
26
27 #include "logging/logLevel.hpp"
28 #include "logging/logPrefix.hpp"
29 #include "logging/logTagSet.hpp"
30 #include "logging/logTag.hpp"
31 #include "memory/allocation.hpp"
32 #include "utilities/debug.hpp"
33 #include "utilities/ostream.hpp"
34
35 //
36 // Logging macros
37 //
38 // Usage:
39 // log_<level>(<comma separated log tags>)(<printf-style log arguments>);
40 // e.g.
41 // log_debug(logging)("message %d", i);
42 //
43 // Note that these macros will not evaluate the arguments unless the logging is enabled.
44 //
45 #define log_error(...) (!log_is_enabled(Error, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Error>
46 #define log_warning(...) (!log_is_enabled(Warning, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Warning>
47 #define log_info(...) (!log_is_enabled(Info, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Info>
48 #define log_debug(...) (!log_is_enabled(Debug, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Debug>
49 #define log_trace(...) (!log_is_enabled(Trace, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Trace>
50 #ifndef PRODUCT
51 #define log_develop(...) (!log_is_enabled(Develop, __VA_ARGS__)) ? (void)0 : Log<LOG_TAGS(__VA_ARGS__)>::write<LogLevel::Develop>
58 #define log_is_enabled(level, ...) (Log<LOG_TAGS(__VA_ARGS__)>::is_level(LogLevel::level))
59
60 //
61 // Log class for more advanced logging scenarios.
62 // Has printf-style member functions for each log level (trace(), debug(), etc).
63 //
64 // Also has outputStream compatible API for the different log-levels.
65 // The streams are resource allocated when requested and are accessed through
66 // calls to <level>_stream() functions (trace_stream(), debug_stream(), etc).
67 //
68 // Example usage:
69 // LogHandle(logging) log;
70 // if (log.is_debug()) {
71 // ...
72 // log.debug("result = %d", result).trace(" tracing info");
73 // obj->print_on(log.debug_stream());
74 // }
75 //
76 #define LogHandle(...) Log<LOG_TAGS(__VA_ARGS__)>
77
78 template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG, LogTagType T3 = LogTag::__NO_TAG,
79 LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
80 class Log VALUE_OBJ_CLASS_SPEC {
81 private:
82 static const size_t LogBufferSize = 512;
83 public:
84 // Make sure no more than the maximum number of tags have been given.
85 // The GuardTag allows this to be detected if/when it happens. If the GuardTag
86 // is not __NO_TAG, the number of tags given exceeds the maximum allowed.
87 STATIC_ASSERT(GuardTag == LogTag::__NO_TAG); // Number of logging tags exceeds maximum supported!
88
89 static bool is_level(LogLevelType level) {
90 return LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().is_level(level);
91 }
92
93 template <LogLevelType Level>
94 ATTRIBUTE_PRINTF(1, 2)
95 static void write(const char* fmt, ...) {
96 va_list args;
97 va_start(args, fmt);
98 vwrite<Level>(fmt, args);
99 va_end(args);
100 };
101
102 template <LogLevelType Level>
103 ATTRIBUTE_PRINTF(1, 0)
104 static void vwrite(const char* fmt, va_list args) {
105 char buf[LogBufferSize];
106 size_t prefix_len = LogPrefix<T0, T1, T2, T3, T4>::prefix(buf, sizeof(buf));
107 int ret = vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
108 assert(ret >= 0 && (size_t)ret < sizeof(buf), "Log message too long");
109 puts<Level>(buf);
110 }
111
112 template <LogLevelType Level>
113 static void puts(const char* string) {
114 LogTagSetMapping<T0, T1, T2, T3, T4>::tagset().log(Level, string);
115 }
116
117 #define LOG_LEVEL(level, name) ATTRIBUTE_PRINTF(2, 0) \
118 Log& v##name(const char* fmt, va_list args) { \
119 vwrite<LogLevel::level>(fmt, args); \
120 return *this; \
121 } \
122 Log& name(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3) { \
123 va_list args; \
124 va_start(args, fmt); \
125 vwrite<LogLevel::level>(fmt, args); \
126 va_end(args); \
127 return *this; \
128 } \
129 static bool is_##name() { \
130 return is_level(LogLevel::level); \
131 } \
132 static outputStream* name##_stream() { \
133 return new logStream(write<LogLevel::level>); \
134 }
135 LOG_LEVEL_LIST
136 #undef LOG_LEVEL
137 };
138
139 #endif // SHARE_VM_LOGGING_LOG_HPP
|