diff options
author | Gabriel Russell <gabriel.russell@mongodb.com> | 2019-10-16 16:11:00 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-10-16 16:11:00 +0000 |
commit | 81e1eb03f722595bc321ed2322ad14901887ab11 (patch) | |
tree | 4bd45a10b11c904c2a67fe3c3475fd4f010416d7 | |
parent | 9bee42b1be57065f6ef963e6aa535a66a39e04f2 (diff) | |
download | mongo-81e1eb03f722595bc321ed2322ad14901887ab11.tar.gz |
SERVER-43746 logv2 Tee and RamLog
-rw-r--r-- | src/mongo/db/commands/generic_servers.cpp | 58 | ||||
-rw-r--r-- | src/mongo/db/commands/server_status.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/initialize_server_global_state.cpp | 29 | ||||
-rw-r--r-- | src/mongo/logger/logstream_builder.cpp | 5 | ||||
-rw-r--r-- | src/mongo/logger/logv2_appender.h | 24 | ||||
-rw-r--r-- | src/mongo/logger/message_event.h | 7 | ||||
-rw-r--r-- | src/mongo/logger/ramlog.h | 4 | ||||
-rw-r--r-- | src/mongo/logv2/log_tag.h | 13 | ||||
-rw-r--r-- | src/mongo/util/log.cpp | 1 |
9 files changed, 108 insertions, 46 deletions
diff --git a/src/mongo/db/commands/generic_servers.cpp b/src/mongo/db/commands/generic_servers.cpp index f89c1975c6c..073a67b22d2 100644 --- a/src/mongo/db/commands/generic_servers.cpp +++ b/src/mongo/db/commands/generic_servers.cpp @@ -37,6 +37,7 @@ #include "mongo/db/commands/shutdown.h" #include "mongo/db/commands/test_commands_enabled.h" #include "mongo/db/log_process_details.h" +#include "mongo/logv2/ramlog.h" #include "mongo/scripting/engine.h" #include "mongo/util/exit.h" #include "mongo/util/fail_point.h" @@ -52,9 +53,6 @@ namespace mongo { namespace { -using std::string; -using std::vector; - class FeaturesCmd : public BasicCommand { public: FeaturesCmd() : BasicCommand("features") {} @@ -71,7 +69,7 @@ public: const BSONObj& cmdObj, std::vector<Privilege>* out) const {} // No auth required virtual bool run(OperationContext* opCtx, - const string& ns, + const std::string& ns, const BSONObj& cmdObj, BSONObjBuilder& result) { if (getGlobalScriptEngine()) { @@ -112,7 +110,7 @@ public: out->push_back(Privilege(ResourcePattern::forClusterResource(), actions)); } bool run(OperationContext* opCtx, - const string& dbname, + const std::string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) { ProcessInfo p; @@ -165,7 +163,7 @@ public: out->push_back(Privilege(ResourcePattern::forClusterResource(), actions)); } virtual bool run(OperationContext* opCtx, - const string&, + const std::string&, const BSONObj& cmdObj, BSONObjBuilder& result) { result.append("argv", serverGlobalParams.argvArray); @@ -195,7 +193,7 @@ public: out->push_back(Privilege(ResourcePattern::forClusterResource(), actions)); } virtual bool run(OperationContext* opCtx, - const string& ns, + const std::string& ns, const BSONObj& cmdObj, BSONObjBuilder& result) { bool didRotate = rotateLogs(serverGlobalParams.logRenameOnRotate, serverGlobalParams.logV2); @@ -230,11 +228,23 @@ public: return "{ getLog : '*' } OR { getLog : 'global' }"; } - virtual bool errmsgRun(OperationContext* opCtx, - const string& dbname, - const BSONObj& cmdObj, - string& errmsg, - BSONObjBuilder& result) { + bool errmsgRun(OperationContext* opCtx, + const std::string& dbname, + const BSONObj& cmdObj, + std::string& errmsg, + BSONObjBuilder& result) override { + if (serverGlobalParams.logV2) { + return errmsgRunImpl<logv2::RamLog>(opCtx, dbname, cmdObj, errmsg, result); + } + return errmsgRunImpl<RamLog>(opCtx, dbname, cmdObj, errmsg, result); + } + + template <typename RamLogType> + bool errmsgRunImpl(OperationContext* opCtx, + const std::string& dbname, + const BSONObj& cmdObj, + std::string& errmsg, + BSONObjBuilder& result) { BSONElement val = cmdObj.firstElement(); if (val.type() != String) { uasserted(ErrorCodes::TypeMismatch, @@ -242,10 +252,10 @@ public: << val.toString(false) << " of type " << typeName(val.type())); } - string p = val.String(); + std::string p = val.String(); if (p == "*") { - vector<string> names; - RamLog::getNames(names); + std::vector<std::string> names; + RamLogType::getNames(names); BSONArrayBuilder arr; for (unsigned i = 0; i < names.size(); i++) { @@ -254,12 +264,12 @@ public: result.appendArray("names", arr.arr()); } else { - RamLog* ramlog = RamLog::getIfExists(p); + RamLogType* ramlog = RamLogType::getIfExists(p); if (!ramlog) { errmsg = str::stream() << "no RamLog named: " << p; return false; } - RamLog::LineIterator rl(ramlog); + typename RamLogType::LineIterator rl(ramlog); result.appendNumber("totalLinesWritten", rl.getTotalLinesWritten()); @@ -298,7 +308,7 @@ public: } virtual bool run(OperationContext* opCtx, - const string& dbname, + const std::string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) { std::string logName; @@ -308,9 +318,15 @@ public: if (logName != "global") { uasserted(ErrorCodes::InvalidOptions, "Only the 'global' log can be cleared"); } - RamLog* ramlog = RamLog::getIfExists(logName); - invariant(ramlog); - ramlog->clear(); + auto clearRamlog = [&](auto* ramlog) { + invariant(ramlog); + ramlog->clear(); + }; + if (serverGlobalParams.logV2) { + clearRamlog(logv2::RamLog::getIfExists(logName)); + } else { + clearRamlog(RamLog::getIfExists(logName)); + } return true; } }; diff --git a/src/mongo/db/commands/server_status.cpp b/src/mongo/db/commands/server_status.cpp index 84b2eae0707..685332111b3 100644 --- a/src/mongo/db/commands/server_status.cpp +++ b/src/mongo/db/commands/server_status.cpp @@ -40,7 +40,6 @@ #include "mongo/util/log.h" #include "mongo/util/net/http_client.h" #include "mongo/util/net/socket_utils.h" -#include "mongo/util/ramlog.h" #include "mongo/util/version.h" namespace mongo { @@ -142,18 +141,6 @@ public: // --- some hard coded global things hard to pull out - { - RamLog::LineIterator rl(RamLog::get("warnings")); - if (rl.lastWrite() >= - time(nullptr) - (10 * 60)) { // only show warnings from last 10 minutes - BSONArrayBuilder arr(result.subarrayStart("warnings")); - while (rl.more()) { - arr.append(rl.next()); - } - arr.done(); - } - } - auto runElapsed = clock->now() - runStart; timeBuilder.appendNumber("at end", durationCount<Milliseconds>(runElapsed)); if (runElapsed > Milliseconds(1000)) { diff --git a/src/mongo/db/initialize_server_global_state.cpp b/src/mongo/db/initialize_server_global_state.cpp index 1a7d2277cfb..174a7d1cddd 100644 --- a/src/mongo/db/initialize_server_global_state.cpp +++ b/src/mongo/db/initialize_server_global_state.cpp @@ -231,10 +231,13 @@ MONGO_INITIALIZER_GENERAL(ServerLogRedirection, "Syslog requested in Windows build; command line processor logic error"); #else std::unique_ptr<logger::Appender<MessageEventEphemeral>> appender; + std::unique_ptr<logger::Appender<MessageEventEphemeral>> javascriptAppender; if (serverGlobalParams.logV2) { appender = std::make_unique<logger::LogV2Appender<MessageEventEphemeral>>( &(lv2Manager.getGlobalDomain())); + javascriptAppender = std::make_unique<logger::LogV2Appender<MessageEventEphemeral>>( + &(lv2Manager.getGlobalDomain())); lv2Config._consoleEnabled = false; lv2Config._syslogEnabled = true; @@ -246,13 +249,13 @@ MONGO_INITIALIZER_GENERAL(ServerLogRedirection, openlog( strdup(sb.str().c_str()), LOG_PID | LOG_CONS, serverGlobalParams.syslogFacility); appender = std::make_unique<SyslogAppender<MessageEventEphemeral>>( - std::make_unique<logger::MessageEventDetailsEncoder>()); - manager->getNamedDomain("javascriptOutput") - ->attachAppender(std::make_unique<SyslogAppender<MessageEventEphemeral>>( - std::make_unique<logger::MessageEventDetailsEncoder>())); + std::make_unique<MessageEventDetailsEncoder>()); + javascriptAppender = std::make_unique<SyslogAppender<MessageEventEphemeral>>( + std::make_unique<MessageEventDetailsEncoder>()); } manager->getGlobalDomain()->clearAppenders(); manager->getGlobalDomain()->attachAppender(std::move(appender)); + manager->getNamedDomain("javascriptOutput")->attachAppender(std::move(javascriptAppender)); #endif // defined(_WIN32) } else if (!serverGlobalParams.logpath.empty()) { @@ -297,11 +300,14 @@ MONGO_INITIALIZER_GENERAL(ServerLogRedirection, } std::unique_ptr<logger::Appender<MessageEventEphemeral>> appender; + std::unique_ptr<logger::Appender<MessageEventEphemeral>> javascriptAppender; if (serverGlobalParams.logV2) { appender = std::make_unique<logger::LogV2Appender<MessageEventEphemeral>>( &(lv2Manager.getGlobalDomain())); + javascriptAppender = std::make_unique<logger::LogV2Appender<MessageEventEphemeral>>( + &(lv2Manager.getGlobalDomain())); lv2Config._consoleEnabled = false; lv2Config._fileEnabled = true; @@ -329,9 +335,8 @@ MONGO_INITIALIZER_GENERAL(ServerLogRedirection, } appender = std::make_unique<RotatableFileAppender<MessageEventEphemeral>>( std::make_unique<MessageEventDetailsEncoder>(), writer.getValue()); - manager->getNamedDomain("javascriptOutput") - ->attachAppender(std::make_unique<RotatableFileAppender<MessageEventEphemeral>>( - std::make_unique<MessageEventDetailsEncoder>(), writer.getValue())); + javascriptAppender = std::make_unique<RotatableFileAppender<MessageEventEphemeral>>( + std::make_unique<MessageEventDetailsEncoder>(), writer.getValue()); if (serverGlobalParams.logAppend && exists) { log() << "***** SERVER RESTARTED *****"; Status status = logger::RotatableFileWriter::Use(writer.getValue()).status(); @@ -342,6 +347,7 @@ MONGO_INITIALIZER_GENERAL(ServerLogRedirection, manager->getGlobalDomain()->clearAppenders(); manager->getGlobalDomain()->attachAppender(std::move(appender)); + manager->getNamedDomain("javascriptOutput")->attachAppender(std::move(javascriptAppender)); } else { if (serverGlobalParams.logV2) { @@ -349,6 +355,9 @@ MONGO_INITIALIZER_GENERAL(ServerLogRedirection, manager->getGlobalDomain()->attachAppender( std::make_unique<logger::LogV2Appender<MessageEventEphemeral>>( &(lv2Manager.getGlobalDomain()))); + manager->getNamedDomain("javascriptOutput") + ->attachAppender(std::make_unique<logger::LogV2Appender<MessageEventEphemeral>>( + &(lv2Manager.getGlobalDomain()))); } else { logger::globalLogManager() ->getNamedDomain("javascriptOutput") @@ -356,9 +365,11 @@ MONGO_INITIALIZER_GENERAL(ServerLogRedirection, std::make_unique<MessageEventDetailsEncoder>())); } } + if (!serverGlobalParams.logV2) { + logger::globalLogDomain()->attachAppender( + std::make_unique<RamLogAppender>(RamLog::get("global"))); + } - logger::globalLogDomain()->attachAppender( - std::make_unique<RamLogAppender>(RamLog::get("global"))); if (serverGlobalParams.logV2) { lv2Config._format = serverGlobalParams.logFormat; diff --git a/src/mongo/logger/logstream_builder.cpp b/src/mongo/logger/logstream_builder.cpp index 5b6115b4cfb..c07c29c3fe5 100644 --- a/src/mongo/logger/logstream_builder.cpp +++ b/src/mongo/logger/logstream_builder.cpp @@ -33,9 +33,11 @@ #include <memory> +#include "mongo/base/checked_cast.h" #include "mongo/base/init.h" #include "mongo/base/status.h" #include "mongo/logger/message_event_utf8_encoder.h" +#include "mongo/logger/ramlog.h" #include "mongo/logger/tee.h" #include "mongo/util/assert_util.h" // TODO: remove apple dep for this in threadlocal.h #include "mongo/util/time_support.h" @@ -94,6 +96,9 @@ LogstreamBuilder::~LogstreamBuilder() { MessageEventEphemeral message( Date_t::now(), _severity, _component, _contextName, _baseMessage); message.setIsTruncatable(_isTruncatable); + if (_tee) { + message.setTeeName(checked_cast<RamLog*>(_tee)->getName()); + } _domain->append(message).transitional_ignore(); if (_tee) { _os->str(""); diff --git a/src/mongo/logger/logv2_appender.h b/src/mongo/logger/logv2_appender.h index b94401877ee..2076fa291a4 100644 --- a/src/mongo/logger/logv2_appender.h +++ b/src/mongo/logger/logv2_appender.h @@ -35,10 +35,29 @@ #include "mongo/logv2/log_component.h" #include "mongo/logv2/log_detail.h" #include "mongo/logv2/log_domain.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[] = { + {"rs"_sd, logv2::LogTag::kRS}, + {"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 */ @@ -51,6 +70,9 @@ public: explicit LogV2Appender(logv2::LogDomain* domain) : _domain(domain) {} Status append(const Event& event) override { + + auto logTagValue = findTeeTag(event.getTeeName()); + logv2::detail::doLog( // We need to cast from the v1 logging severity to the equivalent v2 severity @@ -62,7 +84,7 @@ public: static_cast<std::underlying_type_t<LogComponent::Value>>( static_cast<LogComponent::Value>(event.getComponent())))), _domain, - logv2::LogTag{}}, + logv2::LogTag{logTagValue}}, // stable id doesn't exist in logv1 StringData{}, diff --git a/src/mongo/logger/message_event.h b/src/mongo/logger/message_event.h index 684ac459576..e767a71ecf7 100644 --- a/src/mongo/logger/message_event.h +++ b/src/mongo/logger/message_event.h @@ -64,11 +64,17 @@ public: _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; } @@ -95,6 +101,7 @@ private: StringData _contextName; StringData _message; bool _isTruncatable = true; + StringData _teeName; }; } // namespace logger diff --git a/src/mongo/logger/ramlog.h b/src/mongo/logger/ramlog.h index 7a3ff8cdaaa..e737663083c 100644 --- a/src/mongo/logger/ramlog.h +++ b/src/mongo/logger/ramlog.h @@ -93,6 +93,10 @@ public: */ void write(const std::string& str); + const std::string& getName() const { + return _name; + }; + /** * Empties out the RamLog. */ diff --git a/src/mongo/logv2/log_tag.h b/src/mongo/logv2/log_tag.h index 1576b863f38..dee9e960d4d 100644 --- a/src/mongo/logv2/log_tag.h +++ b/src/mongo/logv2/log_tag.h @@ -36,7 +36,18 @@ namespace mongo { namespace logv2 { class LogTag { public: - enum Value { kNone = 0, kStartupWarnings = 1 << 0, kJavascript = 1 << 1 }; + enum Value { + kNone = 0, + + // replica set ramlog + kRS = 1 << 0, + + // startupWarnings ramlog + kStartupWarnings = 1 << 1, + + // representing the logv1 javascriptOutput domain + kJavascript = 1 << 2, + }; LogTag() : _value(kNone) {} /* implicit */ LogTag(Value value) { diff --git a/src/mongo/util/log.cpp b/src/mongo/util/log.cpp index eb3e85407ea..ce127933ece 100644 --- a/src/mongo/util/log.cpp +++ b/src/mongo/util/log.cpp @@ -101,7 +101,6 @@ void setPlainConsoleLogger() { std::make_unique<logger::MessageEventUnadornedEncoder>())); } -Tee* const warnings = RamLog::get("warnings"); // Things put here go in serverStatus Tee* const startupWarningsLog = RamLog::get("startupWarnings"); // intentionally leaked } // namespace mongo |