Path: blob/master/src/hotspot/share/logging/logMessage.hpp
40930 views
/*1* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/23#ifndef SHARE_LOGGING_LOGMESSAGE_HPP24#define SHARE_LOGGING_LOGMESSAGE_HPP2526#include "logging/log.hpp"27#include "logging/logMessageBuffer.hpp"28#include "logging/logPrefix.hpp"29#include "logging/logTag.hpp"3031// The LogMessage class represents a multi-part/multi-line message32// that is guaranteed to be sent and written to the log outputs33// in a way that prevents interleaving by other log messages.34//35// The interface of LogMessage is very similar to the Log class,36// with printf functions for each level (trace(), debug(), etc).37// The difference is that these functions will append/write to the38// LogMessage, which only buffers the message-parts until the whole39// message is sent to a log (using Log::write). Internal buffers40// are C heap allocated lazily on first write. LogMessages are41// automatically written when they go out of scope.42//43// Example usage:44//45// {46// LogMessage(logging) msg;47// if (msg.is_debug()) {48// msg.debug("debug message");49// msg.trace("additional trace information");50// }51// }52//53// Log outputs on trace level will see both of the messages above,54// and the trace line will immediately follow the debug line.55// They will have identical decorations (apart from level).56// Log outputs on debug level will see the debug message,57// but not the trace message.58//59#define LogMessage(...) LogMessageImpl<LOG_TAGS(__VA_ARGS__)>60template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG,61LogTagType T3 = LogTag::__NO_TAG, LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>62class LogMessageImpl : public LogMessageBuffer {63private:64LogImpl<T0, T1, T2, T3, T4, GuardTag> _log;65bool _has_content;6667public:68LogMessageImpl() : _has_content(false) {69}7071~LogMessageImpl() {72if (_has_content) {73flush();74}75}7677void flush() {78_log.write(*this);79reset();80}8182void reset() {83_has_content = false;84LogMessageBuffer::reset();85}8687ATTRIBUTE_PRINTF(3, 0)88void vwrite(LogLevelType level, const char* fmt, va_list args) {89if (!_has_content) {90_has_content = true;91set_prefix(LogPrefix<T0, T1, T2, T3, T4>::prefix);92}93LogMessageBuffer::vwrite(level, fmt, args);94}9596#define LOG_LEVEL(level, name) \97bool is_##name() const { \98return _log.is_level(LogLevel::level); \99}100LOG_LEVEL_LIST101#undef LOG_LEVEL102};103104#endif // SHARE_LOGGING_LOGMESSAGE_HPP105106107