Changeset 36344 in vbox for trunk/src/VBox
- Timestamp:
- Mar 22, 2011 2:29:37 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 70679
- Location:
- trunk/src/VBox
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxBFE/VBoxBFE.cpp
r35346 r36344 11 11 12 12 /* 13 * Copyright (C) 2006-20 09Oracle Corporation13 * Copyright (C) 2006-2011 Oracle Corporation 14 14 * 15 15 * This file is part of VirtualBox Open Source Edition (OSE), as … … 1136 1136 PRTLOGGER pLogger; 1137 1137 rc2 = RTLogCreateEx(&pLogger, RTLOGFLAGS_PREFIX_TIME_PROG, "all", 1138 "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, 1139 RTLOGDEST_FILE, s_szError, sizeof(s_szError), "./VBoxBFE.log"); 1138 "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_FILE, 1139 NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, 1140 s_szError, sizeof(s_szError), "./VBoxBFE.log"); 1140 1141 if (RT_SUCCESS(rc2)) 1141 1142 { -
trunk/src/VBox/HostDrivers/Support/SUPDrv.c
r36265 r36344 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2011 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 425 425 PRTLOGGER pRelLogger; 426 426 rc = RTLogCreate(&pRelLogger, 0 /* fFlags */, "all", 427 "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, 428 RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER, NULL); 427 "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER, 428 NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, 429 NULL); 429 430 if (RT_SUCCESS(rc)) 430 431 RTLogRelSetDefaultInstance(pRelLogger); … … 4746 4747 s_apszGroups, 4747 4748 RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER, 4749 NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, 4748 4750 NULL); 4749 4751 if (RT_SUCCESS(rc)) -
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r36247 r36344 5394 5394 char szError[RTPATH_MAX + 128] = ""; 5395 5395 int vrc = RTLogCreateEx(&loggerRelease, fFlags, "all", 5396 "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, 5397 RTLOGDEST_FILE, szError, sizeof(szError), logFile.c_str()); 5396 "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_FILE, 5397 NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, 5398 szError, sizeof(szError), logFile.c_str()); 5398 5399 if (RT_SUCCESS(vrc)) 5399 5400 { -
trunk/src/VBox/Main/src-server/generic/OpenGLTestApp.cpp
r33806 r36344 5 5 6 6 /* 7 * Copyright (C) 2009-201 0Oracle Corporation7 * Copyright (C) 2009-2011 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 133 133 134 134 int vrc = RTLogCreateEx(&loggerRelease, fFlags, "all", 135 "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, 136 enmLogDest, szError, sizeof(szError), pszFilenameFmt, pszFilename, RTTimeMilliTS()); 135 "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, enmLogDest, 136 NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, 137 szError, sizeof(szError), pszFilenameFmt, pszFilename, RTTimeMilliTS()); 137 138 if (RT_SUCCESS(vrc)) 138 139 { -
trunk/src/VBox/Main/webservice/vboxweb.cpp
r36168 r36344 111 111 unsigned int g_cMaxKeepAlive = 100; // maximum number of soap requests in one connection 112 112 113 uint32_t g_cHistory = 10; // enable log rotation, 10 files 114 uint32_t g_uHistoryFileTime = RT_SEC_1WEEK; // max 1 week per file 115 uint64_t g_uHistoryFileSize = 100 * _1M; // max 100MB per file 113 116 bool g_fVerbose = false; // be verbose 114 bool g_fStdOutLogging = true; // log to stdout115 PRTSTREAM g_pStrmLog = NULL;116 117 117 118 #if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined (RT_OS_SOLARIS) || defined(RT_OS_FREEBSD) … … 177 178 { "--pidfile", 'P', RTGETOPT_REQ_STRING }, 178 179 { "--logfile", 'F', RTGETOPT_REQ_STRING }, 180 { "--logrotate", 'R', RTGETOPT_REQ_UINT32 }, 181 { "--logsize", 'S', RTGETOPT_REQ_UINT64 }, 182 { "--loginterval", 'I', RTGETOPT_REQ_UINT32 } 179 183 }; 180 184 … … 239 243 case 'F': 240 244 pcszDescr = "Name of file to write log to (no file)."; 245 break; 246 247 case 'R': 248 pcszDescr = "Number of log files (0 disables log rotation)."; 249 break; 250 251 case 'S': 252 pcszDescr = "Maximum size of a log file to trigger rotationi (bytes)."; 253 break; 254 255 case 'I': 256 pcszDescr = "Maximum time interval to trigger log rotation (seconds)."; 241 257 break; 242 258 } … … 582 598 va_end(args); 583 599 584 if (g_fStdOutLogging || g_pStrmLog)585 {586 const char *pcszPrefix = "[ ]";587 util::AutoReadLock thrLock(g_pThreadsLockHandle COMMA_LOCKVAL_SRC_POS);588 ThreadsMap::iterator it = g_mapThreads.find(RTThreadSelf());589 if (it != g_mapThreads.end())590 pcszPrefix = it->second.c_str();591 thrLock.release();592 593 // make a timestamp594 RTTIMESPEC ts;595 RTTimeLocalNow(&ts);596 RTTIME t;597 RTTimeExplode(&t, &ts);598 599 com::Utf8StrFmt strPrefix("%04d-%02u-%02u %02u:%02u:%02u %s",600 t.i32Year, t.u8Month, t.u8MonthDay,601 t.u8Hour, t.u8Minute, t.u8Second,602 pcszPrefix);603 604 // synchronize the actual output605 util::AutoWriteLock logLock(g_pWebLogLockHandle COMMA_LOCKVAL_SRC_POS);606 // terminal607 if (g_fStdOutLogging)608 RTPrintf("%s %s", strPrefix.c_str(), psz);609 610 // log file611 if (g_pStrmLog)612 {613 RTStrmPrintf(g_pStrmLog, "%s %s", strPrefix.c_str(), psz);614 RTStrmFlush(g_pStrmLog);615 }616 617 #ifdef DEBUG618 // debug logger instance619 RTLogLoggerEx(LOG_INSTANCE, RTLOGGRPFLAGS_DJ, LOG_GROUP, "%s %s", pcszPrefix, psz);620 #endif621 622 logLock.release();623 }624 625 600 LogRel(("%s", psz)); 626 601 … … 645 620 pcszFaultString ? pcszFaultString : "[no fault string available]", 646 621 (ppcszDetail && *ppcszDetail) ? *ppcszDetail : "no details available"); 622 } 623 624 static void WebLogHeaderFooter(PRTLOGGER pLoggerRelease, RTLOGPHASE enmPhase, PFNRTLOGPHASEMSG pfnLog) 625 { 626 /* some introductory information */ 627 static RTTIMESPEC timeSpec = {0}; 628 char szTmp[256]; 629 if (enmPhase == RTLOGPHASE_BEGIN) 630 RTTimeNow(&timeSpec); 631 RTTimeSpecToString(&timeSpec, szTmp, sizeof(szTmp)); 632 633 switch (enmPhase) 634 { 635 case RTLOGPHASE_BEGIN: 636 { 637 pfnLog(pLoggerRelease, 638 "VirtualBox web service %s r%u %s (%s %s) release log\n" 639 #ifdef VBOX_BLEEDING_EDGE 640 "EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n" 641 #endif 642 "Log opened %s\n", 643 VBOX_VERSION_STRING, RTBldCfgRevision(), VBOX_BUILD_TARGET, 644 __DATE__, __TIME__, szTmp); 645 646 int vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp)); 647 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) 648 pfnLog(pLoggerRelease, "OS Product: %s\n", szTmp); 649 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp)); 650 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) 651 pfnLog(pLoggerRelease, "OS Release: %s\n", szTmp); 652 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp)); 653 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) 654 pfnLog(pLoggerRelease, "OS Version: %s\n", szTmp); 655 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW) 656 pfnLog(pLoggerRelease, "OS Service Pack: %s\n", szTmp); 657 658 /* the package type is interesting for Linux distributions */ 659 char szExecName[RTPATH_MAX]; 660 char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName)); 661 pfnLog(pLoggerRelease, 662 "Executable: %s\n" 663 "Process ID: %u\n" 664 "Package type: %s" 665 #ifdef VBOX_OSE 666 " (OSE)" 667 #endif 668 "\n", 669 pszExecName ? pszExecName : "unknown", 670 RTProcSelf(), 671 VBOX_PACKAGE_STRING); 672 break; 673 } 674 675 case RTLOGPHASE_PREROTATE: 676 pfnLog(pLoggerRelease, "Log rotated - Log started %s\n", szTmp); 677 break; 678 679 case RTLOGPHASE_POSTROTATE: 680 pfnLog(pLoggerRelease, "Log continuation - Log started %s\n", szTmp); 681 break; 682 683 case RTLOGPHASE_END: 684 pfnLog(pLoggerRelease, "End of log file - Log started %s\n", szTmp); 685 break; 686 687 default: 688 /* nothing */; 689 } 647 690 } 648 691 … … 692 735 693 736 // add the socket to the queue and tell worker threads to 694 // pick up the job n737 // pick up the job 695 738 size_t cItemsOnQ = g_pSoapQ->add(s); 696 739 WebLog("Request %llu on socket %d queued for processing (%d items on Q)\n", i, s, cItemsOnQ); … … 748 791 749 792 int c; 793 const char *pszLogFile = NULL; 750 794 const char *pszPidFile = NULL; 751 795 RTGETOPTUNION ValueUnion; … … 781 825 case 'F': 782 826 { 783 int rc2 = RTStrmOpen(ValueUnion.psz, "a", &g_pStrmLog); 784 if (rc2) 785 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Cannot open log file \"%s\" for writing: %Rrc", ValueUnion.psz, rc2); 786 787 WebLog(VBOX_PRODUCT " Webservice Version %s\n" 788 "Opened log file \"%s\"\n", VBOX_VERSION_STRING, ValueUnion.psz); 827 pszLogFile = ValueUnion.psz; 789 828 break; 790 829 } 830 831 case 'R': 832 g_cHistory = ValueUnion.u32; 833 break; 834 835 case 'S': 836 g_uHistoryFileSize = ValueUnion.u64; 837 break; 838 839 case 'I': 840 g_uHistoryFileTime = ValueUnion.u32; 841 break; 791 842 792 843 case 'P': … … 824 875 } 825 876 } 877 878 /* create release logger */ 879 PRTLOGGER pLoggerRelease; 880 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; 881 RTUINT fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG; 882 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 883 fFlags |= RTLOGFLAGS_USECRLF; 884 #endif 885 char szError[RTPATH_MAX + 128] = ""; 886 int vrc = RTLogCreateEx(&pLoggerRelease, fFlags, "all", 887 "VBOXWEBSRV_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT, 888 WebLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime, 889 szError, sizeof(szError), pszLogFile); 890 if (RT_SUCCESS(vrc)) 891 { 892 /* register this logger as the release logger */ 893 RTLogRelSetDefaultInstance(pLoggerRelease); 894 895 /* Explicitly flush the log in case of VBOXWEBSRV_RELEASE_LOG=buffered. */ 896 RTLogFlush(pLoggerRelease); 897 } 898 else 899 return RTMsgErrorExit(RTEXITCODE_FAILURE, "failed to open release log (%s, %Rrc)", szError, vrc); 826 900 827 901 #if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined (RT_OS_SOLARIS) || defined(RT_OS_FREEBSD) … … 842 916 return RTMsgErrorExit(RTEXITCODE_FAILURE, "failed to daemonize, rc=%Rrc. exiting.", rc); 843 917 844 /* From now on it's a waste of CPU cycles to send logging to stdout. */845 g_fStdOutLogging = false;846 847 918 /* create release logger */ 848 PRTLOGGER loggerRelease;919 PRTLOGGER pLoggerRelease; 849 920 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; 850 921 RTUINT fFlags = RTLOGFLAGS_PREFIX_THREAD | RTLOGFLAGS_PREFIX_TIME_PROG; … … 853 924 #endif 854 925 char szError[RTPATH_MAX + 128] = ""; 855 int vrc = RTLogCreateEx(&loggerRelease, fFlags, "all", 856 "VBOXWEBSRV_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, 857 RTLOGDEST_FILE, szError, sizeof(szError), szLogFile); 926 int vrc = RTLogCreateEx(&pLoggerRelease, fFlags, "all", 927 "VBOXWEBSRV_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_FILE, 928 WebLogHeaderFooter, g_cHistory, g_uHistoryFileSize, g_uHistoryFileTime, 929 szError, sizeof(szError), szLogFile); 858 930 if (RT_SUCCESS(vrc)) 859 931 { 860 /* some introductory information */861 RTTIMESPEC timeSpec;862 char szTmp[256];863 RTTimeSpecToString(RTTimeNow(&timeSpec), szTmp, sizeof(szTmp));864 RTLogRelLogger(loggerRelease, 0, ~0U,865 "VirtualBox web service %s r%u %s (%s %s) release log\n"866 #ifdef VBOX_BLEEDING_EDGE867 "EXPERIMENTAL build " VBOX_BLEEDING_EDGE "\n"868 #endif869 "Log opened %s\n",870 VBOX_VERSION_STRING, RTBldCfgRevision(), VBOX_BUILD_TARGET,871 __DATE__, __TIME__, szTmp);872 873 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_PRODUCT, szTmp, sizeof(szTmp));874 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)875 RTLogRelLogger(loggerRelease, 0, ~0U, "OS Product: %s\n", szTmp);876 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_RELEASE, szTmp, sizeof(szTmp));877 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)878 RTLogRelLogger(loggerRelease, 0, ~0U, "OS Release: %s\n", szTmp);879 vrc = RTSystemQueryOSInfo(RTSYSOSINFO_VERSION, szTmp, sizeof(szTmp));880 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)881 RTLogRelLogger(loggerRelease, 0, ~0U, "OS Version: %s\n", szTmp);882 if (RT_SUCCESS(vrc) || vrc == VERR_BUFFER_OVERFLOW)883 RTLogRelLogger(loggerRelease, 0, ~0U, "OS Service Pack: %s\n", szTmp);884 885 /* the package type is interesting for Linux distributions */886 char szExecName[RTPATH_MAX];887 char *pszExecName = RTProcGetExecutablePath(szExecName, sizeof(szExecName));888 RTLogRelLogger(loggerRelease, 0, ~0U,889 "Executable: %s\n"890 "Process ID: %u\n"891 "Package type: %s"892 #ifdef VBOX_OSE893 " (OSE)"894 #endif895 "\n",896 pszExecName ? pszExecName : "unknown",897 RTProcSelf(),898 VBOX_PACKAGE_STRING);899 900 932 /* register this logger as the release logger */ 901 RTLogRelSetDefaultInstance( loggerRelease);933 RTLogRelSetDefaultInstance(pLoggerRelease); 902 934 903 935 /* Explicitly flush the log in case of VBOXWEBSRV_RELEASE_LOG=buffered. */ 904 RTLogFlush( loggerRelease);936 RTLogFlush(pLoggerRelease); 905 937 } 906 938 else -
trunk/src/VBox/Runtime/VBox/log-vbox.cpp
r34848 r36344 5 5 6 6 /* 7 * Copyright (C) 2006-20 09Oracle Corporation7 * Copyright (C) 2006-2011 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 303 303 RTTimeExplode(&Time, RTTimeNow(&TimeSpec)); 304 304 rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_FILE, 305 NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, 305 306 "./%04d-%02d-%02d-%02d-%02d-%02d.%03d-%s-%d.log", 306 307 Time.i32Year, Time.u8Month, Time.u8MonthDay, Time.u8Hour, Time.u8Minute, Time.u8Second, Time.u32Nanosecond / 10000000, … … 419 420 #else /* IN_RING0 */ 420 421 # ifndef IN_GUEST 421 rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_FILE, "VBox-ring0.log"); 422 rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_FILE, 423 NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, 424 "VBox-ring0.log"); 422 425 # else /* IN_GUEST */ 423 rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_USER, "VBox-ring0.log"); 426 rc = RTLogCreate(&pLogger, 0, NULL, "VBOX_LOG", RT_ELEMENTS(g_apszGroups), &g_apszGroups[0], RTLOGDEST_USER, 427 NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, 428 "VBox-ring0.log"); 424 429 # endif /* IN_GUEST */ 425 430 if (RT_SUCCESS(rc)) -
trunk/src/VBox/Runtime/common/log/log.cpp
r33595 r36344 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2011 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 89 89 static void rtR0LogLoggerExFallback(uint32_t fDestFlags, uint32_t fFlags, const char *pszFormat, va_list va); 90 90 #endif 91 #ifdef IN_RING3 92 static int rtlogFileOpen(PRTLOGGER pLogger, char *pszErrorMsg, size_t cchErrorMsg); 93 static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst); 94 #endif 91 95 static void rtlogFlush(PRTLOGGER pLogger); 92 96 static DECLCALLBACK(size_t) rtLogOutput(void *pv, const char *pachChars, size_t cbChars); 93 97 static DECLCALLBACK(size_t) rtLogOutputPrefixed(void *pv, const char *pachChars, size_t cbChars); 98 static void rtlogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args); 94 99 95 100 … … 190 195 { "file", sizeof("file" ) - 1, RTLOGDEST_FILE }, /* Must be 1st! */ 191 196 { "dir", sizeof("dir" ) - 1, RTLOGDEST_FILE }, /* Must be 2nd! */ 197 { "history", sizeof("history" ) - 1, 0 }, /* Must be 3rd! */ 198 { "histsize", sizeof("histsize") - 1, 0 }, /* Must be 4th! */ 199 { "histtime", sizeof("histtime") - 1, 0 }, /* Must be 5th! */ 192 200 { "stdout", sizeof("stdout" ) - 1, RTLOGDEST_STDOUT }, 193 201 { "stderr", sizeof("stderr" ) - 1, RTLOGDEST_STDERR }, … … 225 233 { 226 234 #ifndef IN_RC 227 if (pLogger->hSpinMtx != NIL_RTSEM FASTMUTEX)235 if (pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX) 228 236 RTSemSpinMutexRelease(pLogger->hSpinMtx); 229 237 #endif … … 233 241 234 242 #ifndef IN_RC 243 # ifdef IN_RING3 244 /** 245 * Logging to file, output callback. 246 * 247 * @param pvArg User argument. 248 * @param pachChars Pointer to an array of utf-8 characters. 249 * @param cbChars Number of bytes in the character array pointed to by pachChars. 250 */ 251 static DECLCALLBACK(size_t) rtlogPhaseWrite(void *pvArg, const char *pachChars, size_t cbChars) 252 { 253 PRTLOGGER pLogger = (PRTLOGGER)pvArg; 254 RTFileWrite(pLogger->pFile->File, pachChars, cbChars, NULL); 255 return cbChars; 256 } 257 258 /** 259 * Callback to format VBox formatting extentions. 260 * See @ref pg_rt_str_format for a reference on the format types. 261 * 262 * @returns The number of bytes formatted. 263 * @param pvArg Formatter argument. 264 * @param pfnOutput Pointer to output function. 265 * @param pvArgOutput Argument for the output function. 266 * @param ppszFormat Pointer to the format string pointer. Advance this till the char 267 * after the format specifier. 268 * @param pArgs Pointer to the argument list. Use this to fetch the arguments. 269 * @param cchWidth Format Width. -1 if not specified. 270 * @param cchPrecision Format Precision. -1 if not specified. 271 * @param fFlags Flags (RTSTR_NTFS_*). 272 * @param chArgSize The argument size specifier, 'l' or 'L'. 273 */ 274 static DECLCALLBACK(size_t) rtlogPhaseFormatStr(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, 275 const char **ppszFormat, va_list *pArgs, int cchWidth, 276 int cchPrecision, unsigned fFlags, char chArgSize) 277 { 278 char ch = *(*ppszFormat)++; 279 280 AssertMsgFailed(("Invalid logger phase format type '%%%c%.10s'!\n", ch, *ppszFormat)); NOREF(ch); 281 282 return 0; 283 } 284 285 /** 286 * Log phase callback function, assumes the lock is already held 287 * 288 * @param pLogger The logger instance. 289 * @param pszFormat Format string. 290 * @param ... Optional arguments as specified in the format string. 291 */ 292 static DECLCALLBACK(void) rtlogPhaseMsgLocked(PRTLOGGER pLogger, const char *pszFormat, ...) 293 { 294 va_list args; 295 AssertPtrReturnVoid(pLogger); 296 AssertPtrReturnVoid(pLogger->pFile); 297 Assert(pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX); 298 299 va_start(args, pszFormat); 300 rtlogLoggerExV(pLogger, 0, ~0, pszFormat, args); 301 va_end(args); 302 } 303 304 /** 305 * Log phase callback function, assumes the lock is not held 306 * 307 * @param pLogger The logger instance. 308 * @param pszFormat Format string. 309 * @param ... Optional arguments as specified in the format string. 310 */ 311 static DECLCALLBACK(void) rtlogPhaseMsgNormal(PRTLOGGER pLogger, const char *pszFormat, ...) 312 { 313 va_list args; 314 AssertPtrReturnVoid(pLogger); 315 AssertPtrReturnVoid(pLogger->pFile); 316 Assert(pLogger->hSpinMtx != NIL_RTSEMSPINMUTEX); 317 318 va_start(args, pszFormat); 319 RTLogLoggerExV(pLogger, 0, ~0, pszFormat, args); 320 va_end(args); 321 } 322 # endif /* IN_RING3 */ 323 235 324 /** 236 325 * Create a logger instance, comprehensive version. … … 246 335 * logger instance. 247 336 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed if pszFilenameFmt specified. 337 * @param pfnPhase Callback function for starting logging and for ending or starting a new file for log history rotation. 338 * @param cHistory Number of old log files to keep when performing log history rotation. 339 * @param cbHistoryFileMax Maximum size of log file when performing history rotation. 0=no size limit. 340 * @param uHistoryTimeSlotLength Maximum time interval per log file when performing history rotation, in seconds. 0=no time limit. 248 341 * @param pszErrorMsg A buffer which is filled with an error message if something fails. May be NULL. 249 342 * @param cchErrorMsg The size of the error message buffer. … … 253 346 RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, 254 347 const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups, 255 uint32_t fDestFlags, char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, va_list args) 348 uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory, 349 uint64_t cbHistoryFileMax, uint32_t uHistoryTimeSlotLength, 350 char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, va_list args) 256 351 { 257 352 int rc; … … 278 373 */ 279 374 cb = RT_OFFSETOF(RTLOGGER, afGroups[cGroups + 1]) + RTPATH_MAX; 375 #ifdef IN_RING3 376 cb += sizeof(RTLOGGERFILE); 377 #endif 280 378 pLogger = (PRTLOGGER)RTMemAllocZVar(cb); 281 379 if (pLogger) … … 289 387 pLogger->cMaxGroups = cGroups; 290 388 pLogger->cGroups = cGroups; 291 pLogger->pszFilename = (char *)&pLogger->afGroups[cGroups + 1]; 292 pLogger->File = NIL_RTFILE; 389 #ifdef IN_RING3 390 pLogger->pFile = (PRTLOGGERFILE)((char *)&pLogger->afGroups[cGroups + 1] + RTPATH_MAX); 391 pLogger->pFile->File = NIL_RTFILE; 392 pLogger->pFile->pszFilename = (char *)&pLogger->afGroups[cGroups + 1]; 393 pLogger->pFile->pfnPhase = pfnPhase; 394 pLogger->pFile->cHistory = cHistory; 395 if (cbHistoryFileMax == 0) 396 pLogger->pFile->cbHistoryFileMax = UINT64_MAX; 397 else 398 pLogger->pFile->cbHistoryFileMax = cbHistoryFileMax; 399 if (uHistoryTimeSlotLength == 0) 400 pLogger->pFile->uHistoryTimeSlotLength = UINT32_MAX; 401 else 402 pLogger->pFile->uHistoryTimeSlotLength = uHistoryTimeSlotLength; 403 #else /* !IN_RING3 */ 404 pLogger->pFile = NULL; 405 #endif /* !IN_RING3 */ 293 406 pLogger->fFlags = fFlags; 294 407 pLogger->fDestFlags = fDestFlags; … … 337 450 if (pszFilenameFmt) 338 451 { 339 RTStrPrintfV(pLogger->p szFilename, RTPATH_MAX, pszFilenameFmt, args);452 RTStrPrintfV(pLogger->pFile->pszFilename, RTPATH_MAX, pszFilenameFmt, args); 340 453 pLogger->fDestFlags |= RTLOGDEST_FILE; 341 454 } … … 384 497 if (pLogger->fDestFlags & RTLOGDEST_FILE) 385 498 { 386 uint32_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_WRITE;387 499 if (pLogger->fFlags & RTLOGFLAGS_APPEND) 388 fOpen |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND; 500 { 501 rc = rtlogFileOpen(pLogger, pszErrorMsg, cchErrorMsg); 502 /* Rotate in case of appending to a too big log file, 503 * otherwise this simply doesn't do anything. */ 504 rtlogRotate(pLogger, 0, true /* fFirst */); 505 } 389 506 else 390 fOpen |= RTFILE_O_CREATE_REPLACE; 391 if (pLogger->fFlags & RTLOGFLAGS_WRITE_THROUGH) 392 fOpen |= RTFILE_O_WRITE_THROUGH; 393 rc = RTFileOpen(&pLogger->File, pLogger->pszFilename, fOpen); 394 if (RT_FAILURE(rc) && pszErrorMsg) 395 RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pszFilename, fOpen); 507 { 508 /* Force rotation if it is configured. */ 509 pLogger->pFile->cbHistoryFileWritten = UINT64_MAX; 510 rtlogRotate(pLogger, 0, true /* fFirst */); 511 /* If the file is not open then rotation is not set up. */ 512 if (pLogger->pFile->File == NIL_RTFILE) 513 { 514 pLogger->pFile->cbHistoryFileWritten = 0; 515 rc = rtlogFileOpen(pLogger, pszErrorMsg, cchErrorMsg); 516 } 517 } 396 518 } 519 520 /* Use the callback to generate some initial log contents. */ 521 Assert(VALID_PTR(pLogger->pFile->pfnPhase) || pLogger->pFile->pfnPhase == NULL); 522 if (pLogger->pFile->pfnPhase) 523 pfnPhase(pLogger, RTLOGPHASE_BEGIN, rtlogPhaseMsgNormal); 397 524 #endif /* IN_RING3 */ 398 525 … … 425 552 } 426 553 #ifdef IN_RING3 427 RTFileClose(pLogger-> File);554 RTFileClose(pLogger->pFile->File); 428 555 #endif 429 556 #if defined(LOG_USE_C99) && defined(RT_WITHOUT_EXEC_ALLOC) … … 456 583 * logger instance. 457 584 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed if pszFilenameFmt specified. 585 * @param pfnPhase Callback function for starting logging and for ending or starting a new file for log history rotation. 586 * @param cHistory Number of old log files to keep when performing log history rotation. 587 * @param cbHistoryFileMax Maximum size of log file when performing history rotation. 0=no size limit. 588 * @param uHistoryTimeSlotLength Maximum time interval per log file when performing history rotation, in seconds. 0=no time limit. 458 589 * @param pszFilenameFmt Log filename format string. Standard RTStrFormat(). 459 590 * @param ... Format arguments. … … 461 592 RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, 462 593 const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups, 463 uint32_t fDestFlags, const char *pszFilenameFmt, ...) 594 uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory, 595 uint64_t cbHistoryFileMax, uint32_t uHistoryTimeSlotLength, 596 const char *pszFilenameFmt, ...) 464 597 { 465 598 va_list args; … … 467 600 468 601 va_start(args, pszFilenameFmt); 469 rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups, fDestFlags, NULL, 0, pszFilenameFmt, args);602 rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups, fDestFlags, pfnPhase, cHistory, cbHistoryFileMax, uHistoryTimeSlotLength, NULL, 0, pszFilenameFmt, args); 470 603 va_end(args); 471 604 return rc; … … 487 620 * logger instance. 488 621 * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed if pszFilenameFmt specified. 622 * @param pfnPhase Callback function for starting logging and for ending or starting a new file for log history rotation. 623 * @param cHistory Number of old log files to keep when performing log history rotation. 624 * @param cbHistoryFileMax Maximum size of log file when performing history rotation. 0=no size limit. 625 * @param uHistoryTimeSlotLength Maximum time interval per log file when performing history rotation, in seconds. 0=no time limit. 489 626 * @param pszErrorMsg A buffer which is filled with an error message if something fails. May be NULL. 490 627 * @param cchErrorMsg The size of the error message buffer. … … 494 631 RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings, 495 632 const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups, 496 uint32_t fDestFlags, char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, ...) 633 uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory, 634 uint64_t cbHistoryFileMax, uint32_t uHistoryTimeSlotLength, 635 char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, ...) 497 636 { 498 637 va_list args; … … 500 639 501 640 va_start(args, pszFilenameFmt); 502 rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups, fDestFlags, p szErrorMsg, cchErrorMsg, pszFilenameFmt, args);641 rc = RTLogCreateExV(ppLogger, fFlags, pszGroupSettings, pszEnvVarBase, cGroups, papszGroups, fDestFlags, pfnPhase, cHistory, cbHistoryFileMax, uHistoryTimeSlotLength, pszErrorMsg, cchErrorMsg, pszFilenameFmt, args); 503 642 va_end(args); 504 643 return rc; … … 545 684 rtlogFlush(pLogger); 546 685 686 #ifdef IN_RING3 687 /* 688 * Add end of logging message. 689 */ 690 if (pLogger->fDestFlags & RTLOGDEST_FILE && pLogger->pFile->File != NIL_RTFILE) 691 pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_END, rtlogPhaseMsgLocked); 692 547 693 /* 548 694 * Close output stuffs. 549 695 */ 550 #ifdef IN_RING3 551 if (pLogger->File != NIL_RTFILE) 552 { 553 int rc2 = RTFileClose(pLogger->File); 696 if (pLogger->pFile->File != NIL_RTFILE) 697 { 698 int rc2 = RTFileClose(pLogger->pFile->File); 554 699 AssertRC(rc2); 555 700 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 556 701 rc = rc2; 557 pLogger-> File = NIL_RTFILE;702 pLogger->pFile->File = NIL_RTFILE; 558 703 } 559 704 #endif … … 766 911 pLogger->fFlags = fFlags; 767 912 pLogger->fDestFlags = fDestFlags & ~RTLOGDEST_FILE; 768 pLogger->File = NIL_RTFILE; 769 pLogger->pszFilename = NULL; 913 pLogger->pFile = NULL; 770 914 pLogger->papszGroups = NULL; 771 915 pLogger->cMaxGroups = (uint32_t)((cbLogger - RT_OFFSETOF(RTLOGGER, afGroups[0])) / sizeof(pLogger->afGroups[0])); … … 1604 1748 { 1605 1749 AssertReturn(cch < RTPATH_MAX, VERR_OUT_OF_RANGE); 1606 memcpy(pLogger->p szFilename, pszVar, cch);1607 pLogger->p szFilename[cch] = '\0';1750 memcpy(pLogger->pFile->pszFilename, pszVar, cch); 1751 pLogger->pFile->pszFilename[cch] = '\0'; 1608 1752 } 1609 1753 /* log directory */ … … 1611 1755 { 1612 1756 char szTmp[RTPATH_MAX]; 1613 const char *pszFile = RTPathFilename(pLogger->p szFilename);1757 const char *pszFile = RTPathFilename(pLogger->pFile->pszFilename); 1614 1758 size_t cchFile = pszFile ? strlen(pszFile) : 0; 1615 1759 AssertReturn(cchFile + cch + 1 < RTPATH_MAX, VERR_OUT_OF_RANGE); 1616 1760 memcpy(szTmp, cchFile ? pszFile : "", cchFile + 1); 1617 1761 1618 memcpy(pLogger->pszFilename, pszVar, cch); 1619 pLogger->pszFilename[cch] = '\0'; 1620 RTPathStripTrailingSlash(pLogger->pszFilename); 1621 1622 cch = strlen(pLogger->pszFilename); 1623 pLogger->pszFilename[cch++] = '/'; 1624 memcpy(&pLogger->pszFilename[cch], szTmp, cchFile); 1625 pLogger->pszFilename[cch+cchFile] = '\0'; 1762 memcpy(pLogger->pFile->pszFilename, pszVar, cch); 1763 pLogger->pFile->pszFilename[cch] = '\0'; 1764 RTPathStripTrailingSlash(pLogger->pFile->pszFilename); 1765 1766 cch = strlen(pLogger->pFile->pszFilename); 1767 pLogger->pFile->pszFilename[cch++] = '/'; 1768 memcpy(&pLogger->pFile->pszFilename[cch], szTmp, cchFile); 1769 pLogger->pFile->pszFilename[cch+cchFile] = '\0'; 1770 } 1771 else if (i == 2 /* history */) 1772 { 1773 if (!fNo) 1774 { 1775 char szTmp[32]; 1776 int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszVar, cch); 1777 if (RT_SUCCESS(rc)) 1778 rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pFile->cHistory); 1779 if (RT_FAILURE(rc)) 1780 AssertMsgFailedReturn(("Invalid history value %s (%Rrc)!\n", 1781 szTmp, rc), rc); 1782 } 1783 else 1784 pLogger->pFile->cHistory = 0; 1785 } 1786 else if (i == 3 /* histsize */) 1787 { 1788 if (!fNo) 1789 { 1790 char szTmp[32]; 1791 int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszVar, cch); 1792 if (RT_SUCCESS(rc)) 1793 rc = RTStrToUInt64Full(szTmp, 0, &pLogger->pFile->cbHistoryFileMax); 1794 if (RT_FAILURE(rc)) 1795 AssertMsgFailedReturn(("Invalid history file size value %s (%Rrc)!\n", 1796 szTmp, rc), rc); 1797 if (pLogger->pFile->cbHistoryFileMax == 0) 1798 pLogger->pFile->cbHistoryFileMax = UINT64_MAX; 1799 } 1800 else 1801 pLogger->pFile->cbHistoryFileMax = UINT64_MAX; 1802 } 1803 else if (i == 4 /* histtime */) 1804 { 1805 if (!fNo) 1806 { 1807 char szTmp[32]; 1808 int rc = RTStrCopyEx(szTmp, sizeof(szTmp), pszVar, cch); 1809 if (RT_SUCCESS(rc)) 1810 rc = RTStrToUInt32Full(szTmp, 0, &pLogger->pFile->uHistoryTimeSlotLength); 1811 if (RT_FAILURE(rc)) 1812 AssertMsgFailedReturn(("Invalid history timespan value %s (%Rrc)!\n", 1813 szTmp, rc), rc); 1814 if (pLogger->pFile->uHistoryTimeSlotLength == 0) 1815 pLogger->pFile->uHistoryTimeSlotLength = UINT32_MAX; 1816 } 1817 else 1818 pLogger->pFile->uHistoryTimeSlotLength = UINT32_MAX; 1626 1819 } 1627 1820 else … … 1704 1897 } 1705 1898 1899 #ifdef IN_RING3 1706 1900 /* 1707 1901 * Add the filename. 1708 1902 */ 1709 1903 if ( (fDestFlags & RTLOGDEST_FILE) 1710 && VALID_PTR(pLogger->p szFilename)1904 && VALID_PTR(pLogger->pFile->pszFilename) 1711 1905 && RT_SUCCESS(rc)) 1712 1906 { 1713 size_t cchFilename = strlen(pLogger->p szFilename);1907 size_t cchFilename = strlen(pLogger->pFile->pszFilename); 1714 1908 if (cchFilename + sizeof("file=") - 1 + fNotFirst + 1 <= cchBuf) 1715 1909 { … … 1718 1912 else 1719 1913 APPEND_SZ("file="); 1720 APPEND_PSZ(pLogger->p szFilename, cchFilename);1914 APPEND_PSZ(pLogger->pFile->pszFilename, cchFilename); 1721 1915 } 1722 1916 else 1723 1917 rc = VERR_BUFFER_OVERFLOW; 1724 1918 } 1919 #endif 1725 1920 1726 1921 #undef APPEND_PSZ … … 2032 2227 2033 2228 /* 2034 * Format the message and perhaps flush it. 2035 */ 2036 if (pLogger->fFlags & (RTLOGFLAGS_PREFIX_MASK | RTLOGFLAGS_USECRLF)) 2037 { 2038 RTLOGOUTPUTPREFIXEDARGS OutputArgs; 2039 OutputArgs.pLogger = pLogger; 2040 OutputArgs.iGroup = iGroup; 2041 OutputArgs.fFlags = fFlags; 2042 RTLogFormatV(rtLogOutputPrefixed, &OutputArgs, pszFormat, args); 2043 } 2044 else 2045 RTLogFormatV(rtLogOutput, pLogger, pszFormat, args); 2046 if ( !(pLogger->fFlags & RTLOGFLAGS_BUFFERED) 2047 && pLogger->offScratch) 2048 rtlogFlush(pLogger); 2229 * Call worker. 2230 */ 2231 rtlogLoggerExV(pLogger, fFlags, iGroup, pszFormat, args); 2049 2232 2050 2233 /* … … 2217 2400 2218 2401 2402 #ifdef IN_RING3 2403 /** 2404 * Opens/creates the log file. 2405 * 2406 * @param pLogger The logger instance to update. NULL is not allowed! 2407 * @param pszErrorMsg A buffer which is filled with an error message if something fails. May be NULL. 2408 * @param cchErrorMsg The size of the error message buffer. 2409 */ 2410 static int rtlogFileOpen(PRTLOGGER pLogger, char *pszErrorMsg, size_t cchErrorMsg) 2411 { 2412 uint32_t fOpen = RTFILE_O_WRITE | RTFILE_O_DENY_WRITE; 2413 if (pLogger->fFlags & RTLOGFLAGS_APPEND) 2414 fOpen |= RTFILE_O_OPEN_CREATE | RTFILE_O_APPEND; 2415 else 2416 fOpen |= RTFILE_O_CREATE_REPLACE; 2417 if (pLogger->fFlags & RTLOGFLAGS_WRITE_THROUGH) 2418 fOpen |= RTFILE_O_WRITE_THROUGH; 2419 int rc = RTFileOpen(&pLogger->pFile->File, pLogger->pFile->pszFilename, fOpen); 2420 if (RT_FAILURE(rc)) 2421 { 2422 pLogger->pFile->File = NIL_RTFILE; 2423 if (pszErrorMsg) 2424 RTStrPrintf(pszErrorMsg, cchErrorMsg, N_("could not open file '%s' (fOpen=%#x)"), pLogger->pFile->pszFilename, fOpen); 2425 } 2426 else 2427 { 2428 rc = RTFileGetSize(pLogger->pFile->File, &pLogger->pFile->cbHistoryFileWritten); 2429 if (RT_FAILURE(rc)) 2430 { 2431 /* Don't complain if this fails, assume the file is empty. */ 2432 pLogger->pFile->cbHistoryFileWritten = 0; 2433 rc = VINF_SUCCESS; 2434 } 2435 } 2436 return rc; 2437 } 2438 2439 2440 /** 2441 * Closes, rotates and opens the log files if necessary. 2442 * Used by the rtlogFlush() function. 2443 * 2444 * @param pLogger The logger instance to update. NULL is not allowed! 2445 * @param uTimeSlit Current time slot (for tikme based rotation). 2446 * @param fFirst Flag whether this is the beginning of logging. 2447 */ 2448 static void rtlogRotate(PRTLOGGER pLogger, uint32_t uTimeSlot, bool fFirst) 2449 { 2450 /* Suppress rotating empty log files simply because the time elapsed. */ 2451 if (RT_UNLIKELY(!pLogger->pFile->cbHistoryFileWritten)) 2452 pLogger->pFile->uHistoryTimeSlotStart = uTimeSlot; 2453 2454 /* Check rotation condition: file still small enough and not too old? */ 2455 if (RT_LIKELY( pLogger->pFile->cbHistoryFileWritten < pLogger->pFile->cbHistoryFileMax 2456 && uTimeSlot == pLogger->pFile->uHistoryTimeSlotStart)) 2457 return; 2458 2459 /* Save "disabled" log flag and make sure logging is disabled. 2460 * The logging in the functions called during log file history 2461 * rotation would cause severe trouble otherwise. */ 2462 uint32_t fOFlags = pLogger->fFlags; 2463 pLogger->fFlags |= RTLOGFLAGS_DISABLED; 2464 2465 /* Disable log rotation temporarily, otherwise with extreme settings and 2466 * chatty phase logging we could run into endless rotation. */ 2467 uint32_t cOHistory = pLogger->pFile->cHistory; 2468 pLogger->pFile->cHistory = 0; 2469 2470 /* Close the old log file. */ 2471 if (pLogger->pFile->File != NIL_RTFILE) 2472 { 2473 /* Use the callback to generate some final log contents, but only if 2474 * this is a rotation with a fully set up logger. Leave the other case 2475 * to the RTLogCreateExV function. */ 2476 if (pLogger->pFile->pfnPhase && !fFirst) 2477 { 2478 uint32_t fODestFlags = pLogger->fDestFlags; 2479 pLogger->fDestFlags &= RTLOGDEST_FILE; 2480 pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_PREROTATE, rtlogPhaseMsgLocked); 2481 pLogger->fDestFlags = fODestFlags; 2482 } 2483 RTFileClose(pLogger->pFile->File); 2484 pLogger->pFile->File = NIL_RTFILE; 2485 } 2486 2487 /* Rotate the log files. */ 2488 if (cOHistory) 2489 { 2490 for (uint32_t i = cOHistory - 1; i + 1 > 0; i--) 2491 { 2492 char szOldName[RTPATH_MAX]; 2493 if (i > 0) 2494 RTStrPrintf(szOldName, sizeof(szOldName), "%s.%u", pLogger->pFile->pszFilename, i); 2495 else 2496 RTStrCopy(szOldName, sizeof(szOldName), pLogger->pFile->pszFilename); 2497 char szNewName[RTPATH_MAX]; 2498 RTStrPrintf(szNewName, sizeof(szNewName), "%s.%u", pLogger->pFile->pszFilename, i + 1); 2499 if (RTFileRename(szOldName, szNewName, 2500 RTFILEMOVE_FLAGS_REPLACE) == VERR_FILE_NOT_FOUND) 2501 RTFileDelete(szNewName); 2502 } 2503 } 2504 /* Delete excess log files. */ 2505 for (uint32_t i = cOHistory + 1; i++; ) 2506 { 2507 char szExcessName[RTPATH_MAX]; 2508 RTStrPrintf(szExcessName, sizeof(szExcessName), "%s.%u", pLogger->pFile->pszFilename, i); 2509 int rc = RTFileDelete(szExcessName); 2510 if (RT_FAILURE(rc)) 2511 break; 2512 } 2513 2514 /* Update logger state and create new log file. */ 2515 pLogger->pFile->cbHistoryFileWritten = 0; 2516 pLogger->pFile->uHistoryTimeSlotStart = uTimeSlot; 2517 rtlogFileOpen(pLogger, NULL, 0); 2518 2519 /* Use the callback to generate some initial log contents, but only if this 2520 * is a rotation with a fully set up logger. Leave the other case to the 2521 * RTLogCreateExV function. */ 2522 if (pLogger->pFile->pfnPhase && !fFirst) 2523 { 2524 uint32_t fODestFlags = pLogger->fDestFlags; 2525 pLogger->fDestFlags &= RTLOGDEST_FILE; 2526 pLogger->pFile->pfnPhase(pLogger, RTLOGPHASE_POSTROTATE, rtlogPhaseMsgLocked); 2527 pLogger->fDestFlags = fODestFlags; 2528 } 2529 2530 /* Restore log rotation to the previous value. */ 2531 pLogger->pFile->cHistory = cOHistory; 2532 2533 /* Restore the log flags to the previous value. */ 2534 pLogger->fFlags = fOFlags; 2535 } 2536 #endif /* IN_RING3 */ 2537 2538 2219 2539 /** 2220 2540 * Writes the buffer to the given log device without checking for buffered … … 2239 2559 if (pLogger->fDestFlags & RTLOGDEST_FILE) 2240 2560 { 2241 RTFileWrite(pLogger->File, pLogger->achScratch, pLogger->offScratch, NULL); 2242 if (pLogger->fFlags & RTLOGFLAGS_FLUSH) 2243 RTFileFlush(pLogger->File); 2561 if (pLogger->pFile->File != NIL_RTFILE) 2562 { 2563 RTFileWrite(pLogger->pFile->File, pLogger->achScratch, pLogger->offScratch, NULL); 2564 if (pLogger->fFlags & RTLOGFLAGS_FLUSH) 2565 RTFileFlush(pLogger->pFile->File); 2566 } 2567 if (pLogger->pFile->cHistory) 2568 pLogger->pFile->cbHistoryFileWritten += pLogger->offScratch; 2244 2569 } 2245 2570 # endif … … 2262 2587 /* empty the buffer. */ 2263 2588 pLogger->offScratch = 0; 2589 2590 # ifdef IN_RING3 2591 /* Rotate the log file if configured. Must be done after everything is 2592 * flushed, since this will also use logging/flushing to write the header 2593 * and footer messages. */ 2594 if ((pLogger->fDestFlags & RTLOGDEST_FILE) && pLogger->pFile->cHistory) 2595 { 2596 rtlogRotate(pLogger, 2597 RTTimeProgramSecTS() / pLogger->pFile->uHistoryTimeSlotLength, 2598 false /* fFirst */); 2599 } 2600 #endif 2264 2601 } 2265 2602 … … 2729 3066 } 2730 3067 3068 /** 3069 * Write to a logger instance (worker function). 3070 * 3071 * This function will check whether the instance, group and flags makes up a 3072 * logging kind which is currently enabled before writing anything to the log. 3073 * 3074 * @param pLogger Pointer to logger instance. Must be non-NULL. 3075 * @param fFlags The logging flags. 3076 * @param iGroup The group. 3077 * The value ~0U is reserved for compatibility with RTLogLogger[V] and is 3078 * only for internal usage! 3079 * @param pszFormat Format string. 3080 * @param args Format arguments. 3081 */ 3082 static void rtlogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args) 3083 { 3084 /* 3085 * Format the message and perhaps flush it. 3086 */ 3087 if (pLogger->fFlags & (RTLOGFLAGS_PREFIX_MASK | RTLOGFLAGS_USECRLF)) 3088 { 3089 RTLOGOUTPUTPREFIXEDARGS OutputArgs; 3090 OutputArgs.pLogger = pLogger; 3091 OutputArgs.iGroup = iGroup; 3092 OutputArgs.fFlags = fFlags; 3093 RTLogFormatV(rtLogOutputPrefixed, &OutputArgs, pszFormat, args); 3094 } 3095 else 3096 RTLogFormatV(rtLogOutput, pLogger, pszFormat, args); 3097 if ( !(pLogger->fFlags & RTLOGFLAGS_BUFFERED) 3098 && pLogger->offScratch) 3099 rtlogFlush(pLogger); 3100 } 3101 -
trunk/src/VBox/Storage/testcase/vditool.cpp
r33567 r36344 5 5 6 6 /* 7 * Copyright (C) 2006-201 0Oracle Corporation7 * Copyright (C) 2006-2011 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 398 398 static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES; 399 399 int rc = RTLogCreate(&pLogger, 0, "all", 400 NULL, RT_ELEMENTS(s_apszGroups), s_apszGroups, 401 RTLOGDEST_STDOUT, NULL); 400 NULL, RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT, 401 NULL /* pfnBeginEnd */, 0 /* cHistory */, 0 /* cbHistoryFileMax */, 0 /* uHistoryTimeMax */, 402 NULL); 402 403 RTLogRelSetDefaultInstance(pLogger); 403 404
Note:
See TracChangeset
for help on using the changeset viewer.