- **extremely lightweight**
It only needs a few megabytes of memory to store all its round robin database.
-
+
Although `netdata` does all its calculation using `long double` (128 bit) arithmetics, it stores all values using a **custom-made 32-bit number**. This custom-made number can store in 29 bits values from -167772150000000.0 to 167772150000000.0 with a precision of 0.00001 (yes, it is a floating point number, meaning that higher integer values have less decimal precision) and 3 bits for flags (2 are currently used and 1 is reserved for future use). This provides an extremely optimized memory footprint with just 0.0001% max accuracy loss (run: `./netdata --unittest` to see it in action).
- **per second data collection**
1. You run a daemon on your linux: netdata.
This deamon is written in C and is extremely lightweight.
-
+
netdata:
- Spawns threads to collect all the data for all sources
- Is a standalone web server.
For example, you can access JSON data by using:
-
+
```
http://127.0.0.1:19999/data/net.eth0
```
-
+
This will give you the JSON file for traffic on eth0.
The above is equivalent to:
-
+
```
http://127.0.0.1:19999/data/net.eth0/3600/1/average/0/0
```
-
+
where:
- 3600 is the number of entries to generate.
- You can stop netdata by killing it with `killall netdata`.
You can stop and start netdata at any point. Netdata saves on exit its round robbin
- database to `/var/cache/netdata` so that it will continue from where it stopped the last time.
+ database to `/var/cache/netdata` so that it will continue from where it stopped the last time.
To access the web site for all graphs, go to:
mysql_exec() {
local ret
-
+
"${@}" -s -e "show global status;"
ret=$?
CHART opensips.shmem_fragments '' "OpenSIPS Shared Memory Fragmentation" "fragments" opensips '' line 20019 $opensips_update_every
DIMENSION shmem_fragments fragments absolute 1 1
EOF
-
+
return 0
}
# even if something goes wrong, no other code can be executed
postfix_q_emails=0
postfix_q_size=0
-
+
eval "`$postfix_postqueue -p |\
grep "^--" |\
sed -e "s/-- \([0-9]\+\) Kbytes in \([0-9]\+\) Requests.$/local postfix_q_size=\1\nlocal postfix_q_emails=\2/g" |\
v="$( cat $f )"
v=$(( v + 1 - 1 ))
[ $v -ne 0 ] && echo "$f" && continue
-
+
echo >&2 "$PROGRAM_NAME: sensors: $f gives zero values"
done
}
DIMENSION server_all_requests requests incremental 1 1
DIMENSION server_all_errors errors incremental -1 1
EOF
-
+
return 0
}
#
# apps.plugin process grouping
-#
+#
# The apps.plugin displays charts with information about the processes running.
# This config allows grouping processes together, so that several processes
# will be reported together.
nfs: rpcbind rpc.statd rpc.idmapd rpc.mountd nfsd4 nfsd4_callbacks nfsd nfsiod
ssh: ssh sshd scp
X: X lightdm xdm pulseaudio gkrellm
-xfce: xfwm4 xfdesktop xfce4-appfinder Thunar xfsettingsd xfce4-panel
+xfce: xfwm4 xfdesktop xfce4-appfinder Thunar xfsettingsd xfce4-panel
gnome: gnome-session gdm gconfd-2 gnome-terminal gnome-screensaver gnome-settings-daemon
named: named rncd
clam: clamd freshclam
where:
- `type.id`
-
+
uniquely identifies the chart,
this is what will be needed to add values to the chart
if [ $(( ${BASH_VERSINFO[0]} )) -lt 4 ]
then
- echo >&2
+ echo >&2
echo >&2 "$PROGRAM_NAME: ERROR"
echo >&2 "BASH version 4 or later is required."
echo >&2 "You are running version: ${BASH_VERSION}"
echo >&2 "Please upgrade."
- echo >&2
+ echo >&2
exit 1
fi
# calculate ms to sleep
mstosleep=$(( t - LOOPSLEEPMS_LASTWORK ))
# echo "# mstosleep is $mstosleep ms"
-
+
# if we are too slow, sleep some time
test $mstosleep -lt 200 && mstosleep=200
local x="$1"
echo "BEGIN $x"
-
+
$tc_cmd -s class show dev $x
-
+
# check FireQOS names for classes
if [ ! -z "$fix_names" -a -f /var/run/fireqos/ifaces/$x ]
then
do
setclassname $(echo $n | tr '|' ' ')
done
-
+
echo "SETDEVICEGROUP $interface_dev"
fi
echo "END $x"
struct target *w;
for(w = target_root ; w ; w = w->next)
if(strncmp(nid, w->id, MAX_NAME) == 0) return w;
-
+
w = calloc(sizeof(struct target), 1);
if(!w) {
error("Cannot allocate %lu bytes of memory", (unsigned long)sizeof(struct target));
for(p = root_of_pids; p ; p = p->next) {
if(p->ppid > 0 && p->ppid <= pid_max && all_pids[p->ppid]) {
if(debug || (p->target && p->target->debug)) fprintf(stderr, "apps.plugin: \tparent of %d %s is %d %s\n", p->pid, p->comm, p->ppid, all_pids[p->ppid]->comm);
-
+
p->parent = all_pids[p->ppid];
p->parent->childs++;
}
w->fds = calloc(sizeof(int), all_files_size);
if(!w->fds)
error("Cannot allocate memory for fds in %s", w->name);
-
+
w->minflt = 0;
w->majflt = 0;
w->utime = 0;
for(p = root_of_pids; p ;) {
if(!p->updated) {
// fprintf(stderr, "\tEXITED %d %s [parent %d %s, target %s] utime=%llu, stime=%llu, cutime=%llu, cstime=%llu, minflt=%llu, majflt=%llu, cminflt=%llu, cmajflt=%llu\n", p->pid, p->comm, p->parent->pid, p->parent->comm, p->target->name, p->utime, p->stime, p->cutime, p->cstime, p->minflt, p->majflt, p->cminflt, p->cmajflt);
-
+
for(c = 0 ; c < p->fds_size ; c++) if(p->fds[c] > 0) {
file_descriptor_not_used(p->fds[c]);
p->fds[c] = 0;
usleep(susec);
bcopy(&now, &last, sizeof(struct timeval));
-
+
current_t = time(NULL);
if(current_t - started_t > 3600) exit(0);
}
/* Remove an element a from the AVL tree t
* returns -1 if the depth of the tree has shrunk
- * Warning: if the element is not present in the tree,
+ * Warning: if the element is not present in the tree,
* returns 0 as if it had been removed succesfully.
*/
int avl_remove(avl_tree* t, avl* a);
mkdir(rundir, 0775);
snprintf(rundir, FILENAME_MAX, "/run/user/%d/netdata", getuid());
}
-
+
snprintf(pidfile, FILENAME_MAX, "%s/netdata.pid", rundir);
if(mkdir(rundir, 0775) != 0) {
}
}
}
-
+
if((dev_null = open("/dev/null", O_RDWR, 0666)) == -1) {
perror("Cannot open /dev/null");
if(input_fd != -1) close(input_fd);
if(close_all_files) {
int i;
for(i = sysconf(_SC_OPEN_MAX); i > 0; i--)
- if(
+ if(
((access_fd && i != *access_fd) || !access_fd)
&& i != dev_null
&& i != input_fd
input_fd = -1;
}
else dup2(dev_null, STDIN_FILENO);
-
+
if(output_fd != -1) {
if(output_fd != STDOUT_FILENO) {
dup2(output_fd, STDOUT_FILENO);
errno = 0;
if(kill(pid, 0) == -1) {
switch(errno) {
- case ESRCH:
+ case ESRCH:
error("Request to kill pid %d, but it is not running.", pid);
break;
}
else {
errno = 0;
-
- void (*old)(int);
+
+ void (*old)(int);
old = signal(sig, SIG_IGN);
if(old == SIG_ERR) {
error("Cannot overwrite signal handler for signal %d", sig);
if(ret == -1) {
switch(errno) {
- case ESRCH:
+ case ESRCH:
error("Cannot kill pid %d, but it is not running.", pid);
break;
pthread_join(w->thread, NULL);
}
- int i;
+ int i;
for (i = 0; static_threads[i].name != NULL ; i++) {
if(static_threads[i].thread) {
debug(D_EXIT, "Stopping %s thread", static_threads[i].name);
}
// --------------------------------------------------------------------
-
+
for (i = 0; static_threads[i].name != NULL ; i++) {
struct netdata_static_thread *st = &static_threads[i];
char *start = &ff->buffer[ff->cursor];
char *s = start;
-
+
while(*s != '\n' && *s != '\0') s++;
*s = '\0';
ff->cursor += ( s - start + 1 );
/*
* This is a library for reading kernel files from /proc
- *
+ *
* The idea is this:
*
* - every file is opened once.
char *s = ff->data, *e = ff->data, *t = ff->data;
uint32_t l = 0, w = 0;
e += ff->len;
-
+
ff->lines = fflines_add(ff->lines, w);
if(!ff->lines) goto cleanup;
fprintf(stdout, "MYPID %d\n", getpid());
fflush(NULL);
#endif
-
+
// ignore all signals
for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV) signal(i, SIG_DFL);
else
*pbuf++ = *pstr;
-
+
pstr++;
}
-
+
*pbuf = '\0';
-
+
return buf;
}
char id[RRD_STATS_NAME_MAX + 1]; // the id of this dimension (for internal identification)
char *name; // the name of this dimension (as presented to user)
char cache_file[FILENAME_MAX+1];
-
+
unsigned long hash; // a simple hash on the id, to speed up searching
// we first compare hashes, and only if the hashes are equal we do string comparisons
int update_every; // every how many seconds is this updated?
unsigned long long first_entry_t; // the timestamp (in microseconds) of the oldest entry in the db
struct timeval last_updated; // when this data set was last updated (updated every time the rrd_stats_done() function)
- struct timeval last_collected_time; //
+ struct timeval last_collected_time; //
unsigned long long usec_since_last_update;
total_number collected_total;
st->priority = config_get_number(st->id, "priority", priority);
st->enabled = enabled;
-
+
st->isdetail = 0;
st->debug = 0;
rd->entries = st->entries;
rd->update_every = st->update_every;
-
+
// append this dimension
if(!st->dimensions)
st->dimensions = rd;
void rrd_stats_dimension_set_by_pointer(RRD_STATS *st, RRD_DIMENSION *rd, collected_number value)
{
if(st) {;}
-
+
gettimeofday(&rd->last_collected_time, NULL);
rd->collected_value = value;
}
// add the value we will overwrite
st->first_entry_t += st->update_every * 1000000ULL;
}
-
+
st->counter++;
st->current_entry = ((st->current_entry + 1) >= st->entries) ? 0 : st->current_entry + 1;
if(!st->first_entry_t) st->first_entry_t = next_ut;
b->buffer = realloc(b->buffer, b->size + increase);
if(!b->buffer) fatal("Failed to increase data buffer from size %d to %d.", b->size, b->size + increase);
-
+
b->size += increase;
}
{
struct web_client *w;
socklen_t addrlen;
-
+
w = calloc(1, sizeof(struct web_client));
if(!w) {
error("Cannot allocate new web_client memory.");
debug(D_WEB_CLIENT_ACCESS, "%llu: New web client from %s on socket %d.", w->id, w->client_ip, w->ifd);
{
- int flag = 1;
+ int flag = 1;
if(setsockopt(w->ifd, SOL_SOCKET, SO_KEEPALIVE, (char *) &flag, sizeof(int)) != 0) error("%llu: Cannot set SO_KEEPALIVE on socket.", w->id);
}
time_t rrd_stats_first_entry_t(RRD_STATS *st)
{
if(!st->first_entry_t) return st->last_updated.tv_sec;
-
+
return st->first_entry_t / 1000000;
}
}
}
pthread_rwlock_unlock(&root_rwlock);
-
+
web_buffer_printf(wb, "\n\t],\n"
"\t\"hostname\": \"%s\",\n"
"\t\"update_every\": %d,\n"
// -------------------------------------------------------------------------
// switch from JSON to google JSON
-
+
char kq[2] = "\"";
char sq[2] = "\"";
switch(type) {
// -------------------------------------------------------------------------
// validate the parameters
-
+
if(entries_to_show < 1) entries_to_show = 1;
if(group < 1) group = 1;
-
+
// make sure current_entry is within limits
long current_entry = (long)st->current_entry - (long)1;
if(current_entry < 0) current_entry = 0;
else if(current_entry >= st->entries) current_entry = st->entries - 1;
-
+
// find the oldest entry of the round-robin
long max_entries_init = (st->counter < (unsigned long)st->entries) ? st->counter : (unsigned long)st->entries;
-
+
time_t time_init = st->last_updated.tv_sec;
-
+
if(before == 0 || before > time_init) before = time_init;
if(after == 0) after = rrd_stats_first_entry_t(st);
// our return value (the last timestamp printed)
// this is required to detect re-transmit in google JSONP
- time_t last_timestamp = 0;
+ time_t last_timestamp = 0;
// -------------------------------------------------------------------------
// find how many dimensions we have
-
+
int dimensions = 0;
RRD_DIMENSION *rd;
for( rd = st->dimensions ; rd ; rd = rd->next) dimensions++;
return 0;
}
-
+
// -------------------------------------------------------------------------
// prepare various strings, to speed up the loop
-
+
char overflow_annotation[201]; snprintf(overflow_annotation, 200, ",{%sv%s:%sRESET OR OVERFLOW%s},{%sv%s:%sThe counters have been wrapped.%s}", kq, kq, sq, sq, kq, kq, sq, sq);
char normal_annotation[201]; snprintf(normal_annotation, 200, ",{%sv%s:null},{%sv%s:null}", kq, kq, kq, kq);
char pre_date[51]; snprintf(pre_date, 50, " {%sc%s:[{%sv%s:%s", kq, kq, kq, kq, sq);
// -------------------------------------------------------------------------
// checks for debuging
-
+
if(st->debug) {
debug(D_RRD_STATS, "%s first_entry_t = %lu, last_entry_t = %lu, duration = %lu, after = %lu, before = %lu, duration = %lu, entries_to_show = %lu, group = %lu, max_entries = %ld"
, st->id
// -------------------------------------------------------------------------
// temp arrays for keeping values per dimension
-
+
calculated_number group_values[dimensions]; // keep sums when grouping
calculated_number print_values[dimensions]; // keep the final value to be printed
int print_hidden[dimensions]; // keep hidden flags
// -------------------------------------------------------------------------
// print the JSON header
-
+
web_buffer_printf(wb, "{\n %scols%s:\n [\n", kq, kq);
web_buffer_printf(wb, " {%sid%s:%s%s,%slabel%s:%stime%s,%spattern%s:%s%s,%stype%s:%sdatetime%s},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq);
web_buffer_printf(wb, " {%sid%s:%s%s,%slabel%s:%s%s,%spattern%s:%s%s,%stype%s:%sstring%s,%sp%s:{%srole%s:%sannotation%s}},\n", kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, sq, sq, kq, kq, kq, kq, sq, sq);
int annotate_reset = 0;
int annotation_count = 0;
-
+
// to allow grouping on the same values, we need a pad
long pad = before % group;
// debug(D_RRD_STATS, "Already printed all rows. Stopping.");
break;
}
-
+
if(group_count != group) {
// this is an incomplete group, skip it.
for( rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++)
group_values[c] = 0;
-
+
group_count = 0;
continue;
}
for(rd = st->dimensions, c = 0 ; rd && c < dimensions ; rd = rd->next, c++) {
calculated_number value = unpack_storage_number(rd->values[t]);
-
+
switch(group_method) {
case GROUP_MAX:
if(abs(value) > abs(group_values[c])) group_values[c] = value;
if(print_this) {
group_count = 0;
-
+
if(annotate_reset) {
annotation_count++;
web_buffer_strcpy(wb, overflow_annotation);
else break;
}
else break;
-
+
} // max_loop
debug(D_RRD_STATS, "RRD_STATS_JSON: %s total %ld bytes", st->name, wb->bytes);
web_buffer_increase(wb, 500);
switch(i) {
case 0:
- web_buffer_printf(wb,
+ web_buffer_printf(wb,
"# NetData Configuration\n"
"# You can uncomment and change any of the options bellow.\n"
"# The value shown in the commented settings, is the default value.\n"
return 404;
}
}
-
+
// pick a Content-Type for the file
if(strstr(filename, ".html") != NULL) w->data->contenttype = CT_TEXT_HTML;
else if(strstr(filename, ".js") != NULL) w->data->contenttype = CT_APPLICATION_X_JAVASCRIPT;
long sent = w->zoutput?(long)w->zstream.total_out:((w->mode == WEB_CLIENT_MODE_FILECOPY)?w->data->rbytes:w->data->bytes);
long size = (w->mode == WEB_CLIENT_MODE_FILECOPY)?w->data->rbytes:w->data->bytes;
-
+
if(w->last_url[0]) log_access("%llu: (sent/all = %ld/%ld bytes %0.0f%%, prep/sent/total = %0.2f/%0.2f/%0.2f ms) %s: '%s'",
w->id,
sent, size, -((size>0)?((float)(size-sent)/(float)size * 100.0):0.0),
else if(strcmp(key, "sig") == 0)
google_sig = value;
-
+
else if(strcmp(key, "out") == 0)
google_out = value;
-
+
else if(strcmp(key, "responseHandler") == 0)
google_responseHandler = value;
-
+
else if(strcmp(key, "outFileName") == 0)
google_outFileName = value;
}
// check the client wants json
if(strcmp(google_out, "json") != 0) {
- w->data->bytes = snprintf(w->data->buffer, w->data->size,
+ w->data->bytes = snprintf(w->data->buffer, w->data->size,
"%s({version:'%s',reqId:'%s',status:'error',errors:[{reason:'invalid_query',message:'output format is not supported',detailed_message:'the format %s requested is not supported by netdata.'}]});",
google_responseHandler, google_version, google_reqId, google_out);
return 200;
}
if(datasource_type == DATASOURCE_GOOGLE_JSONP) {
- w->data->bytes = snprintf(w->data->buffer, w->data->size,
+ w->data->bytes = snprintf(w->data->buffer, w->data->size,
"%s({version:'%s',reqId:'%s',status:'ok',sig:'%lu',table:",
google_responseHandler, google_version, google_reqId, st->last_updated.tv_sec);
}
-
+
debug(D_WEB_CLIENT_ACCESS, "%llu: Sending RRD data '%s' (id %s, %d lines, %d group, %d group_method, %lu after, %lu before).", w->id, st->name, st->id, lines, group_count, group_method, after, before);
unsigned long timestamp_in_data = rrd_stats_json(datasource_type, st, w->data, lines, group_count, group_method, after, before, nonzero);
else {
// the client already has the latest data
- w->data->bytes = snprintf(w->data->buffer, w->data->size,
+ w->data->bytes = snprintf(w->data->buffer, w->data->size,
"%s({version:'%s',reqId:'%s',status:'error',errors:[{reason:'not_modified',message:'Data not modified'}]});",
google_responseHandler, google_version, google_reqId);
}
strcpy(w->data->buffer, "I don't understand you...\r\n");
w->data->bytes = strlen(w->data->buffer);
}
-
+
// free url_decode() buffer
if(pointer_to_free) free(pointer_to_free);
}
strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %Z", &tm);
char custom_header[MAX_HTTP_HEADER_SIZE + 1] = "";
- if(w->response_header[0])
+ if(w->response_header[0])
strcpy(custom_header, w->response_header);
int headerlen = 0;
long web_client_send_chunk_header(struct web_client *w, int len)
{
debug(D_DEFLATE, "%llu: OPEN CHUNK of %d bytes (hex: %x).", w->id, len, len);
- char buf[1024];
+ char buf[1024];
sprintf(buf, "%X\r\n", len);
int bytes = send(w->ofd, buf, strlen(buf), MSG_DONTWAIT);
error("%llu: Cannot request detach of newly created web client thread.", w->id);
w->obsolete = 1;
}
-
+
log_access("%llu: %s connected", w->id, w->client_ip);
}
else debug(D_WEB_CLIENT, "LISTENER: select() didn't do anything.");
char iface[MAX_PROC_NET_DEV_IFACE_NAME + 1] = "";
unsigned long long rbytes, rpackets, rerrors, rdrops, rfifo, rframe, rcompressed, rmulticast;
unsigned long long tbytes, tpackets, terrors, tdrops, tfifo, tcollisions, tcarrier, tcompressed;
-
+
int r;
char *p;
-
+
if(fp) {
if(fseek(fp, 0, SEEK_SET) == -1) {
error("Re-opening file /proc/net/dev.");
return 1;
}
}
-
+
// skip the first two lines
p = fgets(buffer, MAX_PROC_NET_DEV_LINE, fp);
p = fgets(buffer, MAX_PROC_NET_DEV_LINE, fp);
-
+
// read the rest of the lines
for(;1;) {
char *c;
p = fgets(buffer, MAX_PROC_NET_DEV_LINE, fp);
if(!p) break;
-
+
c = strchr(buffer, ':');
if(c) *c = '\t';
-
+
r = sscanf(buffer, "%s %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
iface,
&rbytes, &rpackets, &rerrors, &rdrops, &rfifo, &rframe, &rcompressed, &rmulticast,
rrd_stats_done(st);
}
}
-
+
return 0;
}
char buffer[MAX_PROC_DISKSTATS_LINE+1] = "";
char disk[MAX_PROC_DISKSTATS_DISK_NAME + 1] = "";
-
+
int r;
char *p;
-
+
if(fp) {
if(fseek(fp, 0, SEEK_SET) == -1) {
error("Re-opening file /proc/diskstats.");
return 1;
}
}
-
+
for(;1;) {
unsigned long long major = 0, minor = 0,
reads = 0, reads_merged = 0, readsectors = 0, readms = 0,
p = fgets(buffer, MAX_PROC_DISKSTATS_LINE, fp);
if(!p) break;
-
+
r = sscanf(buffer, "%llu %llu %s %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
&major, &minor, disk,
&reads, &reads_merged, &readsectors, &readms, &writes, &writes_merged, &writesectors, &writems, ¤tios, &iosms, &wiosms
rrd_stats_dimension_set(st, "writes", writes);
rrd_stats_done(st);
}
-
+
// --------------------------------------------------------------------
if(do_merged_ops) {
rrd_stats_done(st);
}
}
-
+
return 0;
}
int do_proc_net_snmp() {
static int do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1,
- do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1,
+ do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1,
do_udp_packets = -1, do_udp_errors = -1;
static FILE *fp = NULL;
if(r != 14) error("Cannot read /proc/net/snmp TCP line. Expected 14 params, read %d.", r);
// --------------------------------------------------------------------
-
+
// see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
if(do_tcp_sockets) {
st = rrd_stats_find(RRD_TYPE_NET_SNMP ".tcpsock");
}
// --------------------------------------------------------------------
-
+
if(do_tcp_packets) {
st = rrd_stats_find(RRD_TYPE_NET_SNMP ".tcppackets");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_tcp_errors) {
st = rrd_stats_find(RRD_TYPE_NET_SNMP ".tcperrors");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_tcp_handshake) {
st = rrd_stats_find(RRD_TYPE_NET_SNMP ".tcphandshake");
if(!st) {
if(r != 6) error("Cannot read /proc/net/snmp UDP line. Expected 6 params, read %d.", r);
// --------------------------------------------------------------------
-
+
// see http://net-snmp.sourceforge.net/docs/mibs/udp.html
if(do_udp_packets) {
st = rrd_stats_find(RRD_TYPE_NET_SNMP ".udppackets");
}
// --------------------------------------------------------------------
-
+
if(do_udp_errors) {
st = rrd_stats_find(RRD_TYPE_NET_SNMP ".udperrors");
if(!st) {
}
}
}
-
+
return 0;
}
InNoRoutes = 0, InTruncatedPkts = 0,
InOctets = 0, InMcastPkts = 0, InBcastPkts = 0, InMcastOctets = 0, InBcastOctets = 0,
OutOctets = 0, OutMcastPkts = 0, OutBcastPkts = 0, OutMcastOctets = 0, OutBcastOctets = 0;
-
+
int r = sscanf(&buffer[7], "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
&InNoRoutes, &InTruncatedPkts, &InMcastPkts, &OutMcastPkts, &InBcastPkts, &OutBcastPkts,
&InOctets, &OutOctets, &InMcastOctets, &OutMcastOctets, &InBcastOctets, &OutBcastOctets);
}
}
}
-
+
return 0;
}
RRD_STATS *st;
// --------------------------------------------------------------------
-
+
if(do_sockets) {
st = rrd_stats_find(RRD_TYPE_NET_STAT_CONNTRACK ".sockets");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_packets) {
st = rrd_stats_find(RRD_TYPE_NET_IPVS ".packets");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_bandwidth) {
st = rrd_stats_find(RRD_TYPE_NET_IPVS ".net");
if(!st) {
if(r != 2) error("Cannot read /proc/stat intr line. Expected 2 params, read %d.", r);
// --------------------------------------------------------------------
-
+
if(do_interrupts) {
st = rrd_stats_find_bytype("system", id);
if(!st) {
if(r != 2) error("Cannot read /proc/stat ctxt line. Expected 2 params, read %d.", r);
// --------------------------------------------------------------------
-
+
if(do_context) {
st = rrd_stats_find_bytype("system", id);
if(!st) {
RRD_STATS *st;
// --------------------------------------------------------------------
-
+
// http://stackoverflow.com/questions/3019748/how-to-reliably-measure-available-memory-in-linux
unsigned long long MemUsed = MemTotal - MemFree - Cached - Buffers;
}
// --------------------------------------------------------------------
-
+
unsigned long long SwapUsed = SwapTotal - SwapFree;
if(do_swap) {
}
// --------------------------------------------------------------------
-
+
if(hwcorrupted && do_hwcorrupt) {
st = rrd_stats_find("mem.hwcorrupt");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_committed) {
st = rrd_stats_find("mem.committed");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_writeback) {
st = rrd_stats_find("mem.writeback");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_kernel) {
st = rrd_stats_find("mem.kernel");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_slab) {
st = rrd_stats_find("mem.slab");
if(!st) {
nr_shmem = 0, nr_dirtied = 0, nr_written = 0, nr_anon_transparent_hugepages = 0, nr_dirty_threshold = 0, nr_dirty_background_threshold = 0,
pgpgin = 0, pgpgout = 0, pswpin = 0, pswpout = 0, pgalloc_dma = 0, pgalloc_dma32 = 0, pgalloc_normal = 0, pgalloc_movable = 0, pgfree = 0, pgactivate = 0, pgdeactivate = 0,
pgfault = 0, pgmajfault = 0, pgrefill_dma = 0, pgrefill_dma32 = 0, pgrefill_normal = 0, pgrefill_movable = 0, pgsteal_kswapd_dma = 0, pgsteal_kswapd_dma32 = 0,
- pgsteal_kswapd_normal = 0, pgsteal_kswapd_movable = 0, pgsteal_direct_dma = 0, pgsteal_direct_dma32 = 0, pgsteal_direct_normal = 0, pgsteal_direct_movable = 0,
+ pgsteal_kswapd_normal = 0, pgsteal_kswapd_movable = 0, pgsteal_direct_dma = 0, pgsteal_direct_dma32 = 0, pgsteal_direct_normal = 0, pgsteal_direct_movable = 0,
pgscan_kswapd_dma = 0, pgscan_kswapd_dma32 = 0, pgscan_kswapd_normal = 0, pgscan_kswapd_movable = 0, pgscan_direct_dma = 0, pgscan_direct_dma32 = 0, pgscan_direct_normal = 0,
pgscan_direct_movable = 0, pginodesteal = 0, slabs_scanned = 0, kswapd_inodesteal = 0, kswapd_low_wmark_hit_quickly = 0, kswapd_high_wmark_hit_quickly = 0,
kswapd_skip_congestion_wait = 0, pageoutrun = 0, allocstall = 0, pgrotated = 0, compact_blocks_moved = 0, compact_pages_moved = 0, compact_pagemigrate_failed = 0,
RRD_STATS *st;
// --------------------------------------------------------------------
-
+
if(do_swapio) {
st = rrd_stats_find("system.swapio");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_io) {
st = rrd_stats_find("system.io");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_pgfaults) {
st = rrd_stats_find("system.pgfaults");
if(!st) {
gettimeofday(&last, NULL);
last.tv_sec -= update_every;
-
+
// disable (by default) various interface that are not needed
config_get_boolean("plugin:proc:/proc/net/dev", "interface lo", 0);
config_get_boolean("plugin:proc:/proc/net/dev", "interface fireqos_monitor", 0);
unsigned long long usec = 0, susec = 0;
for(;1;) {
-
+
// BEGIN -- the job to be done
if(!vdo_proc_net_dev) vdo_proc_net_dev = do_proc_net_dev(usec);
if(!vdo_proc_diskstats) vdo_proc_diskstats = do_proc_diskstats(usec);
if(!vdo_proc_meminfo) vdo_proc_meminfo = do_proc_meminfo(usec);
if(!vdo_proc_vmstat) vdo_proc_vmstat = do_proc_vmstat(usec);
// END -- the job is done
-
+
// find the time to sleep in order to wait exactly update_every seconds
gettimeofday(&now, NULL);
usec = usecdiff(&now, &last) - susec;
debug(D_PROCNETDEV_LOOP, "PROCNETDEV: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec);
-
+
if(usec < (update_every * 1000000ULL / 2ULL)) susec = (update_every * 1000000ULL) - usec;
else susec = update_every * 1000000ULL / 2ULL;
-
+
// --------------------------------------------------------------------
if(!vdo_cpu_netdata && getrusage(RUSAGE_SELF, &me) == 0) {
-
+
unsigned long long cpuuser = me.ru_utime.tv_sec * 1000000ULL + me.ru_utime.tv_usec;
unsigned long long cpusyst = me.ru_stime.tv_sec * 1000000ULL + me.ru_stime.tv_usec;
rrd_stats_dimension_set(stcpu, "user", cpuuser);
rrd_stats_dimension_set(stcpu, "system", cpusyst);
rrd_stats_done(stcpu);
-
+
bcopy(&me, &me_last, sizeof(struct rusage));
// ----------------------------------------------------------------
}
usleep(susec);
-
+
// copy current to last
bcopy(&now, &last, sizeof(struct timeval));
}
static int enable_new_interfaces = -1;
if(enable_new_interfaces == -1) enable_new_interfaces = config_get_boolean("plugin:tc", "enable new interfaces detected at runtime", 1);
-
+
// we only need to add leaf classes
struct tc_class *c, *x;
}
}
}
-
+
// debugging:
/*
for ( c = d->classes ; c ; c = c->next) {
for ( c = d->classes ; c ; c = c->next) {
if(c->isleaf && c->hasparent) {
if(rrd_stats_dimension_set(st, c->id, c->bytes) != 0) {
-
+
// new class, we have to add it
rrd_stats_dimension_add(st, c->id, c->name, 8, 1024 * update_every, RRD_DIMENSION_INCREMENTAL);
rrd_stats_dimension_set(st, c->id, c->bytes);
loop_usec = usecdiff(&now, &last);
usec = loop_usec - susec;
debug(D_PROCNETDEV_LOOP, "CHECK: last loop took %llu usec (worked for %llu, sleeped for %llu).", loop_usec, usec, susec);
-
+
if(usec < (update_every * 1000000ULL / 2ULL)) susec = (update_every * 1000000ULL) - usec;
else susec = update_every * 1000000ULL / 2ULL;
char *qstrsep(char **ptr)
{
if(!*ptr || !**ptr) return NULL;
-
+
char *s, *p = *ptr;
// skip leading spaces
else if(!strcmp(s, "SET")) {
char *t;
while((t = strchr(p, '='))) *t = ' ';
-
+
char *dimension = qstrsep(&p);
char *value = qstrsep(&p);
if(!cd) fatal("Cannot allocate memory for plugin.");
snprintf(cd->id, CONFIG_MAX_NAME, "plugin:%s", pluginname);
-
+
strncpy(cd->filename, file->d_name, FILENAME_MAX);
snprintf(cd->fullfilename, FILENAME_MAX, "%s/%s", dir_name, cd->filename);
pthread_join(w->thread, NULL);
}
- int i;
+ int i;
for (i = 0; static_threads[i].name != NULL ; i++) {
if(static_threads[i].thread) {
debug(D_EXIT, "Stopping %s thread", static_threads[i].name);
error("pid %d killed by signal %d.", info.si_pid, info.si_status);
break;
- case CLD_DUMPED:
+ case CLD_DUMPED:
error("pid %d core dumped by signal %d.", info.si_pid, info.si_status);
break;
mkdir(rundir, 0775);
snprintf(rundir, FILENAME_MAX, "/run/user/%d/netdata", getpid());
}
-
+
snprintf(pidfile, FILENAME_MAX, "%s/netdata.pid", rundir);
if(mkdir(rundir, 0775) != 0)
}
}
}
-
+
if((dev_null = open("/dev/null", O_RDWR, 0666)) == -1) {
perror("Cannot open /dev/null");
if(input_fd != -1) close(input_fd);
// close all files
if(close_all_files) {
for(i = sysconf(_SC_OPEN_MAX); i > 0; i--)
- if(
+ if(
((access_fd && i != *access_fd) || !access_fd)
&& i != dev_null
&& i != input_fd
input_fd = -1;
}
else dup2(dev_null, STDIN_FILENO);
-
+
if(output_fd != -1) {
if(output_fd != STDOUT_FILENO) {
dup2(output_fd, STDOUT_FILENO);
for(rd = st->dimensions ; rd ; rd = rd->next) {
fprintf(stderr, "\t %s " STORAGE_NUMBER_FORMAT " -> ", rd->id, rd->values[c]);
- if(rd == rdabs) v =
- ( oincrement
+ if(rd == rdabs) v =
+ ( oincrement
+ (increment * (1000000 - shift) / 1000000)
+ c * increment
) * 10;
// catch all signals
for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV && i != SIGFPE) signal(i, sig_handler);
-
+
for (i = 0; static_threads[i].name != NULL ; i++) {
struct netdata_static_thread *st = &static_threads[i];
int doit = 1;
loop_usec = usecdiff(&now, &last);
usec = loop_usec - susec;
debug(D_PROCNETDEV_LOOP, "CHECK: last loop took %llu usec (worked for %llu, sleeped for %llu).", loop_usec, usec, susec);
-
+
if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec;
else susec = rrd_update_every * 1000000ULL / 2ULL;
gettimeofday(&now, NULL);
usec = usecdiff(&now, &last) - susec;
debug(D_NFACCT_LOOP, "nfacct.plugin: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec);
-
+
if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec;
else susec = rrd_update_every * 1000000ULL / 2ULL;
if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, rrd_update_every, RRDDIM_INCREMENTAL);
if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].pkts);
}
-
+
rrdset_done(st);
// ----------------------------------------------------------------
if(!rd) rd = rrddim_add(st, nfacct_list->data[i].name, NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL);
if(rd) rrddim_set_by_pointer(st, rd, nfacct_list->data[i].bytes);
}
-
+
rrdset_done(st);
}
// --------------------------------------------------------------------
usleep(susec);
-
+
// copy current to last
bcopy(&now, &last, sizeof(struct timeval));
}
gettimeofday(&last, NULL);
last.tv_sec -= rrd_update_every;
-
+
// disable (by default) various interface that are not needed
config_get_boolean("plugin:proc:/proc/net/dev", "interface lo", 0);
config_get_boolean("plugin:proc:/proc/net/dev", "interface fireqos_monitor", 0);
unsigned long long usec = 0, susec = 0;
for(;1;) {
-
+
// BEGIN -- the job to be done
-
+
if(!vdo_proc_interrupts) {
debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_interrupts().");
vdo_proc_interrupts = do_proc_interrupts(rrd_update_every, usec+susec);
}
// END -- the job is done
-
+
// find the time to sleep in order to wait exactly update_every seconds
gettimeofday(&now, NULL);
usec = usecdiff(&now, &last) - susec;
debug(D_PROCNETDEV_LOOP, "PROCNETDEV: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec);
-
+
if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec;
else susec = rrd_update_every * 1000000ULL / 2ULL;
-
+
// --------------------------------------------------------------------
if(!vdo_cpu_netdata) {
}
usleep(susec);
-
+
// copy current to last
bcopy(&now, &last, sizeof(struct timeval));
}
static int enable_new_interfaces = -1;
if(enable_new_interfaces == -1) enable_new_interfaces = config_get_boolean("plugin:tc", "enable new interfaces detected at runtime", 1);
-
+
// we only need to add leaf classes
struct tc_class *c, *x;
}
}
}
-
+
// debugging:
/*
for ( c = d->classes ; c ; c = c->next) {
if(!rd) {
debug(D_TC_LOOP, "TC: Adding to chart '%s', dimension '%s'", st->id, c->id, c->name);
-
+
// new class, we have to add it
rd = rrddim_add(st, c->id, c->name?c->name:c->id, 8, 1024, RRDDIM_INCREMENTAL);
}
if(unlikely(!cd)) fatal("Cannot allocate memory for plugin.");
snprintf(cd->id, CONFIG_MAX_NAME, "plugin:%s", pluginname);
-
+
strncpy(cd->filename, file->d_name, FILENAME_MAX);
snprintf(cd->fullfilename, FILENAME_MAX, "%s/%s", dir_name, cd->filename);
fprintf(stdout, "MYPID %d\n", getpid());
fflush(NULL);
#endif
-
+
// reset all signals
for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV) signal(i, SIG_DFL);
void mypclose(FILE *fp, pid_t pid) {
debug(D_EXIT, "Request to mypclose() on pid %d", pid);
-
+
/*mypopen_del(fp);*/
fclose(fp);
error("pid %d killed by signal %d.", info.si_pid, info.si_status);
break;
- case CLD_DUMPED:
+ case CLD_DUMPED:
error("pid %d core dumped by signal %d.", info.si_pid, info.si_status);
break;
RRDSET *st;
// --------------------------------------------------------------------
-
+
// http://stackoverflow.com/questions/3019748/how-to-reliably-measure-available-memory-in-linux
unsigned long long MemUsed = MemTotal - MemFree - Cached - Buffers;
}
// --------------------------------------------------------------------
-
+
unsigned long long SwapUsed = SwapTotal - SwapFree;
if(do_swap) {
}
// --------------------------------------------------------------------
-
+
if(hwcorrupted && do_hwcorrupt) {
st = rrdset_find("mem.hwcorrupt");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_committed) {
st = rrdset_find("mem.committed");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_writeback) {
st = rrdset_find("mem.writeback");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_kernel) {
st = rrdset_find("mem.kernel");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_slab) {
st = rrdset_find("mem.slab");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_packets) {
st = rrdset_find(RRD_TYPE_NET_IPVS ".packets");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_bandwidth) {
st = rrdset_find(RRD_TYPE_NET_IPVS ".net");
if(!st) {
InNoRoutes = 0, InTruncatedPkts = 0,
InOctets = 0, InMcastPkts = 0, InBcastPkts = 0, InMcastOctets = 0, InBcastOctets = 0,
OutOctets = 0, OutMcastPkts = 0, OutBcastPkts = 0, OutMcastOctets = 0, OutBcastOctets = 0;
-
+
InNoRoutes = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
InTruncatedPkts = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
InMcastPkts = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
}
}
}
-
+
return 0;
}
error("%s line of /proc/net/rpc/nfsd has %d words, expected %d", type, words, 4);
continue;
}
-
+
rc_hits = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
rc_misses = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
rc_nocache = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
error("%s line of /proc/net/rpc/nfsd has %d words, expected %d", type, words, 6);
continue;
}
-
+
fh_stale = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
fh_total_lookups = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
fh_anonymous_lookups = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
error("%s line of /proc/net/rpc/nfsd has %d words, expected %d", type, words, 3);
continue;
}
-
+
io_read = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
io_write = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
error("%s line of /proc/net/rpc/nfsd has %d words, expected %d", type, words, 13);
continue;
}
-
+
th_threads = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
th_fullcnt = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
th_hist10 = (unsigned long long)(atof(procfile_lineword(ff, l, 3)) * 1000.0);
error("%s line of /proc/net/rpc/nfsd has %d words, expected %d", type, words, 13);
continue;
}
-
+
ra_size = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
ra_hist10 = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
ra_hist20 = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
error("%s line of /proc/net/rpc/nfsd has %d words, expected %d", type, words, 5);
continue;
}
-
+
net_count = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
net_udp_count = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
net_tcp_count = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
error("%s line of /proc/net/rpc/nfsd has %d words, expected %d", type, words, 6);
continue;
}
-
+
rpc_count = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
rpc_bad_format = strtoull(procfile_lineword(ff, l, 2), NULL, 10);
rpc_bad_auth = strtoull(procfile_lineword(ff, l, 3), NULL, 10);
for(i = 0; nfsd_proc_values[i].present2 ; i++)
rrddim_set(st, nfsd_proc_values[i].name, nfsd_proc_values[i].proc2);
-
+
rrdset_done(st);
}
for(i = 0; nfsd_proc_values[i].present3 ; i++)
rrddim_set(st, nfsd_proc_values[i].name, nfsd_proc_values[i].proc3);
-
+
rrdset_done(st);
}
for(i = 0; nfsd_proc_values[i].present4 ; i++)
rrddim_set(st, nfsd_proc_values[i].name, nfsd_proc_values[i].proc4);
-
+
rrdset_done(st);
}
for(i = 0; nfsd4_ops_values[i].present ; i++)
rrddim_set(st, nfsd4_ops_values[i].name, nfsd4_ops_values[i].value);
-
+
rrdset_done(st);
}
int do_proc_net_snmp(int update_every, unsigned long long dt) {
static procfile *ff = NULL;
static int do_ip_packets = -1, do_ip_fragsout = -1, do_ip_fragsin = -1, do_ip_errors = -1,
- do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1,
+ do_tcp_sockets = -1, do_tcp_packets = -1, do_tcp_errors = -1, do_tcp_handshake = -1,
do_udp_packets = -1, do_udp_errors = -1;
if(do_ip_packets == -1) do_ip_packets = config_get_boolean("plugin:proc:/proc/net/snmp", "ipv4 packets", 1);
FragOKs = strtoull(procfile_lineword(ff, l, 17), NULL, 10);
FragFails = strtoull(procfile_lineword(ff, l, 18), NULL, 10);
FragCreates = strtoull(procfile_lineword(ff, l, 19), NULL, 10);
-
+
// these are not counters
if(Forwarding) {}; // is forwarding enabled?
if(DefaultTTL) {}; // the default ttl on packets
if(MaxConn) {};
// --------------------------------------------------------------------
-
+
// see http://net-snmp.sourceforge.net/docs/mibs/tcp.html
if(do_tcp_sockets) {
st = rrdset_find(RRD_TYPE_NET_SNMP ".tcpsock");
}
// --------------------------------------------------------------------
-
+
if(do_tcp_packets) {
st = rrdset_find(RRD_TYPE_NET_SNMP ".tcppackets");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_tcp_errors) {
st = rrdset_find(RRD_TYPE_NET_SNMP ".tcperrors");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_tcp_handshake) {
st = rrdset_find(RRD_TYPE_NET_SNMP ".tcphandshake");
if(!st) {
SndbufErrors = strtoull(procfile_lineword(ff, l, 6), NULL, 10);
// --------------------------------------------------------------------
-
+
// see http://net-snmp.sourceforge.net/docs/mibs/udp.html
if(do_udp_packets) {
st = rrdset_find(RRD_TYPE_NET_SNMP ".udppackets");
}
// --------------------------------------------------------------------
-
+
if(do_udp_errors) {
st = rrdset_find(RRD_TYPE_NET_SNMP ".udperrors");
if(!st) {
}
}
}
-
+
return 0;
}
RRDSET *st;
// --------------------------------------------------------------------
-
+
if(do_sockets) {
st = rrdset_find(RRD_TYPE_NET_STAT_CONNTRACK ".sockets");
if(!st) {
unsigned long long value = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
// --------------------------------------------------------------------
-
+
if(do_interrupts) {
st = rrdset_find_bytype("system", "intr");
if(!st) {
unsigned long long value = strtoull(procfile_lineword(ff, l, 1), NULL, 10);
// --------------------------------------------------------------------
-
+
if(do_context) {
st = rrdset_find_bytype("system", "ctxt");
if(!st) {
nr_shmem = 0, nr_dirtied = 0, nr_written = 0, nr_anon_transparent_hugepages = 0, nr_dirty_threshold = 0, nr_dirty_background_threshold = 0,
pgpgin = 0, pgpgout = 0, pswpin = 0, pswpout = 0, pgalloc_dma = 0, pgalloc_dma32 = 0, pgalloc_normal = 0, pgalloc_movable = 0, pgfree = 0, pgactivate = 0, pgdeactivate = 0,
pgfault = 0, pgmajfault = 0, pgrefill_dma = 0, pgrefill_dma32 = 0, pgrefill_normal = 0, pgrefill_movable = 0, pgsteal_kswapd_dma = 0, pgsteal_kswapd_dma32 = 0,
- pgsteal_kswapd_normal = 0, pgsteal_kswapd_movable = 0, pgsteal_direct_dma = 0, pgsteal_direct_dma32 = 0, pgsteal_direct_normal = 0, pgsteal_direct_movable = 0,
+ pgsteal_kswapd_normal = 0, pgsteal_kswapd_movable = 0, pgsteal_direct_dma = 0, pgsteal_direct_dma32 = 0, pgsteal_direct_normal = 0, pgsteal_direct_movable = 0,
pgscan_kswapd_dma = 0, pgscan_kswapd_dma32 = 0, pgscan_kswapd_normal = 0, pgscan_kswapd_movable = 0, pgscan_direct_dma = 0, pgscan_direct_dma32 = 0, pgscan_direct_normal = 0,
pgscan_direct_movable = 0, pginodesteal = 0, slabs_scanned = 0, kswapd_inodesteal = 0, kswapd_low_wmark_hit_quickly = 0, kswapd_high_wmark_hit_quickly = 0,
kswapd_skip_congestion_wait = 0, pageoutrun = 0, allocstall = 0, pgrotated = 0, compact_blocks_moved = 0, compact_pages_moved = 0, compact_pagemigrate_failed = 0,
RRDSET *st;
// --------------------------------------------------------------------
-
+
if(do_swapio) {
st = rrdset_find("system.swapio");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_io) {
st = rrdset_find("system.io");
if(!st) {
}
// --------------------------------------------------------------------
-
+
if(do_pgfaults) {
st = rrdset_find("system.pgfaults");
if(!st) {
char *s = ff->data, *e = ff->data, *t = ff->data;
uint32_t l = 0, w = 0;
e += ff->len;
-
+
ff->lines = pflines_add(ff->lines, w);
if(unlikely(!ff->lines)) goto cleanup;
/*
* procfile is a library for reading kernel files from /proc
- *
+ *
* The idea is this:
*
* - every file is opened once with procfile_open().
st->priority = config_get_number(st->id, "priority", priority);
st->enabled = enabled;
-
+
st->isdetail = 0;
st->debug = 0;
rd->entries = st->entries;
rd->update_every = st->update_every;
-
+
// prevent incremental calculation spikes
rd->counter = 0;
collected_number rrddim_set_by_pointer(RRDSET *st, RRDDIM *rd, collected_number value)
{
debug(D_RRD_CALLS, "rrddim_set_by_pointer() for chart %s, dimension %s, value " COLLECTED_NUMBER_FORMAT, st->name, rd->name, value);
-
+
gettimeofday(&rd->last_collected_time, NULL);
rd->collected_value = value;
rd->updated = 1;
// this is a pointer to the config structure
// since the config always has a higher priority
// (the user overwrites the name of the charts)
-
+
int algorithm; // the algorithm that is applied to add new collected values
long multiplier; // the multiplier of the collected values
long divisor; // the divider of the collected values
}
}
pthread_rwlock_unlock(&rrdset_root_rwlock);
-
+
buffer_sprintf(wb, "\n\t],\n"
"\t\"hostname\": \"%s\",\n"
"\t\"update_every\": %d,\n"
static char *print_calculated_number_lu_r(char *str, unsigned long uvalue) {
char *wstr = str;
-
+
// print each digit
do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
return wstr;
mine = (calculated_number)sizeof(storage_number) * (calculated_number)loop;
their = (calculated_number)sizeof(calculated_number) * (calculated_number)loop;
-
+
if(mine > their) {
fprintf(stderr, "\nNETDATA NEEDS %0.2Lf TIMES MORE MEMORY. Sorry!\n", (long double)(mine / their));
}
mine = total;
fprintf(stderr, "user %0.5Lf, system %0.5Lf, total %0.5Lf\n", (long double)(user / 1000000.0), (long double)(system / 1000000.0), (long double)(total / 1000000.0));
-
+
// ------------------------------------------------------------------------
fprintf(stderr, "SYSTEM LONG DOUBLE PRINTING: ");
for(rd = st->dimensions ; rd ; rd = rd->next) {
fprintf(stderr, "\t %s " STORAGE_NUMBER_FORMAT " -> ", rd->id, rd->values[c]);
- if(rd == rdabs) v =
- ( oincrement
+ if(rd == rdabs) v =
+ ( oincrement
+ (increment * (1000000 - shift) / 1000000)
+ c * increment
) * 10;
else
*pbuf++ = *pstr;
-
+
pstr++;
}
-
+
*pbuf = '\0';
-
+
return buf;
}
b->buffer = realloc(b->buffer, b->size + increase + sizeof(BUFFER_OVERFLOW_EOF) + 2);
if(!b->buffer) fatal("Failed to increase data buffer from size %d to %d.", b->size + sizeof(BUFFER_OVERFLOW_EOF) + 2, b->size + increase + sizeof(BUFFER_OVERFLOW_EOF) + 2);
-
+
b->size += increase;
buffer_overflow_init(b);
struct web_client *web_client_create(int listener)
{
struct web_client *w;
-
+
w = calloc(1, sizeof(struct web_client));
if(!w) {
error("Cannot allocate new web_client memory.");
<html>
-<head>
+<head>
<title>NetData Dashboard</title>
<style type="text/css">
html{font-family:sans-serif;}
Sparkline charts stretch the values to show the variations between values in more detail.
They also have mouse-hover support.
<br/>
- Sparklines are fantastic. You can inline charts in text. For example this
+ Sparklines are fantastic. You can inline charts in text. For example this
<div style="display: inline; position: relative;"
data-netdata="system.cpu"
data-chart-library="sparkline"
data-width="60"
data-height="15"
data-after="-30"
- </div> is the bandwidth my netdata server is currently transmitting and this
+ </div> is the bandwidth my netdata server is currently transmitting and this
<div style="display: inline; position: relative;"
data-netdata="netdata.requests"
if(typeof jQuery == 'undefined') {
var script = document.createElement('script');
script.type = 'text/javascript';
- script.async = true;
+ script.async = true;
script.src = NETDATA.jQuery;
-
+
// script.onabort = onError;
script.onerror = function(err, t) { NETDATA.error(101, NETDATA.jQuery); };
if(typeof callback == "function")
script.onload = callback;
-
+
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(script, s);
}
NETDATA.loadCharts(targets, ++index, callback);
}
else {
- var url = host + "/api/v1/chart?chart=" + id;
+ var url = host + "/api/v1/chart?chart=" + id;
$.ajax( {
url: url,
var self = $(this);
var lib = self.data('chart-library') || 'dygraph';
var method = lib + 'ChartCreate';
-
+
console.log('Calling ' + method + '()');
NETDATA[method].apply(this, arguments);
})
var self = $(this);
var lib = self.data('chart-library') || 'dygraph';
var method = lib + 'ChartUpdate';
-
+
console.log('Calling ' + method + '()');
NETDATA[method].apply(this, arguments);
});
// get from the 3rd column the 'v' member
//return item.c[3].v;
//});
-
+
// since we downloaded the data
// update the last-updated time to prevent
// another download too soon
var numberDecimalMark = self.data('sparkline-numberDecimalMark') || undefined;
var numberDigitGroupCount = self.data('sparkline-numberDigitGroupCount') || undefined;
var animatedZooms = self.data('sparkline-animatedZooms') || false;
-
+
var options = {
type: type,
lineColor: lineColor,
else
console.log('not updating dygraphs');
};
-
+
NETDATA.dygraphChartCreate = function(event, data) {
var self = $(this);
var width = self.data('width') || NETDATA.chartDefaults.width;
var drawYGrid = self.data('dygraph-drawYGrid') || undefined;
var gridLinePattern = self.data('dygraph-gridLinePattern') || null;
var gridLineWidth = self.data('dygraph-gridLineWidth') || 0.3;
-
+
var options = {
title: title,
titleHeight: titleHeight,
var width = self.data('width') || NETDATA.chartDefaults.width;
var height = self.data('height') || NETDATA.chartDefaults.height;
var chart = self.data('chart');
-
+
self.html('<div id="morris-' + chart.id + '" style="width: ' + width + 'px; height: ' + height + 'px;"></div>');
// remove the 'time' element from the labels
var self = $(this);
var width = self.data('width') || NETDATA.chartDefaults.width;
var height = self.data('height') || NETDATA.chartDefaults.height;
-
+
self.raphael(data, {
width: width,
height: height
var self = $(this);
var width = self.data('width') || NETDATA.chartDefaults.width;
var height = self.data('height') || NETDATA.chartDefaults.height;
-
+
self.raphael(data, {
width: width,
height: height
var width = self.data('width') || NETDATA.chartDefaults.width;
var height = self.data('height') || NETDATA.chartDefaults.height;
var chart = self.data('chart');
-
+
var datatable = new google.visualization.DataTable(data);
var gchart;
NETDATA.errorReset();
- NETDATA._loadjQuery(function() {
+ NETDATA._loadjQuery(function() {
NETDATA.raphaelInitialize(function() {
NETDATA.morrisInitialize(function() {
NETDATA.peityInitialize(function() {
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="description" content="">
<meta name="author" content="costa@tsaousis.gr">
-
+
<title>NetData</title>
<!-- Bootstrap CSS -->
if(a.name < b.name) return -1;
}
else if(a.priority < b.priority) return -1;
-
+
return 1;
}
}
function initMainChartIndex(i) {
- if(mode == MODE_GROUP_THUMBS)
+ if(mode == MODE_GROUP_THUMBS)
initMainChart(groupCharts[i]);
else if(mode == MODE_THUMBS)
// 'maxZoomOut': 1,
//};
//mainchart.last_updated = 0;
-
+
//if(!renderChart(mainchart, pauseGraphs))
pauseGraphs();
}
var timeout = null;
function renderChartCallback() {
last_refresh = new Date().getTime();
-
+
if(!page_is_visible) {
timeout = setTimeout(triggerRefresh, CHARTS_CHECK_NO_FOCUS);
return;
var groupCharts = null;
function initGroupGraphs(group) {
var count = 0;
-
+
if(groupCharts) clearGroupGraphs();
groupCharts = new Array();
return 1;
}
categories.sort(categoriessort);
-
+
function familiessort(a, b) {
if(a.name < b.name) return -1;
return 1;
.done(function(jsondata) {
if(!jsondata || jsondata.length == 0) return;
chart.jsondata = jsondata;
-
+
// Create our data table out of JSON data loaded from server.
chart.datatable = new google.visualization.DataTable(chart.jsondata);
//console.log(chart.datatable);
else
chart.chart = new google.visualization.AreaChart(document.getElementById(chart.div));
}
-
+
if(chart.chart) {
chart.chart.draw(chart.datatable, chart.chartOptions);
chart.refreshCount++;
c.points_to_show = Math.round(data_points / group);
// console.log("rendering with supplied group (group = " + c.group + ", points_to_show = " + c.points_to_show + ')');
}
-
+
// console.log("final configuration (group = " + c.group + ", points_to_show = " + c.points_to_show + ')');
// make sure the line width is not congesting the chart
// do not render curves when we don't have at
// least 2 twice the space per point
- if(!enable_curve || c.points_to_show > (c.chartOptions.width * c.chartOptions.lineWidth / 2) )
+ if(!enable_curve || c.points_to_show > (c.chartOptions.width * c.chartOptions.lineWidth / 2) )
c.chartOptions.curveType = 'none';
else
c.chartOptions.curveType = c.default_curveType;
json.charts[i].chartType = "AreaChart";
json.charts[i].chartOptions.isStacked = false;
json.charts[i].chartOptions.areaOpacity = 0.3;
-
+
json.charts[i].chartOptions.vAxis.viewWindowMode = 'maximized';
json.charts[i].non_zero = 0;
-
+
json.charts[i].group = 3;
break;
json.charts[i].non_zero = 0;
json.charts[i].default_curveType = 'function';
-
+
json.charts[i].group = 3;
break;
}
break;
}
});
-
+
if(typeof doNext == "function") doNext(json);
})
.fail(function() {
* only accounts for vertical position, not horizontal.
*/
$.fn.visible = function(partial){
-
+
var $t = $(this),
$w = $(window),
viewTop = $w.scrollTop(),
_bottom = _top + $t.height(),
compareTop = partial === true ? _bottom : _top,
compareBottom = partial === true ? _top : _bottom;
-
+
return ((compareBottom <= viewBottom) && (compareTop >= viewTop));
};
})(jQuery);