diff options
62 files changed, 62 insertions, 3540 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 7122a1e80d8..d73363814b1 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -54,7 +54,6 @@ env.SConscript( 'executor', 'idl', 'installer', - 'logger', 'logv2', 'platform', 'rpc', @@ -184,14 +183,6 @@ baseEnv.Library( 'bson/simple_bsonelement_comparator.cpp', 'bson/simple_bsonobj_comparator.cpp', 'bson/timestamp.cpp', - 'logger/component_message_log_domain.cpp', - 'logger/console.cpp', - 'logger/log_manager.cpp', - 'logger/logger.cpp', - 'logger/message_event_utf8_encoder.cpp', - 'logger/ramlog.cpp', - 'logger/rotatable_file_manager.cpp', - 'logger/rotatable_file_writer.cpp', 'logv2/attributes.cpp', 'logv2/bson_formatter.cpp', 'logv2/console.cpp', diff --git a/src/mongo/client/sdam/json_test_arg_parser.cpp b/src/mongo/client/sdam/json_test_arg_parser.cpp index 8a27e328114..f686d2a2b04 100644 --- a/src/mongo/client/sdam/json_test_arg_parser.cpp +++ b/src/mongo/client/sdam/json_test_arg_parser.cpp @@ -30,7 +30,6 @@ #include "mongo/client/sdam/json_test_arg_parser.h" -#include "mongo/logger/logger.h" #include "mongo/logv2/log.h" #include "mongo/util/options_parser/environment.h" #include "mongo/util/options_parser/option_section.h" diff --git a/src/mongo/client/sdam/sdam_json_test_runner.cpp b/src/mongo/client/sdam/sdam_json_test_runner.cpp index 6c59878e9e8..7639a1af0b0 100644 --- a/src/mongo/client/sdam/sdam_json_test_runner.cpp +++ b/src/mongo/client/sdam/sdam_json_test_runner.cpp @@ -43,7 +43,6 @@ #include "mongo/client/sdam/json_test_arg_parser.h" #include "mongo/client/sdam/sdam_configuration_parameters_gen.h" #include "mongo/client/sdam/topology_manager.h" -#include "mongo/logger/logger.h" #include "mongo/logv2/log.h" #include "mongo/stdx/unordered_set.h" #include "mongo/util/clock_source_mock.h" @@ -650,8 +649,9 @@ private: int main(int argc, char* argv[]) { ArgParser args(argc, argv); - ::mongo::logger::globalLogDomain()->setMinimumLoggedSeverity( - ::mongo::logv2::LogSeverity::Debug(args.Verbose())); + ::mongo::logv2::LogManager::global().getGlobalSettings().setMinimumLoggedSeverity( + MONGO_LOGV2_DEFAULT_COMPONENT, ::mongo::logv2::LogSeverity::Debug(args.Verbose())); + args.LogParams(); SdamJsonTestRunner testRunner(args.SourceDirectory(), args.TestFilters()); diff --git a/src/mongo/client/sdam/server_selection_json_test_runner.cpp b/src/mongo/client/sdam/server_selection_json_test_runner.cpp index ad689de6881..e8564240137 100644 --- a/src/mongo/client/sdam/server_selection_json_test_runner.cpp +++ b/src/mongo/client/sdam/server_selection_json_test_runner.cpp @@ -44,7 +44,6 @@ #include "mongo/client/sdam/server_description_builder.h" #include "mongo/client/sdam/server_selector.h" #include "mongo/client/sdam/topology_manager.h" -#include "mongo/logger/logger.h" #include "mongo/logv2/log.h" #include "mongo/stdx/unordered_set.h" #include "mongo/util/clock_source_mock.h" @@ -597,8 +596,8 @@ private: int main(int argc, char* argv[]) { ArgParser args(argc, argv); - ::mongo::logger::globalLogDomain()->setMinimumLoggedSeverity( - ::mongo::logv2::LogSeverity::Debug(args.Verbose())); + ::mongo::logv2::LogManager::global().getGlobalSettings().setMinimumLoggedSeverity( + MONGO_LOGV2_DEFAULT_COMPONENT, ::mongo::logv2::LogSeverity::Debug(args.Verbose())); args.LogParams(); ServerSelectionJsonTestRunner testRunner(args.SourceDirectory(), args.TestFilters()); diff --git a/src/mongo/db/commands/generic.cpp b/src/mongo/db/commands/generic.cpp index 19a43f0aa3e..6b4b9600fc1 100644 --- a/src/mongo/db/commands/generic.cpp +++ b/src/mongo/db/commands/generic.cpp @@ -35,7 +35,6 @@ #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/log_process_details.h" #include "mongo/util/processinfo.h" -#include "mongo/util/ramlog.h" #include <sstream> #include <string> diff --git a/src/mongo/db/commands/generic_servers.cpp b/src/mongo/db/commands/generic_servers.cpp index 6f7590620fe..6622321f88b 100644 --- a/src/mongo/db/commands/generic_servers.cpp +++ b/src/mongo/db/commands/generic_servers.cpp @@ -45,7 +45,6 @@ #include "mongo/util/net/socket_utils.h" #include "mongo/util/ntservice.h" #include "mongo/util/processinfo.h" -#include "mongo/util/ramlog.h" #include <string> #include <vector> diff --git a/src/mongo/db/initialize_server_global_state.cpp b/src/mongo/db/initialize_server_global_state.cpp index fdb4744a3fd..7f38a1d4e66 100644 --- a/src/mongo/db/initialize_server_global_state.cpp +++ b/src/mongo/db/initialize_server_global_state.cpp @@ -49,15 +49,6 @@ #include "mongo/base/init.h" #include "mongo/config.h" #include "mongo/db/server_options.h" -#include "mongo/logger/console_appender.h" -#include "mongo/logger/logger.h" -#include "mongo/logger/message_event.h" -#include "mongo/logger/message_event_utf8_encoder.h" -#include "mongo/logger/ramlog.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/logv2/log.h" #include "mongo/logv2/log_domain_global.h" #include "mongo/platform/process_id.h" @@ -296,21 +287,12 @@ void forkServerOrDie() { } MONGO_INITIALIZER_GENERAL(ServerLogRedirection, - ("GlobalLogManager", "EndStartupOptionHandling", "ForkServer"), + ("EndStartupOptionHandling", "ForkServer"), ("default")) (InitializerContext*) { - using logger::LogManager; - using logger::MessageEventDetailsEncoder; - using logger::MessageEventEphemeral; - using logger::MessageEventWithContextEncoder; - using logger::MessageLogDomain; - using logger::RotatableFileAppender; - using logger::StatusWithRotatableFileWriter; - // Hook up this global into our logging encoder auto& lv2Manager = logv2::LogManager::global(); logv2::LogDomainGlobal::ConfigurationOptions lv2Config; - MessageEventDetailsEncoder::setMaxLogSizeKBSource(gMaxLogAttributeSizeKB); lv2Config.maxAttributeSizeKB = &gMaxLogAttributeSizeKB; bool writeServerRestartedAfterLogConfig = false; diff --git a/src/mongo/db/initialize_server_global_state.idl b/src/mongo/db/initialize_server_global_state.idl index 7dd9cafd850..fbe73a53c2f 100644 --- a/src/mongo/db/initialize_server_global_state.idl +++ b/src/mongo/db/initialize_server_global_state.idl @@ -28,7 +28,6 @@ global: cpp_namespace: mongo cpp_includes: - - mongo/logger/message_event_utf8_encoder.h - mongo/logv2/constants.h server_parameters: diff --git a/src/mongo/db/mongod_main.cpp b/src/mongo/db/mongod_main.cpp index e77c153854a..22cdf3d00e5 100644 --- a/src/mongo/db/mongod_main.cpp +++ b/src/mongo/db/mongod_main.cpp @@ -191,7 +191,6 @@ #include "mongo/util/periodic_runner.h" #include "mongo/util/periodic_runner_factory.h" #include "mongo/util/quick_exit.h" -#include "mongo/util/ramlog.h" #include "mongo/util/scopeguard.h" #include "mongo/util/sequence_util.h" #include "mongo/util/signal_handlers.h" diff --git a/src/mongo/db/repl/apply_ops_test.cpp b/src/mongo/db/repl/apply_ops_test.cpp index d370d9c6b92..ed2b3fbe492 100644 --- a/src/mongo/db/repl/apply_ops_test.cpp +++ b/src/mongo/db/repl/apply_ops_test.cpp @@ -40,7 +40,6 @@ #include "mongo/db/repl/replication_coordinator_mock.h" #include "mongo/db/repl/storage_interface_impl.h" #include "mongo/db/service_context_d_test_fixture.h" -#include "mongo/logger/logger.h" #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/unittest/log_test.h" diff --git a/src/mongo/db/repl/cloner_test_fixture.cpp b/src/mongo/db/repl/cloner_test_fixture.cpp index 830b4118e54..8931bc84ff4 100644 --- a/src/mongo/db/repl/cloner_test_fixture.cpp +++ b/src/mongo/db/repl/cloner_test_fixture.cpp @@ -37,7 +37,6 @@ #include "mongo/db/service_context_test_fixture.h" #include "mongo/db/storage/storage_engine_mock.h" #include "mongo/dbtests/mock/mock_dbclient_connection.h" -#include "mongo/logger/logger.h" #include "mongo/unittest/unittest.h" #include "mongo/util/concurrency/thread_pool.h" diff --git a/src/mongo/db/repl/topology_coordinator_v1_test.cpp b/src/mongo/db/repl/topology_coordinator_v1_test.cpp index 3ee3971acbd..c3b36b81bda 100644 --- a/src/mongo/db/repl/topology_coordinator_v1_test.cpp +++ b/src/mongo/db/repl/topology_coordinator_v1_test.cpp @@ -45,7 +45,6 @@ #include "mongo/db/server_options.h" #include "mongo/db/service_context.h" #include "mongo/executor/task_executor.h" -#include "mongo/logger/logger.h" #include "mongo/logv2/log.h" #include "mongo/rpc/metadata/oplog_query_metadata.h" #include "mongo/rpc/metadata/repl_set_metadata.h" diff --git a/src/mongo/db/server_options_helpers.cpp b/src/mongo/db/server_options_helpers.cpp index a0171882e4f..5a6ea0d7917 100644 --- a/src/mongo/db/server_options_helpers.cpp +++ b/src/mongo/db/server_options_helpers.cpp @@ -47,7 +47,6 @@ #include "mongo/config.h" #include "mongo/db/server_options.h" #include "mongo/idl/server_parameter.h" -#include "mongo/logger/message_event_utf8_encoder.h" #include "mongo/logv2/log_component.h" #include "mongo/logv2/log_component_settings.h" #include "mongo/logv2/log_manager.h" @@ -308,14 +307,11 @@ Status storeBaseOptions(const moe::Environment& params) { } if (params.count("systemLog.timeStampFormat")) { - using logger::MessageEventDetailsEncoder; std::string formatterName = params["systemLog.timeStampFormat"].as<string>(); if (formatterName == "iso8601-utc") { - MessageEventDetailsEncoder::setDateFormatter(outputDateAsISOStringUTC); serverGlobalParams.logTimestampFormat = logv2::LogTimestampFormat::kISO8601UTC; setDateFormatIsLocalTimezone(false); } else if (formatterName == "iso8601-local") { - MessageEventDetailsEncoder::setDateFormatter(outputDateAsISOStringLocal); serverGlobalParams.logTimestampFormat = logv2::LogTimestampFormat::kISO8601Local; setDateFormatIsLocalTimezone(true); } else { diff --git a/src/mongo/db/server_options_server_helpers.cpp b/src/mongo/db/server_options_server_helpers.cpp index c895931704d..dc58d92985d 100644 --- a/src/mongo/db/server_options_server_helpers.cpp +++ b/src/mongo/db/server_options_server_helpers.cpp @@ -48,7 +48,6 @@ #include "mongo/db/server_options.h" #include "mongo/db/server_options_base.h" #include "mongo/db/server_options_helpers.h" -#include "mongo/logger/message_event_utf8_encoder.h" #include "mongo/logv2/log.h" #include "mongo/logv2/log_component.h" #include "mongo/transport/message_compressor_registry.h" diff --git a/src/mongo/db/server_options_test.cpp b/src/mongo/db/server_options_test.cpp index 26510278e08..d09cde9b797 100644 --- a/src/mongo/db/server_options_test.cpp +++ b/src/mongo/db/server_options_test.cpp @@ -53,7 +53,6 @@ #include "mongo/db/server_options_base.h" #include "mongo/db/server_options_nongeneral_gen.h" #include "mongo/db/server_options_server_helpers.h" -#include "mongo/logger/logger.h" #include "mongo/unittest/log_test.h" #include "mongo/unittest/unittest.h" #include "mongo/util/errno_util.h" diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp index 9e76a225af5..67c125f0813 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine_test.cpp @@ -46,7 +46,6 @@ #include "mongo/db/storage/wiredtiger/wiredtiger_global_options.h" #include "mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h" #include "mongo/db/storage/wiredtiger/wiredtiger_record_store.h" -#include "mongo/logger/logger.h" #include "mongo/logv2/log.h" #include "mongo/unittest/log_test.h" #include "mongo/unittest/temp_dir.h" diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp index d1842c982c2..2579f47687a 100644 --- a/src/mongo/db/transaction_participant_test.cpp +++ b/src/mongo/db/transaction_participant_test.cpp @@ -51,7 +51,6 @@ #include "mongo/db/stats/fill_locker_info.h" #include "mongo/db/transaction_participant.h" #include "mongo/db/transaction_participant_gen.h" -#include "mongo/logger/logger.h" #include "mongo/stdx/future.h" #include "mongo/unittest/barrier.h" #include "mongo/unittest/death_test.h" diff --git a/src/mongo/dbtests/jstests.cpp b/src/mongo/dbtests/jstests.cpp index 4244b9bb4dc..7a6522c5c81 100644 --- a/src/mongo/dbtests/jstests.cpp +++ b/src/mongo/dbtests/jstests.cpp @@ -40,7 +40,6 @@ #include "mongo/db/hasher.h" #include "mongo/db/json.h" #include "mongo/dbtests/dbtests.h" -#include "mongo/logger/logger.h" #include "mongo/platform/decimal128.h" #include "mongo/scripting/engine.h" #include "mongo/shell/shell_utils.h" @@ -164,104 +163,6 @@ public: } }; -/** Installs a tee for auditing log messages in the same thread. */ -class LogRecordingScope { -public: - LogRecordingScope() - : _handle(mongo::logger::globalLogDomain()->attachAppender(std::make_unique<Tee>(this))) {} - ~LogRecordingScope() { - mongo::logger::globalLogDomain()->detachAppender(_handle); - } - /** @return most recent log entry. */ - bool logged() const { - return _logged; - } - -private: - class Tee : public mongo::logger::Appender<mongo::logger::MessageEventEphemeral> { - public: - Tee(LogRecordingScope* scope) : _scope(scope) {} - Status append(const logger::MessageEventEphemeral& event) override { - // Don't want to consider logging by background threads. - if (mongo::getThreadName() == _scope->_threadName) { - _scope->_logged = true; - } - return Status::OK(); - } - - private: - LogRecordingScope* _scope; - }; - - bool _logged = false; - const string _threadName = mongo::getThreadName().toString(); - mongo::logger::MessageLogDomain::AppenderHandle _handle; -}; - -/** Error logging in Scope::exec(). */ -template <ScopeFactory scopeFactory> -class ExecLogError { -public: - void run() { - unique_ptr<Scope> scope((getGlobalScriptEngine()->*scopeFactory)()); - - // No error is logged when reportError == false. - ASSERT(!scope->exec("notAFunction()", "foo", false, false, false)); - ASSERT(!_logger.logged()); - - // No error is logged for a valid statement. - ASSERT(scope->exec("validStatement = true", "foo", false, true, false)); - ASSERT(!_logger.logged()); - - // An error is logged for an invalid statement when reportError == true. - ASSERT(!scope->exec("notAFunction()", "foo", false, true, false)); - - // Don't check if we're using SpiderMonkey. Our threading model breaks - // this test - // TODO: figure out a way to check for SpiderMonkey - auto ivs = getGlobalScriptEngine()->getInterpreterVersionString(); - std::string prefix("MozJS"); - if (ivs.compare(0, prefix.length(), prefix) != 0) { - ASSERT(_logger.logged()); - } - } - -private: - LogRecordingScope _logger; -}; - -/** Error logging in Scope::invoke(). */ -template <ScopeFactory scopeFactory> -class InvokeLogError { -public: - void run() { - unique_ptr<Scope> scope((getGlobalScriptEngine()->*scopeFactory)()); - - // No error is logged for a valid statement. - ASSERT_EQUALS(0, scope->invoke("validStatement = true", nullptr, nullptr)); - ASSERT(!_logger.logged()); - - // An error is logged for an invalid statement. - try { - scope->invoke("notAFunction()", nullptr, nullptr); - } catch (const DBException&) { - // ignore the exception; just test that we logged something - } - - // Don't check if we're using SpiderMonkey. Our threading model breaks - // this test - // TODO: figure out a way to check for SpiderMonkey - auto ivs = getGlobalScriptEngine()->getInterpreterVersionString(); - std::string prefix("MozJS"); - if (ivs.compare(0, prefix.length(), prefix) != 0) { - ASSERT(_logger.logged()); - } - } - -private: - LogRecordingScope _logger; -}; - template <ScopeFactory scopeFactory> class ObjectMapping { public: @@ -1520,8 +1421,6 @@ public: add<ResetScope<scopeFactory>>(); add<FalseTests<scopeFactory>>(); add<SimpleFunctions<scopeFactory>>(); - add<ExecLogError<scopeFactory>>(); - add<InvokeLogError<scopeFactory>>(); add<ExecTimeout<scopeFactory>>(); add<ExecNoTimeout<scopeFactory>>(); add<InvokeTimeout<scopeFactory>>(); diff --git a/src/mongo/dbtests/repltests.cpp b/src/mongo/dbtests/repltests.cpp index 502acfa0f91..a9cd656c0e9 100644 --- a/src/mongo/dbtests/repltests.cpp +++ b/src/mongo/dbtests/repltests.cpp @@ -46,7 +46,6 @@ #include "mongo/db/repl/repl_client_info.h" #include "mongo/db/repl/replication_coordinator_mock.h" #include "mongo/dbtests/dbtests.h" -#include "mongo/logger/logger.h" #include "mongo/logv2/log.h" #include "mongo/transport/transport_layer_asio.h" diff --git a/src/mongo/logger/SConscript b/src/mongo/logger/SConscript deleted file mode 100644 index 91e950f2f1c..00000000000 --- a/src/mongo/logger/SConscript +++ /dev/null @@ -1,30 +0,0 @@ -# -*- mode: python -*- - -Import("env") - -env = env.Clone() - -# writes multi-byte sequences to console -# to support manual testing of console stream under Windows -# output should be visually verified under Command Prompt or Power Shell -env.Program( - target='console_test', - source=[ - 'console_test.cpp', - ], - LIBDEPS=[ - '$BUILD_DIR/mongo/base', - '$BUILD_DIR/mongo/unittest/unittest_main' - ], - AIB_COMPONENT="standalone-console-test", -) - -env.CppUnitTest( - target='logger_test', - source=[ - 'rotatable_file_writer_test.cpp', - ], - LIBDEPS=[ - '$BUILD_DIR/mongo/base', - ], -) diff --git a/src/mongo/logger/appender.h b/src/mongo/logger/appender.h deleted file mode 100644 index a14bc5b7cc3..00000000000 --- a/src/mongo/logger/appender.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/base/status.h" - -namespace mongo { -namespace logger { - -/** - * Interface for sinks in a logging system. The core of logging is when events of type E are - * appended to instances of Appender<E>. - * - * Example concrete instances are ConsoleAppender<E>, SyslogAppender<E> and - * RotatableFileAppender<E>. - */ -template <typename E> -class Appender { -public: - typedef E Event; - - virtual ~Appender() {} - - /** - * Appends "event", returns Status::OK() on success. - */ - virtual Status append(const Event& event) = 0; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/component_message_log_domain.cpp b/src/mongo/logger/component_message_log_domain.cpp deleted file mode 100644 index c49938bf265..00000000000 --- a/src/mongo/logger/component_message_log_domain.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/logger/component_message_log_domain.h" - -namespace mongo { -namespace logger { - -ComponentMessageLogDomain::ComponentMessageLogDomain() {} - -ComponentMessageLogDomain::~ComponentMessageLogDomain() {} - -bool ComponentMessageLogDomain::hasMinimumLogSeverity(logv2::LogComponent component) const { - return _settings.hasMinimumLogSeverity(component); -} - -bool ComponentMessageLogDomain::shouldLog(logv2::LogComponent component, - logv2::LogSeverity severity) const { - return _settings.shouldLog(component, severity); -} - -bool ComponentMessageLogDomain::shouldLog(logv2::LogComponent component1, - logv2::LogComponent component2, - logv2::LogSeverity severity) const { - return _settings.shouldLog(component1, severity) || _settings.shouldLog(component2, severity); -} - -bool ComponentMessageLogDomain::shouldLog(logv2::LogComponent component1, - logv2::LogComponent component2, - logv2::LogComponent component3, - logv2::LogSeverity severity) const { - return _settings.shouldLog(component1, severity) || _settings.shouldLog(component2, severity) || - _settings.shouldLog(component3, severity); -} - -logv2::LogSeverity ComponentMessageLogDomain::getMinimumLogSeverity() const { - return _settings.getMinimumLogSeverity(logv2::LogComponent::kDefault); -} - -logv2::LogSeverity ComponentMessageLogDomain::getMinimumLogSeverity( - logv2::LogComponent component) const { - return _settings.getMinimumLogSeverity(component); -} - -void ComponentMessageLogDomain::setMinimumLoggedSeverity(logv2::LogSeverity severity) { - _settings.setMinimumLoggedSeverity(logv2::LogComponent::kDefault, severity); -} - -void ComponentMessageLogDomain::setMinimumLoggedSeverity(logv2::LogComponent component, - logv2::LogSeverity severity) { - _settings.setMinimumLoggedSeverity(component, severity); -} - -void ComponentMessageLogDomain::clearMinimumLoggedSeverity(logv2::LogComponent component) { - _settings.clearMinimumLoggedSeverity(component); -} - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/component_message_log_domain.h b/src/mongo/logger/component_message_log_domain.h deleted file mode 100644 index 638f701bc96..00000000000 --- a/src/mongo/logger/component_message_log_domain.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/logger/message_log_domain.h" -#include "mongo/logv2/log_component_settings.h" - -namespace mongo { -namespace logger { - -/** - * Logging domain for ephemeral messages with minimum severity. - */ -class ComponentMessageLogDomain : public MessageLogDomain { - ComponentMessageLogDomain(const ComponentMessageLogDomain&) = delete; - ComponentMessageLogDomain& operator=(const ComponentMessageLogDomain&) = delete; - -public: - ComponentMessageLogDomain(); - - ~ComponentMessageLogDomain(); - - /** - * Predicate that answers the question, "Should I, the caller, append to you, the log - * domain, messages of the given severity?" True means yes. - */ - bool shouldLog(logv2::LogComponent component, logv2::LogSeverity severity) const; - bool shouldLog(logv2::LogComponent component1, - logv2::LogComponent component2, - logv2::LogSeverity severity) const; - bool shouldLog(logv2::LogComponent component1, - logv2::LogComponent component2, - logv2::LogComponent component3, - logv2::LogSeverity severity) const; - - /** - * Returns true if a minimum log severity has been set for this component. - * Called by log level commands to query component severity configuration. - */ - bool hasMinimumLogSeverity(logv2::LogComponent component) const; - - /** - * Gets the minimum severity of messages that should be sent to this LogDomain. - */ - logv2::LogSeverity getMinimumLogSeverity() const; - logv2::LogSeverity getMinimumLogSeverity(logv2::LogComponent component) const; - - /** - * Sets the minimum severity of messages that should be sent to this LogDomain. - */ - void setMinimumLoggedSeverity(logv2::LogSeverity severity); - void setMinimumLoggedSeverity(logv2::LogComponent, logv2::LogSeverity severity); - - /** - * Clears the minimum log severity for component. - * For kDefault, severity level is initialized to default value. - */ - void clearMinimumLoggedSeverity(logv2::LogComponent component); - -private: - logv2::LogComponentSettings _settings; - AtomicWord<bool> _shouldRedact{false}; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/console.cpp b/src/mongo/logger/console.cpp deleted file mode 100644 index 3646076b245..00000000000 --- a/src/mongo/logger/console.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/logger/console.h" - -#include <iostream> - -#include "mongo/base/init.h" -#include "mongo/config.h" - -#ifdef _WIN32 -#include <io.h> -#endif - -namespace mongo { -namespace { - -stdx::mutex& consoleMutex() { - static stdx::mutex instance; // NOLINT - return instance; -} - -#if defined(_WIN32) -/** - * Very basic implementation of a stream buffer backed by - * a fixed sized internal buffer that flushes - * to the console using WriteConsoleW(). - * - * Implementation notes: - * WriteConsoleW() vs std::wcout - * std::wcout produces garbage output for messages containing 2-byte sequences - * under all the terminal environments tested (Command Prompt, Power Shell, Cygwin). - * 3-byte sequences will cause std::wcout to go into a bad state (failbit=true). - * Also tried calling _setmode( _fileno(stdout), ...) with various modes (_O_U16TEXT, - * ...), all of which produces garbage results on the console. - */ - -class ConsoleStreamBuffer : public std::streambuf { -public: - explicit ConsoleStreamBuffer(HANDLE consoleHandle) : _consoleHandle(consoleHandle) { - // leave room at end of buffer for overflow character - setp(&(_buffer[0]), &(_buffer[_bufferSize - 1])); - } - - int_type overflow(int_type ch) override { - if (ch == traits_type::eof()) { - return ch; - } - - // push to end of buffer - *(pptr()) = ch; - pbump(1); - - // If the overflow byte is part of a UTF-8 multi-byte sequence, - // locate the beginning of the byte sequence and determine if - // the byte sequence represents a complete unicode code point. - // If the sequence is complete, proceed to flush the buffer. - // If the sequence is incomplete, flush the buffer up to but - // not including incomplete code point before re-inserting the - // bytes back into the internal buffer. - - if (ch & 0x80) { - // length of unicode byte sequence can be at most 4 in length. See RFC 3629 - int length = 0; - - // do not look back beyond 4 characters (maximum length for UTF-8 sequences) - // p will point to first byte of unicode code point upon exit from loop - char* sequenceBegin = pptr(); - for (int i = 0; i < 4; i++) { - length++; - sequenceBegin--; - // check for beginning of code point - if (*sequenceBegin & 0x40) { - break; - } - // check for invalid byte. all bytes in multi-byte sequence - // should have left most bit set - if (!(*sequenceBegin & 0x80)) { - break; - } - } - - // get expected length of code point - // cast to unsigned type to avoid sign extension - int expectedLength = _bitsToSequenceLength[uint8_t(*sequenceBegin) >> 4]; - - // if beginning of sequence was not found, expectedLength will be zero and - // we will consider the multi-byte sequence to be garbage and flush the - // entire buffer - - // if code point is incomplete, rewind and flush buffer before - // refilling with incomplete byte sequence - if (length < expectedLength) { - // rewind internal buffer to end before unfinished byte sequence - pbump(-length); - - // store result. should eventually return - // original overflow character on success - int_type result = flushToConsole() ? ch : traits_type::eof(); - - // after flushing pptr() will point to beginning of buffer - // copy bytes starting from p to beginning of internal buffer - for (int i = 0; i < length; i++) { - *(pptr()) = *sequenceBegin; - pbump(1); - sequenceBegin++; - } - - return result; - } - } - - return flushToConsole() ? ch : traits_type::eof(); - } - - int sync() override { - return flushToConsole() ? 0 : -1; - } - -private: - // keep this value reasonable. this class is used primarily - // to buffer log messages - static const size_t _bufferSize = 1024U; - - // mapping of leftmost 4 bits of first byte of code point - // to number of expected bytes in complete code point - // 110x -> 2 - // 1110 -> 3 - // 1111 -> 4 - static const int _bitsToSequenceLength[]; - - // In the event that WriteConsoleW fails, return false - // to allow stream to update error state flags (most likely badbit) - - bool flushToConsole() { - std::ptrdiff_t n = pptr() - pbase(); - pbump(-n); - - // convert multi-byte buffer to wide characters and output using WriteConsoleW - - wchar_t bufferWide[_bufferSize]; - int length = MultiByteToWideChar(CP_UTF8, 0, _buffer, n, bufferWide, _bufferSize); - const wchar_t* unwrittenBegin = bufferWide; - int unwrittenCount = length; // m holds number of unwritten wide characters in buffer - - while (unwrittenCount > 0) { - DWORD written; - BOOL success = - WriteConsoleW(_consoleHandle, unwrittenBegin, unwrittenCount, &written, nullptr); - if (!success) { - return false; - } - unwrittenCount -= written; - unwrittenBegin += written; - } - -#ifdef MONGO_CONFIG_DEBUG_BUILD - if (IsDebuggerPresent()) { - bufferWide[std::min(static_cast<size_t>(length), _bufferSize - 1)] = L'\0'; - OutputDebugStringW(bufferWide); - } -#endif - - return true; - } - - HANDLE _consoleHandle; - char _buffer[_bufferSize]; -}; - -// 0x0 - 0xb - invalid start of multi-byte sequence` - -const int ConsoleStreamBuffer::_bitsToSequenceLength[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 4}; - -// Create a output stream to redirect console writes -// to WriteConsoleW() if there is a real console available (FILE_TYPE_CHAR) -// Otherwise, return std::cout -// -// Command Prompt and Power Shell (GetFileType() == FILE_TYPE_CHAR): -// Set the font to either Lucida Console or Consolas to see 2 and 3-byte sequences. -// The fonts provided by the existing Windows console programs do not -// render complex 4-byte sequences propertly. -// File redirection (GetFileType() == FILE_TYPE_DISK): -// When the output is redirected from the console, WriteConsoleW will fail and we -// will fall back on using _write(). -// Cygwin (GetFileType() == FILE_TYPE_PIPE): -// An "invalid handle" error message will be displayed on first log message and -// flushToConsole() will fall back on using _write(). - -std::ostream* getWindowsOutputStream() { - HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD consoleType = GetFileType(consoleHandle); - if (consoleType != FILE_TYPE_CHAR) { - return &std::cout; - } - std::streambuf* windowsStreamBuffer = new ConsoleStreamBuffer(consoleHandle); - std::ostream* windowsOutputStream = new std::ostream(windowsStreamBuffer); - return windowsOutputStream; -} - -std::ostream* windowsOutputStream = getWindowsOutputStream(); -#endif // defined(_WIN32) - -// This initializer causes a Console object to be constructed, which, -// in turn, causes std::ios_base::Init::Init to be called from a -// single threaded context, ensuring that std::cout is prepared in a -// single threaded context and available for all TUs. This is safe -// even for TUs that do not include <iostream>, since either the call -// to Console() here is the first call to that constructor, or the -// first logging call writing via the Console will happen elsewhere in -// the initalizer chain. -MONGO_INITIALIZER(EnsureIosBaseInitConstructed)(InitializerContext*) { - Console forInitializationOnly; - return Status::OK(); -} - -} // namespace - -Console::Console() : _consoleLock() { - // Don't get clever and make this non-static. At least when using - // libc++, ios::base::Init::Init is not thread safe (see - // SERVER-22974). Instead, rely on C++11 magic statics to ensure - // that we create this at the right time. Some systems (like - // VS2013 and older), don't actually implement magic statics - // yet. But that is OK! We ensure that this is called from - // single-threaded context via a mongo initializer above. - static const std::ios_base::Init initializeCout; - - stdx::unique_lock<stdx::mutex> lk(consoleMutex()); - lk.swap(_consoleLock); -} - -std::ostream& Console::out() { -#if defined(_WIN32) - // check value of ostream in case - // static initializer has not been invoked - if (windowsOutputStream) { - return *windowsOutputStream; - } -#endif // defined(_WIN32) - return std::cout; -} - -} // namespace mongo diff --git a/src/mongo/logger/console.h b/src/mongo/logger/console.h deleted file mode 100644 index ecc6b6556ab..00000000000 --- a/src/mongo/logger/console.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <iosfwd> - -#include "mongo/platform/mutex.h" - -namespace mongo { - -/** - * Representation of the console. Use this in place of cout/cin, in applications that write to - * the console from multiple threads (such as those that use the logging subsystem). - * - * The Console type is synchronized such that only one instance may be in the fully constructed - * state at a time. Correct usage is to instantiate one, write or read from it as desired, and - * then destroy it. - * - * The console streams accept UTF-8 encoded data, and attempt to write it to the attached - * console faithfully. - * - * TODO(schwerin): If no console is attached on Windows (services), should writes here go to the - * event logger? - */ -class Console { -public: - Console(); - - std::ostream& out(); - -private: - stdx::unique_lock<stdx::mutex> _consoleLock; -}; - -} // namespace mongo diff --git a/src/mongo/logger/console_appender.h b/src/mongo/logger/console_appender.h deleted file mode 100644 index 26a75ede2c5..00000000000 --- a/src/mongo/logger/console_appender.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - - -#include "mongo/base/status.h" -#include "mongo/logger/appender.h" -#include "mongo/logger/console.h" -#include "mongo/logger/encoder.h" - -namespace mongo { -namespace logger { - -/** - * Appender for writing to the console (stdout). - */ -template <typename Event, typename ConsoleType = Console> -class ConsoleAppender : public Appender<Event> { - ConsoleAppender(const ConsoleAppender&) = delete; - ConsoleAppender& operator=(const ConsoleAppender&) = delete; - -public: - typedef Encoder<Event> EventEncoder; - - // TODO: Remove this ctor once raw pointer use is gone - explicit ConsoleAppender(EventEncoder* encoder) : _encoder(encoder) {} - explicit ConsoleAppender(std::unique_ptr<EventEncoder> encoder) - : _encoder(std::move(encoder)) {} - virtual Status append(const Event& event) { - ConsoleType console; - _encoder->encode(event, console.out()).flush(); - if (!console.out()) - return Status(ErrorCodes::LogWriteFailed, "Error writing log message to console."); - return Status::OK(); - } - -private: - std::unique_ptr<EventEncoder> _encoder; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/console_test.cpp b/src/mongo/logger/console_test.cpp deleted file mode 100644 index 72c4f0370a7..00000000000 --- a/src/mongo/logger/console_test.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -/** - * Unit tests of the unittest framework itself. - */ - -#include "mongo/logger/console.h" -#include "mongo/unittest/unittest.h" -#include <iostream> -#include <ostream> -#include <sstream> -#include <string> - -namespace { - -using std::cout; -using std::endl; -using std::ostream; -using std::string; -using std::stringstream; - -TEST(ConsoleTest, testUtf8) { - // this constant should match ConsoleStreamBuffer::bufferSize in console.cpp - const size_t bufferSize = 1024U; - - mongo::Console console; - ostream& out = console.out(); - - // example unicode code points are from: - // http://en.wikipedia.org/wiki/UTF-8#Examples - struct { - size_t length; - const char* utf8CodePoint; - } data[] = { - {2U, "\xc2\xa2"}, // U+0024 - {3U, "\xe2\x82\xac"}, // U+20AC - {4U, "\xf0\xa4\xad\xa2"}, // U+24B62 - {0, "unused"}, - }; - - // generate strings with unicode point located near end of buffer - // to see how console stream handles incomplete unicode multi-byte sequences - - // to see these multibtye code points in the Windows terminal, set the console font - // to Lucida. Currently the 4-byte sequence used in the test data is still not being - // displayed properly. - - for (int i = 0; data[i].length > 0; i++) { - for (size_t prefixLength = 0; prefixLength <= data[i].length; prefixLength++) { - stringstream descriptionStream; - descriptionStream << "ConsoleTest::testUtf8 - checking handling of " - << "multi-byte sequence. This line contains " << prefixLength - << " of " << data[i].length << "-byte sequence " - << "before the end of the console's internal " << bufferSize - << "-byte buffer"; - string description = descriptionStream.str(); - size_t padLength = bufferSize - prefixLength; - string padding(padLength - description.length(), '.'); - string line = description + padding + data[i].utf8CodePoint; - out << line << endl; - } - } - - // check if out is std::cout - out << "ConsoleTest::testUtf8 - Console::out() is using " - << (out.rdbuf() == cout.rdbuf() ? "std::cout" : "custom output stream") << endl; -} - -} // namespace diff --git a/src/mongo/logger/encoder.h b/src/mongo/logger/encoder.h deleted file mode 100644 index 29226dc2f5c..00000000000 --- a/src/mongo/logger/encoder.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <iosfwd> - -namespace mongo { -namespace logger { - -/** - * Interface for objects that encode Events to std::ostreams. - * - * Most appender implementations write to streams, and Encoders represent the process of - * encoding events into streams. - */ -template <typename Event> -class Encoder { -public: - virtual ~Encoder() {} - virtual std::ostream& encode(const Event& event, std::ostream& os) = 0; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/log_domain.h b/src/mongo/logger/log_domain.h deleted file mode 100644 index d2eadd98b9c..00000000000 --- a/src/mongo/logger/log_domain.h +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <list> -#include <memory> -#include <string> - -#include "mongo/logger/appender.h" -#include "mongo/logv2/log_severity.h" - -namespace mongo::logger { - -/** - * Logging domain for events of type E. - * - * A logging domain consists of a set of Appenders. - * - * TODO: The severity doesn't seem to apply for auditing, maybe it only belongs on the - * MessageLogManager? We don't really have multiple tunable logging domains, right now. Other - * than the global domain, shouldLog doesn't matter. - * - * Usage: Configure the log domain in a single threaded context, using attachAppender, - * detachAppender and clearAppenders(). The domain takes ownership of any attached appender, - * returning an AppenderHandle for each attached appender. That handle may be used later to - * detach the appender, causing the domain to release ownership of it. Mostly, this - * attach/detach behavior is useful in testing, since you do not want to change the appenders of - * a domain that is currently receiving append() calls. - * - * Once you've configured the domain, call append() from potentially many threads, to add log - * messages. - */ -template <typename E> -class LogDomain { - using Event = E; - using AppenderList = std::list<std::unique_ptr<Appender<Event>>>; - using AppendersIter = typename AppenderList::iterator; - -public: - /** - * Opaque handle returned by attachAppender(), which can be subsequently passed to - * detachAppender() to detach an appender from an instance of LogDomain. - */ - class AppenderHandle { - private: - friend class LogDomain; - explicit AppenderHandle(AppendersIter iter) : _iter{iter} {} - AppendersIter _iter; - }; - - LogDomain() = default; - ~LogDomain() = default; - - LogDomain(const LogDomain&) = delete; - LogDomain& operator=(const LogDomain&) = delete; - - /** - * Receives an event for logging, calling append(event) on all attached appenders. - * - * If any appender fails, the behavior is determined by the abortOnFailure flag: - * *If abortOnFailure is set, ::abort() is immediately called. - * *If abortOnFailure is not set, the error is returned and no further appenders are called. - */ - Status append(const Event& event) { - for (auto& appender : _appenders) { - if (Status status = appender->append(event); !status.isOK()) { - if (_abortOnFailure) { - ::abort(); - } - return status; - } - } - return Status::OK(); - } - - /** - * Gets the state of the abortOnFailure flag. - */ - bool getAbortOnFailure() const { - return _abortOnFailure; - } - - /** - * Sets the state of the abortOnFailure flag. - */ - void setAbortOnFailure(bool abortOnFailure) { - _abortOnFailure = abortOnFailure; - } - - /** - * Attaches `appender`. Returns a handle for use with `detachAppender`. - */ - AppenderHandle attachAppender(std::unique_ptr<Appender<Event>> appender) { - return AppenderHandle(_appenders.insert(_appenders.end(), std::move(appender))); - } - - /** - * Detaches the appender referenced by `handle`, returning it. - */ - std::unique_ptr<Appender<Event>> detachAppender(AppenderHandle handle) { - auto result = std::move(*handle._iter); - _appenders.erase(handle._iter); - return result; - } - - /** - * Destroy all attached appenders, invalidating all handles. - */ - void clearAppenders() { - _appenders.clear(); - } - -private: - AppenderList _appenders; - bool _abortOnFailure = false; -}; - -} // namespace mongo::logger diff --git a/src/mongo/logger/log_manager.cpp b/src/mongo/logger/log_manager.cpp deleted file mode 100644 index febbf917c7c..00000000000 --- a/src/mongo/logger/log_manager.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kDefault - -#include "mongo/platform/basic.h" - -#include "mongo/logger/log_manager.h" - -#include "mongo/logger/console_appender.h" -#include "mongo/logger/logv2_appender.h" -#include "mongo/logger/message_event_utf8_encoder.h" -#include "mongo/logv2/log_domain_global.h" - -namespace mongo { -namespace logger { - -LogManager::LogManager() { - reattachDefaultConsoleAppender(); -} - -LogManager::~LogManager() { - for (DomainsByNameMap::iterator iter = _domains.begin(); iter != _domains.end(); ++iter) { - delete iter->second; - } -} - -MessageLogDomain* LogManager::getNamedDomain(const std::string& name) { - MessageLogDomain*& domain = _domains[name]; - if (!domain) { - domain = new MessageLogDomain; - } - return domain; -} - -void LogManager::detachDefaultConsoleAppender() { - invariant(_defaultAppender); - _globalDomain.detachAppender(*_defaultAppender); - _defaultAppender = {}; -} - -void LogManager::reattachDefaultConsoleAppender() { - invariant(!_defaultAppender); - auto appender = std::make_unique<logger::LogV2Appender<MessageEventEphemeral>>( - &logv2::LogManager::global().getGlobalDomain(), false); - _defaultAppender = _globalDomain.attachAppender(std::move(appender)); -} - -bool LogManager::isDefaultConsoleAppenderAttached() const { - return static_cast<bool>(_defaultAppender); -} - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/log_manager.h b/src/mongo/logger/log_manager.h deleted file mode 100644 index a2ca582e124..00000000000 --- a/src/mongo/logger/log_manager.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <boost/optional.hpp> -#include <string> - -#include "mongo/logger/component_message_log_domain.h" -#include "mongo/logger/rotatable_file_writer.h" -#include "mongo/stdx/unordered_map.h" - -namespace mongo { -namespace logger { - -/** - * Container for managing log domains. - * - * Use this while setting up the logging system, before launching any threads. - */ -class LogManager { - LogManager(const LogManager&) = delete; - LogManager& operator=(const LogManager&) = delete; - -public: - LogManager(); - ~LogManager(); - - /** - * Gets the global domain for this manager. It has no name. - * Will attach a default console log appender. - */ - ComponentMessageLogDomain* getGlobalDomain() { - return &_globalDomain; - } - - /** - * Get the log domain with the given name, creating if needed. - */ - MessageLogDomain* getNamedDomain(const std::string& name); - - /** - * Detaches the default console log appender - * - * @note This function is not thread safe. - */ - void detachDefaultConsoleAppender(); - - /** - * Reattaches the default console log appender - * - * @note This function is not thread safe. - */ - void reattachDefaultConsoleAppender(); - - /** - * Checks if the default console log appender is attached - */ - bool isDefaultConsoleAppenderAttached() const; - -private: - typedef stdx::unordered_map<std::string, MessageLogDomain*> DomainsByNameMap; - - DomainsByNameMap _domains; - ComponentMessageLogDomain _globalDomain; - boost::optional<ComponentMessageLogDomain::AppenderHandle> _defaultAppender; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/logger.cpp b/src/mongo/logger/logger.cpp deleted file mode 100644 index 2068e5fa6c8..00000000000 --- a/src/mongo/logger/logger.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/logger/logger.h" - -#include "mongo/base/init.h" -#include "mongo/base/status.h" -#include "mongo/platform/compiler.h" - -namespace mongo { -namespace logger { - -static LogManager* theGlobalLogManager; // NULL at program start, before even static - // initialization. - -static RotatableFileManager theGlobalRotatableFileManager; - -LogManager* globalLogManager() { - if (MONGO_unlikely(!theGlobalLogManager)) { - theGlobalLogManager = new LogManager; - } - return theGlobalLogManager; -} - -RotatableFileManager* globalRotatableFileManager() { - return &theGlobalRotatableFileManager; -} - -/** - * Just in case no static initializer called globalLogManager, make sure that the global log - * manager is instantiated while we're still in a single-threaded context. - */ -MONGO_INITIALIZER_GENERAL(GlobalLogManager, ("ValidateLocale"), ("default"))(InitializerContext*) { - globalLogManager(); - return Status::OK(); -} - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/logger.h b/src/mongo/logger/logger.h deleted file mode 100644 index 9adb6017c36..00000000000 --- a/src/mongo/logger/logger.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/logger/log_manager.h" -#include "mongo/logger/message_log_domain.h" -#include "mongo/logger/rotatable_file_manager.h" - -namespace mongo { -namespace logger { - -/** - * Gets a global singleton instance of RotatableFileManager. - */ -RotatableFileManager* globalRotatableFileManager(); - -/** - * Gets a global singleton instance of LogManager. - */ -LogManager* globalLogManager(); - -/** - * Gets the global MessageLogDomain associated for the global log manager. - */ -inline ComponentMessageLogDomain* globalLogDomain() { - return globalLogManager()->getGlobalDomain(); -} - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/logv2_appender.h b/src/mongo/logger/logv2_appender.h deleted file mode 100644 index bde2add88d5..00000000000 --- a/src/mongo/logger/logv2_appender.h +++ /dev/null @@ -1,129 +0,0 @@ -/** - * Copyright (C) 2019-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/base/status.h" -#include "mongo/logger/appender.h" -#include "mongo/logger/message_event_utf8_encoder.h" -#include "mongo/logv2/log_component.h" -#include "mongo/logv2/log_detail.h" -#include "mongo/logv2/log_domain.h" -#include "mongo/logv2/log_options.h" -#include "mongo/logv2/log_tag.h" - -namespace mongo { -namespace logger { - - -namespace { - -auto findTeeTag(StringData teeName) { - static constexpr std::pair<StringData, logv2::LogTag::Value> kTees[] = { - {"startupWarnings"_sd, logv2::LogTag::kStartupWarnings}, - }; - if (teeName.empty()) - return logv2::LogTag::kNone; - for (auto&& e : kTees) - if (e.first == teeName) - return e.second; - MONGO_UNREACHABLE; -} - -} // namespace - -/** - * Appender for writing to a logv2 domain - */ -template <typename Event> -class LogV2Appender : public Appender<Event> { -public: - LogV2Appender(const LogV2Appender&) = delete; - LogV2Appender& operator=(const LogV2Appender&) = delete; - - explicit LogV2Appender(logv2::LogDomain* domain, - bool warnOnLargeMessages, - logv2::LogTag extraTag = logv2::LogTag::kNone) - : _domain(domain), _tag(extraTag), _warnOnLargeMessages(warnOnLargeMessages) {} - - Status append(const Event& event) override { - - auto logTagValue = findTeeTag(event.getTeeName()); - auto message = event.getMessage(); - if (message.endsWith("\n")) { - message = message.substr(0, message.size() - 1); - } - size_t maxSizeKB = MessageEventDetailsEncoder::getMaxLogSizeKB(); - - if (_warnOnLargeMessages && event.isTruncatable() && message.size() > maxSizeKB * 1024) { - logv2::detail::doLog( - 0, - logv2::LogSeverity::cast(event.getSeverity().toInt()), - logv2::LogOptions{ - event.getComponent(), - _domain, - logv2::LogTag{static_cast<logv2::LogTag::Value>( - static_cast<std::underlying_type_t<logv2::LogTag::Value>>(logTagValue) | - static_cast<std::underlying_type_t<logv2::LogTag::Value>>(_tag))}}, - - "warning: log line attempted ({}kB) over max size ({}kB)", - "size"_attr = message.size() / 1024, - "maxSize"_attr = maxSizeKB); - } - - logv2::detail::doLog( - 0, - // We need to cast from the v1 logging severity to the equivalent v2 severity - logv2::LogSeverity::cast(event.getSeverity().toInt()), - - // Similarly, we need to transcode the options. They don't offer a cast - // operator, so we need to do some metaprogramming on the types. - logv2::LogOptions{ - event.getComponent(), - _domain, - logv2::LogTag{static_cast<logv2::LogTag::Value>( - static_cast<std::underlying_type_t<logv2::LogTag::Value>>(logTagValue) | - static_cast<std::underlying_type_t<logv2::LogTag::Value>>(_tag))}, - event.isTruncatable() ? logv2::LogTruncation::Enabled - : logv2::LogTruncation::Disabled, - logv2::FatalMode::kContinue}, - - "{}", - "message"_attr = message); - return Status::OK(); - } - -private: - logv2::LogDomain* _domain; - logv2::LogTag _tag; - bool _warnOnLargeMessages; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/message_event.h b/src/mongo/logger/message_event.h deleted file mode 100644 index 146afc248df..00000000000 --- a/src/mongo/logger/message_event.h +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <cstdint> - -#include "mongo/base/string_data.h" -#include "mongo/logv2/log_component.h" -#include "mongo/logv2/log_severity.h" -#include "mongo/util/time_support.h" - -namespace mongo { -namespace logger { - -/** - * Free form text log message object that does not own the storage behind its message and - * contextName. - * - * Used and owned by one thread. This is the message type used by MessageLogDomain. - */ -class MessageEventEphemeral { -public: - MessageEventEphemeral(Date_t date, - logv2::LogSeverity severity, - StringData contextName, - StringData message) - : MessageEventEphemeral( - date, severity, logv2::LogComponent::kDefault, contextName, message) {} - - MessageEventEphemeral(Date_t date, - logv2::LogSeverity severity, - logv2::LogComponent component, - StringData contextName, - StringData message) - : _date(date), - _severity(severity), - _component(component), - _contextName(contextName), - _message(message) {} - - void setTeeName(StringData tee) { - _teeName = tee; - } - MessageEventEphemeral& setIsTruncatable(bool value) { - _isTruncatable = value; - return *this; - } - - StringData getTeeName() const { - return _teeName; - } - Date_t getDate() const { - return _date; - } - logv2::LogSeverity getSeverity() const { - return _severity; - } - logv2::LogComponent getComponent() const { - return _component; - } - StringData getContextName() const { - return _contextName; - } - StringData getMessage() const { - return _message; - } - bool isTruncatable() const { - return _isTruncatable; - } - -private: - Date_t _date; - logv2::LogSeverity _severity; - logv2::LogComponent _component; - StringData _contextName; - StringData _message; - bool _isTruncatable = true; - StringData _teeName; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/message_event_utf8_encoder.cpp b/src/mongo/logger/message_event_utf8_encoder.cpp deleted file mode 100644 index 3ffcc7b9354..00000000000 --- a/src/mongo/logger/message_event_utf8_encoder.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/logger/message_event_utf8_encoder.h" - -#include <iostream> - -#include "mongo/util/time_support.h" - -namespace mongo { - -namespace logger { - -const int LogContext::kDefaultMaxLogSizeKB; - -LogContext::LogContext() - : _dateFormatter{outputDateAsISOStringLocal}, _maxLogSizeSource{nullptr} {}; - -LogContext& MessageEventDetailsEncoder::getGlobalLogContext() { - static LogContext context; - return context; -} - -void MessageEventDetailsEncoder::setMaxLogSizeKBSource(const AtomicWord<int>& source) { - invariant(getGlobalLogContext()._maxLogSizeSource == nullptr); - getGlobalLogContext()._maxLogSizeSource = &source; -} - -int MessageEventDetailsEncoder::getMaxLogSizeKB() { - auto* source = getGlobalLogContext()._maxLogSizeSource; - - // If not initialized, use the default - if (source == nullptr) - return LogContext::kDefaultMaxLogSizeKB; - - // If initialized, use the reference - // TODO: This seems like a CST seq'd load we don't need. `loadRelaxed()`? - return source->load(); -} - -void MessageEventDetailsEncoder::setDateFormatter(DateFormatter dateFormatter) { - getGlobalLogContext()._dateFormatter = dateFormatter; -} - -DateFormatter MessageEventDetailsEncoder::getDateFormatter() { - return getGlobalLogContext()._dateFormatter; -} - -namespace { -#ifdef _WIN32 -constexpr auto kEOL = "\r\n"_sd; -#else -constexpr auto kEOL = "\n"_sd; -#endif -} // namespace - -MessageEventDetailsEncoder::~MessageEventDetailsEncoder() {} -std::ostream& MessageEventDetailsEncoder::encode(const MessageEventEphemeral& event, - std::ostream& os) { - const auto maxLogSizeKB = getMaxLogSizeKB(); - - const size_t maxLogSize = maxLogSizeKB * 1024; - - getDateFormatter()(os, event.getDate()); - os << ' '; - - const auto severity = event.getSeverity(); - os << severity.toStringDataCompact(); - os << ' '; - - logv2::LogComponent component = event.getComponent(); - os << component; - os << ' '; - - StringData contextName = event.getContextName(); - if (!contextName.empty()) { - os << '[' << contextName << "] "; - } - - StringData msg = event.getMessage(); - -#ifdef _WIN32 - // We need to translate embedded Unix style line endings into Windows style endings. - std::string tempstr; - size_t embeddedNewLine = msg.find('\n'); - - if (embeddedNewLine != std::string::npos) { - tempstr = msg.toString().replace(embeddedNewLine, 1, "\r\n"); - - embeddedNewLine = tempstr.find('\n', embeddedNewLine + 2); - while (embeddedNewLine != std::string::npos) { - tempstr = tempstr.replace(embeddedNewLine, 1, "\r\n"); - - embeddedNewLine = tempstr.find('\n', embeddedNewLine + 2); - } - - msg = tempstr; - } -#endif - - if (event.isTruncatable() && msg.size() > maxLogSize) { - os << "warning: log line attempted (" << msg.size() / 1024 << "kB) over max size (" - << maxLogSizeKB << "kB), printing beginning and end ... "; - os << msg.substr(0, maxLogSize / 3); - os << " .......... "; - os << msg.substr(msg.size() - (maxLogSize / 3)); - } else { - os << msg; - } - - if (!msg.endsWith(kEOL)) - os << kEOL; - - return os; -} - -MessageEventWithContextEncoder::~MessageEventWithContextEncoder() {} -std::ostream& MessageEventWithContextEncoder::encode(const MessageEventEphemeral& event, - std::ostream& os) { - logv2::LogComponent component = event.getComponent(); - os << component; - os << ' '; - - StringData contextName = event.getContextName(); - if (!contextName.empty()) { - os << '[' << contextName << "] "; - } - StringData message = event.getMessage(); - os << message; - if (!message.endsWith("\n")) - os << '\n'; - return os; -} - -MessageEventUnadornedEncoder::~MessageEventUnadornedEncoder() {} -std::ostream& MessageEventUnadornedEncoder::encode(const MessageEventEphemeral& event, - std::ostream& os) { - StringData message = event.getMessage(); - os << message; - if (!message.endsWith("\n")) - os << '\n'; - return os; -} - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/message_event_utf8_encoder.h b/src/mongo/logger/message_event_utf8_encoder.h deleted file mode 100644 index 89102401ecf..00000000000 --- a/src/mongo/logger/message_event_utf8_encoder.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <iosfwd> - -#include "mongo/logger/encoder.h" -#include "mongo/logger/message_event.h" -#include "mongo/util/time_support.h" - -namespace mongo { -namespace logger { - -typedef void (*DateFormatter)(std::ostream&, Date_t); - -/** - * This is the logging context for the MessageEventDetailsEncoder below. It actively controls how - * the output is encoded. As of now, there can be only one. - */ -struct LogContext { - static constexpr int kDefaultMaxLogSizeKB = 10; - - LogContext(); - - DateFormatter _dateFormatter; - const AtomicWord<int>* _maxLogSizeSource; -}; - -/** - * Encoder that writes log messages of the style that MongoDB writes to console and files. - */ -class MessageEventDetailsEncoder : public Encoder<MessageEventEphemeral> { -public: - /** - * Sets the date formatter function for all instances of MessageEventDetailsEncoder. - * - * Only and always safe to call during single-threaded execution, as in during start-up - * intiailization. - */ - static void setDateFormatter(DateFormatter dateFormatter); - - /** - * Gets the date formatter function in use by instances of MessageEventDetailsEncoder. - * - * Always safe to call. - */ - static DateFormatter getDateFormatter(); - - /** - * Sets a static wrapper to track an atomic variable reference - * - * Only safe to call once during single-threaded execution, as in during start-up - * initialization. - */ - static void setMaxLogSizeKBSource(const AtomicWord<int>& source); - - /** - * Loads a max log size from the reference set above. If no reference has been set, it returns - * the default. Note that this has to be an atomic operation, cache values when possible. - * - * Always safe to call. - */ - static int getMaxLogSizeKB(); - - virtual ~MessageEventDetailsEncoder(); - virtual std::ostream& encode(const MessageEventEphemeral& event, std::ostream& os); - -private: - /** - * Grab the singleton LogContext - */ - static LogContext& getGlobalLogContext(); -}; - -/** - * Encoder that generates log messages suitable for syslog. - */ -class MessageEventWithContextEncoder : public Encoder<MessageEventEphemeral> { -public: - virtual ~MessageEventWithContextEncoder(); - virtual std::ostream& encode(const MessageEventEphemeral& event, std::ostream& os); -}; - - -/** - * Encoder that generates log messages containing only the raw text of the message. - */ -class MessageEventUnadornedEncoder : public Encoder<MessageEventEphemeral> { -public: - virtual ~MessageEventUnadornedEncoder(); - virtual std::ostream& encode(const MessageEventEphemeral& event, std::ostream& os); -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/message_log_domain.h b/src/mongo/logger/message_log_domain.h deleted file mode 100644 index d5cd0754124..00000000000 --- a/src/mongo/logger/message_log_domain.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <memory> -#include <string> -#include <vector> - -#include "mongo/logger/log_domain.h" -#include "mongo/logger/message_event.h" - -namespace mongo { -namespace logger { - -typedef LogDomain<MessageEventEphemeral> MessageLogDomain; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/ramlog.cpp b/src/mongo/logger/ramlog.cpp deleted file mode 100644 index 938ab194608..00000000000 --- a/src/mongo/logger/ramlog.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/logger/ramlog.h" - -#include "mongo/base/init.h" -#include "mongo/base/status.h" -#include "mongo/logger/message_event_utf8_encoder.h" -#include "mongo/util/str.h" - -namespace mongo { - -using std::string; - -namespace { -typedef std::map<string, RamLog*> RM; -stdx::mutex* _namedLock = nullptr; -RM* _named = nullptr; - -} // namespace - -RamLog::RamLog(const std::string& name) : _name(name), _totalLinesWritten(0), _lastWrite(0) { - clear(); - for (int i = 0; i < N; i++) - lines[i][C - 1] = 0; -} - -RamLog::~RamLog() {} - -void RamLog::write(const std::string& str) { - stdx::lock_guard<stdx::mutex> lk(_mutex); - _lastWrite = time(nullptr); - _totalLinesWritten++; - - char* p = lines[(h + n) % N]; - - unsigned sz = str.size(); - if (0 == sz) - return; - if (sz < C) { - if (str.c_str()[sz - 1] == '\n') { - memcpy(p, str.c_str(), sz - 1); - p[sz - 1] = 0; - } else - memcpy(p, str.c_str(), sz); - } else { - memcpy(p, str.c_str(), C - 1); - } - - if (n < N) - n++; - else - h = (h + 1) % N; -} - -void RamLog::clear() { - stdx::lock_guard<stdx::mutex> lk(_mutex); - _totalLinesWritten = 0; - _lastWrite = 0; - h = 0; - n = 0; - for (int i = 0; i < N; i++) - lines[i][0] = 0; -} - -time_t RamLog::LineIterator::lastWrite() { - return _ramlog->_lastWrite; -} - -long long RamLog::LineIterator::getTotalLinesWritten() { - return _ramlog->_totalLinesWritten; -} - -const char* RamLog::getLine_inlock(unsigned lineNumber) const { - if (lineNumber >= n) - return ""; - return lines[(lineNumber + h) % N]; // h = 0 unless n == N, hence modulo N. -} - -int RamLog::repeats(const std::vector<const char*>& v, int i) { - for (int j = i - 1; j >= 0 && j + 8 > i; j--) { - if (strcmp(v[i] + 24, v[j] + 24) == 0) { - for (int x = 1;; x++) { - if (j + x == i) - return j; - if (i + x >= (int)v.size()) - return -1; - if (strcmp(v[i + x] + 24, v[j + x] + 24)) - return -1; - } - return -1; - } - } - return -1; -} - - -string RamLog::clean(const std::vector<const char*>& v, int i, string line) { - if (line.empty()) - line = v[i]; - if (i > 0 && strncmp(v[i], v[i - 1], 11) == 0) - return string(" ") + line.substr(11); - return v[i]; -} - -/* turn http:... into an anchor */ -string RamLog::linkify(const char* s) { - const char* p = s; - const char* h = strstr(p, "http://"); - if (h == nullptr) - return s; - - const char* sp = h + 7; - while (*sp && *sp != ' ') - sp++; - - string url(h, sp - h); - std::stringstream ss; - ss << string(s, h - s) << "<a href=\"" << url << "\">" << url << "</a>" << sp; - return ss.str(); -} - -RamLog::LineIterator::LineIterator(RamLog* ramlog) - : _ramlog(ramlog), _lock(ramlog->_mutex), _nextLineIndex(0) {} - -RamLogAppender::RamLogAppender(RamLog* ramlog) : _ramlog(ramlog) {} -RamLogAppender::~RamLogAppender() {} - -Status RamLogAppender::append(const logger::MessageEventEphemeral& event) { - std::ostringstream ss; - logger::MessageEventDetailsEncoder encoder; - encoder.encode(event, ss); - _ramlog->write(ss.str()); - return Status::OK(); -} - -// --------------- -// static things -// --------------- - -RamLog* RamLog::get(const std::string& name) { - if (!_namedLock) { - // Guaranteed to happen before multi-threaded operation. - _namedLock = new stdx::mutex(); // NOLINT - } - - stdx::lock_guard<stdx::mutex> lk(*_namedLock); - if (!_named) { - // Guaranteed to happen before multi-threaded operation. - _named = new RM(); - } - - auto [iter, isNew] = _named->try_emplace(name); - if (isNew) - iter->second = new RamLog(name); - return iter->second; -} - -RamLog* RamLog::getIfExists(const std::string& name) { - if (!_named) - return nullptr; - stdx::lock_guard<stdx::mutex> lk(*_namedLock); - auto iter = _named->find(name); - return iter == _named->end() ? nullptr : iter->second; -} - -void RamLog::getNames(std::vector<string>& names) { - if (!_named) - return; - - stdx::lock_guard<stdx::mutex> lk(*_namedLock); - for (RM::iterator i = _named->begin(); i != _named->end(); ++i) { - if (i->second->n) - names.push_back(i->first); - } -} - -/** - * Ensures that RamLog::get() is called at least once during single-threaded operation, - * ensuring that _namedLock and _named are initialized safely. - */ -MONGO_INITIALIZER(RamLogCatalog)(InitializerContext*) { - if (!_namedLock) { - if (_named) { - return Status(ErrorCodes::InternalError, - "Inconsistent intiailization of RamLogCatalog."); - } - _namedLock = new stdx::mutex(); // NOLINT - _named = new RM(); - } - - return Status::OK(); -} -} // namespace mongo diff --git a/src/mongo/logger/ramlog.h b/src/mongo/logger/ramlog.h deleted file mode 100644 index 49f6fd140b5..00000000000 --- a/src/mongo/logger/ramlog.h +++ /dev/null @@ -1,190 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <boost/version.hpp> -#include <sstream> -#include <string> -#include <vector> - -#include "mongo/base/status.h" -#include "mongo/base/string_data.h" -#include "mongo/logger/appender.h" -#include "mongo/logger/message_event.h" -#include "mongo/logger/tee.h" -#include "mongo/platform/mutex.h" -#include "mongo/util/concurrency/mutex.h" - -namespace mongo { - -/** - * Fixed-capacity log of line-oriented messages. - * - * Holds up to RamLog::N lines of up to RamLog::C bytes, each. - * - * RamLogs are stored in a global registry, accessed via RamLog::get() and - * RamLog::getIfExists(). - * - * RamLogs and their registry are self-synchronizing. See documentary comments. - * To read a RamLog, instantiate a RamLog::LineIterator, documented below. - */ -class RamLog : public logger::Tee { - RamLog(const RamLog&) = delete; - RamLog& operator=(const RamLog&) = delete; - -public: - class LineIterator; - friend class RamLog::LineIterator; - - /** - * Returns a pointer to the ramlog named "name", creating one if it did not already exist. - * - * Synchronizes on the RamLog catalog lock, _namedLock. - */ - static RamLog* get(const std::string& name); - - /** - * Returns a pointer to the ramlog named "name", or NULL if no such ramlog exists. - * - * Synchronizes on the RamLog catalog lock, _namedLock. - */ - static RamLog* getIfExists(const std::string& name); - - /** - * Writes the names of all existing ramlogs into "names". - * - * Synchronizes on the RamLog catalog lock, _namedLock. - */ - static void getNames(std::vector<std::string>& names); - - /** - * Writes "str" as a line into the RamLog. If "str" is longer than the maximum - * line size, RamLog::C, truncates the line to the first C bytes. If "str" - * is shorter than RamLog::C and has a terminal '\n', it omits that character. - * - * Synchronized on the instance's own mutex, _mutex. - */ - void write(const std::string& str); - - const std::string& getName() const { - return _name; - }; - - /** - * Empties out the RamLog. - */ - void clear(); - -private: - static int repeats(const std::vector<const char*>& v, int i); - static std::string clean(const std::vector<const char*>& v, int i, std::string line = ""); - - /* turn http:... into an anchor */ - static std::string linkify(const char* s); - - explicit RamLog(const std::string& name); - ~RamLog(); // want this private as we want to leak so we can use them till the very end - - enum { - N = 1024, // number of lines - C = 2048 // max size of line - }; - - const char* getLine_inlock(unsigned lineNumber) const; - - stdx::mutex _mutex; // Guards all non-static data. // NOLINT - char lines[N][C]; - unsigned h; // current position - unsigned n; // number of lines stores 0 o N - std::string _name; - long long _totalLinesWritten; - - time_t _lastWrite; -}; - -/** - * Iterator over the lines of a RamLog. - * - * Also acts as a means of inspecting other properites of a ramlog consistently. - * - * Instances of LineIterator hold the lock for the underlying RamLog for their whole lifetime, - * and so should not be kept around. - */ -class RamLog::LineIterator { - LineIterator(const LineIterator&) = delete; - LineIterator& operator=(const LineIterator&) = delete; - -public: - explicit LineIterator(RamLog* ramlog); - - /** - * Returns true if there are more lines available to return by calls to next(). - */ - bool more() const { - return _nextLineIndex < _ramlog->n; - } - - /** - * Returns the next line and advances the iterator. - */ - const char* next() { - return _ramlog->getLine_inlock(_nextLineIndex++); // Postfix increment. - } - - /** - * Returns the time of the last write to the ramlog. - */ - time_t lastWrite(); - - /** - * Returns the total number of lines ever written to the ramlog. - */ - long long getTotalLinesWritten(); - -private: - const RamLog* _ramlog; - stdx::lock_guard<stdx::mutex> _lock; - unsigned _nextLineIndex; -}; - -/** - * Appender for appending MessageEvents to a RamLog. - */ -class RamLogAppender : public logger::Appender<logger::MessageEventEphemeral> { -public: - explicit RamLogAppender(RamLog* ramlog); - virtual ~RamLogAppender(); - - virtual Status append(const logger::MessageEventEphemeral& event); - -private: - RamLog* _ramlog; -}; -} // namespace mongo diff --git a/src/mongo/logger/redaction.cpp b/src/mongo/logger/redaction.cpp deleted file mode 100644 index 7e200e9993b..00000000000 --- a/src/mongo/logger/redaction.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kDefault - -#include "mongo/platform/basic.h" - -#include "mongo/logv2/redaction.h" - -#include "mongo/base/status.h" -#include "mongo/bson/bsonobj.h" -#include "mongo/util/assert_util.h" -#include "mongo/util/log.h" - -namespace mongo { - -namespace { - -constexpr auto kRedactionDefaultMask = "###"_sd; - -} // namespace - -BSONObj redact(const BSONObj& objectToRedact) { - if (!logger::globalLogDomain()->shouldRedactLogs()) { - return objectToRedact; - } - - return objectToRedact.redact(); -} - -StringData redact(StringData stringToRedact) { - if (!logger::globalLogDomain()->shouldRedactLogs()) { - return stringToRedact; - } - - // Return the default mask. - return kRedactionDefaultMask; -} - -std::string redact(const Status& statusToRedact) { - if (!logger::globalLogDomain()->shouldRedactLogs()) { - return statusToRedact.toString(); - } - - // Construct a status representation without the reason() - StringBuilder sb; - sb << statusToRedact.codeString(); - if (!statusToRedact.isOK()) - sb << ": " << kRedactionDefaultMask; - return sb.str(); -} - -std::string redact(const DBException& exceptionToRedact) { - if (!logger::globalLogDomain()->shouldRedactLogs()) { - return exceptionToRedact.toString(); - } - - // Construct an exception representation with the what() - std::stringstream ss; - ss << exceptionToRedact.code() << " " << kRedactionDefaultMask; - return ss.str(); -} - -} // namespace mongo diff --git a/src/mongo/logger/rotatable_file_appender.h b/src/mongo/logger/rotatable_file_appender.h deleted file mode 100644 index 72f5a6fae94..00000000000 --- a/src/mongo/logger/rotatable_file_appender.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - - -#include "mongo/base/status.h" -#include "mongo/logger/appender.h" -#include "mongo/logger/encoder.h" -#include "mongo/logger/rotatable_file_writer.h" - -namespace mongo { -namespace logger { - -/** - * Appender for writing to instances of RotatableFileWriter. - */ -template <typename Event> -class RotatableFileAppender : public Appender<Event> { - RotatableFileAppender(const RotatableFileAppender&) = delete; - RotatableFileAppender& operator=(const RotatableFileAppender&) = delete; - -public: - typedef Encoder<Event> EventEncoder; - - // TODO: Remove this ctor once raw pointer use is gone - RotatableFileAppender(EventEncoder* encoder, RotatableFileWriter* writer) - : _encoder(encoder), _writer(writer) {} - /** - * Constructs an appender, that owns "encoder", but not "writer." Caller must - * keep "writer" in scope at least as long as the constructed appender. - */ - RotatableFileAppender(std::unique_ptr<EventEncoder> encoder, RotatableFileWriter* writer) - : _encoder(std::move(encoder)), _writer(writer) {} - - virtual Status append(const Event& event) { - RotatableFileWriter::Use useWriter(_writer); - Status status = useWriter.status(); - if (!status.isOK()) - return status; - _encoder->encode(event, useWriter.stream()).flush(); - return useWriter.status(); - } - -private: - std::unique_ptr<EventEncoder> _encoder; - RotatableFileWriter* _writer; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/rotatable_file_manager.cpp b/src/mongo/logger/rotatable_file_manager.cpp deleted file mode 100644 index ca5b1c3f745..00000000000 --- a/src/mongo/logger/rotatable_file_manager.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/logger/rotatable_file_manager.h" - -#include "mongo/logger/rotatable_file_writer.h" - -namespace mongo { -namespace logger { - -RotatableFileManager::RotatableFileManager() {} - -RotatableFileManager::~RotatableFileManager() { - for (WriterByNameMap::iterator iter = _writers.begin(); iter != _writers.end(); ++iter) { - delete iter->second; - } -} - -StatusWithRotatableFileWriter RotatableFileManager::openFile(const std::string& fileName, - bool append) { - if (_writers.count(fileName) > 0) { - return StatusWithRotatableFileWriter(ErrorCodes::FileAlreadyOpen, - "File \"" + fileName + "\" already opened."); - } - std::unique_ptr<RotatableFileWriter> writer(new RotatableFileWriter); - RotatableFileWriter::Use writerUse(writer.get()); - Status status = writerUse.setFileName(fileName, append); - if (!status.isOK()) - return StatusWithRotatableFileWriter(status); - _writers.insert(std::make_pair(fileName, writer.get())); - return StatusWith<RotatableFileWriter*>(writer.release()); -} - -RotatableFileWriter* RotatableFileManager::getFile(const std::string& name) { - auto iter = _writers.find(name); - return iter == _writers.end() ? nullptr : iter->second; -} - -RotatableFileManager::FileNameStatusPairVector RotatableFileManager::rotateAll( - bool renameFiles, const std::string& renameTargetSuffix) { - FileNameStatusPairVector badStatuses; - for (WriterByNameMap::const_iterator iter = _writers.begin(); iter != _writers.end(); ++iter) { - Status status = RotatableFileWriter::Use(iter->second) - .rotate(renameFiles, iter->first + renameTargetSuffix); - if (!status.isOK()) { - badStatuses.push_back(std::make_pair(iter->first, status)); - } - } - return badStatuses; -} - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/rotatable_file_manager.h b/src/mongo/logger/rotatable_file_manager.h deleted file mode 100644 index 79b5f97a7c1..00000000000 --- a/src/mongo/logger/rotatable_file_manager.h +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <string> -#include <utility> -#include <vector> - -#include "mongo/base/status.h" -#include "mongo/base/status_with.h" -#include "mongo/logger/rotatable_file_writer.h" -#include "mongo/stdx/unordered_map.h" - -namespace mongo { -namespace logger { - -typedef StatusWith<RotatableFileWriter*> StatusWithRotatableFileWriter; - -/** - * Utility object that owns and manages rotation for RotatableFileWriters. - * - * Unlike RotatableFileWriter, this type leaves synchronization to its consumers. - */ -class RotatableFileManager { - RotatableFileManager(const RotatableFileManager&) = delete; - RotatableFileManager& operator=(const RotatableFileManager&) = delete; - -public: - typedef std::pair<std::string, Status> FileNameStatusPair; - typedef std::vector<FileNameStatusPair> FileNameStatusPairVector; - - RotatableFileManager(); - ~RotatableFileManager(); - - /** - * Opens "name" in mode "append" and returns a new RotatableFileWriter set to - * operate on the file. - * - * If the manager already has opened "name", returns ErrorCodes::FileAlreadyOpen. - * May also return failure codes issued by RotatableFileWriter::Use::setFileName(). - */ - StatusWithRotatableFileWriter openFile(const std::string& name, bool append); - - /** - * Gets a RotatableFileWriter for writing to "name", if the manager owns one, or NULL if - * not. - */ - RotatableFileWriter* getFile(const std::string& name); - - /** - * Rotates all managed files, renaming each file by appending "renameTargetSuffix". - * - * renameFiles - true we rename the log file, false we expect it was renamed externally - * - * Returns a vector of <filename, Status> pairs for filenames with non-OK rotate status. - * An empty vector indicates that all files were rotated successfully. - */ - FileNameStatusPairVector rotateAll(bool renameFiles, const std::string& renameTargetSuffix); - -private: - typedef stdx::unordered_map<std::string, RotatableFileWriter*> WriterByNameMap; - - WriterByNameMap _writers; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/rotatable_file_writer.cpp b/src/mongo/logger/rotatable_file_writer.cpp deleted file mode 100644 index 0c5ed612b99..00000000000 --- a/src/mongo/logger/rotatable_file_writer.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include "mongo/logger/rotatable_file_writer.h" - -#include <boost/filesystem/operations.hpp> -#include <cstdio> -#include <fstream> - -#include "mongo/base/string_data.h" -#include "mongo/util/str.h" - -namespace mongo { -namespace logger { - -namespace { -/** - * Renames file "oldName" to "newName". - * - * Both names are UTF-8 encoded. - */ -int renameFile(const std::string& oldName, const std::string& newName); -} // namespace - -#ifdef _WIN32 -namespace { - -/** - * Converts UTF-8 encoded "utf8Str" to std::wstring. - */ -std::wstring utf8ToWide(StringData utf8Str) { - if (utf8Str.empty()) - return std::wstring(); - - // A Windows wchar_t encoding of a unicode codepoint never takes more instances of wchar_t - // than the UTF-8 encoding takes instances of char. - std::unique_ptr<wchar_t[]> tempBuffer(new wchar_t[utf8Str.size()]); - tempBuffer[0] = L'\0'; - int finalSize = MultiByteToWideChar(CP_UTF8, // Code page - 0, // Flags - utf8Str.rawData(), // Input string - utf8Str.size(), // Count - tempBuffer.get(), // UTF-16 output buffer - utf8Str.size() // Buffer size in wide characters - ); - // TODO(schwerin): fassert finalSize > 0? - return std::wstring(tempBuffer.get(), finalSize); -} - - -/** - * Minimal implementation of a std::streambuf for writing to Win32 files via HANDLEs. - * - * We require this implementation and the std::ostream subclass below to handle the following: - * (1) Opening files for shared-delete access, so that open file handles may be renamed. - * (2) Opening files with non-ASCII characters in their names. - */ -class Win32FileStreambuf : public std::streambuf { - Win32FileStreambuf(const Win32FileStreambuf&) = delete; - Win32FileStreambuf& operator=(const Win32FileStreambuf&) = delete; - -public: - Win32FileStreambuf(); - virtual ~Win32FileStreambuf(); - - bool open(StringData fileName, bool append); - bool is_open() { - return _fileHandle != INVALID_HANDLE_VALUE; - } - -private: - virtual std::streamsize xsputn(const char* s, std::streamsize count); - virtual int_type overflow(int_type ch = traits_type::eof()); - - HANDLE _fileHandle; -}; - -/** - * Minimal implementation of a stream to Win32 files. - */ -class Win32FileOStream : public std::ostream { - Win32FileOStream(const Win32FileOStream&) = delete; - Win32FileOStream& operator=(const Win32FileOStream&) = delete; - -public: - /** - * Constructs an instance, opening "fileName" in append or truncate mode according to - * "append". - */ - Win32FileOStream(const std::string& fileName, bool append) : std::ostream(&_buf), _buf() { - if (!_buf.open(fileName, append)) { - setstate(failbit); - } - } - - virtual ~Win32FileOStream() {} - -private: - Win32FileStreambuf _buf; -}; - -Win32FileStreambuf::Win32FileStreambuf() : _fileHandle(INVALID_HANDLE_VALUE) {} -Win32FileStreambuf::~Win32FileStreambuf() { - if (is_open()) { - CloseHandle(_fileHandle); // TODO(schwerin): Should we check for failure? - } -} - -bool Win32FileStreambuf::open(StringData fileName, bool append) { - _fileHandle = CreateFileW(utf8ToWide(fileName).c_str(), // lpFileName - GENERIC_WRITE, // dwDesiredAccess - FILE_SHARE_DELETE | FILE_SHARE_READ, // dwShareMode - nullptr, // lpSecurityAttributes - OPEN_ALWAYS, // dwCreationDisposition - FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes - nullptr // hTemplateFile - ); - - - if (INVALID_HANDLE_VALUE == _fileHandle) - return false; - - LARGE_INTEGER zero; - zero.QuadPart = 0LL; - - if (append) { - if (SetFilePointerEx(_fileHandle, zero, nullptr, FILE_END)) { - return true; - } - } else { - if (SetFilePointerEx(_fileHandle, zero, nullptr, FILE_BEGIN) && SetEndOfFile(_fileHandle)) { - return true; - } - } - // TODO(schwerin): Record error info? - CloseHandle(_fileHandle); - return false; -} - -// Called when strings are written to ostream -std::streamsize Win32FileStreambuf::xsputn(const char* s, std::streamsize count) { - DWORD totalBytesWritten = 0; - - while (count > totalBytesWritten) { - DWORD bytesWritten; - if (!WriteFile(_fileHandle, s, count - totalBytesWritten, &bytesWritten, nullptr)) { - break; - } - - totalBytesWritten += bytesWritten; - } - - return totalBytesWritten; -} - -// Overflow is called for single character writes to the ostream -Win32FileStreambuf::int_type Win32FileStreambuf::overflow(int_type ch) { - if (ch == traits_type::eof()) - return ~ch; // Returning traits_type::eof() => failure, anything else => success. - char toPut = static_cast<char>(ch); - if (1 == xsputn(&toPut, 1)) - return ch; - return traits_type::eof(); -} - -} // namespace -#endif - -RotatableFileWriter::RotatableFileWriter() : _stream(nullptr) {} - -RotatableFileWriter::Use::Use(RotatableFileWriter* writer) - : _writer(writer), _lock(writer->_mutex) {} - -Status RotatableFileWriter::Use::setFileName(const std::string& name, bool append) { - _writer->_fileName = name; - return _openFileStream(append); -} - -Status RotatableFileWriter::Use::rotate(bool renameOnRotate, const std::string& renameTarget) { - if (_writer->_stream) { - _writer->_stream->flush(); - - if (renameOnRotate) { - try { - if (boost::filesystem::exists(renameTarget)) { - return Status(ErrorCodes::FileRenameFailed, - str::stream() - << "Renaming file " << _writer->_fileName << " to " - << renameTarget << " failed; destination already exists"); - } - } catch (const std::exception& e) { - return Status(ErrorCodes::FileRenameFailed, - str::stream() << "Renaming file " << _writer->_fileName << " to " - << renameTarget - << " failed; Cannot verify whether destination " - "already exists: " - << e.what()); - } - - boost::system::error_code ec; - boost::filesystem::rename(_writer->_fileName, renameTarget, ec); - if (ec) { - return Status(ErrorCodes::FileRenameFailed, - str::stream() - << "Failed to rename \"" << _writer->_fileName << "\" to \"" - << renameTarget << "\": " << ec.message()); - // TODO(schwerin): Make errnoWithDescription() available in the logger library, and - // use it here. - } - } - } - return _openFileStream(false); -} - -Status RotatableFileWriter::Use::status() { - if (!_writer->_stream) { - return Status(ErrorCodes::FileNotOpen, - str::stream() << "File \"" << _writer->_fileName << "\" not open"); - } - if (_writer->_stream->fail()) { - return Status(ErrorCodes::FileStreamFailed, - str::stream() << "File \"" << _writer->_fileName << "\" in failed state"); - } - return Status::OK(); -} - -Status RotatableFileWriter::Use::_openFileStream(bool append) { - using std::swap; - -#ifdef _WIN32 - std::unique_ptr<std::ostream> newStream(new Win32FileOStream(_writer->_fileName, append)); -#else - std::ios::openmode mode = std::ios::out; - if (append) { - mode |= std::ios::app; - } else { - mode |= std::ios::trunc; - } - std::unique_ptr<std::ostream> newStream(new std::ofstream(_writer->_fileName.c_str(), mode)); -#endif - - if (newStream->fail()) { - return Status(ErrorCodes::FileNotOpen, "Failed to open \"" + _writer->_fileName + "\""); - } - swap(_writer->_stream, newStream); - return status(); -} - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/rotatable_file_writer.h b/src/mongo/logger/rotatable_file_writer.h deleted file mode 100644 index ab6fe578281..00000000000 --- a/src/mongo/logger/rotatable_file_writer.h +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <memory> -#include <ostream> -#include <string> - -#include "mongo/base/status.h" -#include "mongo/platform/mutex.h" - -namespace mongo { -namespace logger { - -/** - * A synchronized file output stream writer, with support for file rotation. - * - * To enforce proper locking, instances of RotatableFileWriter may only be manipulated by - * instantiating a RotatableFileWriter::Use guard object, which exposes the relevant - * manipulation methods for the stream. For any instance of RotatableFileWriter, at most one - * fully constructed instance of RotatableFileWriter::Use exists at a time, providing mutual - * exclusion. - * - * Behavior is undefined if two instances of RotatableFileWriter should simultaneously have the - * same value for their fileName. - */ -class RotatableFileWriter { - RotatableFileWriter(const RotatableFileWriter&) = delete; - RotatableFileWriter& operator=(const RotatableFileWriter&) = delete; - -public: - /** - * Guard class representing synchronous use of an instance of RotatableFileWriter. - */ - class Use { - Use(const Use&) = delete; - Use& operator=(const Use&) = delete; - - public: - /** - * Constructs a Use object for "writer", and lock "writer". - */ - explicit Use(RotatableFileWriter* writer); - - /** - * Sets the name of the target file to which stream() writes to "name". - * - * May be called repeatedly. - * - * If this method does not return Status::OK(), it is not safe to call rotate() or - * stream(). - * - * Set "append" to true to open "name" in append mode. Otherwise, it is truncated. - */ - Status setFileName(const std::string& name, bool append); - - /** - * Rotates the currently opened file into "renameTarget", and open a new file - * with the name previously set via setFileName(). - * - * renameFiles - true we rename the log file, false we expect it was renamed externally - * - * Returns Status::OK() on success. If the rename fails, returns - * ErrorCodes::FileRenameFailed, and the stream continues to write to the unrotated - * file. If the rename succeeds but the subsequent file open fails, returns - * ErrorCodes::FileNotOpen, and the stream continues to target the original file, though - * under its new name. - */ - Status rotate(bool renameFile, const std::string& renameTarget); - - /** - * Returns the status of the stream. - * - * One of Status::OK(), ErrorCodes::FileNotOpen and ErrorCodes::FileStreamFailed. - */ - Status status(); - - /** - * Returns a reference to the std::ostream() through which users may write to the file. - */ - std::ostream& stream() { - return *_writer->_stream; - } - - private: - /** - * Helper that opens the file named by setFileName(), in the mode specified by "append". - * - * Returns Status::OK() on success and ErrorCodes::FileNotOpen on failure. - */ - Status _openFileStream(bool append); - - RotatableFileWriter* _writer; - stdx::unique_lock<Latch> _lock; - }; - - /** - * Constructs an instance of RotatableFileWriter. - */ - RotatableFileWriter(); - -private: - friend class RotatableFileWriter::Use; - Mutex _mutex = MONGO_MAKE_LATCH("RotatableFileWriter::_mutex"); - std::string _fileName; - std::unique_ptr<std::ostream> _stream; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logger/rotatable_file_writer_test.cpp b/src/mongo/logger/rotatable_file_writer_test.cpp deleted file mode 100644 index ee97a5bede2..00000000000 --- a/src/mongo/logger/rotatable_file_writer_test.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#include "mongo/platform/basic.h" - -#include <fstream> - -#include "mongo/logger/rotatable_file_writer.h" -#include "mongo/unittest/unittest.h" - -namespace { -using namespace mongo; -using namespace mongo::logger; - -const std::string logFileName("LogTest_RotatableFileAppender.txt"); -const std::string logFileNameRotated("LogTest_RotatableFileAppender_Rotated.txt"); - -// TODO(schwerin): Create a safe, uniform mechanism by which unit tests may read and write -// temporary files. -class RotatableFileWriterTest : public mongo::unittest::Test { -public: - RotatableFileWriterTest() { - unlink(logFileName.c_str()); - unlink(logFileNameRotated.c_str()); - } - - virtual ~RotatableFileWriterTest() { - unlink(logFileName.c_str()); - unlink(logFileNameRotated.c_str()); - } -}; - -TEST_F(RotatableFileWriterTest, RotationTest) { - using namespace logger; - - { - RotatableFileWriter writer; - RotatableFileWriter::Use writerUse(&writer); - ASSERT_OK(writerUse.setFileName(logFileName, false)); - ASSERT_TRUE(writerUse.stream() << "Level 1 message." << std::endl); - ASSERT_TRUE(writerUse.stream() << "Level 2 message." << std::endl); - ASSERT_OK(writerUse.rotate(true, logFileNameRotated)); - ASSERT_TRUE(writerUse.stream() << "Level 3 message." << std::endl); - ASSERT_TRUE(writerUse.stream() << "Level 4 message." << std::endl); - } - - { - std::ifstream ifs(logFileNameRotated.c_str()); - ASSERT_TRUE(ifs.is_open()); - ASSERT_TRUE(ifs.good()); - std::string input; - ASSERT_TRUE(std::getline(ifs, input)); - ASSERT_EQUALS(input, "Level 1 message."); - ASSERT_TRUE(std::getline(ifs, input)); - ASSERT_EQUALS(input, "Level 2 message."); - ASSERT_TRUE(std::getline(ifs, input).fail()); - ASSERT_TRUE(ifs.eof()); - } - - { - std::ifstream ifs(logFileName.c_str()); - ASSERT_TRUE(ifs.is_open()); - ASSERT_TRUE(ifs.good()); - std::string input; - ASSERT_TRUE(std::getline(ifs, input)); - ASSERT_EQUALS(input, "Level 3 message."); - ASSERT_TRUE(std::getline(ifs, input)); - ASSERT_EQUALS(input, "Level 4 message."); - ASSERT_TRUE(std::getline(ifs, input).fail()); - ASSERT_TRUE(ifs.eof()); - } - - { - RotatableFileWriter writer; - RotatableFileWriter::Use writerUse(&writer); - ASSERT_OK(writerUse.setFileName(logFileName, true)); - ASSERT_TRUE(writerUse.stream() << "Level 5 message." << std::endl); - ASSERT_TRUE(writerUse.stream() << "Level 6 message." << std::endl); - } - - { - std::ifstream ifs(logFileName.c_str()); - ASSERT_TRUE(ifs.is_open()); - ASSERT_TRUE(ifs.good()); - std::string input; - ASSERT_TRUE(std::getline(ifs, input)); - ASSERT_EQUALS(input, "Level 3 message."); - ASSERT_TRUE(std::getline(ifs, input)); - ASSERT_EQUALS(input, "Level 4 message."); - ASSERT_FALSE(std::getline(ifs, input).fail()); - ASSERT_EQUALS(input, "Level 5 message."); - ASSERT_TRUE(std::getline(ifs, input)); - ASSERT_EQUALS(input, "Level 6 message."); - ASSERT_TRUE(std::getline(ifs, input).fail()); - ASSERT_TRUE(ifs.eof()); - } - - { - RotatableFileWriter writer; - RotatableFileWriter::Use writerUse(&writer); - ASSERT_OK(writerUse.setFileName(logFileName, false)); - ASSERT_TRUE(writerUse.stream() << "Level 7 message." << std::endl); - ASSERT_TRUE(writerUse.stream() << "Level 8 message." << std::endl); - } - - { - std::ifstream ifs(logFileName.c_str()); - ASSERT_TRUE(ifs.is_open()); - ASSERT_TRUE(ifs.good()); - std::string input; - ASSERT_TRUE(std::getline(ifs, input)); - ASSERT_EQUALS(input, "Level 7 message."); - ASSERT_FALSE(std::getline(ifs, input).fail()); - ASSERT_EQUALS(input, "Level 8 message."); - ASSERT_TRUE(std::getline(ifs, input).fail()); - ASSERT_TRUE(ifs.eof()); - } -} - -} // namespace diff --git a/src/mongo/logger/syslog_appender.h b/src/mongo/logger/syslog_appender.h deleted file mode 100644 index 2d2c65fb706..00000000000 --- a/src/mongo/logger/syslog_appender.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#ifndef _WIN32 // TODO(schwerin): Should be #if MONGO_CONFIG_HAVE_SYSLOG_H? - -#include <sstream> -#include <syslog.h> - -#include "mongo/base/status.h" -#include "mongo/logger/appender.h" -#include "mongo/logger/encoder.h" - -namespace mongo { -namespace logger { - -/** - * Appender for writing to syslog. Users must have separately called openlog(). - */ -template <typename Event> -class SyslogAppender : public Appender<Event> { - SyslogAppender(const SyslogAppender&) = delete; - SyslogAppender& operator=(const SyslogAppender&) = delete; - -public: - typedef Encoder<Event> EventEncoder; - - // TODO: Remove this ctor once raw pointer use is gone - explicit SyslogAppender(EventEncoder* encoder) : _encoder(encoder) {} - explicit SyslogAppender(std::unique_ptr<EventEncoder> encoder) : _encoder(std::move(encoder)) {} - virtual Status append(const Event& event) { - std::ostringstream os; - _encoder->encode(event, os); - if (!os) - return Status(ErrorCodes::LogWriteFailed, "Error writing log message to syslog."); - syslog(getSyslogPriority(event.getSeverity()), "%s", os.str().c_str()); - return Status::OK(); - } - -private: - int getSyslogPriority(logv2::LogSeverity severity) { - if (severity <= logv2::LogSeverity::Debug(1)) - return LOG_DEBUG; - if (severity == logv2::LogSeverity::Warning()) - return LOG_WARNING; - if (severity == logv2::LogSeverity::Error()) - return LOG_ERR; - if (severity >= logv2::LogSeverity::Severe()) - return LOG_CRIT; - // Info() and Log(). - return LOG_INFO; - } - std::unique_ptr<EventEncoder> _encoder; -}; - -} // namespace logger -} // namespace mongo - -#endif diff --git a/src/mongo/logger/tee.h b/src/mongo/logger/tee.h deleted file mode 100644 index fba45890ec9..00000000000 --- a/src/mongo/logger/tee.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include <string> - -namespace mongo { -namespace logger { - -class Tee { -public: - virtual ~Tee() {} - - /** - * Implementations of Tee::write must handle their own synchronization. Callers may assume - * it is safe to call this method at any time from any thread. - */ - virtual void write(const std::string& str) = 0; -}; - -} // namespace logger -} // namespace mongo diff --git a/src/mongo/logv2/log_manager.cpp b/src/mongo/logv2/log_manager.cpp index a9c6ca5013e..4794636ea45 100644 --- a/src/mongo/logv2/log_manager.cpp +++ b/src/mongo/logv2/log_manager.cpp @@ -35,9 +35,11 @@ #include <boost/log/core.hpp> +#include "mongo/base/init.h" #include "mongo/logv2/log.h" #include "mongo/logv2/log_domain.h" #include "mongo/logv2/log_domain_global.h" +#include "mongo/logv2/log_util.h" namespace mongo::logv2 { @@ -98,4 +100,11 @@ LogComponentSettings& LogManager::getGlobalSettings() { return getGlobalDomainInternal().settings(); } +MONGO_INITIALIZER(GlobalLogRotator)(InitializerContext*) { + addLogRotator([](bool renameFiles, StringData suffix) { + return LogManager::global().getGlobalDomainInternal().rotate(renameFiles, suffix); + }); + return Status::OK(); +} + } // namespace mongo::logv2 diff --git a/src/mongo/logv2/log_util.cpp b/src/mongo/logv2/log_util.cpp index 79f2abbd88a..0e7a6526a80 100644 --- a/src/mongo/logv2/log_util.cpp +++ b/src/mongo/logv2/log_util.cpp @@ -31,38 +31,41 @@ #include "mongo/logv2/log_util.h" -#include "mongo/logger/logger.h" -#include "mongo/logger/rotatable_file_manager.h" #include "mongo/logv2/log.h" -#include "mongo/logv2/log_domain_global.h" -#include "mongo/logv2/log_manager.h" +#include "mongo/platform/atomic_word.h" #include "mongo/util/time_support.h" #include <string> +#include <vector> namespace mongo::logv2 { namespace { AtomicWord<bool> redactionEnabled{false}; +std::vector<LogRotateCallback> logRotateCallbacks; +} // namespace + +void addLogRotator(LogRotateCallback cb) { + logRotateCallbacks.push_back(std::move(cb)); } + bool rotateLogs(bool renameFiles) { // Rotate on both logv1 and logv2 so all files that need rotation gets rotated - LOGV2(23166, "Log rotation initiated"); std::string suffix = "." + terseCurrentTime(false); - Status resultv2 = - logv2::LogManager::global().getGlobalDomainInternal().rotate(renameFiles, suffix); - if (!resultv2.isOK()) - LOGV2_WARNING(23168, "Log rotation failed", "reason"_attr = resultv2); + LOGV2(23166, "Log rotation initiated", "suffix"_attr = suffix); + bool success = true; - using logger::RotatableFileManager; - RotatableFileManager* manager = logger::globalRotatableFileManager(); - RotatableFileManager::FileNameStatusPairVector result(manager->rotateAll(renameFiles, suffix)); - for (RotatableFileManager::FileNameStatusPairVector::iterator it = result.begin(); - it != result.end(); - it++) { - LOGV2_WARNING( - 23169, "Rotating log file failed", "file"_attr = it->first, "reason"_attr = it->second); + // Call each callback in turn. + // If they fail, they must log why. + // We only return true if all succeed. + for (const auto& cb : logRotateCallbacks) { + auto status = cb(renameFiles, suffix); + if (!status.isOK()) { + LOGV2_WARNING(23168, "Log rotation failed", "reason"_attr = status); + success = false; + } } - return resultv2.isOK() && result.empty(); + + return success; } bool shouldRedactLogs() { diff --git a/src/mongo/logv2/log_util.h b/src/mongo/logv2/log_util.h index c03d81f05f6..bd7bda6865e 100644 --- a/src/mongo/logv2/log_util.h +++ b/src/mongo/logv2/log_util.h @@ -29,7 +29,16 @@ #pragma once +#include <functional> + +#include <mongo/base/status.h> +#include <mongo/base/string_data.h> + namespace mongo::logv2 { + +using LogRotateCallback = std::function<Status(bool, StringData)>; +void addLogRotator(LogRotateCallback cb); + /** * Rotates the log files. Returns true if all logs rotate successfully. * diff --git a/src/mongo/s/transaction_router_test.cpp b/src/mongo/s/transaction_router_test.cpp index 949cb9e4be6..e2eda963a62 100644 --- a/src/mongo/s/transaction_router_test.cpp +++ b/src/mongo/s/transaction_router_test.cpp @@ -40,7 +40,6 @@ #include "mongo/db/namespace_string.h" #include "mongo/db/repl/read_concern_args.h" #include "mongo/db/vector_clock.h" -#include "mongo/logger/logger.h" #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/s/catalog/type_shard.h" #include "mongo/s/router_transactions_metrics.h" diff --git a/src/mongo/shell/mongo_main.cpp b/src/mongo/shell/mongo_main.cpp index d8be01a8e0f..3343a61075c 100644 --- a/src/mongo/shell/mongo_main.cpp +++ b/src/mongo/shell/mongo_main.cpp @@ -58,9 +58,6 @@ #include "mongo/db/log_process_details.h" #include "mongo/db/server_options.h" #include "mongo/db/wire_version.h" -#include "mongo/logger/console_appender.h" -#include "mongo/logger/logger.h" -#include "mongo/logger/message_event_utf8_encoder.h" #include "mongo/logv2/attributes.h" #include "mongo/logv2/component_settings_filter.h" #include "mongo/logv2/console.h" @@ -134,20 +131,21 @@ MONGO_INITIALIZER_WITH_PREREQUISITES(WireSpec, ("EndStartupOptionSetup"))(Initia const auto kAuthParam = "authSource"s; /** - * This throws away all log output while inside of a LoggingDisabledScope. + * Basic Logv2 console backend. Provides scoped logging disable. */ -class ShellConsoleAppender final : public logger::ConsoleAppender<logger::MessageEventEphemeral> { - using Base = logger::ConsoleAppender<logger::MessageEventEphemeral>; - friend class ShellBackend; - +class ShellBackend final : public boost::log::sinks::text_ostream_backend { public: - using Base::Base; + void consume(boost::log::record_view const& rec, string_type const& formatted_message) { + using boost::log::extract; - Status append(const Event& event) override { auto lk = stdx::lock_guard(mx); - if (!loggingEnabled) - return Status::OK(); - return Base::append(event); + if (!loggingEnabled && + !extract<logv2::LogTag>(logv2::attributes::tags(), rec) + .get() + .has(logv2::LogTag::kAllowDuringPromptingShell)) { + return; + } + boost::log::sinks::text_ostream_backend::consume(rec, formatted_message); } struct LoggingDisabledScope { @@ -175,29 +173,11 @@ private: // This needs to use a mutex rather than an atomic bool because we need to ensure that no more // logging will happen once we return from disable(). - static inline Mutex mx = MONGO_MAKE_LATCH("ShellConsoleAppender::mx"); + static inline Mutex mx = MONGO_MAKE_LATCH("ShellBackend::mx"); static inline bool loggingEnabled = true; }; /** - * Logv2 equivalent of ShellConsoleAppender above. Sharing the lock and LoggingDisabledScope. - */ -class ShellBackend final : public boost::log::sinks::text_ostream_backend { -public: - void consume(boost::log::record_view const& rec, string_type const& formatted_message) { - using boost::log::extract; - - auto lk = stdx::lock_guard(ShellConsoleAppender::mx); - if (!ShellConsoleAppender::loggingEnabled && - !extract<logv2::LogTag>(logv2::attributes::tags(), rec) - .get() - .has(logv2::LogTag::kAllowDuringPromptingShell)) - return; - boost::log::sinks::text_ostream_backend::consume(rec, formatted_message); - } -}; - -/** * Formatter to provide specialized formatting for logs from javascript engine */ class ShellFormatter final : private logv2::PlainFormatter, private logv2::JSONFormatter { @@ -330,7 +310,7 @@ void quitNicely(int sig) { // the returned string is allocated with strdup() or malloc() and must be freed by calling free() char* shellReadline(const char* prompt, int handlesigint = 0) { - auto lds = ShellConsoleAppender::LoggingDisabledScope(); + auto lds = ShellBackend::LoggingDisabledScope(); atPrompt.store(true); char* ret = linenoise(prompt); @@ -641,7 +621,7 @@ static void edit(const std::string& whatToEdit) { StringBuilder sb; sb << editor << " " << filename; int ret = [&] { - auto lds = ShellConsoleAppender::LoggingDisabledScope(); + auto lds = ShellBackend::LoggingDisabledScope(); return ::system(sb.str().c_str()); }(); if (ret) { diff --git a/src/mongo/unittest/integration_test_main.cpp b/src/mongo/unittest/integration_test_main.cpp index 0e2e14870a6..6fb5a68fb5e 100644 --- a/src/mongo/unittest/integration_test_main.cpp +++ b/src/mongo/unittest/integration_test_main.cpp @@ -43,7 +43,6 @@ #include "mongo/db/server_options_helpers.h" #include "mongo/db/service_context.h" #include "mongo/db/wire_version.h" -#include "mongo/logger/logger.h" #include "mongo/logv2/log.h" #include "mongo/transport/transport_layer_asio.h" #include "mongo/unittest/unittest.h" diff --git a/src/mongo/unittest/unittest.cpp b/src/mongo/unittest/unittest.cpp index 22fb7285a18..2e8dafe95c3 100644 --- a/src/mongo/unittest/unittest.cpp +++ b/src/mongo/unittest/unittest.cpp @@ -42,12 +42,6 @@ #include <memory> #include <pcrecpp.h> -#include "mongo/logger/console_appender.h" -#include "mongo/logger/log_manager.h" -#include "mongo/logger/logger.h" -#include "mongo/logger/message_event_utf8_encoder.h" -#include "mongo/logger/message_log_domain.h" - #include "mongo/base/checked_cast.h" #include "mongo/base/init.h" #include "mongo/db/server_options.h" diff --git a/src/mongo/unittest/unittest.h b/src/mongo/unittest/unittest.h index be634883635..3a919ddba8a 100644 --- a/src/mongo/unittest/unittest.h +++ b/src/mongo/unittest/unittest.h @@ -49,7 +49,6 @@ #include "mongo/base/status_with.h" #include "mongo/base/string_data.h" -#include "mongo/logger/message_log_domain.h" #include "mongo/logv2/log_detail.h" #include "mongo/unittest/bson_test_util.h" #include "mongo/unittest/unittest_helpers.h" diff --git a/src/mongo/unittest/unittest_main.cpp b/src/mongo/unittest/unittest_main.cpp index 9dcc36f6630..b1286ed772a 100644 --- a/src/mongo/unittest/unittest_main.cpp +++ b/src/mongo/unittest/unittest_main.cpp @@ -36,7 +36,6 @@ #include "mongo/base/status.h" #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/wire_version.h" -#include "mongo/logger/logger.h" #include "mongo/logv2/log_domain_global.h" #include "mongo/logv2/log_manager.h" #include "mongo/unittest/log_test.h" diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp index 033948415fa..99a1fef567a 100644 --- a/src/mongo/util/net/ssl_manager.cpp +++ b/src/mongo/util/net/ssl_manager.cpp @@ -626,7 +626,7 @@ TLSVersionCounts& TLSVersionCounts::get(ServiceContext* serviceContext) { return getTLSVersionCounts(serviceContext); } -MONGO_INITIALIZER_WITH_PREREQUISITES(SSLManagerLogger, ("SSLManager", "GlobalLogManager")) +MONGO_INITIALIZER_WITH_PREREQUISITES(SSLManagerLogger, ("SSLManager")) (InitializerContext*) { if (!isSSLServer || (sslGlobalParams.sslMode.load() != SSLParams::SSLMode_disabled)) { const auto& config = SSLManagerCoordinator::get()->getSSLManager()->getSSLConfiguration(); diff --git a/src/mongo/util/options_parser/startup_option_init.cpp b/src/mongo/util/options_parser/startup_option_init.cpp index 84a53890c12..efc1ed82567 100644 --- a/src/mongo/util/options_parser/startup_option_init.cpp +++ b/src/mongo/util/options_parser/startup_option_init.cpp @@ -79,7 +79,7 @@ void StaticInit() { {"StartupOptionStorage"}, {"PostStartupOptionStorage"}, }}; - std::stack<StackEntry> stack{{{&stages, {"GlobalLogManager", "ValidateLocale"}, {"default"}}}}; + std::stack<StackEntry> stack{{{&stages, {"ValidateLocale"}, {"default"}}}}; while (!stack.empty()) { auto top = stack.top(); stack.pop(); diff --git a/src/mongo/util/ramlog.h b/src/mongo/util/ramlog.h deleted file mode 100644 index 1752c41be1e..00000000000 --- a/src/mongo/util/ramlog.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (C) 2018-present MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the Server Side Public License, version 1, - * as published by MongoDB, Inc. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * Server Side Public License for more details. - * - * You should have received a copy of the Server Side Public License - * along with this program. If not, see - * <http://www.mongodb.com/licensing/server-side-public-license>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the Server Side Public License in all respects for - * all of the code used other than as permitted herein. If you modify file(s) - * with this exception, you may extend this exception to your version of the - * file(s), but you are not obligated to do so. If you do not wish to do so, - * delete this exception statement from your version. If you delete this - * exception statement from all source files in the program, then also delete - * it in the license file. - */ - -#pragma once - -#include "mongo/logger/ramlog.h" diff --git a/src/mongo/util/version_impl.cpp b/src/mongo/util/version_impl.cpp index fdd0d327b63..c729751f0b9 100644 --- a/src/mongo/util/version_impl.cpp +++ b/src/mongo/util/version_impl.cpp @@ -101,7 +101,7 @@ const InterpolatedVersionInfo interpolatedVersionInfo; MONGO_INITIALIZER_GENERAL(EnableVersionInfo, MONGO_NO_PREREQUISITES, - ("BeginStartupOptionRegistration", "GlobalLogManager")) + ("BeginStartupOptionRegistration")) (InitializerContext*) { VersionInfoInterface::enable(&interpolatedVersionInfo); return Status::OK(); |