Skip to content

Commit 6cf9b34

Browse files
committed
logging: Limit early logging buffer
Log messages created prior to StartLogging() being called go into a buffer. Enforce a limit on the size of this buffer.
1 parent 0b1960f commit 6cf9b34

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/logging.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

66
#include <logging.h>
7+
#include <memusage.h>
78
#include <util/fs.h>
89
#include <util/string.h>
910
#include <util/threadnames.h>
@@ -71,6 +72,9 @@ bool BCLog::Logger::StartLogging()
7172

7273
// dump buffered messages from before we opened the log
7374
m_buffering = false;
75+
if (m_buffer_lines_discarded > 0) {
76+
LogPrintStr_(strprintf("Early logging buffer overflowed, %d log lines discarded.\n", m_buffer_lines_discarded), __func__, __FILE__, __LINE__, BCLog::ALL, Level::Info);
77+
}
7478
while (!m_msgs_before_open.empty()) {
7579
const std::string& s = m_msgs_before_open.front();
7680

@@ -82,6 +86,7 @@ bool BCLog::Logger::StartLogging()
8286

8387
m_msgs_before_open.pop_front();
8488
}
89+
m_cur_buffer_memusage = 0;
8590
if (m_print_to_console) fflush(stdout);
8691

8792
return true;
@@ -94,6 +99,11 @@ void BCLog::Logger::DisconnectTestLogger()
9499
if (m_fileout != nullptr) fclose(m_fileout);
95100
m_fileout = nullptr;
96101
m_print_callbacks.clear();
102+
m_max_buffer_memusage = DEFAULT_MAX_LOG_BUFFER;
103+
m_cur_buffer_memusage = 0;
104+
m_buffer_lines_discarded = 0;
105+
m_msgs_before_open.clear();
106+
97107
}
98108

99109
void BCLog::Logger::DisableLogging()
@@ -362,9 +372,19 @@ std::string BCLog::Logger::GetLogPrefix(BCLog::LogFlags category, BCLog::Level l
362372
return s;
363373
}
364374

375+
static size_t MemUsage(const std::string& str)
376+
{
377+
return str.size() + memusage::MallocUsage(sizeof(memusage::list_node<std::string>));
378+
}
379+
365380
void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level)
366381
{
367382
StdLockGuard scoped_lock(m_cs);
383+
return LogPrintStr_(str, logging_function, source_file, source_line, category, level);
384+
}
385+
386+
void BCLog::Logger::LogPrintStr_(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level)
387+
{
368388
std::string str_prefixed = LogEscapeMessage(str);
369389

370390
if (m_started_new_line) {
@@ -387,6 +407,17 @@ void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& loggi
387407
if (m_buffering) {
388408
// buffer if we haven't started logging yet
389409
m_msgs_before_open.push_back(str_prefixed);
410+
411+
m_cur_buffer_memusage += MemUsage(str_prefixed);
412+
while (m_cur_buffer_memusage > m_max_buffer_memusage) {
413+
if (m_msgs_before_open.empty()) {
414+
m_cur_buffer_memusage = 0;
415+
break;
416+
}
417+
m_cur_buffer_memusage -= MemUsage(m_msgs_before_open.front());
418+
m_msgs_before_open.pop_front();
419+
++m_buffer_lines_discarded;
420+
}
390421
return;
391422
}
392423

src/logging.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ namespace BCLog {
7979
Error,
8080
};
8181
constexpr auto DEFAULT_LOG_LEVEL{Level::Debug};
82+
constexpr size_t DEFAULT_MAX_LOG_BUFFER{1'000'000}; // buffer up to 1MB of log data prior to StartLogging
8283

8384
class Logger
8485
{
@@ -88,6 +89,9 @@ namespace BCLog {
8889
FILE* m_fileout GUARDED_BY(m_cs) = nullptr;
8990
std::list<std::string> m_msgs_before_open GUARDED_BY(m_cs);
9091
bool m_buffering GUARDED_BY(m_cs) = true; //!< Buffer messages before logging can be started.
92+
size_t m_max_buffer_memusage GUARDED_BY(m_cs){DEFAULT_MAX_LOG_BUFFER};
93+
size_t m_cur_buffer_memusage GUARDED_BY(m_cs){0};
94+
size_t m_buffer_lines_discarded GUARDED_BY(m_cs){0};
9195

9296
/**
9397
* m_started_new_line is a state variable that will suppress printing of
@@ -111,6 +115,10 @@ namespace BCLog {
111115
/** Slots that connect to the print signal */
112116
std::list<std::function<void(const std::string&)>> m_print_callbacks GUARDED_BY(m_cs) {};
113117

118+
/** Send a string to the log output (internal) */
119+
void LogPrintStr_(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level)
120+
EXCLUSIVE_LOCKS_REQUIRED(m_cs);
121+
114122
public:
115123
bool m_print_to_console = false;
116124
bool m_print_to_file = false;

0 commit comments

Comments
 (0)