void CatalogManagerReplicaSet::logChange(const string& clientAddress, const string& what, const string& ns, const BSONObj& detail) { if (_changeLogCollectionCreated.load() == 0) { BSONObj createCmd = BSON("create" << ChangelogType::ConfigNS << "capped" << true << "size" << kChangeLogCollectionSize); auto result = _runConfigServerCommandWithNotMasterRetries("config", createCmd); if (!result.isOK()) { LOG(1) << "couldn't create changelog collection: " << causedBy(result.getStatus()); return; } Status commandStatus = Command::getStatusFromCommandResult(result.getValue()); if (commandStatus.isOK() || commandStatus == ErrorCodes::NamespaceExists) { _changeLogCollectionCreated.store(1); } else { LOG(1) << "couldn't create changelog collection: " << causedBy(commandStatus); return; } } Date_t now = grid.shardRegistry()->getExecutor()->now(); std::string hostName = grid.shardRegistry()->getNetwork()->getHostName(); const string changeID = str::stream() << hostName << "-" << now.toString() << "-" << OID::gen(); ChangelogType changeLog; changeLog.setChangeID(changeID); changeLog.setServer(hostName); changeLog.setClientAddr(clientAddress); changeLog.setTime(now); changeLog.setNS(ns); changeLog.setWhat(what); changeLog.setDetails(detail); BSONObj changeLogBSON = changeLog.toBSON(); log() << "about to log metadata event: " << changeLogBSON; Status result = insert(ChangelogType::ConfigNS, changeLogBSON, NULL); if (!result.isOK()) { warning() << "Error encountered while logging config change with ID " << changeID << ": " << result; } }
Status logConfigChange(const ConnectionString& configLoc, const string& clientHost, const string& ns, const string& description, const BSONObj& details) { // // The code for writing to the changelog collection exists elsewhere - we duplicate here to // avoid dependency issues. // TODO: Merge again once config.cpp is cleaned up. // string changeID = stream() << getHostNameCached() << "-" << terseCurrentTime() << "-" << OID::gen(); ChangelogType changelog; changelog.setChangeID(changeID); changelog.setServer(getHostNameCached()); changelog.setClientAddr(clientHost == "" ? "N/A" : clientHost); changelog.setTime(jsTime()); changelog.setWhat(description); changelog.setNS(ns); changelog.setDetails(details); log() << "about to log new metadata event: " << changelog.toBSON() << endl; scoped_ptr<ScopedDbConnection> connPtr; try { connPtr.reset(new ScopedDbConnection(configLoc, 30)); ScopedDbConnection& conn = *connPtr; // TODO: better way here static bool createdCapped = false; if (!createdCapped) { try { conn->createCollection(ChangelogType::ConfigNS, 1024 * 1024 * 10, true); } catch (const DBException& e) { // don't care, someone else may have done this for us // if there's still a problem, caught in outer try LOG(1) << "couldn't create the changelog, continuing " << e << endl; } createdCapped = true; } connPtr->done(); } catch (const DBException& e) { // if we got here, it means the config change is only in the log, // it didn't make it to config.changelog log() << "not logging config change: " << changeID << causedBy(e) << endl; return e.toStatus(); } Status result = clusterInsert( ChangelogType::ConfigNS, changelog.toBSON(), WriteConcernOptions::AllConfigs, NULL ); if ( !result.isOK() ) { return Status( result.code(), str::stream() << "failed to write to changelog: " << result.reason() ); } return result; }