diff options
Diffstat (limited to 'util/log.cpp')
-rw-r--r-- | util/log.cpp | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/util/log.cpp b/util/log.cpp index bc48584..0dc75ed 100644 --- a/util/log.cpp +++ b/util/log.cpp @@ -25,12 +25,16 @@ using namespace std; #ifdef _WIN32 # include <io.h> +# include <fcntl.h> #else # include <cxxabi.h> # include <sys/file.h> #endif -//#include "../db/jsobj.h" +#ifdef _WIN32 +# define dup2 _dup2 // Microsoft headers use ISO C names +# define fileno _fileno +#endif namespace mongo { @@ -85,55 +89,72 @@ namespace mongo { } if ( _file ) { -#ifdef _WIN32 - cout << "log rotation net yet supported on windows" << endl; - return; -#else - struct tm t; - localtime_r( &_opened , &t ); +#ifdef POSIX_FADV_DONTNEED + posix_fadvise(fileno(_file), 0, 0, POSIX_FADV_DONTNEED); +#endif + + // Rename the (open) existing log file to a timestamped name stringstream ss; - ss << _path << "." << terseCurrentTime(false); + ss << _path << "." << terseCurrentTime( false ); string s = ss.str(); rename( _path.c_str() , s.c_str() ); -#endif } - - FILE* tmp = freopen(_path.c_str(), (_append ? "a" : "w"), stdout); - if (!tmp) { + FILE* tmp = 0; // The new file using the original logpath name + +#if _WIN32 + // We rename an open log file (above, on next rotation) and the trick to getting Windows to do that is + // to open the file with FILE_SHARE_DELETE. So, we can't use the freopen() call that non-Windows + // versions use because it would open the file without the FILE_SHARE_DELETE flag we need. + // + HANDLE newFileHandle = CreateFileA( + _path.c_str(), + GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if ( INVALID_HANDLE_VALUE != newFileHandle ) { + int newFileDescriptor = _open_osfhandle( reinterpret_cast<intptr_t>(newFileHandle), _O_APPEND ); + tmp = _fdopen( newFileDescriptor, _append ? "a" : "w" ); + } +#else + tmp = freopen(_path.c_str(), _append ? "a" : "w", stdout); +#endif + if ( !tmp ) { cerr << "can't open: " << _path.c_str() << " for log file" << endl; dbexit( EXIT_BADOPTIONS ); - assert(0); + assert( 0 ); } -#ifdef _WIN32 // windows has these functions it just gives them a funny name -# define dup2 _dup2 -# define fileno _fileno -#endif - // redirect stderr to log file - dup2(fileno(tmp), 2); + // redirect stdout and stderr to log file + dup2( fileno( tmp ), 1 ); // stdout + dup2( fileno( tmp ), 2 ); // stderr Logstream::setLogFile(tmp); // after this point no thread will be using old file +#if _WIN32 + if ( _file ) + fclose( _file ); // In Windows, we still have the old file open, close it now +#endif + #if 0 // enable to test redirection cout << "written to cout" << endl; cerr << "written to cerr" << endl; log() << "written to log()" << endl; #endif - _file = tmp; - _opened = time(0); + _file = tmp; // Save new file for next rotation } private: - bool _enabled; string _path; bool _append; - FILE * _file; - time_t _opened; } loggingManager; |