diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-03-31 12:59:21 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-03-31 12:59:21 +0000 |
commit | bb8713bbc1c4594366fc735c04910edbf4c61aab (patch) | |
tree | d7da56c0b89aa371dd8ad986995dd145fdf6670a /collectors/proc.plugin | |
parent | Releasing debian version 1.29.3-4. (diff) | |
download | netdata-bb8713bbc1c4594366fc735c04910edbf4c61aab.tar.xz netdata-bb8713bbc1c4594366fc735c04910edbf4c61aab.zip |
Merging upstream version 1.30.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'collectors/proc.plugin')
-rw-r--r-- | collectors/proc.plugin/proc_diskstats.c | 64 | ||||
-rw-r--r-- | collectors/proc.plugin/proc_net_dev.c | 430 | ||||
-rw-r--r-- | collectors/proc.plugin/proc_self_mountinfo.c | 17 | ||||
-rw-r--r-- | collectors/proc.plugin/proc_self_mountinfo.h | 7 |
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 */ |