< prev index next >

src/share/vm/logging/logMessage.hpp

Print this page
rev 10535 : [mq]: 8145934
rev 10536 : [mq]: 8145934.alternative
rev 10537 : [mq]: 8145934.02


  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 #ifndef SHARE_VM_LOGGING_LOGMESSAGE_HPP
  25 #define SHARE_VM_LOGGING_LOGMESSAGE_HPP
  26 
  27 #include "logging/log.hpp"
  28 #include "logging/logMessageBuffer.hpp"
  29 #include "logging/logPrefix.hpp"
  30 #include "logging/logTag.hpp"
  31 
  32 // The LogMessage class represents a multi-part/multi-line message
  33 // that is guaranteed to be sent and written to the log outputs
  34 // in a way that prevents interleaving by other log messages.
  35 //
  36 // The interface of LogMessage is very similar to the Log class,
  37 // with printf functions for each level (trace(), debug(), etc).
  38 // The difference is that these functions will append/write to the
  39 // LogMessage, which only buffers the message-parts until the whole
  40 // message is sent to a log (using Log::write). If TLS has been
  41 // initialized, messages will be resource allocated, otherwise
  42 // they will be C heap allocated.
  43 //
  44 // Example usage:
  45 //
  46 // {
  47 //   LogMessage(logging) msg;
  48 //   if (msg.is_debug()) {
  49 //     ResourceMark rm;
  50 //     msg.debug("debug message");
  51 //     msg.trace("additional trace information");
  52 //   }
  53 // }
  54 //
  55 // Log outputs on trace level will see both of the messages above,
  56 // and the trace line will immediately follow the debug line.
  57 // They will have identical decorations (apart from level).
  58 // Log outputs on debug level will see the debug message,
  59 // but not the trace message.
  60 //
  61 #define LogMessage(...) ScopedLogMessage<LOG_TAGS(__VA_ARGS__)>
  62 template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG,
  63           LogTagType T3 = LogTag::__NO_TAG, LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
  64 class ScopedLogMessage : public LogMessageBuffer {
  65  private:
  66   Log<T0, T1, T2, T3, T4> _log;

  67 
  68  public:
  69   ScopedLogMessage() {
  70     set_prefix(LogPrefix<T0, T1, T2, T3, T4>::prefix);
  71   }
  72 
  73   ~ScopedLogMessage() {
  74     if (_line_count > 0) {





  75       _log.write(*this);













  76     }

  77   }
  78 
  79 #define LOG_LEVEL(level, name) \
  80   bool is_##name() const { \
  81     return _log.is_level(LogLevel::level); \
  82   }
  83   LOG_LEVEL_LIST
  84 #undef LOG_LEVEL
  85 };
  86 
  87 #endif // SHARE_VM_LOGGING_LOGMESSAGE_HPP


  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 #ifndef SHARE_VM_LOGGING_LOGMESSAGE_HPP
  25 #define SHARE_VM_LOGGING_LOGMESSAGE_HPP
  26 
  27 #include "logging/log.hpp"
  28 #include "logging/logMessageBuffer.hpp"
  29 #include "logging/logPrefix.hpp"
  30 #include "logging/logTag.hpp"
  31 
  32 // The LogMessage class represents a multi-part/multi-line message
  33 // that is guaranteed to be sent and written to the log outputs
  34 // in a way that prevents interleaving by other log messages.
  35 //
  36 // The interface of LogMessage is very similar to the Log class,
  37 // with printf functions for each level (trace(), debug(), etc).
  38 // The difference is that these functions will append/write to the
  39 // LogMessage, which only buffers the message-parts until the whole
  40 // message is sent to a log (using Log::write). Internal buffers
  41 // are C heap allocated lazily on first write. LogMessages are
  42 // automatically written when they go out of scope.
  43 //
  44 // Example usage:
  45 //
  46 // {
  47 //   LogMessage(logging) msg;
  48 //   if (msg.is_debug()) {

  49 //     msg.debug("debug message");
  50 //     msg.trace("additional trace information");
  51 //   }
  52 // }
  53 //
  54 // Log outputs on trace level will see both of the messages above,
  55 // and the trace line will immediately follow the debug line.
  56 // They will have identical decorations (apart from level).
  57 // Log outputs on debug level will see the debug message,
  58 // but not the trace message.
  59 //
  60 #define LogMessage(...) ScopedLogMessage<LOG_TAGS(__VA_ARGS__)>
  61 template <LogTagType T0, LogTagType T1 = LogTag::__NO_TAG, LogTagType T2 = LogTag::__NO_TAG,
  62           LogTagType T3 = LogTag::__NO_TAG, LogTagType T4 = LogTag::__NO_TAG, LogTagType GuardTag = LogTag::__NO_TAG>
  63 class ScopedLogMessage : public LogMessageBuffer {
  64  private:
  65   Log<T0, T1, T2, T3, T4> _log;
  66   bool _has_content;
  67 
  68  public:
  69   ScopedLogMessage() : _has_content(false) {

  70   }
  71 
  72   ~ScopedLogMessage() {
  73     if (_has_content) {
  74       flush();
  75     }
  76   }
  77 
  78   void flush() {
  79     _log.write(*this);
  80     reset();
  81   }
  82 
  83   void reset() {
  84     _has_content = false;
  85     LogMessageBuffer::reset();
  86   }
  87 
  88   ATTRIBUTE_PRINTF(3, 0)
  89   void vwrite(LogLevelType level, const char* fmt, va_list args) {
  90     if (!_has_content) {
  91       _has_content = true;
  92       set_prefix(LogPrefix<T0, T1, T2, T3, T4>::prefix);
  93     }
  94     LogMessageBuffer::vwrite(level, fmt, args);
  95   }
  96 
  97 #define LOG_LEVEL(level, name) \
  98   bool is_##name() const { \
  99     return _log.is_level(LogLevel::level); \
 100   }
 101   LOG_LEVEL_LIST
 102 #undef LOG_LEVEL
 103 };
 104 
 105 #endif // SHARE_VM_LOGGING_LOGMESSAGE_HPP
< prev index next >