// ----------------------------------------------------------------------------
+extern size_t rrd_hosts_available;
extern time_t rrdhost_free_orphan_time;
extern void rrd_init(char *hostname);
-extern RRDHOST *rrdhost_find_guid(const char *guid, uint32_t hash);
+extern RRDHOST *rrdhost_find_by_hostname(const char *hostname, uint32_t hash);
+extern RRDHOST *rrdhost_find_by_guid(const char *guid, uint32_t hash);
+
extern RRDHOST *rrdhost_find_or_create(
const char *hostname
, const char *guid
",\n\t\"dimensions_count\": %zu"
",\n\t\"alarms_count\": %zu"
",\n\t\"rrd_memory_bytes\": %zu"
- "\n}\n"
+ ",\n\t\"hosts_count\": %zu"
+ ",\n\t\"hosts\": ["
, c
, dimensions
, alarms
, memory
+ , rrd_hosts_available
);
+
+ if(unlikely(rrd_hosts_available > 1)) {
+ rrd_rdlock();
+ RRDHOST *h;
+ rrdhost_foreach_read(h)
+ buffer_sprintf(wb,
+ "%s\n\t\t{"
+ "\n\t\t\t\"hostname\": \"%s\""
+ "\n\t\t}"
+ , (h != localhost)?",":""
+ , h->hostname
+ );
+ rrd_unlock();
+ }
+ else {
+ buffer_sprintf(wb,
+ "\n\t\t{"
+ "\n\t\t\t\"hostname\": \"%s\""
+ "\n\t\t}"
+ , host->hostname
+ );
+ }
+
+ buffer_sprintf(wb, "\n\t]\n}\n");
}
// ----------------------------------------------------------------------------
#include "common.h"
RRDHOST *localhost = NULL;
-
+size_t rrd_hosts_available = 0;
pthread_rwlock_t rrd_rwlock = PTHREAD_RWLOCK_INITIALIZER;
time_t rrdhost_free_orphan_time = 3600;
.rwlock = AVL_LOCK_INITIALIZER
};
-RRDHOST *rrdhost_find_guid(const char *guid, uint32_t hash) {
+RRDHOST *rrdhost_find_by_guid(const char *guid, uint32_t hash) {
debug(D_RRDHOST, "Searching in index for host with guid '%s'", guid);
RRDHOST tmp;
return (RRDHOST *)avl_search_lock(&(rrdhost_root_index), (avl *) &tmp);
}
+RRDHOST *rrdhost_find_by_hostname(const char *hostname, uint32_t hash) {
+ if(unlikely(!strcmp(hostname, "localhost")))
+ return localhost;
+
+ if(unlikely(!hash)) hash = simple_hash(hostname);
+
+ rrd_rdlock();
+ RRDHOST *host;
+ rrdhost_foreach_read(host) {
+ if(unlikely((hash == host->hash_hostname && !strcmp(hostname, host->hostname)))) {
+ rrd_unlock();
+ return host;
+ }
+ }
+ rrd_unlock();
+
+ return NULL;
+}
+
#define rrdhost_index_add(rrdhost) (RRDHOST *)avl_insert_lock(&(rrdhost_root_index), (avl *)(rrdhost))
#define rrdhost_index_del(rrdhost) (RRDHOST *)avl_remove_lock(&(rrdhost_root_index), (avl *)(rrdhost))
);
}
+ rrd_hosts_available++;
rrd_unlock();
return host;
) {
debug(D_RRDHOST, "Searching for host '%s' with guid '%s'", hostname, guid);
- RRDHOST *host = rrdhost_find_guid(guid, 0);
+ RRDHOST *host = rrdhost_find_by_guid(guid, 0);
if(!host) {
host = rrdhost_create(
hostname
rrdhost_unlock(host);
freez(host);
- info("Host memory cleanup completed...");
+ rrd_hosts_available--;
}
void rrdhost_free_all(void) {
void rrdhost_save(RRDHOST *host) {
if(!host) return;
- info("Saving host '%s' database...", host->hostname);
+ info("Saving database of host '%s'...", host->hostname);
RRDSET *st;
RRDDIM *rd;
}
void rrdhost_save_all(void) {
- info("Saving database...");
+ info("Saving database [%zu hosts(s)]...", rrd_hosts_available);
rrd_rdlock();
uint32_t hash = simple_hash(tok);
- if(unlikely(hash == hash_localhost && !strcmp(tok, "localhost")))
- return web_client_process_url(localhost, w, url);
-
- rrd_rdlock();
- RRDHOST *h;
- rrdhost_foreach_read(h) {
- if(unlikely((hash == h->hash_hostname && !strcmp(tok, h->hostname)) ||
- (hash == h->hash_machine_guid && !strcmp(tok, h->machine_guid)))) {
- rrd_unlock();
- return web_client_process_url(h, w, url);
- }
- }
- rrd_unlock();
+ host = rrdhost_find_by_hostname(tok, hash);
+ if(!host) host = rrdhost_find_by_guid(tok, hash);
+
+ if(host) return web_client_process_url(host, w, url);
}
buffer_flush(w->response.data);
var netdataRegistryCallback = function(machines_array) {
var el = '';
var a1 = '';
- var found = 0;
+ var found = 0, hosted = 0;
+ var len, i, url, hostname, icon;
+
+ if(options.hosts.length > 1) {
+ el += '<li><a href="#" onClick="return false;" style="color: #666;" target="_blank">remote databases mirrored to this host</a></li>';
+ a1 += '<li><a href="#" onClick="return false;"><i class="fa fa-info-circle" aria-hidden="true" style="color: #666;"></i></a></li>';
+
+ var base = document.location.origin.toString() + document.location.pathname.toString();
+ if(base.endsWith("/host/" + options.hostname + "/"))
+ base = base.substring(0, base.length - ("/host/" + options.hostname + "/").toString().length);
+
+ if(base.endsWith("/"))
+ base = base.substring(0, base.length - 1);
+
+ i = 0;
+ len = options.hosts.length;
+ while(len--) {
+ hostname = options.hosts[i].hostname;
+ if(i == 0) {
+ url = base + "/";
+ icon = "home";
+ }
+ else {
+ url = base + "/host/" + hostname + "/";
+ icon = "window-restore";
+ }
+
+ el += '<li id="registry_server_hosted_' + len.toString() + '"><a class="registry_link" href="' + url + '" onClick="return gotoHostedModalHandler(\'' + url + '\');">' + hostname + '</a></li>';
+ a1 += '<li id="registry_action_hosted_' + len.toString() + '"><a class="registry_link" href="' + url + '" onClick="return gotoHostedModalHandler(\'' + url + '\');"><i class="fa fa-' + icon + '" aria-hidden="true" style="color: #999;"></i></a></li>';
+ hosted++;
+ i++;
+ }
+
+ el += '<li role="separator" class="divider"></li>';
+ a1 += '<li role="separator" class="divider"></li>';
+ }
if(machines_array === null) {
var ret = loadLocalStorage("registryCallback");
return 0;
});
- var len = machines.length;
+ len = machines.length;
while(len--) {
var u = machines[len];
found++;
location.reload();
}
+ function gotoHostedModalHandler(url) {
+ document.location = url + urlOptions.genHash();
+ return false;
+ }
+
var gotoServerValidateRemaining = 0;
var gotoServerMiddleClick = false;
var gotoServerStop = false;
categories_idx: {},
families: [],
families_idx: {},
+ hosts: [],
chartsPerRow: 0,
// chartsMinWidth: 1450,
options.version = data.version;
netdataDashboard.os = data.os;
+ if(typeof data.hosts != 'undefined')
+ options.hosts = data.hosts;
+
// update the dashboard hostname
document.getElementById('hostname').innerHTML = options.hostname;
document.getElementById('hostname').href = NETDATA.serverDefault;