From faa0ec0def1317f9005d3b0935aff83666f47404 Mon Sep 17 00:00:00 2001 From: Henrik Edin Date: Thu, 10 Oct 2019 15:24:38 +0000 Subject: SERVER-43759 Implement log domains with filtering. Does not require modifications to boost::log. --- src/mongo/SConscript | 1 + src/mongo/logv2/attributes.cpp | 21 ++-- src/mongo/logv2/attributes.h | 1 + src/mongo/logv2/component_settings_filter.h | 12 ++- src/mongo/logv2/domain_filter.h | 60 +++++++++++ src/mongo/logv2/log.cpp | 6 +- src/mongo/logv2/log_detail.cpp | 6 +- src/mongo/logv2/log_domain.cpp | 12 ++- src/mongo/logv2/log_domain.h | 18 ++-- src/mongo/logv2/log_domain_global.cpp | 5 +- src/mongo/logv2/log_domain_global.h | 5 +- src/mongo/logv2/log_domain_impl.h | 55 ---------- src/mongo/logv2/log_domain_internal.cpp | 36 +++++++ src/mongo/logv2/log_domain_internal.h | 54 ++++++++++ src/mongo/logv2/log_manager.cpp | 34 ++++--- src/mongo/logv2/log_source.h | 20 ++-- src/mongo/logv2/log_test_v2.cpp | 149 ++++------------------------ src/mongo/logv2/log_test_v2.h | 47 +-------- src/mongo/logv2/logv2_bm.cpp | 10 +- src/mongo/logv2/tagged_severity_filter.h | 10 +- 20 files changed, 264 insertions(+), 298 deletions(-) create mode 100644 src/mongo/logv2/domain_filter.h delete mode 100644 src/mongo/logv2/log_domain_impl.h create mode 100644 src/mongo/logv2/log_domain_internal.cpp create mode 100644 src/mongo/logv2/log_domain_internal.h diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 51695b49167..77c87f51dc7 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -117,6 +117,7 @@ baseEnv.Library( 'logv2/log_component_settings.cpp', 'logv2/log_domain.cpp', 'logv2/log_domain_global.cpp', + 'logv2/log_domain_internal.cpp', 'logv2/log_manager.cpp', 'logv2/log_record.cpp', 'logv2/log_severity.cpp', diff --git a/src/mongo/logv2/attributes.cpp b/src/mongo/logv2/attributes.cpp index 786d2d56934..b5b2c4f4d7b 100644 --- a/src/mongo/logv2/attributes.cpp +++ b/src/mongo/logv2/attributes.cpp @@ -33,43 +33,48 @@ namespace mongo { namespace logv2 { namespace attributes { +const boost::log::attribute_name& domain() { + static const boost::log::attribute_name attr("domain"); + return attr; +} + const boost::log::attribute_name& severity() { - static boost::log::attribute_name attr("severity"); + static const boost::log::attribute_name attr("severity"); return attr; } const boost::log::attribute_name& component() { - static boost::log::attribute_name attr("component"); + static const boost::log::attribute_name attr("component"); return attr; } const boost::log::attribute_name& timeStamp() { - static boost::log::attribute_name attr("time_stamp"); + static const boost::log::attribute_name attr("time_stamp"); return attr; } const boost::log::attribute_name& threadName() { - static boost::log::attribute_name attr("thread_name"); + static const boost::log::attribute_name attr("thread_name"); return attr; } const boost::log::attribute_name& tags() { - static boost::log::attribute_name attr("tags"); + static const boost::log::attribute_name attr("tags"); return attr; } const boost::log::attribute_name& stableId() { - static boost::log::attribute_name attr("id"); + static const boost::log::attribute_name attr("id"); return attr; } const boost::log::attribute_name& message() { - static boost::log::attribute_name attr("message"); + static const boost::log::attribute_name attr("message"); return attr; } const boost::log::attribute_name& attributes() { - static boost::log::attribute_name attr("attributes"); + static const boost::log::attribute_name attr("attributes"); return attr; } diff --git a/src/mongo/logv2/attributes.h b/src/mongo/logv2/attributes.h index e3ab0cc831a..26c9a109db3 100644 --- a/src/mongo/logv2/attributes.h +++ b/src/mongo/logv2/attributes.h @@ -36,6 +36,7 @@ namespace logv2 { namespace attributes { // Reusable attribute names, so they only need to be constructed once. +const boost::log::attribute_name& domain(); const boost::log::attribute_name& severity(); const boost::log::attribute_name& component(); const boost::log::attribute_name& timeStamp(); diff --git a/src/mongo/logv2/component_settings_filter.h b/src/mongo/logv2/component_settings_filter.h index ccd3f675edc..a1edf3198b1 100644 --- a/src/mongo/logv2/component_settings_filter.h +++ b/src/mongo/logv2/component_settings_filter.h @@ -33,6 +33,7 @@ #include #include "mongo/logv2/attributes.h" +#include "mongo/logv2/domain_filter.h" #include "mongo/logv2/log_component.h" #include "mongo/logv2/log_component_settings.h" #include "mongo/logv2/log_severity.h" @@ -41,18 +42,19 @@ namespace mongo { namespace logv2 { // Boost::log filter that enables logging if Component+Severity match current settings -class ComponentSettingsFilter { +class ComponentSettingsFilter : public DomainFilter { public: - ComponentSettingsFilter(LogComponentSettings& settings) : _settings(settings) {} - bool operator()(boost::log::attribute_value_set const& attrs) { - using namespace boost::log; + ComponentSettingsFilter(const LogDomain& domain) + : DomainFilter(domain), _settings(domain.settings()) {} + bool filter(boost::log::attribute_value_set const& attrs) const { + using boost::log::extract; return _settings.shouldLog(extract(attributes::component(), attrs).get(), extract(attributes::severity(), attrs).get()); } private: - LogComponentSettings& _settings; + const LogComponentSettings& _settings; }; } // namespace logv2 diff --git a/src/mongo/logv2/domain_filter.h b/src/mongo/logv2/domain_filter.h new file mode 100644 index 00000000000..372ba055e56 --- /dev/null +++ b/src/mongo/logv2/domain_filter.h @@ -0,0 +1,60 @@ +/** + * 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 + * . + * + * 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 +#include + +#include "mongo/logv2/attributes.h" +#include "mongo/logv2/log_domain.h" + +namespace mongo { +namespace logv2 { + +// Boost::log filter that enables logging if domain match. Using CRTP, users should inherit from +// this and provide the concrete type as the template argument to this class. +template +class DomainFilter { +public: + DomainFilter(const LogDomain& domain) : _domain(&domain.internal()) {} + + bool operator()(boost::log::attribute_value_set const& attrs) { + using boost::log::extract; + + return extract(attributes::domain(), attrs).get() == _domain && + static_cast(this)->filter(attrs); + } + +private: + const LogDomain::Internal* _domain; +}; + +} // namespace logv2 +} // namespace mongo diff --git a/src/mongo/logv2/log.cpp b/src/mongo/logv2/log.cpp index 8b0b2aab30f..21bbe2e50d8 100644 --- a/src/mongo/logv2/log.cpp +++ b/src/mongo/logv2/log.cpp @@ -34,7 +34,7 @@ #include "mongo/logv2/attributes.h" #include "mongo/logv2/log.h" #include "mongo/logv2/log_domain.h" -#include "mongo/logv2/log_domain_impl.h" +#include "mongo/logv2/log_domain_internal.h" #include "mongo/logv2/log_options.h" #include "mongo/logv2/log_record_impl.h" #include "mongo/logv2/log_source.h" @@ -48,7 +48,7 @@ void doLogImpl(LogSeverity const& severity, StringData stable_id, StringData message, AttributeArgumentSet const& attrs) { - auto& source = options.domain().impl().source(); + auto& source = options.domain().internal().source(); auto record = source.open_record(severity, options.component(), options.tags(), stable_id); if (record) { record.attribute_values().insert( @@ -69,7 +69,7 @@ void doLogRecordImpl(LogRecord&& record, LogDomain& domain, StringData message, AttributeArgumentSet const& attrs) { - auto& source = domain.impl().source(); + auto& source = domain.internal().source(); auto rec = std::move(record.impl()->_record); if (rec) { rec.attribute_values().insert( diff --git a/src/mongo/logv2/log_detail.cpp b/src/mongo/logv2/log_detail.cpp index 8b0b2aab30f..21bbe2e50d8 100644 --- a/src/mongo/logv2/log_detail.cpp +++ b/src/mongo/logv2/log_detail.cpp @@ -34,7 +34,7 @@ #include "mongo/logv2/attributes.h" #include "mongo/logv2/log.h" #include "mongo/logv2/log_domain.h" -#include "mongo/logv2/log_domain_impl.h" +#include "mongo/logv2/log_domain_internal.h" #include "mongo/logv2/log_options.h" #include "mongo/logv2/log_record_impl.h" #include "mongo/logv2/log_source.h" @@ -48,7 +48,7 @@ void doLogImpl(LogSeverity const& severity, StringData stable_id, StringData message, AttributeArgumentSet const& attrs) { - auto& source = options.domain().impl().source(); + auto& source = options.domain().internal().source(); auto record = source.open_record(severity, options.component(), options.tags(), stable_id); if (record) { record.attribute_values().insert( @@ -69,7 +69,7 @@ void doLogRecordImpl(LogRecord&& record, LogDomain& domain, StringData message, AttributeArgumentSet const& attrs) { - auto& source = domain.impl().source(); + auto& source = domain.internal().source(); auto rec = std::move(record.impl()->_record); if (rec) { rec.attribute_values().insert( diff --git a/src/mongo/logv2/log_domain.cpp b/src/mongo/logv2/log_domain.cpp index 749bbe1e15e..3563230a4ba 100644 --- a/src/mongo/logv2/log_domain.cpp +++ b/src/mongo/logv2/log_domain.cpp @@ -28,20 +28,22 @@ */ #include "mongo/logv2/log_domain.h" -#include "mongo/logv2/log_domain_impl.h" +#include "mongo/logv2/log_domain_internal.h" #include "mongo/logv2/log_record_impl.h" namespace mongo { namespace logv2 { -LogDomain::LogDomain(std::unique_ptr impl) : _impl(std::move(impl)) {} +LogDomain::LogDomain(std::unique_ptr internalDomain) + : _internal(std::move(internalDomain)) {} +LogDomain::~LogDomain() = default; -LogComponentSettings& LogDomain::settings() { - return impl().settings(); +const LogComponentSettings& LogDomain::settings() const { + return internal().settings(); } LogRecord LogDomain::openRecord(LogSeverity severity, LogComponent component, LogTag tags) { std::unique_ptr record_impl; - auto record = impl().source().open_record(severity, component, tags, StringData{}); + auto record = internal().source().open_record(severity, component, tags, StringData{}); if (record) { record_impl = std::make_unique(std::move(record)); } diff --git a/src/mongo/logv2/log_domain.h b/src/mongo/logv2/log_domain.h index 08b260bf563..457089ed103 100644 --- a/src/mongo/logv2/log_domain.h +++ b/src/mongo/logv2/log_domain.h @@ -36,22 +36,28 @@ namespace mongo { namespace logv2 { -class LogDomainImpl; class LogComponentSettings; // Log domain class, implemented with the pimpl idiom to not leak out boost::log types class LogDomain { public: - LogDomain(std::unique_ptr impl); - LogDomainImpl& impl() { - return *_impl; + class Internal; + + explicit LogDomain(std::unique_ptr internalDomain); + ~LogDomain(); + + Internal& internal() { + return *_internal; + } + const Internal& internal() const { + return *_internal; } - LogComponentSettings& settings(); + const LogComponentSettings& settings() const; LogRecord openRecord(LogSeverity severity, LogComponent component, LogTag tags); private: - std::unique_ptr _impl; + std::unique_ptr _internal; }; } // namespace logv2 diff --git a/src/mongo/logv2/log_domain_global.cpp b/src/mongo/logv2/log_domain_global.cpp index 16e00e8f4cc..e71adbeaea6 100644 --- a/src/mongo/logv2/log_domain_global.cpp +++ b/src/mongo/logv2/log_domain_global.cpp @@ -35,12 +35,9 @@ namespace mongo { namespace logv2 { LogSource& LogDomainGlobal::source() { // Use a thread_local logger so we don't need to have locking - thread_local LogSource lg; + thread_local LogSource lg(this); return lg; } -boost::shared_ptr LogDomainGlobal::core() { - return boost::log::core::get(); -} } // namespace logv2 } // namespace mongo diff --git a/src/mongo/logv2/log_domain_global.h b/src/mongo/logv2/log_domain_global.h index b93daa9750e..70368014080 100644 --- a/src/mongo/logv2/log_domain_global.h +++ b/src/mongo/logv2/log_domain_global.h @@ -29,14 +29,13 @@ #pragma once -#include "mongo/logv2/log_domain_impl.h" +#include "mongo/logv2/log_domain_internal.h" namespace mongo { namespace logv2 { -class LogDomainGlobal : public LogDomainImpl { +class LogDomainGlobal : public LogDomain::Internal { public: LogSource& source() override; - boost::shared_ptr core() override; }; } // namespace logv2 } // namespace mongo diff --git a/src/mongo/logv2/log_domain_impl.h b/src/mongo/logv2/log_domain_impl.h deleted file mode 100644 index 6e82687eda8..00000000000 --- a/src/mongo/logv2/log_domain_impl.h +++ /dev/null @@ -1,55 +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 - * . - * - * 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/logv2/log_component_settings.h" -#include "mongo/logv2/log_source.h" -#include - -namespace mongo { -namespace logv2 { -class LogDomainImpl { -public: - LogDomainImpl() {} - virtual ~LogDomainImpl() {} - - virtual LogSource& source() = 0; - virtual boost::shared_ptr core() = 0; - - LogComponentSettings& settings() { - return _settings; - } - -private: - LogComponentSettings _settings; -}; - -} // namespace logv2 -} // namespace mongo diff --git a/src/mongo/logv2/log_domain_internal.cpp b/src/mongo/logv2/log_domain_internal.cpp new file mode 100644 index 00000000000..9b0e4454962 --- /dev/null +++ b/src/mongo/logv2/log_domain_internal.cpp @@ -0,0 +1,36 @@ +/** + * 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 + * . + * + * 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 "log_domain_internal.h" + +namespace mongo { +namespace logv2 { +LogDomain::Internal::~Internal() = default; +} // namespace logv2 +} // namespace mongo diff --git a/src/mongo/logv2/log_domain_internal.h b/src/mongo/logv2/log_domain_internal.h new file mode 100644 index 00000000000..123cbc6b9a6 --- /dev/null +++ b/src/mongo/logv2/log_domain_internal.h @@ -0,0 +1,54 @@ +/** + * 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 + * . + * + * 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/logv2/log_component_settings.h" +#include "mongo/logv2/log_domain.h" +#include "mongo/logv2/log_source.h" + +namespace mongo { +namespace logv2 { +class LogDomain::Internal { +public: + Internal() = default; + virtual ~Internal(); + + virtual LogSource& source() = 0; + + const LogComponentSettings& settings() const { + return _settings; + } + +private: + LogComponentSettings _settings; +}; + +} // namespace logv2 +} // namespace mongo diff --git a/src/mongo/logv2/log_manager.cpp b/src/mongo/logv2/log_manager.cpp index b7887864867..50d1ee2947f 100644 --- a/src/mongo/logv2/log_manager.cpp +++ b/src/mongo/logv2/log_manager.cpp @@ -97,7 +97,7 @@ struct LogManager::Impl { Impl() { _consoleBackend = boost::make_shared(); - _consoleBackend->set_filter(ComponentSettingsFilter(_globalDomain.settings())); + _consoleBackend->set_filter(ComponentSettingsFilter(_globalDomain)); _consoleBackend->set_formatter(TextFormatter()); _consoleBackend->locked_backend()->add_stream( @@ -106,12 +106,12 @@ struct LogManager::Impl { _consoleBackend->locked_backend()->auto_flush(); _globalLogCacheBackend = RamLogSink::create(RamLog::get("global")); - _globalLogCacheBackend->set_filter(ComponentSettingsFilter(_globalDomain.settings())); + _globalLogCacheBackend->set_filter(ComponentSettingsFilter(_globalDomain)); _globalLogCacheBackend->set_formatter(TextFormatter()); _startupWarningsBackend = RamLogSink::create(RamLog::get("startupWarnings")); - _startupWarningsBackend->set_filter( - TaggedSeverityFilter({LogTag::kStartupWarnings}, LogSeverity::Warning())); + _startupWarningsBackend->set_filter(TaggedSeverityFilter( + _globalDomain, {LogTag::kStartupWarnings}, LogSeverity::Warning())); _startupWarningsBackend->set_formatter(TextFormatter()); } @@ -127,7 +127,7 @@ struct LogManager::Impl { // backend->set_severity_mapper( // boost::log::sinks::syslog::direct_severity_mapping("Severity")); _syslogBackend = boost::make_shared(backend); - _syslogBackend->set_filter(ComponentSettingsFilter(_globalDomain.settings())); + _syslogBackend->set_filter(ComponentSettingsFilter(_globalDomain)); _syslogBackend->set_formatter(TextFormatter()); #endif } @@ -141,7 +141,7 @@ struct LogManager::Impl { backend->set_file_collector(boost::make_shared(!append)); _rotatableFileBackend = boost::make_shared(backend); - _rotatableFileBackend->set_filter(ComponentSettingsFilter(_globalDomain.settings())); + _rotatableFileBackend->set_filter(ComponentSettingsFilter(_globalDomain)); _rotatableFileBackend->set_formatter(TextFormatter()); } @@ -217,14 +217,15 @@ void LogManager::setOutputFormat(LogFormat format) { void LogManager::detachDefaultBackends() { invariant(isDefaultBackendsAttached()); - _impl->_globalDomain.impl().core()->remove_sink(_impl->_startupWarningsBackend); - _impl->_globalDomain.impl().core()->remove_sink(_impl->_globalLogCacheBackend); - _impl->_globalDomain.impl().core()->remove_sink(_impl->_consoleBackend); + auto logCore = boost::log::core::get(); + logCore->remove_sink(_impl->_startupWarningsBackend); + logCore->remove_sink(_impl->_globalLogCacheBackend); + logCore->remove_sink(_impl->_consoleBackend); _impl->_defaultBackendsAttached = false; } void LogManager::detachConsoleBackend() { - _impl->_globalDomain.impl().core()->remove_sink(_impl->_consoleBackend); + boost::log::core::get()->remove_sink(_impl->_consoleBackend); } void LogManager::setupRotatableFileBackend(std::string path, bool append) { @@ -237,24 +238,25 @@ void LogManager::setupSyslogBackend(int syslogFacility) { void LogManager::reattachSyslogBackend() { #ifndef _WIN32 - _impl->_globalDomain.impl().core()->add_sink(_impl->_syslogBackend); + boost::log::core::get()->add_sink(_impl->_syslogBackend); #endif } void LogManager::reattachRotatableFileBackend() { - _impl->_globalDomain.impl().core()->add_sink(_impl->_rotatableFileBackend); + boost::log::core::get()->add_sink(_impl->_rotatableFileBackend); } void LogManager::reattachConsoleBackend() { - _impl->_globalDomain.impl().core()->add_sink(_impl->_consoleBackend); + boost::log::core::get()->add_sink(_impl->_consoleBackend); } void LogManager::reattachDefaultBackends() { invariant(!isDefaultBackendsAttached()); - _impl->_globalDomain.impl().core()->add_sink(_impl->_consoleBackend); - _impl->_globalDomain.impl().core()->add_sink(_impl->_globalLogCacheBackend); - _impl->_globalDomain.impl().core()->add_sink(_impl->_startupWarningsBackend); + auto logCore = boost::log::core::get(); + logCore->add_sink(_impl->_consoleBackend); + logCore->add_sink(_impl->_globalLogCacheBackend); + logCore->add_sink(_impl->_startupWarningsBackend); _impl->_defaultBackendsAttached = true; } diff --git a/src/mongo/logv2/log_source.h b/src/mongo/logv2/log_source.h index 2a3b43653bf..7510a68d352 100644 --- a/src/mongo/logv2/log_source.h +++ b/src/mongo/logv2/log_source.h @@ -29,6 +29,7 @@ #pragma once +#include #include #include #include @@ -38,6 +39,7 @@ #include "mongo/logv2/attributes.h" #include "mongo/logv2/log_component.h" +#include "mongo/logv2/log_domain.h" #include "mongo/logv2/log_severity.h" #include "mongo/logv2/log_tag.h" #include "mongo/util/time_support.h" @@ -49,20 +51,17 @@ namespace logv2 { class LogSource : public boost::log::sources:: basic_logger { private: -private: - typedef boost::log::sources:: - basic_logger - base_type; + using Base = boost::log::sources:: + basic_logger; public: - LogSource() : LogSource(boost::log::core::get()) {} - - LogSource(boost::log::core_ptr core) - : base_type(core), + LogSource(const LogDomain::Internal* domain) + : _domain(domain), _severity(LogSeverity::Log()), _component(LogComponent::kDefault), _tags(LogTag::kNone), _id(StringData{}) { + add_attribute_unlocked(attributes::domain(), _domain); add_attribute_unlocked(attributes::severity(), _severity); add_attribute_unlocked(attributes::component(), _component); add_attribute_unlocked(attributes::tags(), _tags); @@ -85,13 +84,13 @@ public: _component.set(component); _tags.set(tags); _id.set(stable_id); - return base_type::open_record_unlocked(); + return Base::open_record_unlocked(); } else return boost::log::record(); } void push_record(BOOST_RV_REF(boost::log::record) rec) { - base_type::push_record_unlocked(boost::move(rec)); + Base::push_record_unlocked(boost::move(rec)); _severity.set(LogSeverity::Log()); _component.set(LogComponent::kDefault); _tags.set(LogTag::kNone); @@ -99,6 +98,7 @@ public: } private: + boost::log::attributes::constant _domain; boost::log::attributes::mutable_constant _severity; boost::log::attributes::mutable_constant _component; boost::log::attributes::mutable_constant _tags; diff --git a/src/mongo/logv2/log_test_v2.cpp b/src/mongo/logv2/log_test_v2.cpp index fd290d8d808..9d07aaca2c2 100644 --- a/src/mongo/logv2/log_test_v2.cpp +++ b/src/mongo/logv2/log_test_v2.cpp @@ -89,10 +89,8 @@ struct formatter : public mongo::logv2::FormatterBase }; } // namespace fmt - -using namespace mongo::logv2; - namespace mongo { +namespace logv2 { namespace { class LogTestBackend : public boost::log::sinks:: @@ -135,15 +133,14 @@ public: LogDuringInitTester() { std::vector lines; auto sink = LogTestBackend::create(lines); - sink->set_filter( - ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); sink->set_formatter(PlainFormatter()); - LogManager::global().getGlobalDomain().impl().core()->add_sink(sink); + boost::log::core::get()->add_sink(sink); LOGV2("log during init"); ASSERT(lines.back() == "log during init"); - LogManager::global().getGlobalDomain().impl().core()->remove_sink(sink); + boost::log::core::get()->remove_sink(sink); } }; @@ -152,7 +149,7 @@ LogDuringInitTester logDuringInit; TEST_F(LogTestV2, Basic) { std::vector lines; auto sink = LogTestBackend::create(lines); - sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); sink->set_formatter(PlainFormatter()); attach(sink); @@ -188,7 +185,7 @@ TEST_F(LogTestV2, Basic) { TEST_F(LogTestV2, TextFormat) { std::vector lines; auto sink = LogTestBackend::create(lines); - sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); sink->set_formatter(TextFormatter()); attach(sink); @@ -210,7 +207,7 @@ TEST_F(LogTestV2, TextFormat) { TEST_F(LogTestV2, JSONFormat) { std::vector lines; auto sink = LogTestBackend::create(lines); - sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); sink->set_formatter(JsonFormatter()); attach(sink); @@ -263,22 +260,19 @@ TEST_F(LogTestV2, JSONFormat) { TEST_F(LogTestV2, Threads) { std::vector linesPlain; auto plainSink = LogTestBackend::create(linesPlain); - plainSink->set_filter( - ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + plainSink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); plainSink->set_formatter(PlainFormatter()); attach(plainSink); std::vector linesText; auto textSink = LogTestBackend::create(linesText); - textSink->set_filter( - ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + textSink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); textSink->set_formatter(TextFormatter()); attach(textSink); std::vector linesJson; auto jsonSink = LogTestBackend::create(linesJson); - jsonSink->set_filter( - ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + jsonSink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); jsonSink->set_formatter(JsonFormatter()); attach(jsonSink); @@ -318,14 +312,13 @@ TEST_F(LogTestV2, Ramlog) { RamLog* ramlog = RamLog::get("test_ramlog"); auto sink = RamLogSink::create(ramlog); - sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); sink->set_formatter(PlainFormatter()); attach(sink); std::vector lines; auto testSink = LogTestBackend::create(lines); - testSink->set_filter( - ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + testSink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); testSink->set_formatter(PlainFormatter()); attach(testSink); @@ -345,36 +338,27 @@ TEST_F(LogTestV2, Ramlog) { TEST_F(LogTestV2, MultipleDomains) { std::vector global_lines; auto sink = LogTestBackend::create(global_lines); - sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); sink->set_formatter(PlainFormatter()); attach(sink); - // Example how a second domain can be created. This method requires multiple boost log core - // instances (MongoDB customization) - class OtherDomainImpl : public LogDomainImpl { + // Example how a second domain can be created. + class OtherDomainImpl : public LogDomain::Internal { public: - OtherDomainImpl() : _core(boost::log::core::create()) {} + OtherDomainImpl() {} LogSource& source() override { - thread_local LogSource lg(_core); + thread_local LogSource lg(this); return lg; } - boost::shared_ptr core() override { - return _core; - } - - private: - boost::shared_ptr _core; }; LogDomain other_domain(std::make_unique()); std::vector other_lines; auto other_sink = LogTestBackend::create(other_lines); - other_sink->set_filter( - ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + other_sink->set_filter(ComponentSettingsFilter(other_domain)); other_sink->set_formatter(PlainFormatter()); - other_domain.impl().core()->add_sink(other_sink); - + attach(other_sink); LOGV2_OPTIONS({&other_domain}, "test"); ASSERT(global_lines.empty()); @@ -385,98 +369,6 @@ TEST_F(LogTestV2, MultipleDomains) { ASSERT(other_lines.back() == "test"); } -TEST_F(LogTestV2, MultipleDomainsFiltering) { - std::vector global_lines; - auto sink = LogTestBackend::create(global_lines); - sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); - sink->set_formatter(PlainFormatter()); - attach(sink); - - // Example on how we could instead support multiple domains using just a single boost::log::core - // (no modifications needed) - enum DomainId { Domain1, Domain2 }; - - // Log source that add an attribute for domain - class FilteringLogSource : public LogSource { - public: - FilteringLogSource(DomainId domainId) : _component(domainId) { - add_attribute_unlocked("domain", _component); - } - - private: - boost::log::attributes::constant _component; - }; - - // Domains with different value of the above attribute - class OtherDomainImpl1 : public LogDomainImpl { - public: - OtherDomainImpl1() {} - - LogSource& source() override { - thread_local FilteringLogSource lg(DomainId::Domain1); - return lg; - } - boost::shared_ptr core() override { - return boost::log::core::get(); - } - }; - - class OtherDomainImpl2 : public LogDomainImpl { - public: - OtherDomainImpl2() {} - - LogSource& source() override { - thread_local FilteringLogSource lg(DomainId::Domain2); - return lg; - } - boost::shared_ptr core() override { - return boost::log::core::get(); - } - }; - - // Filtering function to check the domain attribute - class MultipleDomainFiltering : public ComponentSettingsFilter { - public: - MultipleDomainFiltering(DomainId domainId, LogComponentSettings& settings) - : ComponentSettingsFilter(settings), _domainId(domainId) {} - - bool operator()(boost::log::attribute_value_set const& attrs) { - using namespace boost::log; - - return extract("domain", attrs).get() == _domainId && - ComponentSettingsFilter::operator()(attrs); - } - - private: - DomainId _domainId; - }; - - LogDomain domain1(std::make_unique()); - std::vector domain1_lines; - auto domain1_sink = LogTestBackend::create(domain1_lines); - domain1_sink->set_filter(MultipleDomainFiltering( - DomainId::Domain1, LogManager::global().getGlobalDomain().settings())); - domain1_sink->set_formatter(PlainFormatter()); - domain1.impl().core()->add_sink(domain1_sink); - - LogDomain domain2(std::make_unique()); - std::vector domain2_lines; - auto domain2_sink = LogTestBackend::create(domain2_lines); - domain2_sink->set_filter(MultipleDomainFiltering( - DomainId::Domain2, LogManager::global().getGlobalDomain().settings())); - domain2_sink->set_formatter(PlainFormatter()); - domain2.impl().core()->add_sink(domain2_sink); - - - LOGV2_OPTIONS({&domain1}, "test domain1"); - ASSERT(domain1_lines.back() == "test domain1"); - ASSERT(domain2_lines.empty()); - - LOGV2_OPTIONS({&domain2}, "test domain2"); - ASSERT(domain1_lines.back() == "test domain1"); - ASSERT(domain2_lines.back() == "test domain2"); -} - TEST_F(LogTestV2, FileLogging) { auto logv2_dir = std::make_unique("logv2"); @@ -494,7 +386,7 @@ TEST_F(LogTestV2, FileLogging) { auto sink = boost::make_shared< boost::log::sinks::synchronous_sink>(backend); - sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain().settings())); + sink->set_filter(ComponentSettingsFilter(LogManager::global().getGlobalDomain())); sink->set_formatter(PlainFormatter()); attach(sink); @@ -535,4 +427,5 @@ TEST_F(LogTestV2, FileLogging) { } } // namespace +} // namespace logv2 } // namespace mongo diff --git a/src/mongo/logv2/log_test_v2.h b/src/mongo/logv2/log_test_v2.h index 62f1ef1ccca..ef22a9441ac 100644 --- a/src/mongo/logv2/log_test_v2.h +++ b/src/mongo/logv2/log_test_v2.h @@ -30,7 +30,7 @@ #pragma once #include "mongo/logv2/log_domain.h" -#include "mongo/logv2/log_domain_impl.h" +#include "mongo/logv2/log_domain_internal.h" #include "mongo/logv2/log_manager.h" #include "mongo/unittest/unittest.h" @@ -50,55 +50,16 @@ class LogTestV2 : public unittest::Test { public: LogTestV2() { LogManager::global().detachDefaultBackends(); - /*auto backend = boost::make_shared(_logLines); - _sink = boost::make_shared>( - std::move(backend));*/ } - virtual ~LogTestV2() { + ~LogTestV2() override { LogManager::global().reattachDefaultBackends(); - // LogManager::global().getGlobalDomain().impl().core()->remove_sink(_sink); - LogManager::global().getGlobalDomain().impl().core()->remove_all_sinks(); + boost::log::core::get()->remove_all_sinks(); } void attach(boost::shared_ptr sink) { - LogManager::global().getGlobalDomain().impl().core()->add_sink(std::move(sink)); + boost::log::core::get()->add_sink(std::move(sink)); } - - /* void attach(std::function filter, - std::function - formatter) { - _sink->set_filter(std::move(filter)); - _sink->set_formatter(std::move(formatter)); - LogManager::global().getGlobalDomain().impl().core()->add_sink(_sink); - } - - std::string const& last() { - return _logLines.back(); - } - - std::size_t count() { - return _logLines.size(); - }*/ - -private: - /*class LogTestBackend - : public boost::log::sinks:: - basic_formatted_sink_backend { - public: - LogTestBackend(std::vector& logLines) : _logLines(logLines) {} - - void consume(boost::log::record_view const& rec, string_type const& formatted_string) { - _logLines.push_back(formatted_string); - } - - private: - std::vector& _logLines; - }; - - std::vector _logLines; - boost::shared_ptr> _sink;*/ }; } // namespace logv2 diff --git a/src/mongo/logv2/logv2_bm.cpp b/src/mongo/logv2/logv2_bm.cpp index 1b29b84164d..c4c601c9802 100644 --- a/src/mongo/logv2/logv2_bm.cpp +++ b/src/mongo/logv2/logv2_bm.cpp @@ -35,7 +35,7 @@ #include "mongo/logger/message_event_utf8_encoder.h" #include "mongo/logv2/component_settings_filter.h" #include "mongo/logv2/log.h" -#include "mongo/logv2/log_domain_impl.h" +#include "mongo/logv2/log_domain_internal.h" #include "mongo/logv2/text_formatter.h" #include "mongo/platform/basic.h" #include "mongo/util/log.h" @@ -141,14 +141,14 @@ private: _sink = boost::make_shared< boost::log::sinks::synchronous_sink>(backend); - _sink->set_filter(logv2::ComponentSettingsFilter( - logv2::LogManager::global().getGlobalDomain().settings())); + _sink->set_filter( + logv2::ComponentSettingsFilter(logv2::LogManager::global().getGlobalDomain())); _sink->set_formatter(logv2::TextFormatter()); - logv2::LogManager::global().getGlobalDomain().impl().core()->add_sink(_sink); + boost::log::core::get()->add_sink(_sink); } void tearDownAppender() { - logv2::LogManager::global().getGlobalDomain().impl().core()->remove_sink(_sink); + boost::log::core::get()->remove_sink(_sink); logv2::LogManager::global().reattachDefaultBackends(); } diff --git a/src/mongo/logv2/tagged_severity_filter.h b/src/mongo/logv2/tagged_severity_filter.h index 312f53f9209..6ebf3234b51 100644 --- a/src/mongo/logv2/tagged_severity_filter.h +++ b/src/mongo/logv2/tagged_severity_filter.h @@ -33,6 +33,7 @@ #include #include "mongo/logv2/attributes.h" +#include "mongo/logv2/domain_filter.h" #include "mongo/logv2/log_severity.h" #include "mongo/logv2/log_tag.h" @@ -40,11 +41,12 @@ namespace mongo { namespace logv2 { // Boost::log filter that enables logging if Tag exists with Severity over threshold -class TaggedSeverityFilter { +class TaggedSeverityFilter : public DomainFilter { public: - TaggedSeverityFilter(LogTag tag, LogSeverity severity) : _tag(tag), _severity(severity) {} - bool operator()(boost::log::attribute_value_set const& attrs) { - using namespace boost::log; + TaggedSeverityFilter(const LogDomain& domain, LogTag tag, LogSeverity severity) + : DomainFilter(domain), _tag(tag), _severity(severity) {} + bool filter(boost::log::attribute_value_set const& attrs) const { + using boost::log::extract; return _tag.has(extract(attributes::tags(), attrs).get()) && extract(attributes::severity(), attrs).get() <= _severity; -- cgit v1.2.1