@@ -76,15 +76,16 @@ bool BCLog::Logger::StartLogging()
76
76
LogPrintStr_ (strprintf (" Early logging buffer overflowed, %d log lines discarded.\n " , m_buffer_lines_discarded), __func__, __FILE__, __LINE__, BCLog::ALL, Level::Info);
77
77
}
78
78
while (!m_msgs_before_open.empty ()) {
79
- const std::string& s = m_msgs_before_open.front ();
79
+ const auto & buflog = m_msgs_before_open.front ();
80
+ std::string s{buflog.str };
81
+ FormatLogStrInPlace (s, buflog.category , buflog.level , buflog.source_file , buflog.source_line , buflog.logging_function , buflog.threadname , buflog.now , buflog.mocktime );
82
+ m_msgs_before_open.pop_front ();
80
83
81
84
if (m_print_to_file) FileWriteStr (s, m_fileout);
82
85
if (m_print_to_console) fwrite (s.data (), 1 , s.size (), stdout);
83
86
for (const auto & cb : m_print_callbacks) {
84
87
cb (s);
85
88
}
86
-
87
- m_msgs_before_open.pop_front ();
88
89
}
89
90
m_cur_buffer_memusage = 0 ;
90
91
if (m_print_to_console) fflush (stdout);
@@ -298,28 +299,23 @@ std::string BCLog::Logger::LogLevelsString() const
298
299
return Join (std::vector<BCLog::Level>{levels.begin (), levels.end ()}, " , " , [](BCLog::Level level) { return LogLevelToStr (level); });
299
300
}
300
301
301
- std::string BCLog::Logger::LogTimestampStr (const std::string& str)
302
+ std::string BCLog::Logger::LogTimestampStr (SystemClock::time_point now, std::chrono::seconds mocktime) const
302
303
{
303
304
std::string strStamped;
304
305
305
306
if (!m_log_timestamps)
306
- return str;
307
-
308
- if (m_started_new_line) {
309
- const auto now{SystemClock::now ()};
310
- const auto now_seconds{std::chrono::time_point_cast<std::chrono::seconds>(now)};
311
- strStamped = FormatISO8601DateTime (TicksSinceEpoch<std::chrono::seconds>(now_seconds));
312
- if (m_log_time_micros && !strStamped.empty ()) {
313
- strStamped.pop_back ();
314
- strStamped += strprintf (" .%06dZ" , Ticks<std::chrono::microseconds>(now - now_seconds));
315
- }
316
- std::chrono::seconds mocktime = GetMockTime ();
317
- if (mocktime > 0s) {
318
- strStamped += " (mocktime: " + FormatISO8601DateTime (count_seconds (mocktime)) + " )" ;
319
- }
320
- strStamped += ' ' + str;
321
- } else
322
- strStamped = str;
307
+ return strStamped;
308
+
309
+ const auto now_seconds{std::chrono::time_point_cast<std::chrono::seconds>(now)};
310
+ strStamped = FormatISO8601DateTime (TicksSinceEpoch<std::chrono::seconds>(now_seconds));
311
+ if (m_log_time_micros && !strStamped.empty ()) {
312
+ strStamped.pop_back ();
313
+ strStamped += strprintf (" .%06dZ" , Ticks<std::chrono::microseconds>(now - now_seconds));
314
+ }
315
+ if (mocktime > 0s) {
316
+ strStamped += " (mocktime: " + FormatISO8601DateTime (count_seconds (mocktime)) + " )" ;
317
+ }
318
+ strStamped += ' ' ;
323
319
324
320
return strStamped;
325
321
}
@@ -372,9 +368,24 @@ std::string BCLog::Logger::GetLogPrefix(BCLog::LogFlags category, BCLog::Level l
372
368
return s;
373
369
}
374
370
375
- static size_t MemUsage (const std::string& str )
371
+ static size_t MemUsage (const BCLog::Logger::BufferedLog& buflog )
376
372
{
377
- return str.size () + memusage::MallocUsage (sizeof (memusage::list_node<std::string>));
373
+ return buflog.str .size () + buflog.logging_function .size () + buflog.source_file .size () + buflog.threadname .size () + memusage::MallocUsage (sizeof (memusage::list_node<BCLog::Logger::BufferedLog>));
374
+ }
375
+
376
+ void BCLog::Logger::FormatLogStrInPlace (std::string& str, BCLog::LogFlags category, BCLog::Level level, const std::string& source_file, int source_line, const std::string& logging_function, const std::string& threadname, SystemClock::time_point now, std::chrono::seconds mocktime) const
377
+ {
378
+ str.insert (0 , GetLogPrefix (category, level));
379
+
380
+ if (m_log_sourcelocations) {
381
+ str.insert (0 , " [" + RemovePrefix (source_file, " ./" ) + " :" + ToString (source_line) + " ] [" + logging_function + " ] " );
382
+ }
383
+
384
+ if (m_log_threadnames) {
385
+ str.insert (0 , " [" + (threadname.empty () ? " unknown" : threadname) + " ] " );
386
+ }
387
+
388
+ str.insert (0 , LogTimestampStr (now, mocktime));
378
389
}
379
390
380
391
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,28 +398,37 @@ void BCLog::Logger::LogPrintStr_(const std::string& str, const std::string& logg
387
398
{
388
399
std::string str_prefixed = LogEscapeMessage (str);
389
400
390
- if (m_started_new_line) {
391
- str_prefixed.insert (0 , GetLogPrefix (category, level));
392
- }
393
-
394
- if (m_log_sourcelocations && m_started_new_line) {
395
- str_prefixed.insert (0 , " [" + RemovePrefix (source_file, " ./" ) + " :" + ToString (source_line) + " ] [" + logging_function + " ] " );
396
- }
397
-
398
- if (m_log_threadnames && m_started_new_line) {
399
- const auto & threadname = util::ThreadGetInternalName ();
400
- str_prefixed.insert (0 , " [" + (threadname.empty () ? " unknown" : threadname) + " ] " );
401
- }
402
-
403
- str_prefixed = LogTimestampStr (str_prefixed);
404
-
401
+ const bool starts_new_line = m_started_new_line;
405
402
m_started_new_line = !str.empty () && str[str.size ()-1 ] == ' \n ' ;
406
403
407
404
if (m_buffering) {
408
- // buffer if we haven't started logging yet
409
- m_msgs_before_open.push_back (str_prefixed);
405
+ if (!starts_new_line) {
406
+ if (!m_msgs_before_open.empty ()) {
407
+ m_msgs_before_open.back ().str += str_prefixed;
408
+ m_cur_buffer_memusage += str_prefixed.size ();
409
+ return ;
410
+ } else {
411
+ // unlikely edge case; add a marker that something was trimmed
412
+ str_prefixed.insert (0 , " [...] " );
413
+ }
414
+ }
415
+
416
+ {
417
+ BufferedLog buf{
418
+ .now =SystemClock::now (),
419
+ .mocktime =GetMockTime (),
420
+ .str =str_prefixed,
421
+ .logging_function =logging_function,
422
+ .source_file =source_file,
423
+ .threadname =util::ThreadGetInternalName (),
424
+ .source_line =source_line,
425
+ .category =category,
426
+ .level =level,
427
+ };
428
+ m_cur_buffer_memusage += MemUsage (buf);
429
+ m_msgs_before_open.push_back (std::move (buf));
430
+ }
410
431
411
- m_cur_buffer_memusage += MemUsage (str_prefixed);
412
432
while (m_cur_buffer_memusage > m_max_buffer_memusage) {
413
433
if (m_msgs_before_open.empty ()) {
414
434
m_cur_buffer_memusage = 0 ;
@@ -418,9 +438,14 @@ void BCLog::Logger::LogPrintStr_(const std::string& str, const std::string& logg
418
438
m_msgs_before_open.pop_front ();
419
439
++m_buffer_lines_discarded;
420
440
}
441
+
421
442
return ;
422
443
}
423
444
445
+ if (starts_new_line) {
446
+ FormatLogStrInPlace (str_prefixed, category, level, source_file, source_line, logging_function, util::ThreadGetInternalName (), SystemClock::now (), GetMockTime ());
447
+ }
448
+
424
449
if (m_print_to_console) {
425
450
// print to console
426
451
fwrite (str_prefixed.data (), 1 , str_prefixed.size (), stdout);
0 commit comments