src/proc_net_dev.c
src/proc_net_ip_vs_stats.c
src/proc_net_netstat.c
+ src/proc_net_rpc_nfs.c
src/proc_net_rpc_nfsd.c
src/proc_net_snmp6.c
src/proc_net_snmp.c
src/proc_net_stat_conntrack.c
src/proc_net_stat_synproxy.c
+ src/proc_net_softnet_stat.c
src/proc_self_mountinfo.c
src/proc_self_mountinfo.h
src/proc_softirqs.c
<a href="https://scan.coverity.com/projects/firehol-netdata"><img alt="Coverity Scan Build Status" src="https://scan.coverity.com/projects/9140/badge.svg"/></a>
[![Docker Pulls](https://img.shields.io/docker/pulls/titpetric/netdata.svg)](https://hub.docker.com/r/titpetric/netdata/)
-[![User Base](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=persons&label=user%20base&units=null&value_color=blue&precision=0&v41)](https://registry.my-netdata.io/#netdata_registry)
-[![Monitored Servers](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=machines&label=servers%20monitored&units=null&value_color=orange&precision=0&v41)](https://registry.my-netdata.io/#netdata_registry)
-[![Sessions Served](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_sessions&label=sessions%20served&units=null&value_color=yellowgreen&precision=0&v41)](https://registry.my-netdata.io/#netdata_registry)
+[![User Base](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=persons&label=user%20base&units=null&value_color=blue&precision=0&v42)](https://registry.my-netdata.io/#netdata_registry)
+[![Monitored Servers](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=machines&label=servers%20monitored&units=null&value_color=orange&precision=0&v42)](https://registry.my-netdata.io/#netdata_registry)
+[![Sessions Served](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_sessions&label=sessions%20served&units=null&value_color=yellowgreen&precision=0&v42)](https://registry.my-netdata.io/#netdata_registry)
-[![New Users Today](http://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=persons&after=-86400&options=unaligned&group=incremental-sum&label=new%20users%20today&units=null&value_color=blue&precision=0&v41)](https://registry.my-netdata.io/#netdata_registry)
-[![New Machines Today](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=machines&group=incremental-sum&after=-86400&options=unaligned&label=servers%20added%20today&units=null&value_color=orange&precision=0&v41)](https://registry.my-netdata.io/#netdata_registry)
-[![Sessions Today](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_sessions&after=-86400&group=incremental-sum&options=unaligned&label=sessions%20served%20today&units=null&value_color=yellowgreen&precision=0&v41)](https://registry.my-netdata.io/#netdata_registry)
+[![New Users Today](http://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=persons&after=-86400&options=unaligned&group=incremental-sum&label=new%20users%20today&units=null&value_color=blue&precision=0&v42)](https://registry.my-netdata.io/#netdata_registry)
+[![New Machines Today](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_entries&dimensions=machines&group=incremental-sum&after=-86400&options=unaligned&label=servers%20added%20today&units=null&value_color=orange&precision=0&v42)](https://registry.my-netdata.io/#netdata_registry)
+[![Sessions Today](https://registry.my-netdata.io/api/v1/badge.svg?chart=netdata.registry_sessions&after=-86400&group=incremental-sum&options=unaligned&label=sessions%20served%20today&units=null&value_color=yellowgreen&precision=0&v42)](https://registry.my-netdata.io/#netdata_registry)
# netdata
---
-**Real-time performance monitoring, done right!**
+**Real-time performance and health monitoring, done right!**
This is the default dashboard of **netdata**:
- real-time, per second updates, snappy refreshes!
- 300+ charts out of the box, 2000+ metrics monitored!
- zero configuration, zero maintenance, zero dependencies!
+ - dozens of health monitoring alarms, out of the box!
Live demo: [http://my-netdata.io](http://my-netdata.io)
This is what you get:
-- **Stunning bootstrap dashboards**, out of the box (themable: dark, light)
+- **Stunning bootstrap dashboards**, out of the box (theme-able: dark, light)
- **Blazingly fast** and **super efficient**, mostly written in C (for default installations, expect just 2% of a single core CPU usage and a few MB of RAM)
-- **Zero configuration** - you just install it and it autodetects everything
+- **Zero configuration** - you just install it and it auto-detects everything
- **Zero dependencies**, it is its own web server for its static web files and its web API
- **Zero maintenance**, you just run it, it does the rest
- **Custom dashboards** that can be built using simple HTML (no javascript necessary)
-- **Extensible**, you can monitor anything you can get a metric for, using its Plugin API (anything can be a netdata plugin - from BASH to node.js, so you can easily monitor any application, any API)
+- **Extensible**, you can monitor anything you can get a metric for, using its Plugin API (anything can be a netdata plugin - from BASH to python and node.js, so you can easily monitor any application, any API)
- **Embeddable**, it can run anywhere a Linux kernel runs (even IoT) and its charts can be embedded on your web pages too
---
- **Entropy** (random numbers pool, using in cryptography)
-- **NFS file servers**, v2, v3, v4 (I/O, cache, read ahead, RPC calls)
+- **NFS file servers and clients**, v2, v3, v4 (I/O, cache, read ahead, RPC calls)
- **Network QoS** (yes, the only tool that visualizes network `tc` classes in realtime)
- **Users and User Groups resource usage**, by summarizing the process tree per user and group (CPU, memory, disk reads, disk writes, swap, threads, pipes, sockets, etc)
-- **Apache web server** mod-status (v2.2, v2.4) and cache log statistics (multiple servers)
+- **Apache web servers** mod-status (v2.2, v2.4) and cache log statistics (multiple servers - compatible with lighttpd too)
-- **Nginx web server** stub-status (multiple servers)
+- **Nginx web servers** stub-status (multiple servers)
- **mySQL databases** (multiple servers, each showing: bandwidth, queries/s, handlers, locks, issues, tmp operations, connections, binlog metrics, threads, innodb metrics, etc)
- **memcached databases** (multiple servers, each showing: bandwidth, connections, items, etc)
-- **ISC Bind name server** (multiple servers, each showing: clients, requests, queries, updates, failures and several per view metrics)
+- **ISC Bind name servers** (multiple servers, each showing: clients, requests, queries, updates, failures and several per view metrics)
-- **Postfix email server** message queue (entries, size)
+- **Postfix email servers** message queue (entries, size)
-- **exim email server** message queue (emails queued)
+- **exim email servers** message queue (emails queued)
- **IPFS** (Bandwidth, Peers)
-- **Squid proxy server** (multiple servers, each showing: clients bandwidth and requests, servers bandwidth and requests)
+- **Squid proxy servers** (multiple servers, each showing: clients bandwidth and requests, servers bandwidth and requests)
- **Hardware sensors** (temperature, voltage, fans, power, humidity, etc)
-- **NUT UPSes** (load, charge, battery voltage, temperature, utility metrics, output metrics)
+- **NUT and APC UPSes** (load, charge, battery voltage, temperature, utility metrics, output metrics)
- **Tomcat** (accesses, threads, free memory, volume)
REINSTALL_PWD="${PWD}"
REINSTALL_COMMAND="$(printf "%q " "$0" "${@}"; printf "\n")"
+banner() {
+ local l1=" ^" \
+ l2=" |.-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-" \
+ l3=" | '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' " \
+ l4=" +----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+--->" \
+ sp=" " \
+ netdata="netdata" start end msg="${*}"
+
+ [ ${#msg} -lt ${#netdata} ] && msg="${msg}${sp:0:$(( ${#netdata} - ${#msg}))}"
+ [ ${#msg} -gt $(( ${#l2} - 20 )) ] && msg="${msg:0:$(( ${#l2} - 23 ))}..."
+
+ start="$(( ${#l2} / 2 - 4 ))"
+ [ $(( start + ${#msg} + 4 )) -gt ${#l2} ] && start=$((${#l2} - ${#msg} - 4))
+ end=$(( ${start} + ${#msg} + 4 ))
+
+ echo >&2
+ echo >&2 "${l1}"
+ echo >&2 "${l2:0:start}${sp:0:2}${netdata}${sp:0:$((end - start - 2 - ${#netdata}))}${l2:end:$((${#l2} - end))}"
+ echo >&2 "${l3:0:start}${sp:0:2}${msg}${sp:0:2}${l3:end:$((${#l2} - end))}"
+ echo >&2 "${l4}"
+ echo >&2
+}
+
service="$(which service 2>/dev/null || command -v service 2>/dev/null)"
systemctl="$(which systemctl 2>/dev/null || command -v systemctl 2>/dev/null)"
service() {
LIBS_ARE_HERE=0
usage() {
+ banner "installer command line options"
cat <<USAGE
${ME} <installer options>
fi
done
+banner "real-time performance monitoring, done right!"
cat <<BANNER
-Welcome to netdata!
-The real-time performance monitoring system.
-
-You are about to build and install netdata to your system.
+ You are about to build and install netdata to your system.
-It will be installed at these locations:
+ It will be installed at these locations:
- - the daemon at ${NETDATA_PREFIX}/usr/sbin/netdata
- - config files at ${NETDATA_PREFIX}/etc/netdata
- - web files at ${NETDATA_PREFIX}/usr/share/netdata
- - plugins at ${NETDATA_PREFIX}/usr/libexec/netdata
- - cache files at ${NETDATA_PREFIX}/var/cache/netdata
- - db files at ${NETDATA_PREFIX}/var/lib/netdata
- - log files at ${NETDATA_PREFIX}/var/log/netdata
- - pid file at ${NETDATA_PREFIX}/var/run
+ - the daemon at ${NETDATA_PREFIX}/usr/sbin/netdata
+ - config files at ${NETDATA_PREFIX}/etc/netdata
+ - web files at ${NETDATA_PREFIX}/usr/share/netdata
+ - plugins at ${NETDATA_PREFIX}/usr/libexec/netdata
+ - cache files at ${NETDATA_PREFIX}/var/cache/netdata
+ - db files at ${NETDATA_PREFIX}/var/lib/netdata
+ - log files at ${NETDATA_PREFIX}/var/log/netdata
+ - pid file at ${NETDATA_PREFIX}/var/run
-This installer allows you to change the installation path.
-Press Control-C and run the same command with --help for help.
+ This installer allows you to change the installation path.
+ Press Control-C and run the same command with --help for help.
BANNER
then
if [ -z "${NETDATA_PREFIX}" ]
then
+ banner "wrong command line options!"
cat <<NONROOTNOPREFIX
Sorry! This will fail!
then
echo "Will skip autoreconf step"
else
+ banner "autotools v2.60 required"
cat <<"EOF"
-------------------------------------------------------------------------------
fi
build_error() {
+ banner "sorry, it failed to build..."
cat <<EOF
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Sorry! NetData failed to build...
+Sorry! netdata failed to build...
You many need to check these:
fi
chmod 0664 "${NETDATA_PREFIX}/etc/netdata/netdata.conf"
fi
- echo >&2 "OK. It is now installed and ready."
+ banner "is installed now!"
+ echo >&2 " enjoy real-time performance and health monitoring..."
exit 0
fi
${NETDATA_PREFIX}/usr/sbin/netdata
-Enjoy!
-
END
echo >&2 "Uninstall script generated: ./netdata-uninstaller.sh"
-cat >netdata-updater.sh.new <<REINSTALL
+if [ -d .git ]
+ then
+ cat >netdata-updater.sh.new <<REINSTALL
#!/usr/bin/env bash
+force=0
+[ "\${1}" = "-f" ] && force=1
+
export PATH="\${PATH}:${PATH}"
export CFLAGS="${CFLAGS}"
-LAST_UID="${UID}"
-if [ "\${LAST_UID}" != "\${UID}" ]
+INSTALL_UID="${UID}"
+if [ "\${INSTALL_UID}" != "\${UID}" ]
then
- echo >&2 "This script should be run as user with uid \${LAST_UID} but it now runs with uid \${UID}"
+ echo >&2 "This script should be run as user with uid \${INSTALL_UID} but it now runs with uid \${UID}"
exit 1
fi
# make sure we cd to the working directory
cd "${REINSTALL_PWD}" || exit 1
+# make sure there is .git here
+[ \${force} -eq 0 -a ! -d .git ] && echo >&2 "No git structures found at: ${REINSTALL_PWD} (use -f for force re-install)" && exit 1
+
# signal netdata to start saving its database
# this is handy if your database is big
pids=\$(pidof netdata)
[ ! -z "\${pids}" ] && kill -USR1 \${pids}
+tmp=
+if [ -t 2 ]
+ then
+ # we are running on a terminal
+ # open fd 3 and send it to stderr
+ exec 3>&2
+else
+ # we are headless
+ # create a temporary file for the log
+ tmp=\$(mktemp /tmp/netdata-updater-log-XXXXXX.log)
+ # open fd 3 and send it to tmp
+ exec 3>\${tmp}
+fi
+
+info() {
+ echo >&3 "\$(date) : INFO: " "\${@}"
+}
+
+emptyline() {
+ echo >&3
+}
+
+error() {
+ echo >&3 "\$(date) : ERROR: " "\${@}"
+}
+
# this is what we will do if it fails (head-less only)
failed() {
- echo >&2 "\$(date) : FAILED TO UPDATE NETDATA : \${1}"
- cat >&2 "\${tmp}"
- rm "\${tmp}"
- exit 1
+ error "FAILED TO UPDATE NETDATA : \${1}"
+
+ if [ ! -z "\${tmp}" ]
+ then
+ cat >&2 "\${tmp}"
+ rm "\${tmp}"
+ fi
+ exit 1
}
get_latest_commit_id() {
- git log | grep ^commit | head -n 1 | cut -d ' ' -f 2
+ git log -1 2>&3 |\\
+ grep ^commit 2>&3 |\\
+ head -n 1 2>&3 |\\
+ cut -d ' ' -f 2 2>&3
}
-last_commit="\$(get_latest_commit_id)"
-[ -z "\${last_commit}" ] && failed "CANNOT GET LAST COMMIT ID"
-
update() {
- if [ -t 1 -a -t 2 ]
- then
- # running on a terminal
- echo >&2 "Running on a terminal - (this script also supports running headless from crontab)"
+ [ -z "\${tmp}" ] && info "Running on a terminal - (this script also supports running headless from crontab)"
- echo >&2
- echo >&2 "Updating source..."
- git pull || exit 1
- new_commit="\$(get_latest_commit_id)"
- [ -z "\${new_commit}" ] && echo >&2 "CANNOT GET NEW LAST COMMIT ID" && exit 1
- [ "\${new_commit}" = "\${last_commit}" ] && echo >&2 "Nothing to be done!" && exit 0
+ emptyline
- echo >&2
- echo >&2 "re-installing..."
- ${REINSTALL_COMMAND// --dont-wait/} --dont-wait || exit 1
+ if [ -d .git ]
+ then
+ info "Updating netdata source from github..."
- else
- # running head-less
- # do not generate any output, unless we fail
+ last_commit="\$(get_latest_commit_id)"
+ [ \${force} -eq 0 -a -z "\${last_commit}" ] && failed "CANNOT GET LAST COMMIT ID (use -f for force re-install)"
- # create a temporary file for the log
- tmp=\$(mktemp /tmp/netdata-updater-log-XXXXXX.log)
+ git pull >&3 2>&3 || failed "CANNOT FETCH LATEST SOURCE (use -f for force re-install)"
- # update source from git
- git pull >>"\${tmp}" 2>&1 || failed "CANNOT FETCH LATEST SOURCE"
new_commit="\$(get_latest_commit_id)"
- [ -z "\${new_commit}" ] && failed "CANNOT GET NEW LAST COMMIT ID"
- [ "\${new_commit}" = "\${last_commit}" ] && exit 0
-
- # install the latest version
- ${REINSTALL_COMMAND// --dont-wait/} --dont-wait >>"\${tmp}" 2>&1 || failed "CANNOT BUILD AND INSTALL NETDATA"
-
- rm "\${tmp}"
+ if [ \${force} -eq 0 ]
+ then
+ [ -z "\${new_commit}" ] && failed "CANNOT GET NEW LAST COMMIT ID (use -f for force re-install)"
+ [ "\${new_commit}" = "\${last_commit}" ] && info "Nothing to be done! (use -f to force re-install)" && exit 0
+ fi
+ elif [ \${force} -eq 0 ]
+ then
+ failed "CANNOT FIND GIT STRUCTURES IN \$(pwd) (use -f for force re-install)"
fi
+ emptyline
+ info "Re-installing netdata..."
+ ${REINSTALL_COMMAND// --dont-wait/} --dont-wait >&3 2>&3 || failed "FAILED TO COMPILE/INSTALL NETDATA"
+
+ [ ! -z "\${tmp}" ] && rm "\${tmp}" && tmp=
return 0
}
###############################################################################
###############################################################################
REINSTALL
-chmod 755 netdata-updater.sh.new
-mv -f netdata-updater.sh.new netdata-updater.sh
-echo >&2 "Update script generated : ./netdata-updater.sh"
+ chmod 755 netdata-updater.sh.new
+ mv -f netdata-updater.sh.new netdata-updater.sh
+ echo >&2 "Update script generated : ./netdata-updater.sh"
+elif [ -f "netdata-updater.sh" ]
+ then
+ rm "netdata-updater.sh"
+fi
+
+banner "is installed and running now!"
+echo >&2 " enjoy real-time performance and health monitoring..."
+echo >&2
+exit 0
if(do_per_core) {
for(l = 0; l < lines ;l++) {
char id[50+1];
- snprintfz(id, 50, "cpu%d_softnet_stat", l);
+ snprintfz(id, 50, "cpu%u_softnet_stat", l);
st = rrdset_find_bytype("cpu", id);
if(!st) {
char title[100+1];
- snprintfz(title, 100, "CPU%d softnet_stat", l);
+ snprintfz(title, 100, "CPU%u softnet_stat", l);
st = rrdset_create("cpu", id, NULL, "softnet_stat", NULL, title, "events/s", 4101 + l, update_every, RRDSET_TYPE_LINE);
for(w = 0; w < allocated_columns ;w++)
#define CT_IMAGE_BMP 21
#define buffer_cacheable(wb) do { (wb)->options |= WB_CONTENT_CACHEABLE; if((wb)->options & WB_CONTENT_NO_CACHEABLE) (wb)->options &= ~WB_CONTENT_NO_CACHEABLE; } while(0)
-#define buffer_no_cacheable(wb) do { (wb)->options |= WB_CONTENT_NO_CACHEABLE; if((wb)->options & WB_CONTENT_CACHEABLE) (wb)->options &= ~WB_CONTENT_CACHEABLE; } while(0)
+#define buffer_no_cacheable(wb) do { (wb)->options |= WB_CONTENT_NO_CACHEABLE; if((wb)->options & WB_CONTENT_CACHEABLE) (wb)->options &= ~WB_CONTENT_CACHEABLE; (wb)->expires = 0; } while(0)
#define buffer_strlen(wb) ((wb)->len)
extern const char *buffer_tostring(BUFFER *wb);
}
if(!chart || !*chart) {
+ buffer_no_cacheable(w->response.data);
buffer_sprintf(w->response.data, "No chart id is given at the request.");
goto cleanup;
}
RRDSET *st = rrdset_find(chart);
if(!st) st = rrdset_find_byname(chart);
if(!st) {
+ buffer_no_cacheable(w->response.data);
buffer_svg(w->response.data, "chart not found", 0, "", NULL, NULL, 1, -1);
ret = 200;
goto cleanup;
if(alarm) {
rc = rrdcalc_find(st, alarm);
if (!rc) {
+ buffer_no_cacheable(w->response.data);
buffer_svg(w->response.data, "alarm not found", 0, "", NULL, NULL, 1, -1);
ret = 200;
goto cleanup;
else if(options & RRDR_OPTION_NOT_ALIGNED)
refresh = st->update_every;
else {
- refresh = (before - after);
+ refresh = (int)(before - after);
if(refresh < 0) refresh = -refresh;
}
}
calculated_number n = rc->value;
if(isnan(n) || isinf(n)) n = 0;
- if (refresh > 0)
+ if (refresh > 0) {
buffer_sprintf(w->response.header, "Refresh: %d\r\n", refresh);
+ w->response.data->expires = time(NULL) + refresh;
+ }
+ else buffer_no_cacheable(w->response.data);
if(!value_color) {
switch(rc->status) {
}
}
- buffer_svg(w->response.data, label, rc->value * multiply / divide, units, label_color, value_color, 0, precision);
+ buffer_svg(w->response.data,
+ label,
+ rc->value * multiply / divide,
+ units,
+ label_color,
+ value_color,
+ 0,
+ precision);
ret = 200;
}
else {
// if the collected value is too old, don't calculate its value
if (rrdset_last_entry_t(st) >= (time(NULL) - (st->update_every * st->gap_when_lost_iterations_above)))
- ret = rrd2value(st, w->response.data, &n, (dimensions) ? buffer_tostring(dimensions) : NULL, points, after,
- before, group, options, NULL, &latest_timestamp, &value_is_null);
+ ret = rrd2value(st,
+ w->response.data,
+ &n,
+ (dimensions) ? buffer_tostring(dimensions) : NULL,
+ points,
+ after,
+ before,
+ group,
+ options,
+ NULL,
+ &latest_timestamp,
+ &value_is_null);
// if the value cannot be calculated, show empty badge
if (ret != 200) {
+ buffer_no_cacheable(w->response.data);
value_is_null = 1;
n = 0;
ret = 200;
}
- else if (refresh > 0)
+ else if (refresh > 0) {
buffer_sprintf(w->response.header, "Refresh: %d\r\n", refresh);
+ w->response.data->expires = time(NULL) + refresh;
+ }
+ else buffer_no_cacheable(w->response.data);
// render the badge
- buffer_svg(w->response.data, label, n * multiply / divide, units, label_color, value_color, value_is_null,
+ buffer_svg(w->response.data,
+ label,
+ n * multiply / divide,
+ units,
+ label_color,
+ value_color,
+ value_is_null,
precision);
}
if(unlikely(!w->response.data->date))
w->response.data->date = w->tv_ready.tv_sec;
+ if(unlikely(code != 200))
+ buffer_no_cacheable(w->response.data);
+
// set a proper expiration date, if not already set
if(unlikely(!w->response.data->expires)) {
if(w->response.data->options & WB_CONTENT_NO_CACHEABLE)
}
NETDATA.alarms.last_notification_id = data[0].unique_id;
+ NETDATA.localStorageSet('last_notification_id', NETDATA.alarms.last_notification_id, null);
// console.log('last notification id = ' + NETDATA.alarms.last_notification_id);
})
},
while(host.slice(-1) === '/')
host = host.substring(0, host.length - 1);
NETDATA.alarms.server = host;
-
+
+ NETDATA.alarms.last_notification_id = NETDATA.localStorageGet('last_notification_id', NETDATA.alarms.last_notification_id, null);
+
if(NETDATA.alarms.onclick === null)
NETDATA.alarms.onclick = NETDATA.alarms.scrollToAlarm;