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 22namespace v8 { 23 24namespace base { 25template <typename T> 26class Vector; 27} // namespace base 28 29namespace internal { 30 31class Logger; 32 33enum class LogSeparator { kSeparator }; 34 35// Functions and data for performing output of log messages. 36class 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); 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 137template <> 138Log::MessageBuilder& Log::MessageBuilder::operator<<<LogSeparator>( 139 LogSeparator separator); 140template <> 141Log::MessageBuilder& Log::MessageBuilder::operator<<<void*>(void* pointer); 142template <> 143Log::MessageBuilder& Log::MessageBuilder::operator<<<const char*>( 144 const char* string); 145template <> 146Log::MessageBuilder& Log::MessageBuilder::operator<<<char>(char c); 147template <> 148Log::MessageBuilder& Log::MessageBuilder::operator<<<String>(String string); 149template <> 150Log::MessageBuilder& Log::MessageBuilder::operator<<<Symbol>(Symbol symbol); 151template <> 152Log::MessageBuilder& Log::MessageBuilder::operator<<<Name>(Name name); 153 154} // namespace internal 155} // namespace v8 156 157#endif // V8_LOGGING_LOG_UTILS_H_ 158