1
0
Fork 0

Version/Engine Cluster Health (#7474)

* Export Version and Engine in Cluster Health. Additionally export `versionString` in registered Servers.

* Updated Changelog.
This commit is contained in:
Lars Maier 2018-11-27 14:56:00 +01:00 committed by Max Neunhöffer
parent 7213b80c6c
commit f3ade0f860
3 changed files with 49 additions and 19 deletions

View File

@ -1,6 +1,8 @@
devel
-----
* Export Version and Storage Engine in `_admin/cluster/health` for Coordinators and DBServers.
* fixed Foxx complaining about valid `$schema` value in manifest.json
* Foxx `req.makeAbsolute` now will return meaningful values when ArangoDB is using

View File

@ -53,13 +53,17 @@ struct HealthRecord {
std::string advertisedEndpoint;
std::string lastAcked;
std::string hostId;
std::string serverVersion;
std::string engine;
size_t version;
explicit HealthRecord() : version(0) {}
HealthRecord(
std::string const& sn, std::string const& ep, std::string const& ho) :
shortName(sn), endpoint(ep), hostId(ho), version(0) {}
std::string const& sn, std::string const& ep, std::string const& ho,
std::string const& en, std::string const& sv) :
shortName(sn), endpoint(ep), hostId(ho), serverVersion(sv),
engine(en), version(0) {}
explicit HealthRecord(Node const& node) {
*this = node;
@ -94,6 +98,12 @@ struct HealthRecord {
if (node.has("AdvertisedEndpoint")) {
version = 3;
advertisedEndpoint = node.hasAsString("AdvertisedEndpoint").first;
if (node.has("Engine") && node.has("Version")) {
version = 4;
engine = node.hasAsString("Engine").first;
serverVersion = node.hasAsString("Version").first;
}
}
} else if (node.has("LastHeartbeatStatus")) {
version = 1;
@ -116,6 +126,8 @@ struct HealthRecord {
advertisedEndpoint = other.advertisedEndpoint;
endpoint = other.endpoint;
hostId = other.hostId;
engine = other.engine;
serverVersion = other.serverVersion;
version = other.version;
return *this;
}
@ -128,6 +140,8 @@ struct HealthRecord {
obj.add("Host", VPackValue(hostId));
obj.add("SyncStatus", VPackValue(syncStatus));
obj.add("Status", VPackValue(status));
obj.add("Version", VPackValue(serverVersion));
obj.add("Engine", VPackValue(engine));
if (syncTime.empty()) {
obj.add("Timestamp",
VPackValue(timepointToString(std::chrono::system_clock::now())));
@ -443,18 +457,31 @@ std::vector<check_t> Supervision::check(std::string const& type) {
shortName = tmp_shortName.first;
// "/arango/Current/<serverId>/endpoint"
// "/arango/Current/ServersRegistered/<server-id>/endpoint"
std::string endpoint;
std::string epPath = serverID + "/endpoint";
if (serversRegistered.has(epPath)) {
endpoint = serversRegistered.hasAsString(epPath).first;
}
// "/arango/Current/<serverId>/host"
// "/arango/Current/ServersRegistered/<server-id>/host"
std::string hostId;
std::string hoPath = serverID + "/host";
if (serversRegistered.has(hoPath)) {
hostId = serversRegistered.hasAsString(hoPath).first;
}
// "/arango/Current/ServersRegistered/<server-id>/serverVersion"
std::string serverVersion;
std::string svPath = serverID + "/versionString";
if (serversRegistered.has(svPath)) {
serverVersion = serversRegistered.hasAsString(svPath).first;
}
// "/arango/Current/ServersRegistered/<server-id>/engine"
std::string engine;
std::string enPath = serverID + "/engine";
if (serversRegistered.has(enPath)) {
engine = serversRegistered.hasAsString(enPath).first;
}
// "/arango/Current/<serverId>/externalEndpoint"
/*std::string externalEndpoint;
@ -464,8 +491,8 @@ std::vector<check_t> Supervision::check(std::string const& type) {
}*/
// Health records from persistence, from transience and a new one
HealthRecord transist(shortName, endpoint, hostId);
HealthRecord persist(shortName, endpoint, hostId);
HealthRecord transist(shortName, endpoint, hostId, engine, serverVersion);
HealthRecord persist(shortName, endpoint, hostId, engine, serverVersion);
// Get last health entries from transient and persistent key value stores
if (_transient.has(healthPrefix + serverID)) {
@ -1021,7 +1048,7 @@ void Supervision::workJobs() {
void Supervision::readyOrphanedIndexCreations() {
_lock.assertLockedByCurrentThread();
if (_snapshot.has(planColPrefix) && _snapshot.has(curColPrefix)) {
auto const& plannedDBs = _snapshot(planColPrefix).children();
auto const& currentDBs = _snapshot(curColPrefix);
@ -1053,7 +1080,7 @@ void Supervision::readyOrphanedIndexCreations() {
for (auto const& sh : shards.children()) {
auto const& shname = sh.first;
if (currentDBs.has(colPath + shname + "/indexes")) {
auto const& curIndexes =
currentDBs(colPath + shname + "/indexes").slice();
@ -1107,7 +1134,7 @@ void Supervision::readyOrphanedIndexCreations() {
{ VPackObjectBuilder precondition(envelope.get());
envelope->add(
VPackValue(
_agencyPrefix + planColPrefix + colPath + "indexes"));
_agencyPrefix + planColPrefix + colPath + "indexes"));
envelope->add(indexes); }
}}
@ -1116,7 +1143,7 @@ void Supervision::readyOrphanedIndexCreations() {
LOG_TOPIC(DEBUG, Logger::SUPERVISION)
<< "failed to report ready index to agency. Will retry.";
}
}
}
}
}
}

View File

@ -484,16 +484,16 @@ static constexpr char const* currentServersRegisteredPref = "/Current/ServersReg
/// @brief check equality of engines with other registered servers
bool ServerState::checkEngineEquality(AgencyComm& comm) {
std::string engineName = EngineSelectorFeature::engineName();
AgencyCommResult result = comm.getValues(currentServersRegisteredPref);
if (result.successful()) { // no error if we cannot reach agency directly
auto slicePath = AgencyCommManager::slicePath(currentServersRegisteredPref);
VPackSlice servers = result.slice()[0].get(slicePath);
if (!servers.isObject()) {
return true; // do not do anything harsh here
}
for (VPackObjectIterator::ObjectPair pair : VPackObjectIterator(servers)) {
if (pair.value.isObject()) {
VPackSlice engineStr = pair.value.get("engine");
@ -503,7 +503,7 @@ bool ServerState::checkEngineEquality(AgencyComm& comm) {
}
}
}
return true;
}
@ -645,7 +645,7 @@ bool ServerState::registerAtAgencyPhase1(AgencyComm& comm,
bool ServerState::registerAtAgencyPhase2(AgencyComm& comm) {
TRI_ASSERT(!_id.empty() && !_myEndpoint.empty());
while (!application_features::ApplicationServer::isStopping()) {
VPackBuilder builder;
try {
@ -654,14 +654,15 @@ bool ServerState::registerAtAgencyPhase2(AgencyComm& comm) {
builder.add("advertisedEndpoint", VPackValue(_advertisedEndpoint));
builder.add("host", VPackValue(getHost()));
builder.add("version", VPackValue(rest::Version::getNumericServerVersion()));
builder.add("versionString", VPackValue(rest::Version::getServerVersion()));
builder.add("engine", VPackValue(EngineSelectorFeature::engineName()));
} catch (...) {
LOG_TOPIC(FATAL, arangodb::Logger::CLUSTER) << "out of memory";
FATAL_ERROR_EXIT();
}
auto result = comm.setValue(currentServersRegisteredPref + _id, builder.slice(), 0.0);
if (result.successful()) {
return true;
} else {
@ -669,10 +670,10 @@ bool ServerState::registerAtAgencyPhase2(AgencyComm& comm) {
<< "failed to register server in agency: http code: "
<< result.httpCode() << ", body: '" << result.body() << "', retrying ...";
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return false;
}