summaryrefslogtreecommitdiffstats
path: root/collectors/proc.plugin
diff options
context:
space:
mode:
Diffstat (limited to 'collectors/proc.plugin')
-rw-r--r--collectors/proc.plugin/proc_diskstats.c64
-rw-r--r--collectors/proc.plugin/proc_net_dev.c430
-rw-r--r--collectors/proc.plugin/proc_self_mountinfo.c17
-rw-r--r--collectors/proc.plugin/proc_self_mountinfo.h7
4 files changed, 393 insertions, 125 deletions
diff --git a/collectors/proc.plugin/proc_diskstats.c b/collectors/proc.plugin/proc_diskstats.c
index eee0cbe7..b5d02f32 100644
--- a/collectors/proc.plugin/proc_diskstats.c
+++ b/collectors/proc.plugin/proc_diskstats.c
@@ -17,6 +17,7 @@
static struct disk {
char *disk; // the name of the disk (sda, sdb, etc, after being looked up)
char *device; // the device of the disk (before being looked up)
+ uint32_t hash;
unsigned long major;
unsigned long minor;
int sector_size;
@@ -73,6 +74,9 @@ static struct disk {
RRDSET *st_backlog;
RRDDIM *rd_backlog_backlog;
+ RRDSET *st_busy;
+ RRDDIM *rd_busy_busy;
+
RRDSET *st_util;
RRDDIM *rd_util_utilization;
@@ -390,7 +394,7 @@ static inline int get_disk_name_from_path(const char *path, char *result, size_t
continue;
}
- if(major(sb.st_rdev) != major || minor(sb.st_rdev) != minor) {
+ if(major(sb.st_rdev) != major || minor(sb.st_rdev) != minor || strcmp(basename(filename), disk)) {
//info("DEVICE-MAPPER ('%s', %lu:%lu): filename '%s' does not match %lu:%lu.", disk, major, minor, filename, (unsigned long)major(sb.st_rdev), (unsigned long)minor(sb.st_rdev));
continue;
}
@@ -544,13 +548,17 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
struct disk *d;
+ uint32_t hash = simple_hash(disk);
+
// search for it in our RAM list.
// this is sequential, but since we just walk through
// and the number of disks / partitions in a system
// should not be that many, it should be acceptable
- for(d = disk_root; d ; d = d->next)
- if(unlikely(d->major == major && d->minor == minor))
+ for(d = disk_root; d ; d = d->next){
+ if (unlikely(
+ d->major == major && d->minor == minor && d->hash == hash && !strcmp(d->device, disk)))
return d;
+ }
// not found
// create a new disk structure
@@ -558,6 +566,7 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
d->disk = get_disk_name(major, minor, disk);
d->device = strdupz(disk);
+ d->hash = simple_hash(d->device);
d->major = major;
d->minor = minor;
d->type = DISK_TYPE_UNKNOWN; // Default type. Changed later if not correct.
@@ -624,12 +633,12 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
// check if we can find its mount point
// mountinfo_find() can be called with NULL disk_mountinfo_root
- struct mountinfo *mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor);
+ struct mountinfo *mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor, d->device);
if(unlikely(!mi)) {
// mountinfo_free_all can be called with NULL
mountinfo_free_all(disk_mountinfo_root);
disk_mountinfo_root = mountinfo_read(0);
- mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor);
+ mi = mountinfo_find(disk_mountinfo_root, d->major, d->minor, d->device);
}
if(unlikely(mi))
@@ -942,13 +951,6 @@ int do_proc_diskstats(int update_every, usec_t dt) {
// I/O completion time and the backlog that may be accumulating.
backlog_ms = str2ull(procfile_lineword(ff, l, 13)); // rq_ticks
-
- // --------------------------------------------------------------------------
- // remove slashes from disk names
- char *s;
- for(s = disk; *s ;s++)
- if(*s == '/') *s = '_';
-
// --------------------------------------------------------------------------
// get a disk structure for the disk
@@ -1094,7 +1096,7 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_backlog, RRDSET_FLAG_DETAIL);
- d->rd_backlog_backlog = rrddim_add(d->st_backlog, "backlog", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_backlog_backlog = rrddim_add(d->st_backlog, "backlog", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
}
else rrdset_next(d->st_backlog);
@@ -1108,6 +1110,34 @@ int do_proc_diskstats(int update_every, usec_t dt) {
(busy_ms || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
d->do_util = CONFIG_BOOLEAN_YES;
+ if(unlikely(!d->st_busy)) {
+ d->st_busy = rrdset_create_localhost(
+ "disk_busy"
+ , d->device
+ , d->disk
+ , family
+ , "disk.busy"
+ , "Disk Busy Time"
+ , "milliseconds"
+ , PLUGIN_PROC_NAME
+ , PLUGIN_PROC_MODULE_DISKSTATS_NAME
+ , NETDATA_CHART_PRIO_DISK_BUSY
+ , update_every
+ , RRDSET_TYPE_AREA
+ );
+
+ rrdset_flag_set(d->st_busy, RRDSET_FLAG_DETAIL);
+
+ d->rd_busy_busy =
+ rrddim_add(d->st_busy, "busy", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(d->st_busy);
+
+ last_busy_ms = rrddim_set_by_pointer(d->st_busy, d->rd_busy_busy, busy_ms);
+ rrdset_done(d->st_busy);
+
+ // --------------------------------------------------------------------
+
if(unlikely(!d->st_util)) {
d->st_util = rrdset_create_localhost(
"disk_util"
@@ -1126,11 +1156,15 @@ int do_proc_diskstats(int update_every, usec_t dt) {
rrdset_flag_set(d->st_util, RRDSET_FLAG_DETAIL);
- d->rd_util_utilization = rrddim_add(d->st_util, "utilization", NULL, 1, 10, RRD_ALGORITHM_INCREMENTAL);
+ d->rd_util_utilization = rrddim_add(d->st_util, "utilization", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
else rrdset_next(d->st_util);
- last_busy_ms = rrddim_set_by_pointer(d->st_util, d->rd_util_utilization, busy_ms);
+ collected_number disk_utilization = (busy_ms - last_busy_ms) / (10 * update_every);
+ if (disk_utilization > 100)
+ disk_utilization = 100;
+
+ rrddim_set_by_pointer(d->st_util, d->rd_util_utilization, disk_utilization);
rrdset_done(d->st_util);
}
diff --git a/collectors/proc.plugin/proc_net_dev.c b/collectors/proc.plugin/proc_net_dev.c
index a7db37e6..24715f29 100644
--- a/collectors/proc.plugin/proc_net_dev.c
+++ b/collectors/proc.plugin/proc_net_dev.c
@@ -5,6 +5,8 @@
#define PLUGIN_PROC_MODULE_NETDEV_NAME "/proc/net/dev"
#define CONFIG_SECTION_PLUGIN_PROC_NETDEV "plugin:" PLUGIN_PROC_CONFIG_NAME ":" PLUGIN_PROC_MODULE_NETDEV_NAME
+#define STATE_LENGTH_MAX 32
+
// As defined in https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-net
const char *operstate_names[] = { "unknown", "notpresent", "down", "lowerlayerdown", "testing", "dormant", "up" };
@@ -41,6 +43,11 @@ static struct netdev {
int do_fifo;
int do_compressed;
int do_events;
+ int do_speed;
+ int do_duplex;
+ int do_operstate;
+ int do_carrier;
+ int do_mtu;
const char *chart_type_net_bytes;
const char *chart_type_net_packets;
@@ -49,6 +56,11 @@ static struct netdev {
const char *chart_type_net_events;
const char *chart_type_net_drops;
const char *chart_type_net_compressed;
+ const char *chart_type_net_speed;
+ const char *chart_type_net_duplex;
+ const char *chart_type_net_operstate;
+ const char *chart_type_net_carrier;
+ const char *chart_type_net_mtu;
const char *chart_id_net_bytes;
const char *chart_id_net_packets;
@@ -57,6 +69,11 @@ static struct netdev {
const char *chart_id_net_events;
const char *chart_id_net_drops;
const char *chart_id_net_compressed;
+ const char *chart_id_net_speed;
+ const char *chart_id_net_duplex;
+ const char *chart_id_net_operstate;
+ const char *chart_id_net_carrier;
+ const char *chart_id_net_mtu;
const char *chart_family;
@@ -86,6 +103,8 @@ static struct netdev {
kernel_uint_t speed;
kernel_uint_t duplex;
kernel_uint_t operstate;
+ unsigned long long carrier;
+ unsigned long long mtu;
// charts
RRDSET *st_bandwidth;
@@ -95,6 +114,11 @@ static struct netdev {
RRDSET *st_fifo;
RRDSET *st_compressed;
RRDSET *st_events;
+ RRDSET *st_speed;
+ RRDSET *st_duplex;
+ RRDSET *st_operstate;
+ RRDSET *st_carrier;
+ RRDSET *st_mtu;
// dimensions
RRDDIM *rd_rbytes;
@@ -115,18 +139,19 @@ static struct netdev {
RRDDIM *rd_tcarrier;
RRDDIM *rd_tcompressed;
- usec_t speed_last_collected_usec;
- usec_t duplex_last_collected_usec;
- usec_t operstate_last_collected_usec;
+ RRDDIM *rd_speed;
+ RRDDIM *rd_duplex;
+ RRDDIM *rd_operstate;
+ RRDDIM *rd_carrier;
+ RRDDIM *rd_mtu;
char *filename_speed;
RRDSETVAR *chart_var_speed;
char *filename_duplex;
- RRDSETVAR *chart_var_duplex;
-
char *filename_operstate;
- RRDSETVAR *chart_var_operstate;
+ char *filename_carrier;
+ char *filename_mtu;
struct netdev *next;
} *netdev_root = NULL, *netdev_last_used = NULL;
@@ -143,6 +168,11 @@ static void netdev_charts_release(struct netdev *d) {
if(d->st_fifo) rrdset_is_obsolete(d->st_fifo);
if(d->st_compressed) rrdset_is_obsolete(d->st_compressed);
if(d->st_events) rrdset_is_obsolete(d->st_events);
+ if(d->st_speed) rrdset_is_obsolete(d->st_speed);
+ if(d->st_duplex) rrdset_is_obsolete(d->st_duplex);
+ if(d->st_operstate) rrdset_is_obsolete(d->st_operstate);
+ if(d->st_carrier) rrdset_is_obsolete(d->st_carrier);
+ if(d->st_mtu) rrdset_is_obsolete(d->st_mtu);
d->st_bandwidth = NULL;
d->st_compressed = NULL;
@@ -151,6 +181,11 @@ static void netdev_charts_release(struct netdev *d) {
d->st_events = NULL;
d->st_fifo = NULL;
d->st_packets = NULL;
+ d->st_speed = NULL;
+ d->st_duplex = NULL;
+ d->st_operstate = NULL;
+ d->st_carrier = NULL;
+ d->st_mtu = NULL;
d->rd_rbytes = NULL;
d->rd_rpackets = NULL;
@@ -170,9 +205,13 @@ static void netdev_charts_release(struct netdev *d) {
d->rd_tcarrier = NULL;
d->rd_tcompressed = NULL;
+ d->rd_speed = NULL;
+ d->rd_duplex = NULL;
+ d->rd_operstate = NULL;
+ d->rd_carrier = NULL;
+ d->rd_mtu = NULL;
+
d->chart_var_speed = NULL;
- d->chart_var_duplex = NULL;
- d->chart_var_operstate = NULL;
}
static void netdev_free_chart_strings(struct netdev *d) {
@@ -183,6 +222,11 @@ static void netdev_free_chart_strings(struct netdev *d) {
freez((void *)d->chart_type_net_events);
freez((void *)d->chart_type_net_fifo);
freez((void *)d->chart_type_net_packets);
+ freez((void *)d->chart_type_net_speed);
+ freez((void *)d->chart_type_net_duplex);
+ freez((void *)d->chart_type_net_operstate);
+ freez((void *)d->chart_type_net_carrier);
+ freez((void *)d->chart_type_net_mtu);
freez((void *)d->chart_id_net_bytes);
freez((void *)d->chart_id_net_compressed);
@@ -191,6 +235,11 @@ static void netdev_free_chart_strings(struct netdev *d) {
freez((void *)d->chart_id_net_events);
freez((void *)d->chart_id_net_fifo);
freez((void *)d->chart_id_net_packets);
+ freez((void *)d->chart_id_net_speed);
+ freez((void *)d->chart_id_net_duplex);
+ freez((void *)d->chart_id_net_operstate);
+ freez((void *)d->chart_id_net_carrier);
+ freez((void *)d->chart_id_net_mtu);
freez((void *)d->chart_family);
}
@@ -204,6 +253,8 @@ static void netdev_free(struct netdev *d) {
freez((void *)d->filename_speed);
freez((void *)d->filename_duplex);
freez((void *)d->filename_operstate);
+ freez((void *)d->filename_carrier);
+ freez((void *)d->filename_mtu);
freez((void *)d);
netdev_added--;
}
@@ -325,6 +376,11 @@ static inline void netdev_rename_cgroup(struct netdev *d, struct netdev_rename *
d->chart_type_net_events = strdupz(buffer);
d->chart_type_net_fifo = strdupz(buffer);
d->chart_type_net_packets = strdupz(buffer);
+ d->chart_type_net_speed = strdupz(buffer);
+ d->chart_type_net_duplex = strdupz(buffer);
+ d->chart_type_net_operstate = strdupz(buffer);
+ d->chart_type_net_carrier = strdupz(buffer);
+ d->chart_type_net_mtu = strdupz(buffer);
snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_%s", r->container_device);
d->chart_id_net_bytes = strdupz(buffer);
@@ -347,6 +403,21 @@ static inline void netdev_rename_cgroup(struct netdev *d, struct netdev_rename *
snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_packets_%s", r->container_device);
d->chart_id_net_packets = strdupz(buffer);
+ snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_speed_%s", r->container_device);
+ d->chart_id_net_speed = strdupz(buffer);
+
+ snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_duplex_%s", r->container_device);
+ d->chart_id_net_duplex = strdupz(buffer);
+
+ snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_operstate_%s", r->container_device);
+ d->chart_id_net_operstate = strdupz(buffer);
+
+ snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_carrier_%s", r->container_device);
+ d->chart_id_net_carrier = strdupz(buffer);
+
+ snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_mtu_%s", r->container_device);
+ d->chart_id_net_mtu = strdupz(buffer);
+
snprintfz(buffer, RRD_ID_LENGTH_MAX, "net %s", r->container_device);
d->chart_family = strdupz(buffer);
@@ -451,6 +522,11 @@ static struct netdev *get_netdev(const char *name) {
d->chart_type_net_events = strdupz("net_events");
d->chart_type_net_fifo = strdupz("net_fifo");
d->chart_type_net_packets = strdupz("net_packets");
+ d->chart_type_net_speed = strdupz("net_speed");
+ d->chart_type_net_duplex = strdupz("net_duplex");
+ d->chart_type_net_operstate = strdupz("net_operstate");
+ d->chart_type_net_carrier = strdupz("net_carrier");
+ d->chart_type_net_mtu = strdupz("net_mtu");
d->chart_id_net_bytes = strdupz(d->name);
d->chart_id_net_compressed = strdupz(d->name);
@@ -459,6 +535,11 @@ static struct netdev *get_netdev(const char *name) {
d->chart_id_net_events = strdupz(d->name);
d->chart_id_net_fifo = strdupz(d->name);
d->chart_id_net_packets = strdupz(d->name);
+ d->chart_id_net_speed = strdupz(d->name);
+ d->chart_id_net_duplex = strdupz(d->name);
+ d->chart_id_net_operstate = strdupz(d->name);
+ d->chart_id_net_carrier = strdupz(d->name);
+ d->chart_id_net_mtu = strdupz(d->name);
d->chart_family = strdupz(d->name);
d->priority = NETDATA_CHART_PRIO_FIRST_NET_IFACE;
@@ -485,14 +566,13 @@ int do_proc_net_dev(int update_every, usec_t dt) {
static procfile *ff = NULL;
static int enable_new_interfaces = -1;
static int do_bandwidth = -1, do_packets = -1, do_errors = -1, do_drops = -1, do_fifo = -1, do_compressed = -1,
- do_events = -1;
+ do_events = -1, do_speed = -1, do_duplex = -1, do_operstate = -1, do_carrier = -1, do_mtu = -1;
static char *path_to_sys_devices_virtual_net = NULL, *path_to_sys_class_net_speed = NULL,
*proc_net_dev_filename = NULL;
static char *path_to_sys_class_net_duplex = NULL;
static char *path_to_sys_class_net_operstate = NULL;
- static long long int dt_to_refresh_speed = 0;
- static long long int dt_to_refresh_duplex = 0;
- static long long int dt_to_refresh_operstate = 0;
+ static char *path_to_sys_class_net_carrier = NULL;
+ static char *path_to_sys_class_net_mtu = NULL;
if(unlikely(enable_new_interfaces == -1)) {
char filename[FILENAME_MAX + 1];
@@ -512,6 +592,12 @@ int do_proc_net_dev(int update_every, usec_t dt) {
snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/class/net/%s/operstate");
path_to_sys_class_net_operstate = config_get(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "path to get net device operstate", filename);
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/class/net/%s/carrier");
+ path_to_sys_class_net_carrier = config_get(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "path to get net device carrier", filename);
+
+ snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/class/net/%s/mtu");
+ path_to_sys_class_net_mtu = config_get(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "path to get net device mtu", filename);
+
enable_new_interfaces = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "enable new interfaces detected at runtime", CONFIG_BOOLEAN_AUTO);
@@ -522,19 +608,13 @@ int do_proc_net_dev(int update_every, usec_t dt) {
do_fifo = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "fifo for all interfaces", CONFIG_BOOLEAN_AUTO);
do_compressed = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "compressed packets for all interfaces", CONFIG_BOOLEAN_AUTO);
do_events = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "frames, collisions, carrier counters for all interfaces", CONFIG_BOOLEAN_AUTO);
+ do_speed = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "speed for all interfaces", CONFIG_BOOLEAN_AUTO);
+ do_duplex = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "duplex for all interfaces", CONFIG_BOOLEAN_AUTO);
+ do_operstate = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "operstate for all interfaces", CONFIG_BOOLEAN_AUTO);
+ do_carrier = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "carrier for all interfaces", CONFIG_BOOLEAN_AUTO);
+ do_mtu = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "mtu for all interfaces", CONFIG_BOOLEAN_AUTO);
disabled_list = simple_pattern_create(config_get(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "disable by default interfaces matching", "lo fireqos* *-ifb"), NULL, SIMPLE_PATTERN_EXACT);
-
- dt_to_refresh_speed = config_get_number(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "refresh interface speed every seconds", 10) * USEC_PER_SEC;
- dt_to_refresh_duplex = config_get_number(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "refresh interface duplex every seconds", 10) * USEC_PER_SEC;
- dt_to_refresh_operstate = config_get_number(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "refresh interface operstate every seconds", 10) * USEC_PER_SEC;
-
- if (dt_to_refresh_operstate < 0)
- dt_to_refresh_operstate = 0;
- if (dt_to_refresh_duplex < 0)
- dt_to_refresh_duplex = 0;
- if (dt_to_refresh_speed < 0)
- dt_to_refresh_speed = 0;
}
if(unlikely(!ff)) {
@@ -595,9 +675,16 @@ int do_proc_net_dev(int update_every, usec_t dt) {
snprintfz(buffer, FILENAME_MAX, path_to_sys_class_net_duplex, d->name);
d->filename_duplex = strdupz(buffer);
}
+
snprintfz(buffer, FILENAME_MAX, path_to_sys_class_net_operstate, d->name);
d->filename_operstate = strdupz(buffer);
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_class_net_carrier, d->name);
+ d->filename_carrier = strdupz(buffer);
+
+ snprintfz(buffer, FILENAME_MAX, path_to_sys_class_net_mtu, d->name);
+ d->filename_mtu = strdupz(buffer);
+
snprintfz(buffer, FILENAME_MAX, "plugin:proc:/proc/net/dev:%s", d->name);
d->enabled = config_get_boolean_ondemand(buffer, "enabled", d->enabled);
d->virtual = config_get_boolean(buffer, "virtual", d->virtual);
@@ -612,6 +699,11 @@ int do_proc_net_dev(int update_every, usec_t dt) {
d->do_fifo = config_get_boolean_ondemand(buffer, "fifo", do_fifo);
d->do_compressed = config_get_boolean_ondemand(buffer, "compressed", do_compressed);
d->do_events = config_get_boolean_ondemand(buffer, "events", do_events);
+ d->do_speed = config_get_boolean_ondemand(buffer, "speed", do_speed);
+ d->do_duplex = config_get_boolean_ondemand(buffer, "duplex", do_duplex);
+ d->do_operstate = config_get_boolean_ondemand(buffer, "operstate", do_operstate);
+ d->do_carrier = config_get_boolean_ondemand(buffer, "carrier", do_carrier);
+ d->do_mtu = config_get_boolean_ondemand(buffer, "mtu", do_mtu);
}
if(unlikely(!d->enabled))
@@ -659,6 +751,55 @@ int do_proc_net_dev(int update_every, usec_t dt) {
d->tcarrier = str2kernel_uint_t(procfile_lineword(ff, l, 15));
}
+ if (d->do_duplex != CONFIG_BOOLEAN_NO && d->filename_duplex) {
+ char buffer[STATE_LENGTH_MAX + 1];
+
+ if (read_file(d->filename_duplex, buffer, STATE_LENGTH_MAX)) {
+ error("Cannot refresh interface %s duplex state by reading '%s'. I will stop updating it.", d->name, d->filename_duplex);
+ freez(d->filename_duplex);
+ d->filename_duplex = NULL;
+ } else {
+ // values can be unknown, half or full -- just check the first letter for speed
+ if (buffer[0] == 'f')
+ d->duplex = 2;
+ else if (buffer[0] == 'h')
+ d->duplex = 1;
+ else
+ d->duplex = 0;
+ }
+ }
+
+ if(d->do_operstate != CONFIG_BOOLEAN_NO && d->filename_operstate) {
+ char buffer[STATE_LENGTH_MAX + 1], *trimmed_buffer;
+
+ if (read_file(d->filename_operstate, buffer, STATE_LENGTH_MAX)) {
+ error(
+ "Cannot refresh %s operstate by reading '%s'. Will not update its status anymore.",
+ d->name, d->filename_operstate);
+ freez(d->filename_operstate);
+ d->filename_operstate = NULL;
+ } else {
+ trimmed_buffer = trim(buffer);
+ d->operstate = get_operstate(trimmed_buffer);
+ }
+ }
+
+ if (d->do_carrier != CONFIG_BOOLEAN_NO && d->filename_carrier) {
+ if (read_single_number_file(d->filename_carrier, &d->carrier)) {
+ error("Cannot refresh interface %s carrier state by reading '%s'. Stop updating it.", d->name, d->filename_carrier);
+ freez(d->filename_carrier);
+ d->filename_carrier = NULL;
+ }
+ }
+
+ if (d->do_mtu != CONFIG_BOOLEAN_NO && d->filename_mtu) {
+ if (read_single_number_file(d->filename_mtu, &d->mtu)) {
+ error("Cannot refresh mtu for interface %s by reading '%s'. Stop updating it.", d->name, d->filename_carrier);
+ freez(d->filename_carrier);
+ d->filename_carrier = NULL;
+ }
+ }
+
//info("PROC_NET_DEV: %s speed %zu, bytes %zu/%zu, packets %zu/%zu/%zu, errors %zu/%zu, drops %zu/%zu, fifo %zu/%zu, compressed %zu/%zu, rframe %zu, tcollisions %zu, tcarrier %zu"
// , d->name, d->speed
// , d->rbytes, d->tbytes
@@ -715,102 +856,179 @@ int do_proc_net_dev(int update_every, usec_t dt) {
// update the interface speed
if(d->filename_speed) {
- d->speed_last_collected_usec += dt;
-
- if(unlikely(d->speed_last_collected_usec >= (usec_t)dt_to_refresh_speed)) {
-
- if(unlikely(!d->chart_var_speed)) {
- d->chart_var_speed = rrdsetvar_custom_chart_variable_create(d->st_bandwidth, "nic_speed_max");
- if(!d->chart_var_speed) {
- error("Cannot create interface %s chart variable 'nic_speed_max'. Will not update its speed anymore.", d->name);
- freez(d->filename_speed);
- d->filename_speed = NULL;
- }
+ if(unlikely(!d->chart_var_speed)) {
+ d->chart_var_speed = rrdsetvar_custom_chart_variable_create(d->st_bandwidth, "nic_speed_max");
+ if(!d->chart_var_speed) {
+ error("Cannot create interface %s chart variable 'nic_speed_max'. Will not update its speed anymore.", d->name);
+ freez(d->filename_speed);
+ d->filename_speed = NULL;
}
+ }
- if(d->filename_speed && d->chart_var_speed) {
- if(read_single_number_file(d->filename_speed, (unsigned long long *) &d->speed)) {
- error("Cannot refresh interface %s speed by reading '%s'. Will not update its speed anymore.", d->name, d->filename_speed);
- freez(d->filename_speed);
- d->filename_speed = NULL;
- }
- else {
- rrdsetvar_custom_chart_variable_set(d->chart_var_speed, (calculated_number) d->speed);
- d->speed_last_collected_usec = 0;
+ if(d->filename_speed && d->chart_var_speed) {
+ if(read_single_number_file(d->filename_speed, (unsigned long long *) &d->speed)) {
+ error("Cannot refresh interface %s speed by reading '%s'. Will not update its speed anymore.", d->name, d->filename_speed);
+ freez(d->filename_speed);
+ d->filename_speed = NULL;
+ }
+ else {
+ rrdsetvar_custom_chart_variable_set(d->chart_var_speed, (calculated_number) d->speed * KILOBITS_IN_A_MEGABIT);
+
+ if(d->do_speed != CONFIG_BOOLEAN_NO) {
+ if(unlikely(!d->st_speed)) {
+ d->st_speed = rrdset_create_localhost(
+ d->chart_type_net_speed
+ , d->chart_id_net_speed
+ , NULL
+ , d->chart_family
+ , "net.speed"
+ , "Interface Speed"
+ , "kilobits/s"
+ , PLUGIN_PROC_NAME
+ , PLUGIN_PROC_MODULE_NETDEV_NAME
+ , d->priority + 7
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_speed, RRDSET_FLAG_DETAIL);
+
+ rrdset_update_labels(d->st_speed, d->chart_labels);
+
+ d->rd_speed = rrddim_add(d->st_speed, "speed", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(d->st_speed);
+
+ rrddim_set_by_pointer(d->st_speed, d->rd_speed, (collected_number)d->speed * KILOBITS_IN_A_MEGABIT);
+ rrdset_done(d->st_speed);
}
}
}
}
+ }
- if (d->filename_duplex) {
- d->duplex_last_collected_usec += dt;
+ // --------------------------------------------------------------------
- if (unlikely(d->duplex_last_collected_usec >= (usec_t)dt_to_refresh_duplex)) {
- if (unlikely(!d->chart_var_duplex)) {
- d->chart_var_duplex = rrdsetvar_custom_chart_variable_create(d->st_bandwidth, "duplex");
- if (!d->chart_var_duplex) {
- error("Cannot create interface %s chart variable 'duplex'. Will not update the duplex status anymore.", d->name);
- freez(d->filename_duplex);
- d->filename_duplex = NULL;
- }
- }
+ if(d->do_duplex != CONFIG_BOOLEAN_NO && d->filename_duplex) {
+ if(unlikely(!d->st_duplex)) {
+ d->st_duplex = rrdset_create_localhost(
+ d->chart_type_net_duplex
+ , d->chart_id_net_duplex
+ , NULL
+ , d->chart_family
+ , "net.duplex"
+ , "Interface Duplex State"
+ , "state"
+ , PLUGIN_PROC_NAME
+ , PLUGIN_PROC_MODULE_NETDEV_NAME
+ , d->priority + 8
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
- if (d->filename_duplex && d->chart_var_duplex) {
- char buffer[32 + 1];
-
- if (read_file(d->filename_duplex, buffer, 32)) {
- error("Cannot refresh interface %s duplex state by reading '%s'. I will stop updating it.", d->name, d->filename_duplex);
- freez(d->filename_duplex);
- d->filename_duplex = NULL;
- } else {
- // values can be unknown, half or full -- just check the first letter for speed
- if (buffer[0] == 'f')
- d->duplex = 2;
- else if (buffer[0] == 'h')
- d->duplex = 1;
- else
- d->duplex = 0;
-
- rrdsetvar_custom_chart_variable_set(d->chart_var_duplex, (calculated_number)d->duplex);
- d->duplex_last_collected_usec = 0;
- }
- }
- }
+ rrdset_flag_set(d->st_duplex, RRDSET_FLAG_DETAIL);
+
+ rrdset_update_labels(d->st_duplex, d->chart_labels);
+
+ d->rd_duplex = rrddim_add(d->st_duplex, "duplex", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
+ else rrdset_next(d->st_duplex);
- if (d->filename_operstate) {
- d->operstate_last_collected_usec += dt;
-
- if (unlikely(d->operstate_last_collected_usec >= (usec_t)dt_to_refresh_operstate)) {
- if (unlikely(!d->chart_var_operstate)) {
- d->chart_var_operstate = rrdsetvar_custom_chart_variable_create(d->st_bandwidth, "operstate");
- if (!d->chart_var_operstate) {
- error(
- "Cannot create interface %s chart variable 'operstate'. I will stop updating it.",
- d->name);
- freez(d->filename_operstate);
- d->filename_operstate = NULL;
- }
- }
+ rrddim_set_by_pointer(d->st_duplex, d->rd_duplex, (collected_number)d->duplex);
+ rrdset_done(d->st_duplex);
+ }
- if (d->filename_operstate && d->chart_var_operstate) {
- char buffer[32 + 1], *trimmed_buffer;
-
- if (read_file(d->filename_operstate, buffer, 32)) {
- error(
- "Cannot refresh %s operstate by reading '%s'. Will not update its status anymore.",
- d->name, d->filename_operstate);
- freez(d->filename_operstate);
- d->filename_operstate = NULL;
- } else {
- trimmed_buffer = trim(buffer);
- d->operstate = get_operstate(trimmed_buffer);
- rrdsetvar_custom_chart_variable_set(d->chart_var_operstate, (calculated_number)d->operstate);
- d->operstate_last_collected_usec = 0;
- }
- }
- }
+ // --------------------------------------------------------------------
+
+ if(d->do_operstate != CONFIG_BOOLEAN_NO && d->filename_operstate) {
+ if(unlikely(!d->st_operstate)) {
+ d->st_operstate = rrdset_create_localhost(
+ d->chart_type_net_operstate
+ , d->chart_id_net_operstate
+ , NULL
+ , d->chart_family
+ , "net.operstate"
+ , "Interface Operational State"
+ , "state"
+ , PLUGIN_PROC_NAME
+ , PLUGIN_PROC_MODULE_NETDEV_NAME
+ , d->priority + 9
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_operstate, RRDSET_FLAG_DETAIL);
+
+ rrdset_update_labels(d->st_operstate, d->chart_labels);
+
+ d->rd_operstate = rrddim_add(d->st_operstate, "state", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(d->st_operstate);
+
+ rrddim_set_by_pointer(d->st_operstate, d->rd_operstate, (collected_number)d->operstate);
+ rrdset_done(d->st_operstate);
+ }
+
+ // --------------------------------------------------------------------
+
+ if(d->do_carrier != CONFIG_BOOLEAN_NO && d->filename_carrier) {
+ if(unlikely(!d->st_carrier)) {
+ d->st_carrier = rrdset_create_localhost(
+ d->chart_type_net_carrier
+ , d->chart_id_net_carrier
+ , NULL
+ , d->chart_family
+ , "net.carrier"
+ , "Inteface Physical Link State"
+ , "state"
+ , PLUGIN_PROC_NAME
+ , PLUGIN_PROC_MODULE_NETDEV_NAME
+ , d->priority + 10
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_carrier, RRDSET_FLAG_DETAIL);
+
+ rrdset_update_labels(d->st_carrier, d->chart_labels);
+
+ d->rd_carrier = rrddim_add(d->st_carrier, "carrier", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
}
+ else rrdset_next(d->st_carrier);
+
+ rrddim_set_by_pointer(d->st_carrier, d->rd_carrier, (collected_number)d->carrier);
+ rrdset_done(d->st_carrier);
+ }
+
+ // --------------------------------------------------------------------
+
+ if(d->do_mtu != CONFIG_BOOLEAN_NO && d->filename_mtu) {
+ if(unlikely(!d->st_mtu)) {
+ d->st_mtu = rrdset_create_localhost(
+ d->chart_type_net_mtu
+ , d->chart_id_net_mtu
+ , NULL
+ , d->chart_family
+ , "net.mtu"
+ , "Interface MTU"
+ , "octets"
+ , PLUGIN_PROC_NAME
+ , PLUGIN_PROC_MODULE_NETDEV_NAME
+ , d->priority + 11
+ , update_every
+ , RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(d->st_mtu, RRDSET_FLAG_DETAIL);
+
+ rrdset_update_labels(d->st_mtu, d->chart_labels);
+
+ d->rd_mtu = rrddim_add(d->st_mtu, "mtu", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(d->st_mtu);
+
+ rrddim_set_by_pointer(d->st_mtu, d->rd_mtu, (collected_number)d->mtu);
+ rrdset_done(d->st_mtu);
}
// --------------------------------------------------------------------
diff --git a/collectors/proc.plugin/proc_self_mountinfo.c b/collectors/proc.plugin/proc_self_mountinfo.c
index 3f17ccce..ca00f8a8 100644
--- a/collectors/proc.plugin/proc_self_mountinfo.c
+++ b/collectors/proc.plugin/proc_self_mountinfo.c
@@ -47,11 +47,17 @@
// find the mount info with the given major:minor
// in the supplied linked list of mountinfo structures
-struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor) {
+struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor, char *device) {
struct mountinfo *mi;
+ uint32_t hash = simple_hash(device);
+
for(mi = root; mi ; mi = mi->next)
- if(unlikely(mi->major == major && mi->minor == minor))
+ if (unlikely(
+ mi->major == major &&
+ mi->minor == minor &&
+ mi->mount_source_name_hash == hash &&
+ !strcmp(mi->mount_source_name, device)))
return mi;
return NULL;
@@ -120,6 +126,7 @@ static void mountinfo_free(struct mountinfo *mi) {
*/
freez(mi->filesystem);
freez(mi->mount_source);
+ freez(mi->mount_source_name);
freez(mi->super_options);
freez(mi);
}
@@ -273,6 +280,9 @@ struct mountinfo *mountinfo_read(int do_statvfs) {
mi->mount_source = strdupz_decoding_octal(procfile_lineword(ff, l, w)); w++;
mi->mount_source_hash = simple_hash(mi->mount_source);
+ mi->mount_source_name = strdupz(basename(mi->mount_source));
+ mi->mount_source_name_hash = simple_hash(mi->mount_source_name);
+
mi->super_options = strdupz(procfile_lineword(ff, l, w)); w++;
if(unlikely(is_read_only(mi->super_options)))
@@ -316,6 +326,9 @@ struct mountinfo *mountinfo_read(int do_statvfs) {
mi->mount_source = NULL;
mi->mount_source_hash = 0;
+ mi->mount_source_name = NULL;
+ mi->mount_source_name_hash = 0;
+
mi->super_options = NULL;
mi->st_dev = 0;
diff --git a/collectors/proc.plugin/proc_self_mountinfo.h b/collectors/proc.plugin/proc_self_mountinfo.h
index 15d63c78..92918a73 100644
--- a/collectors/proc.plugin/proc_self_mountinfo.h
+++ b/collectors/proc.plugin/proc_self_mountinfo.h
@@ -38,6 +38,9 @@ struct mountinfo {
char *mount_source; // mount source: filesystem-specific information or "none".
uint32_t mount_source_hash;
+ char *mount_source_name;
+ uint32_t mount_source_name_hash;
+
char *super_options; // super options: per-superblock options.
uint32_t flags;
@@ -47,11 +50,11 @@ struct mountinfo {
struct mountinfo *next;
};
-extern struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor);
+extern struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor, char *device);
extern struct mountinfo *mountinfo_find_by_filesystem_mount_source(struct mountinfo *root, const char *filesystem, const char *mount_source);
extern struct mountinfo *mountinfo_find_by_filesystem_super_option(struct mountinfo *root, const char *filesystem, const char *super_options);
extern void mountinfo_free_all(struct mountinfo *mi);
extern struct mountinfo *mountinfo_read(int do_statvfs);
-#endif /* NETDATA_PROC_SELF_MOUNTINFO_H */ \ No newline at end of file
+#endif /* NETDATA_PROC_SELF_MOUNTINFO_H */