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