summaryrefslogtreecommitdiff
path: root/src/mongo/db/initialize_server_global_state.cpp
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@10gen.com>2013-07-01 14:35:03 -0400
committerAndy Schwerin <schwerin@10gen.com>2013-07-09 16:43:33 -0400
commitea22c3173541606519ddcb6da578b837a092b1c1 (patch)
treed3736e74ee67126f00466eec1686578ba8797749 /src/mongo/db/initialize_server_global_state.cpp
parent4bab9b0ee8dbffa00c4c86ea20195524a90f81f4 (diff)
downloadmongo-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.cpp87
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);
}