diff options
author | Andy Schwerin <schwerin@10gen.com> | 2013-07-01 14:35:03 -0400 |
---|---|---|
committer | Andy Schwerin <schwerin@10gen.com> | 2013-07-09 16:43:33 -0400 |
commit | ea22c3173541606519ddcb6da578b837a092b1c1 (patch) | |
tree | d3736e74ee67126f00466eec1686578ba8797749 /src/mongo/db/initialize_server_global_state.cpp | |
parent | 4bab9b0ee8dbffa00c4c86ea20195524a90f81f4 (diff) | |
download | mongo-ea22c3173541606519ddcb6da578b837a092b1c1.tar.gz |
SERVER-10084 New logging implementation.
This change-set:
* Introduces a new top-level directory, mongo/logger, containing most of the implementation of logging functionality formerly found in log.cpp/log.h.
* Cleans up existing, unusual uses of the logging system that were not trivially compatible with the new implementation.
* Replaces Logstream/Nulstream with a LogstreamBuilder object, whose destructor writes log messages. This new LogstreamBuilder is reentrant, unlike the old logging code, which was thread-safe but not reentrant. Additionally, std::endl is no longer required to terminate a log line. When a LogstreamBuilder goes out of scope, the log message gets committed.
* Separates the log system into several components: a global LogManager, several LogDomains, various kinds of Appenders (e.g., SyslogAppender) and Encoders (for formatting messages).
* Allows unit tests to capture and examine log output.
This patch does _not_ introduce support for hierarchical log domains, or for enabling and disabling specific log domains when the server is running in a multi-threaded mode. This is future work.
Diffstat (limited to 'src/mongo/db/initialize_server_global_state.cpp')
-rw-r--r-- | src/mongo/db/initialize_server_global_state.cpp | 87 |
1 files changed, 69 insertions, 18 deletions
diff --git a/src/mongo/db/initialize_server_global_state.cpp b/src/mongo/db/initialize_server_global_state.cpp index 9d20834d5b2..125ab6fccf1 100644 --- a/src/mongo/db/initialize_server_global_state.cpp +++ b/src/mongo/db/initialize_server_global_state.cpp @@ -19,15 +19,25 @@ #include "mongo/db/initialize_server_global_state.h" #include <boost/filesystem/operations.hpp> +#include <memory> #ifndef _WIN32 +#include <syslog.h> #include <sys/types.h> #include <sys/wait.h> #endif +#include "mongo/base/init.h" #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/security_key.h" #include "mongo/db/cmdline.h" +#include "mongo/logger/logger.h" +#include "mongo/logger/message_event.h" +#include "mongo/logger/message_event_utf8_encoder.h" +#include "mongo/logger/rotatable_file_appender.h" +#include "mongo/logger/rotatable_file_manager.h" +#include "mongo/logger/rotatable_file_writer.h" +#include "mongo/logger/syslog_appender.h" #include "mongo/platform/process_id.h" #include "mongo/util/log.h" #include "mongo/util/net/listen.h" @@ -132,14 +142,13 @@ namespace mongo { // this is run in the final child process (the server) - // stdout handled in initLogging - //fclose(stdout); - //freopen("/dev/null", "w", stdout); - - fclose(stderr); - fclose(stdin); + FILE* f = freopen("/dev/null", "w", stdout); + if ( f == NULL ) { + cout << "Cant reassign stdout while forking server process: " << strerror(errno) << endl; + return false; + } - FILE* f = freopen("/dev/null", "w", stderr); + f = freopen("/dev/null", "w", stderr); if ( f == NULL ) { cout << "Cant reassign stderr while forking server process: " << strerror(errno) << endl; return false; @@ -160,32 +169,74 @@ namespace mongo { _exit(EXIT_FAILURE); } - bool initializeServerGlobalState() { + MONGO_INITIALIZER_GENERAL(ServerLogRedirection, + ("GlobalLogManager", "globalVariablesConfigured"), + ("default"))( + InitializerContext*) { - Listener::globalTicketHolder.resize( cmdLine.maxConns ); + using logger::LogManager; + using logger::MessageEventEphemeral; + using logger::MessageEventDetailsEncoder; + using logger::MessageEventWithContextEncoder; + using logger::MessageLogDomain; + using logger::RotatableFileAppender; + using logger::StatusWithRotatableFileWriter; #ifndef _WIN32 - if (!fs::is_directory(cmdLine.socket)) { - cout << cmdLine.socket << " must be a directory" << endl; - return false; - } + using logger::SyslogAppender; if (cmdLine.logWithSyslog) { StringBuilder sb; sb << cmdLine.binaryName << "." << cmdLine.port; - Logstream::useSyslog( sb.str().c_str() ); + openlog(strdup(sb.str().c_str()), LOG_PID | LOG_CONS, LOG_USER); + LogManager* manager = logger::globalLogManager(); + manager->getGlobalDomain()->clearAppenders(); + manager->getGlobalDomain()->attachAppender( + MessageLogDomain::AppenderAutoPtr( + new SyslogAppender<MessageEventEphemeral>( + new logger::MessageEventWithContextEncoder))); + manager->getNamedDomain("javascriptOutput")->attachAppender( + MessageLogDomain::AppenderAutoPtr( + new SyslogAppender<MessageEventEphemeral>( + new logger::MessageEventWithContextEncoder))); } -#endif +#endif // defined(_WIN32) + if (!cmdLine.logpath.empty()) { fassert(16448, !cmdLine.logWithSyslog); string absoluteLogpath = boost::filesystem::absolute( cmdLine.logpath, cmdLine.cwd).string(); - if (!initLogging(absoluteLogpath, cmdLine.logAppend)) { - cout << "Bad logpath value: \"" << absoluteLogpath << "\"; terminating." << endl; - return false; + StatusWithRotatableFileWriter writer = + logger::globalRotatableFileManager()->openFile(absoluteLogpath, cmdLine.logAppend); + if (!writer.isOK()) { + return writer.getStatus(); } + LogManager* manager = logger::globalLogManager(); + manager->getGlobalDomain()->clearAppenders(); + manager->getGlobalDomain()->attachAppender( + MessageLogDomain::AppenderAutoPtr( + new RotatableFileAppender<MessageEventEphemeral>( + new MessageEventDetailsEncoder, writer.getValue()))); + manager->getNamedDomain("javascriptOutput")->attachAppender( + MessageLogDomain::AppenderAutoPtr( + new RotatableFileAppender<MessageEventEphemeral>( + new MessageEventDetailsEncoder, writer.getValue()))); } + return Status::OK(); + } + + bool initializeServerGlobalState() { + + Listener::globalTicketHolder.resize( cmdLine.maxConns ); + +#ifndef _WIN32 + if (!fs::is_directory(cmdLine.socket)) { + cout << cmdLine.socket << " must be a directory" << endl; + return false; + } +#endif + if (!cmdLine.pidFile.empty()) { writePidFile(cmdLine.pidFile); } |