logMessageBuffer.hpp revision 11209:c84a6ce067ad
184865Sobrien/* 284865Sobrien * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 384865Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 484865Sobrien * 584865Sobrien * This code is free software; you can redistribute it and/or modify it 684865Sobrien * under the terms of the GNU General Public License version 2 only, as 784865Sobrien * published by the Free Software Foundation. 884865Sobrien * 984865Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT 1084865Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1184865Sobrien * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1284865Sobrien * version 2 for more details (a copy is included in the LICENSE file that 1384865Sobrien * accompanied this code). 1484865Sobrien * 1584865Sobrien * You should have received a copy of the GNU General Public License version 1684865Sobrien * 2 along with this work; if not, write to the Free Software Foundation, 1784865Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1884865Sobrien * 19218822Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20218822Sdim * or visit www.oracle.com if you need additional information or have any 2184865Sobrien * questions. 2284865Sobrien * 2384865Sobrien */ 2484865Sobrien#ifndef SHARE_VM_LOGGING_LOGMESSAGEBUFFER_HPP 2584865Sobrien#define SHARE_VM_LOGGING_LOGMESSAGEBUFFER_HPP 2684865Sobrien 2784865Sobrien#include "logging/logDecorations.hpp" 2884865Sobrien#include "logging/logLevel.hpp" 2984865Sobrien#include "memory/allocation.hpp" 3084865Sobrien 3184865Sobrienclass LogMessageBuffer : public StackObj { 3284865Sobrien friend class LogMessageTest; 3384865Sobrien protected: 3484865Sobrien struct LogLine VALUE_OBJ_CLASS_SPEC { 3584865Sobrien LogLevelType level; 3684865Sobrien size_t message_offset; 3784865Sobrien }; 3884865Sobrien static const size_t InitialLineCapacity = 10; 3984865Sobrien static const size_t InitialMessageBufferCapacity = 1024; 4084865Sobrien 4184865Sobrien size_t _message_buffer_size; 4284865Sobrien size_t _message_buffer_capacity; 4384865Sobrien char* _message_buffer; 4484865Sobrien 4584865Sobrien size_t _line_count; 4684865Sobrien size_t _line_capacity; 4784865Sobrien LogLine* _lines; 4884865Sobrien 4984865Sobrien bool _allocated; 5084865Sobrien LogLevelType _least_detailed_level; 5184865Sobrien size_t (*_prefix_fn)(char*, size_t); 5284865Sobrien 5384865Sobrien void initialize_buffers(); 5484865Sobrien 5584865Sobrien private: 5684865Sobrien // Forbid copy assignment and copy constructor. 5784865Sobrien void operator=(const LogMessageBuffer& ref) {} 5884865Sobrien LogMessageBuffer(const LogMessageBuffer& ref) {} 5984865Sobrien 6084865Sobrien public: 6184865Sobrien LogMessageBuffer(); 6284865Sobrien ~LogMessageBuffer(); 6384865Sobrien 6484865Sobrien class Iterator { 6584865Sobrien private: 6684865Sobrien const LogMessageBuffer& _message; 6784865Sobrien size_t _current_line_index; 6884865Sobrien LogLevelType _level; 6984865Sobrien LogDecorations &_decorations; 7084865Sobrien 7184865Sobrien void skip_messages_with_finer_level(); 7284865Sobrien 7384865Sobrien public: 7484865Sobrien Iterator(const LogMessageBuffer& message, LogLevelType level, LogDecorations& decorations) 7584865Sobrien : _message(message), _level(level), _decorations(decorations), _current_line_index(0) { 7684865Sobrien skip_messages_with_finer_level(); 7784865Sobrien } 7884865Sobrien 7984865Sobrien void operator++(int) { 8084865Sobrien _current_line_index++; 8184865Sobrien skip_messages_with_finer_level(); 8284865Sobrien } 8384865Sobrien 8484865Sobrien bool is_at_end() { 8584865Sobrien return _current_line_index == _message._line_count; 8684865Sobrien } 8784865Sobrien 8884865Sobrien const char* message() const { 8984865Sobrien return _message._message_buffer + _message._lines[_current_line_index].message_offset; 9084865Sobrien } 9184865Sobrien 9284865Sobrien const LogDecorations& decorations() { 9384865Sobrien _decorations.set_level(_message._lines[_current_line_index].level); 9484865Sobrien return _decorations; 9584865Sobrien } 9684865Sobrien }; 9784865Sobrien 9884865Sobrien void reset(); 9984865Sobrien 10084865Sobrien LogLevelType least_detailed_level() const { 10184865Sobrien return _least_detailed_level; 10284865Sobrien } 10384865Sobrien 10484865Sobrien Iterator iterator(LogLevelType level, LogDecorations& decorations) const { 10584865Sobrien return Iterator(*this, level, decorations); 10684865Sobrien } 10784865Sobrien 10884865Sobrien // Lines in LogMessageBuffers are not automatically prefixed based on tags 10984865Sobrien // like regular simple messages (see LogPrefix.hpp for more about prefixes). 11084865Sobrien // It is, however, possible to specify a prefix per LogMessageBuffer, 11184865Sobrien // using set_prefix(). Lines added to the LogMessageBuffer after a prefix 11284865Sobrien // function has been set will be prefixed automatically. 11384865Sobrien // Setting this to NULL will disable prefixing. 11484865Sobrien void set_prefix(size_t (*prefix_fn)(char*, size_t)) { 11584865Sobrien _prefix_fn = prefix_fn; 11684865Sobrien } 11784865Sobrien 11884865Sobrien ATTRIBUTE_PRINTF(3, 4) 11984865Sobrien void write(LogLevelType level, const char* fmt, ...); 12084865Sobrien 12184865Sobrien ATTRIBUTE_PRINTF(3, 0) 12284865Sobrien virtual void vwrite(LogLevelType level, const char* fmt, va_list args); 12384865Sobrien 12484865Sobrien#define LOG_LEVEL(level, name) \ 12584865Sobrien LogMessageBuffer& v##name(const char* fmt, va_list args) ATTRIBUTE_PRINTF(2, 0); \ 12684865Sobrien LogMessageBuffer& name(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3); 12784865Sobrien LOG_LEVEL_LIST 12884865Sobrien#undef LOG_LEVEL 12984865Sobrien}; 13084865Sobrien 13184865Sobrien#endif // SHARE_VM_LOGGING_LOGMESSAGEBUFFER_HPP 13284865Sobrien