summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrik Edin <henrik.edin@mongodb.com>2019-10-10 15:24:38 +0000
committerevergreen <evergreen@mongodb.com>2019-10-10 15:24:38 +0000
commitfaa0ec0def1317f9005d3b0935aff83666f47404 (patch)
treeda02baa10300943b2c0c9c4893ad464bb275b0e8
parent6b94e0025991847cb4a145351bfeee12f4af92e4 (diff)
downloadmongo-faa0ec0def1317f9005d3b0935aff83666f47404.tar.gz
SERVER-43759 Implement log domains with filtering.
Does not require modifications to boost::log.
-rw-r--r--src/mongo/SConscript1
-rw-r--r--src/mongo/logv2/attributes.cpp21
-rw-r--r--src/mongo/logv2/attributes.h1
-rw-r--r--src/mongo/logv2/component_settings_filter.h12
-rw-r--r--src/mongo/logv2/domain_filter.h60
-rw-r--r--src/mongo/logv2/log.cpp6
-rw-r--r--src/mongo/logv2/log_detail.cpp6
-rw-r--r--src/mongo/logv2/log_domain.cpp12
-rw-r--r--src/mongo/logv2/log_domain.h18
-rw-r--r--src/mongo/logv2/log_domain_global.cpp5
-rw-r--r--src/mongo/logv2/log_domain_global.h5
-rw-r--r--src/mongo/logv2/log_domain_internal.cpp36
-rw-r--r--src/mongo/logv2/log_domain_internal.h (renamed from src/mongo/logv2/log_domain_impl.h)11
-rw-r--r--src/mongo/logv2/log_manager.cpp34
-rw-r--r--src/mongo/logv2/log_source.h20
-rw-r--r--src/mongo/logv2/log_test_v2.cpp149
-rw-r--r--src/mongo/logv2/log_test_v2.h47
-rw-r--r--src/mongo/logv2/logv2_bm.cpp10
-rw-r--r--src/mongo/logv2/tagged_severity_filter.h10
19 files changed, 215 insertions, 249 deletions
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 <boost/log/attributes/value_extraction.hpp>
#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<ComponentSettingsFilter> {
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<LogComponent>(attributes::component(), attrs).get(),
extract<LogSeverity>(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
+ * <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/log/attributes/attribute_value_set.hpp>
+#include <boost/log/attributes/value_extraction.hpp>
+
+#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 Filter>
+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<const LogDomain::Internal*>(attributes::domain(), attrs).get() == _domain &&
+ static_cast<const Filter*>(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<LogDomainImpl> impl) : _impl(std::move(impl)) {}
+LogDomain::LogDomain(std::unique_ptr<LogDomain::Internal> 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<LogRecordImpl> 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<LogRecordImpl>(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<LogDomainImpl> impl);
- LogDomainImpl& impl() {
- return *_impl;
+ class Internal;
+
+ explicit LogDomain(std::unique_ptr<Internal> 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<LogDomainImpl> _impl;
+ std::unique_ptr<Internal> _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<boost::log::core> 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<boost::log::core> core() override;
};
} // 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
+ * <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 "log_domain_internal.h"
+
+namespace mongo {
+namespace logv2 {
+LogDomain::Internal::~Internal() = default;
+} // namespace logv2
+} // namespace mongo
diff --git a/src/mongo/logv2/log_domain_impl.h b/src/mongo/logv2/log_domain_internal.h
index 6e82687eda8..123cbc6b9a6 100644
--- a/src/mongo/logv2/log_domain_impl.h
+++ b/src/mongo/logv2/log_domain_internal.h
@@ -30,20 +30,19 @@
#pragma once
#include "mongo/logv2/log_component_settings.h"
+#include "mongo/logv2/log_domain.h"
#include "mongo/logv2/log_source.h"
-#include <boost/log/core.hpp>
namespace mongo {
namespace logv2 {
-class LogDomainImpl {
+class LogDomain::Internal {
public:
- LogDomainImpl() {}
- virtual ~LogDomainImpl() {}
+ Internal() = default;
+ virtual ~Internal();
virtual LogSource& source() = 0;
- virtual boost::shared_ptr<boost::log::core> core() = 0;
- LogComponentSettings& settings() {
+ const LogComponentSettings& settings() const {
return _settings;
}
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>();
- _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<int>("Severity"));
_syslogBackend = boost::make_shared<SyslogBackend>(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<RotateCollector>(!append));
_rotatableFileBackend = boost::make_shared<RotatableFileBackend>(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 <boost/log/attributes/constant.hpp>
#include <boost/log/attributes/function.hpp>
#include <boost/log/attributes/mutable_constant.hpp>
#include <boost/log/keywords/channel.hpp>
@@ -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<char, LogSource, boost::log::sources::single_thread_model> {
private:
-private:
- typedef boost::log::sources::
- basic_logger<char, LogSource, boost::log::sources::single_thread_model>
- base_type;
+ using Base = boost::log::sources::
+ basic_logger<char, LogSource, boost::log::sources::single_thread_model>;
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<const LogDomain::Internal*> _domain;
boost::log::attributes::mutable_constant<LogSeverity> _severity;
boost::log::attributes::mutable_constant<LogComponent> _component;
boost::log::attributes::mutable_constant<LogTag> _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<TypeWithCustomFormatting> : 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<boost::log::core> core() override {
- return _core;
- }
-
- private:
- boost::shared_ptr<boost::log::core> _core;
};
LogDomain other_domain(std::make_unique<OtherDomainImpl>());
std::vector<std::string> 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<std::string> 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<DomainId> _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<boost::log::core> 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<boost::log::core> 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<DomainId>("domain", attrs).get() == _domainId &&
- ComponentSettingsFilter::operator()(attrs);
- }
-
- private:
- DomainId _domainId;
- };
-
- LogDomain domain1(std::make_unique<OtherDomainImpl1>());
- std::vector<std::string> 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<OtherDomainImpl2>());
- std::vector<std::string> 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<mongo::unittest::TempDir>("logv2");
@@ -494,7 +386,7 @@ TEST_F(LogTestV2, FileLogging) {
auto sink = boost::make_shared<
boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend>>(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<LogTestBackend>(_logLines);
- _sink = boost::make_shared<boost::log::sinks::synchronous_sink<LogTestBackend>>(
- 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<boost::log::sinks::sink> sink) {
- LogManager::global().getGlobalDomain().impl().core()->add_sink(std::move(sink));
+ boost::log::core::get()->add_sink(std::move(sink));
}
-
- /* void attach(std::function<bool(boost::log::attribute_value_set const&)> filter,
- std::function<void(boost::log::record_view const&,
- boost::log::formatting_ostream&)>
- 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<char, boost::log::sinks::synchronized_feeding> {
- public:
- LogTestBackend(std::vector<std::string>& logLines) : _logLines(logLines) {}
-
- void consume(boost::log::record_view const& rec, string_type const& formatted_string) {
- _logLines.push_back(formatted_string);
- }
-
- private:
- std::vector<std::string>& _logLines;
- };
-
- std::vector<std::string> _logLines;
- boost::shared_ptr<boost::log::sinks::synchronous_sink<LogTestBackend>> _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<boost::log::sinks::text_ostream_backend>>(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 <boost/log/attributes/value_extraction.hpp>
#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<TaggedSeverityFilter> {
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<LogTag>(attributes::tags(), attrs).get()) &&
extract<LogSeverity>(attributes::severity(), attrs).get() <= _severity;