1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_LOGGING_LOG_UTILS_H_ 6 #define V8_LOGGING_LOG_UTILS_H_ 7 8 #include <stdio.h> 9 10 #include <atomic> 11 #include <cstdarg> 12 #include <memory> 13 14 #include "src/base/compiler-specific.h" 15 #include "src/base/optional.h" 16 #include "src/base/platform/mutex.h" 17 #include "src/common/assert-scope.h" 18 #include "src/flags/flags.h" 19 #include "src/utils/allocation.h" 20 #include "src/utils/ostreams.h" 21 22 namespace v8 { 23 24 namespace base { 25 template <typename T> 26 class Vector; 27 } // namespace base 28 29 namespace internal { 30 31 class Logger; 32 33 enum class LogSeparator { kSeparator }; 34 35 // Functions and data for performing output of log messages. 36 class Log { 37 public: 38 explicit Log(Logger* logger, std::string log_file_name); 39 40 V8_EXPORT_PRIVATE static bool IsLoggingToConsole(std::string file_name); 41 V8_EXPORT_PRIVATE static bool IsLoggingToTemporaryFile(std::string file_name); 42 43 // Frees all resources acquired in Initialize and Open... functions. 44 // When a temporary file is used for the log, returns its stream descriptor, 45 // leaving the file open. 46 FILE* Close(); 47 48 std::string file_name() const; 49 50 // Size of buffer used for formatting log messages. 51 static const int kMessageBufferSize = 2048; 52 53 // This mode is only used in tests, as temporary files are automatically 54 // deleted on close and thus can't be accessed afterwards. 55 V8_EXPORT_PRIVATE static const char* const kLogToTemporaryFile; 56 static const char* const kLogToConsole; 57 58 // Utility class for formatting log messages. It escapes the given messages 59 // and then appends them to the static buffer in Log. 60 class MessageBuilder { 61 public: 62 ~MessageBuilder() = default; 63 64 void AppendString(String str, 65 base::Optional<int> length_limit = base::nullopt); 66 void AppendString(base::Vector<const char> str); 67 void AppendString(const char* str); 68 void AppendString(const char* str, size_t length, bool is_one_byte = true); 69 void PRINTF_FORMAT(2, 3) AppendFormatString(const char* format, ...); 70 void AppendCharacter(char c); 71 void AppendTwoByteCharacter(char c1, char c2); 72 void AppendSymbolName(Symbol symbol); 73 74 // Delegate insertion to the underlying {log_}. 75 // All appended strings are escaped to maintain one-line log entries. 76 template <typename T> 77 MessageBuilder& operator<<(T value) { 78 log_->os_ << value; 79 return *this; 80 } 81 82 // Finish the current log line an flush the it to the log file. 83 void WriteToLogFile(); 84 85 private: 86 // Create a message builder starting from position 0. 87 // This acquires the mutex in the log as well. 88 explicit MessageBuilder(Log* log); 89 90 // Prints the format string into |log_->format_buffer_|. Returns the length 91 // of the result, or kMessageBufferSize if it was truncated. 92 int PRINTF_FORMAT(2, 0) 93 FormatStringIntoBuffer(const char* format, va_list args); 94 95 void AppendSymbolNameDetails(String str, bool show_impl_info); 96 97 void PRINTF_FORMAT(2, 3) AppendRawFormatString(const char* format, ...); 98 void AppendRawCharacter(const char character); 99 100 Log* log_; 101 NoGarbageCollectionMutexGuard lock_guard_; 102 103 friend class Log; 104 }; 105 106 // Use this method to create an instance of Log::MessageBuilder. This method 107 // will return null if logging is disabled. 108 std::unique_ptr<Log::MessageBuilder> NewMessageBuilder(); 109 110 private: 111 static FILE* CreateOutputHandle(std::string file_name); mutex()112 base::Mutex* mutex() { return &mutex_; } 113 114 void WriteLogHeader(); 115 116 Logger* logger_; 117 118 std::string file_name_; 119 120 // When logging is active output_handle_ is used to store a pointer to log 121 // destination. mutex_ should be acquired before using output_handle_. 122 FILE* output_handle_; 123 124 OFStream os_; 125 126 // mutex_ is a Mutex used for enforcing exclusive 127 // access to the formatting buffer and the log file or log memory buffer. 128 base::Mutex mutex_; 129 130 // Buffer used for formatting log messages. This is a singleton buffer and 131 // mutex_ should be acquired before using it. 132 std::unique_ptr<char[]> format_buffer_; 133 134 friend class Logger; 135 }; 136 137 template <> 138 Log::MessageBuilder& Log::MessageBuilder::operator<<<LogSeparator>( 139 LogSeparator separator); 140 template <> 141 Log::MessageBuilder& Log::MessageBuilder::operator<<<void*>(void* pointer); 142 template <> 143 Log::MessageBuilder& Log::MessageBuilder::operator<<<const char*>( 144 const char* string); 145 template <> 146 Log::MessageBuilder& Log::MessageBuilder::operator<<<char>(char c); 147 template <> 148 Log::MessageBuilder& Log::MessageBuilder::operator<<<String>(String string); 149 template <> 150 Log::MessageBuilder& Log::MessageBuilder::operator<<<Symbol>(Symbol symbol); 151 template <> 152 Log::MessageBuilder& Log::MessageBuilder::operator<<<Name>(Name name); 153 154 } // namespace internal 155 } // namespace v8 156 157 #endif // V8_LOGGING_LOG_UTILS_H_ 158