diff options
author | Tad Marshall <tad@10gen.com> | 2011-11-23 15:14:39 -0500 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2011-12-22 11:57:34 -0500 |
commit | 8cd62bc27c3cec5eba8a763c0529637ff6a6f8c3 (patch) | |
tree | 13793c4106ee28361c8a1e8d6724d7ad3fdf05b2 | |
parent | a719914879ba9fa847bb9df596df956506054acf (diff) | |
download | mongo-8cd62bc27c3cec5eba8a763c0529637ff6a6f8c3.tar.gz |
SERVER-2612 -- support logRotate under windows
Add code to support the "logRotate" server command (e.g. "db.runCommand({logRotate:1})").
Windows does not support the "kill -SIGUSR1 <pid>" alternative that is available in
Linux.
-rw-r--r-- | util/log.cpp | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/util/log.cpp b/util/log.cpp index 51f59be239b..0dc75eddf6e 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,60 +89,72 @@ namespace mongo { } if ( _file ) { -#ifdef _WIN32 - cout << "log rotation net yet supported on windows" << endl; - return; -#else #ifdef POSIX_FADV_DONTNEED posix_fadvise(fileno(_file), 0, 0, POSIX_FADV_DONTNEED); #endif - struct tm t; - localtime_r( &_opened , &t ); - + // 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; |