diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/catalog/SConscript | 15 | ||||
-rw-r--r-- | src/mongo/db/catalog/health_log.cpp | 80 | ||||
-rw-r--r-- | src/mongo/db/catalog/health_log.h | 93 | ||||
-rw-r--r-- | src/mongo/db/catalog/health_log.idl | 59 | ||||
-rw-r--r-- | src/mongo/db/db.cpp | 6 |
5 files changed, 253 insertions, 0 deletions
diff --git a/src/mongo/db/catalog/SConscript b/src/mongo/db/catalog/SConscript index e39e37db406..d42ba033db3 100644 --- a/src/mongo/db/catalog/SConscript +++ b/src/mongo/db/catalog/SConscript @@ -40,6 +40,20 @@ env.Library( ) env.Library( + target='health_log', + source=[ + "health_log.cpp", + env.Idlc("health_log.idl")[0], + ], + LIBDEPS=[ + "$BUILD_DIR/mongo/base", + "$BUILD_DIR/mongo/db/concurrency/deferred_writer", + "$BUILD_DIR/mongo/db/service_context", + "$BUILD_DIR/mongo/idl/idl_parser", + ], +); + +env.Library( target='index_key_validate', source=[ "index_key_validate.cpp", @@ -205,6 +219,7 @@ env.Library( 'collection_options', 'database', 'database_holder', + 'health_log', 'index_catalog', 'index_catalog_entry', 'index_create', diff --git a/src/mongo/db/catalog/health_log.cpp b/src/mongo/db/catalog/health_log.cpp new file mode 100644 index 00000000000..fedfec68eab --- /dev/null +++ b/src/mongo/db/catalog/health_log.cpp @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2017 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * 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 GNU Affero General 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/db/catalog/health_log.h" +#include "mongo/db/catalog/health_log_gen.h" +#include "mongo/db/concurrency/write_conflict_exception.h" +#include "mongo/db/db_raii.h" + +namespace mongo { + +namespace { +const ServiceContext::Decoration<HealthLog> getHealthLog = + ServiceContext::declareDecoration<HealthLog>(); + +const int64_t kDefaultHealthlogSize = 100'000'000; + +CollectionOptions getOptions(void) { + CollectionOptions options; + options.capped = true; + options.cappedSize = kDefaultHealthlogSize; + return options; +} +} + +HealthLog::HealthLog() : _writer(nss, getOptions(), kMaxBufferSize) {} + +void HealthLog::startup(void) { + _writer.startup(std::string("healthlog writer")); +} + +void HealthLog::shutdown(void) { + _writer.shutdown(); +} + +HealthLog& HealthLog::get(ServiceContext* svcCtx) { + return getHealthLog(svcCtx); +} + +HealthLog& HealthLog::get(OperationContext* opCtx) { + return getHealthLog(opCtx->getServiceContext()); +} + +bool HealthLog::log(const HealthLogEntry& entry) { + BSONObjBuilder builder; + OID oid; + oid.init(); + builder.append("_id", oid); + entry.serialize(&builder); + return _writer.insertDocument(builder.obj()); +} + +const NamespaceString HealthLog::nss("local", "system.healthlog"); +} diff --git a/src/mongo/db/catalog/health_log.h b/src/mongo/db/catalog/health_log.h new file mode 100644 index 00000000000..84de0e215ab --- /dev/null +++ b/src/mongo/db/catalog/health_log.h @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2017 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * 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 GNU Affero General 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/disallow_copying.h" +#include "mongo/db/concurrency/deferred_writer.h" +#include "mongo/db/service_context.h" + +namespace mongo { + +class HealthLogEntry; + +/** + * The interface to the local healthlog. + * + * This class contains facilities for creating and asynchronously writing to the local healthlog + * collection. There should only be one instance of this class, initialized on startup and cleaned + * up on shutdown. + */ +class HealthLog { + MONGO_DISALLOW_COPYING(HealthLog); + +public: + /** + * Required to use HealthLog as a ServiceContext decorator. + * + * Should not be used anywhere else. + */ + HealthLog(); + + /** + * The maximum size of the in-memory buffer of health-log entries, in bytes. + */ + static const int64_t kMaxBufferSize = 25'000'000; + + /** + * Start the worker thread writing the buffer to the collection. + */ + void startup(void); + + /** + * Stop the worker thread. + */ + void shutdown(void); + + /** + * The name of the collection. + */ + static const NamespaceString nss; + + /** + * Get the current context's HealthLog. + */ + static HealthLog& get(ServiceContext* ctx); + static HealthLog& get(OperationContext* ctx); + + /** + * Asynchronously insert the given entry. + * + * Return `false` iff there is no more space in the buffer. + */ + bool log(const HealthLogEntry& entry); + +private: + DeferredWriter _writer; +}; +} diff --git a/src/mongo/db/catalog/health_log.idl b/src/mongo/db/catalog/health_log.idl new file mode 100644 index 00000000000..f38bc85a72a --- /dev/null +++ b/src/mongo/db/catalog/health_log.idl @@ -0,0 +1,59 @@ +# Copyright (C) 2017 MongoDB Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3, +# as published by the Free Software Foundation. +# +# 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 +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +global: + cpp_namespace: "mongo" + +imports: + - "mongo/idl/basic_types.idl" + +types: + _id_key: + bson_serialization_type: any + description: "An _id value." + cpp_type: "mongo::BSONKey" + serializer: "mongo::BSONKey::serializeToBSON" + deserializer: "mongo::BSONKey::parseFromBSON" + +enums: + Severity: + description: "The severity of a healthlog entry." + type: string + values: + Info: "info" + Warning: "warning" + Error: "error" + Scope: + description: "The scope covered by a healthlog entry." + type: string + values: + Cluster: "cluster" + Node: "node" + Database: "database" + Collection: "collection" + Index: "index" + Document: "document" + +structs: + HealthLogEntry: + description: "An entry in system.local.healthlog." + fields: + namespace: namespacestring + timestamp: date + severity: Severity + msg: string + scope: Scope + operation: string + data: object diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 7f7c49adfc4..c5497433a2f 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -53,6 +53,7 @@ #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_catalog_entry.h" #include "mongo/db/catalog/database_holder.h" +#include "mongo/db/catalog/health_log.h" #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/catalog/index_key_validate.h" #include "mongo/db/client.h" @@ -600,6 +601,9 @@ ExitCode _initAndListen(int listenPort) { exitCleanly(EXIT_CLEAN); } + // Start up health log writer thread. + HealthLog::get(startupOpCtx.get()).startup(); + uassertStatusOK(getGlobalAuthorizationManager()->initialize(startupOpCtx.get())); /* this is for security on certain platforms (nonce generation) */ @@ -1077,6 +1081,8 @@ static void shutdownTask() { ShardingState::get(opCtx)->shutDown(opCtx); } + HealthLog::get(serviceContext).shutdown(); + // We should always be able to acquire the global lock at shutdown. // // TODO: This call chain uses the locker directly, because we do not want to start an |