summaryrefslogtreecommitdiff
path: root/util/log.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'util/log.cpp')
-rw-r--r--util/log.cpp69
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;