| 516 | } |
| 517 | |
| 518 | void BCLog::Logger::ShrinkDebugFile() |
| 519 | { |
| 520 | STDLOCK(m_cs); |
| 521 | |
| 522 | // Amount of debug.log to save at end when shrinking (must fit in memory) |
| 523 | constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000; |
| 524 | |
| 525 | assert(!m_file_path.empty()); |
| 526 | |
| 527 | // Scroll debug.log if it's getting too big |
| 528 | FILE* file = fsbridge::fopen(m_file_path, "r"); |
| 529 | |
| 530 | // Special files (e.g. device nodes) may not have a size. |
| 531 | size_t log_size = 0; |
| 532 | try { |
| 533 | log_size = fs::file_size(m_file_path); |
| 534 | } catch (const fs::filesystem_error&) {} |
| 535 | |
| 536 | // If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE |
| 537 | // trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes |
| 538 | if (file && log_size > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10)) |
| 539 | { |
| 540 | // Restart the file with some of the end |
| 541 | std::vector<char> vch(RECENT_DEBUG_HISTORY_SIZE, 0); |
| 542 | if (fseek(file, -((long)vch.size()), SEEK_END)) { |
| 543 | // LogWarning, except with m_cs held |
| 544 | LogPrint_({ |
| 545 | .category = BCLog::ALL, |
| 546 | .level = Level::Warning, |
| 547 | .should_ratelimit = true, |
| 548 | .source_loc = SourceLocation{__func__}, |
| 549 | .message = "Failed to shrink debug log file: fseek(...) failed", |
| 550 | }); |
| 551 | fclose(file); |
| 552 | return; |
| 553 | } |
| 554 | int nBytes = fread(vch.data(), 1, vch.size(), file); |
| 555 | fclose(file); |
| 556 | |
| 557 | file = fsbridge::fopen(m_file_path, "w"); |
| 558 | if (file) |
| 559 | { |
| 560 | fwrite(vch.data(), 1, nBytes, file); |
| 561 | fclose(file); |
| 562 | } |
| 563 | } |
| 564 | else if (file != nullptr) |
| 565 | fclose(file); |
| 566 | } |
| 567 | |
| 568 | void BCLog::LogRateLimiter::Reset() |
| 569 | { |
no test coverage detected