diff options
| -rw-r--r-- | src/main_gui.cpp | 15 | ||||
| -rw-r--r-- | src/util.cpp | 5 | ||||
| -rw-r--r-- | src/util.h | 29 |
3 files changed, 49 insertions, 0 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp index 211e1e2..05f5ecf 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp | |||
| @@ -111,6 +111,7 @@ static void PrintUsage() | |||
| 111 | printf(" /help, -help, --help, /?\n"); | 111 | printf(" /help, -help, --help, /?\n"); |
| 112 | printf(" /datadir=PATH\n"); | 112 | printf(" /datadir=PATH\n"); |
| 113 | printf(" /debug\n"); | 113 | printf(" /debug\n"); |
| 114 | printf(" /maxdebugfilesize=N (roll debug.log at N MB, default 1024; 0 = never)\n"); | ||
| 114 | printf(" /gen\n"); | 115 | printf(" /gen\n"); |
| 115 | printf(" /nogui or /daemon\n"); | 116 | printf(" /nogui or /daemon\n"); |
| 116 | printf(" /selftest=wallet-keypool, wallet-hd, wallet-format, wallet-crypto, wallet-encrypt,\n"); | 117 | printf(" /selftest=wallet-keypool, wallet-hd, wallet-format, wallet-crypto, wallet-encrypt,\n"); |
| @@ -191,6 +192,20 @@ static void ParseStartupArguments(int argc, char* argv[]) | |||
| 191 | if (arg(argc,argv,"/debug") || arg(argc,argv,"-debug")) | 192 | if (arg(argc,argv,"/debug") || arg(argc,argv,"-debug")) |
| 192 | fDebug = true; | 193 | fDebug = true; |
| 193 | 194 | ||
| 195 | // /maxdebugfilesize=N -- roll debug.log to debug.log.old once it passes | ||
| 196 | // N MB, checked on each write. Default is 1024 (see util.cpp); 0 turns | ||
| 197 | // the check off and leaves rotation entirely to logrotate. | ||
| 198 | string strMaxDebugSize = argval2(argc, argv, "/maxdebugfilesize", "-maxdebugfilesize"); | ||
| 199 | if (!strMaxDebugSize.empty()) | ||
| 200 | { | ||
| 201 | int64 nMB = atoi64(strMaxDebugSize.c_str()); | ||
| 202 | if (nMB < 0) | ||
| 203 | fprintf(stderr, "Ignoring /maxdebugfilesize=%s: not a size in MB\n", | ||
| 204 | strMaxDebugSize.c_str()); | ||
| 205 | else | ||
| 206 | nMaxDebugFileSize = nMB * 1024 * 1024; | ||
| 207 | } | ||
| 208 | |||
| 194 | if (arg(argc,argv,"/gen") || arg(argc,argv,"-gen")) | 209 | if (arg(argc,argv,"/gen") || arg(argc,argv,"-gen")) |
| 195 | { | 210 | { |
| 196 | fGenerateBitcoins = 1; | 211 | fGenerateBitcoins = 1; |
diff --git a/src/util.cpp b/src/util.cpp index 0cd0133..52cda84 100644 --- a/src/util.cpp +++ b/src/util.cpp | |||
| @@ -8,6 +8,11 @@ | |||
| 8 | 8 | ||
| 9 | bool fDebug = false; | 9 | bool fDebug = false; |
| 10 | 10 | ||
| 11 | // In-process cap for debug.log, in bytes. Default matches the 1G trigger of | ||
| 12 | // the shipped logrotate policy so a long-running node stays bounded even | ||
| 13 | // without it; -maxdebugfilesize=N (MB) tunes it, 0 disables. | ||
| 14 | int64 nMaxDebugFileSize = 1024 * 1024 * (int64)1024; | ||
| 15 | |||
| 11 | // --------------------------------------------------------------------------- | 16 | // --------------------------------------------------------------------------- |
| 12 | // Categorized, burst-collapsing logging -- see the LogPrint doc comment in | 17 | // Categorized, burst-collapsing logging -- see the LogPrint doc comment in |
| 13 | // util.h for the problem this solves. | 18 | // util.h for the problem this solves. |
| @@ -87,6 +87,11 @@ inline T& REF(const T& val) | |||
| 87 | 87 | ||
| 88 | extern bool fDebug; | 88 | extern bool fDebug; |
| 89 | 89 | ||
| 90 | // debug.log is rolled to debug.log.old once it grows past this many bytes | ||
| 91 | // (set from -maxdebugfilesize, in MB; 0 disables the check). See the roll | ||
| 92 | // site in OutputDebugStringF() below. | ||
| 93 | extern int64 nMaxDebugFileSize; | ||
| 94 | |||
| 90 | // --------------------------------------------------------------------------- | 95 | // --------------------------------------------------------------------------- |
| 91 | // Categorized, burst-collapsing logging | 96 | // Categorized, burst-collapsing logging |
| 92 | // | 97 | // |
| @@ -391,6 +396,30 @@ inline int OutputDebugStringF(const char* pszFormat, ...) | |||
| 391 | strDebugFile = "debug.log"; | 396 | strDebugFile = "debug.log"; |
| 392 | } | 397 | } |
| 393 | FILE* fileout = fopen(strDebugFile.c_str(), "a"); | 398 | FILE* fileout = fopen(strDebugFile.c_str(), "a"); |
| 399 | if (fileout && nMaxDebugFileSize > 0) | ||
| 400 | { | ||
| 401 | // Roll an overgrown debug.log before adding to it. Nothing in the | ||
| 402 | // tree shrinks this file once the process is running (there is no | ||
| 403 | // ShrinkDebugFile, and even Bitcoin's only ran at startup), so a | ||
| 404 | // node that stays up for months grows the log without bound -- | ||
| 405 | // production hit ~2 GiB. The file is opened and closed per line, | ||
| 406 | // so a rename is safe here: the next line simply reopens the | ||
| 407 | // path. One generation is kept as debug.log.old; logrotate | ||
| 408 | // (contrib/logrotate/) handles anything longer-term. | ||
| 409 | int nSize = GetFilesize(fileout); | ||
| 410 | if (nSize >= 0 && (int64)nSize > nMaxDebugFileSize) | ||
| 411 | { | ||
| 412 | fclose(fileout); | ||
| 413 | string strOldFile = strDebugFile + ".old"; | ||
| 414 | remove(strOldFile.c_str()); // rename() won't clobber on Windows | ||
| 415 | rename(strDebugFile.c_str(), strOldFile.c_str()); | ||
| 416 | fileout = fopen(strDebugFile.c_str(), "a"); | ||
| 417 | if (fileout) | ||
| 418 | fprintf(fileout, | ||
| 419 | "debug.log grew past %lld MB; previous contents moved to debug.log.old (-maxdebugfilesize)\n", | ||
| 420 | (long long)(nMaxDebugFileSize / 1024 / 1024)); | ||
| 421 | } | ||
| 422 | } | ||
| 394 | if (fileout) | 423 | if (fileout) |
| 395 | { | 424 | { |
| 396 | va_list arg_ptr; | 425 | va_list arg_ptr; |