@cryptotaxi247 / netdata-1 / commits / 46af7de42

Add carrier and mtu charts for network interfaces (#10866)

Co-authored-by: Ilya Mashchenko <ilya@netdata.cloud>

Vladimir Kobal committed Mar 26, 2021 at 17:49 UTC 46af7de4252a139c1f4ba3369f0b2f76194657e1
2 files changed +140 -2
collectors/proc.plugin/proc_net_dev.c
+136 -2
@@ -46,6 +46,8 @@ static struct netdev {
46 int do_speed;
47 int do_duplex;
48 int do_operstate;
49 + int do_carrier;
50 + int do_mtu;
51
52 const char *chart_type_net_bytes;
53 const char *chart_type_net_packets;
@@ -57,6 +59,8 @@ static struct netdev {
59 const char *chart_type_net_speed;
60 const char *chart_type_net_duplex;
61 const char *chart_type_net_operstate;
62 + const char *chart_type_net_carrier;
63 + const char *chart_type_net_mtu;
64
65 const char *chart_id_net_bytes;
66 const char *chart_id_net_packets;
@@ -68,6 +72,8 @@ static struct netdev {
72 const char *chart_id_net_speed;
73 const char *chart_id_net_duplex;
74 const char *chart_id_net_operstate;
75 + const char *chart_id_net_carrier;
76 + const char *chart_id_net_mtu;
77
78 const char *chart_family;
79
@@ -97,6 +103,8 @@ static struct netdev {
103 kernel_uint_t speed;
104 kernel_uint_t duplex;
105 kernel_uint_t operstate;
106 + unsigned long long carrier;
107 + unsigned long long mtu;
108
109 // charts
110 RRDSET *st_bandwidth;
@@ -109,6 +117,8 @@ static struct netdev {
117 RRDSET *st_speed;
118 RRDSET *st_duplex;
119 RRDSET *st_operstate;
120 + RRDSET *st_carrier;
121 + RRDSET *st_mtu;
122
123 // dimensions
124 RRDDIM *rd_rbytes;
@@ -132,13 +142,16 @@ static struct netdev {
142 RRDDIM *rd_speed;
143 RRDDIM *rd_duplex;
144 RRDDIM *rd_operstate;
145 + RRDDIM *rd_carrier;
146 + RRDDIM *rd_mtu;
147
148 char *filename_speed;
149 RRDSETVAR *chart_var_speed;
150
151 char *filename_duplex;
140 -
152 char *filename_operstate;
153 + char *filename_carrier;
154 + char *filename_mtu;
155
156 struct netdev *next;
157 } *netdev_root = NULL, *netdev_last_used = NULL;
@@ -158,6 +171,8 @@ static void netdev_charts_release(struct netdev *d) {
171 if(d->st_speed) rrdset_is_obsolete(d->st_speed);
172 if(d->st_duplex) rrdset_is_obsolete(d->st_duplex);
173 if(d->st_operstate) rrdset_is_obsolete(d->st_operstate);
174 + if(d->st_carrier) rrdset_is_obsolete(d->st_carrier);
175 + if(d->st_mtu) rrdset_is_obsolete(d->st_mtu);
176
177 d->st_bandwidth = NULL;
178 d->st_compressed = NULL;
@@ -169,6 +184,8 @@ static void netdev_charts_release(struct netdev *d) {
184 d->st_speed = NULL;
185 d->st_duplex = NULL;
186 d->st_operstate = NULL;
187 + d->st_carrier = NULL;
188 + d->st_mtu = NULL;
189
190 d->rd_rbytes = NULL;
191 d->rd_rpackets = NULL;
@@ -191,6 +208,8 @@ static void netdev_charts_release(struct netdev *d) {
208 d->rd_speed = NULL;
209 d->rd_duplex = NULL;
210 d->rd_operstate = NULL;
211 + d->rd_carrier = NULL;
212 + d->rd_mtu = NULL;
213
214 d->chart_var_speed = NULL;
215 }
@@ -206,6 +225,8 @@ static void netdev_free_chart_strings(struct netdev *d) {
225 freez((void *)d->chart_type_net_speed);
226 freez((void *)d->chart_type_net_duplex);
227 freez((void *)d->chart_type_net_operstate);
228 + freez((void *)d->chart_type_net_carrier);
229 + freez((void *)d->chart_type_net_mtu);
230
231 freez((void *)d->chart_id_net_bytes);
232 freez((void *)d->chart_id_net_compressed);
@@ -217,6 +238,8 @@ static void netdev_free_chart_strings(struct netdev *d) {
238 freez((void *)d->chart_id_net_speed);
239 freez((void *)d->chart_id_net_duplex);
240 freez((void *)d->chart_id_net_operstate);
241 + freez((void *)d->chart_id_net_carrier);
242 + freez((void *)d->chart_id_net_mtu);
243
244 freez((void *)d->chart_family);
245 }
@@ -230,6 +253,8 @@ static void netdev_free(struct netdev *d) {
253 freez((void *)d->filename_speed);
254 freez((void *)d->filename_duplex);
255 freez((void *)d->filename_operstate);
256 + freez((void *)d->filename_carrier);
257 + freez((void *)d->filename_mtu);
258 freez((void *)d);
259 netdev_added--;
260 }
@@ -354,6 +379,8 @@ static inline void netdev_rename_cgroup(struct netdev *d, struct netdev_rename *
379 d->chart_type_net_speed = strdupz(buffer);
380 d->chart_type_net_duplex = strdupz(buffer);
381 d->chart_type_net_operstate = strdupz(buffer);
382 + d->chart_type_net_carrier = strdupz(buffer);
383 + d->chart_type_net_mtu = strdupz(buffer);
384
385 snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_%s", r->container_device);
386 d->chart_id_net_bytes = strdupz(buffer);
@@ -385,6 +412,12 @@ static inline void netdev_rename_cgroup(struct netdev *d, struct netdev_rename *
412 snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_operstate_%s", r->container_device);
413 d->chart_id_net_operstate = strdupz(buffer);
414
415 + snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_carrier_%s", r->container_device);
416 + d->chart_id_net_carrier = strdupz(buffer);
417 +
418 + snprintfz(buffer, RRD_ID_LENGTH_MAX, "net_mtu_%s", r->container_device);
419 + d->chart_id_net_mtu = strdupz(buffer);
420 +
421 snprintfz(buffer, RRD_ID_LENGTH_MAX, "net %s", r->container_device);
422 d->chart_family = strdupz(buffer);
423
@@ -492,6 +525,8 @@ static struct netdev *get_netdev(const char *name) {
525 d->chart_type_net_speed = strdupz("net_speed");
526 d->chart_type_net_duplex = strdupz("net_duplex");
527 d->chart_type_net_operstate = strdupz("net_operstate");
528 + d->chart_type_net_carrier = strdupz("net_carrier");
529 + d->chart_type_net_mtu = strdupz("net_mtu");
530
531 d->chart_id_net_bytes = strdupz(d->name);
532 d->chart_id_net_compressed = strdupz(d->name);
@@ -503,6 +538,8 @@ static struct netdev *get_netdev(const char *name) {
538 d->chart_id_net_speed = strdupz(d->name);
539 d->chart_id_net_duplex = strdupz(d->name);
540 d->chart_id_net_operstate = strdupz(d->name);
541 + d->chart_id_net_carrier = strdupz(d->name);
542 + d->chart_id_net_mtu = strdupz(d->name);
543
544 d->chart_family = strdupz(d->name);
545 d->priority = NETDATA_CHART_PRIO_FIRST_NET_IFACE;
@@ -529,11 +566,13 @@ int do_proc_net_dev(int update_every, usec_t dt) {
566 static procfile *ff = NULL;
567 static int enable_new_interfaces = -1;
568 static int do_bandwidth = -1, do_packets = -1, do_errors = -1, do_drops = -1, do_fifo = -1, do_compressed = -1,
532 - do_events = -1, do_speed = -1, do_duplex = -1, do_operstate = -1;
569 + do_events = -1, do_speed = -1, do_duplex = -1, do_operstate = -1, do_carrier = -1, do_mtu = -1;
570 static char *path_to_sys_devices_virtual_net = NULL, *path_to_sys_class_net_speed = NULL,
571 *proc_net_dev_filename = NULL;
572 static char *path_to_sys_class_net_duplex = NULL;
573 static char *path_to_sys_class_net_operstate = NULL;
574 + static char *path_to_sys_class_net_carrier = NULL;
575 + static char *path_to_sys_class_net_mtu = NULL;
576
577 if(unlikely(enable_new_interfaces == -1)) {
578 char filename[FILENAME_MAX + 1];
@@ -553,6 +592,12 @@ int do_proc_net_dev(int update_every, usec_t dt) {
592 snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/class/net/%s/operstate");
593 path_to_sys_class_net_operstate = config_get(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "path to get net device operstate", filename);
594
595 + snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/class/net/%s/carrier");
596 + path_to_sys_class_net_carrier = config_get(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "path to get net device carrier", filename);
597 +
598 + snprintfz(filename, FILENAME_MAX, "%s%s", netdata_configured_host_prefix, "/sys/class/net/%s/mtu");
599 + path_to_sys_class_net_mtu = config_get(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "path to get net device mtu", filename);
600 +
601
602 enable_new_interfaces = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "enable new interfaces detected at runtime", CONFIG_BOOLEAN_AUTO);
603
@@ -566,6 +611,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
611 do_speed = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "speed for all interfaces", CONFIG_BOOLEAN_AUTO);
612 do_duplex = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "duplex for all interfaces", CONFIG_BOOLEAN_AUTO);
613 do_operstate = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "operstate for all interfaces", CONFIG_BOOLEAN_AUTO);
614 + do_carrier = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "carrier for all interfaces", CONFIG_BOOLEAN_AUTO);
615 + do_mtu = config_get_boolean_ondemand(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "mtu for all interfaces", CONFIG_BOOLEAN_AUTO);
616
617 disabled_list = simple_pattern_create(config_get(CONFIG_SECTION_PLUGIN_PROC_NETDEV, "disable by default interfaces matching", "lo fireqos* *-ifb"), NULL, SIMPLE_PATTERN_EXACT);
618 }
@@ -628,9 +675,16 @@ int do_proc_net_dev(int update_every, usec_t dt) {
675 snprintfz(buffer, FILENAME_MAX, path_to_sys_class_net_duplex, d->name);
676 d->filename_duplex = strdupz(buffer);
677 }
678 +
679 snprintfz(buffer, FILENAME_MAX, path_to_sys_class_net_operstate, d->name);
680 d->filename_operstate = strdupz(buffer);
681
682 + snprintfz(buffer, FILENAME_MAX, path_to_sys_class_net_carrier, d->name);
683 + d->filename_carrier = strdupz(buffer);
684 +
685 + snprintfz(buffer, FILENAME_MAX, path_to_sys_class_net_mtu, d->name);
686 + d->filename_mtu = strdupz(buffer);
687 +
688 snprintfz(buffer, FILENAME_MAX, "plugin:proc:/proc/net/dev:%s", d->name);
689 d->enabled = config_get_boolean_ondemand(buffer, "enabled", d->enabled);
690 d->virtual = config_get_boolean(buffer, "virtual", d->virtual);
@@ -648,6 +702,8 @@ int do_proc_net_dev(int update_every, usec_t dt) {
702 d->do_speed = config_get_boolean_ondemand(buffer, "speed", do_speed);
703 d->do_duplex = config_get_boolean_ondemand(buffer, "duplex", do_duplex);
704 d->do_operstate = config_get_boolean_ondemand(buffer, "operstate", do_operstate);
705 + d->do_carrier = config_get_boolean_ondemand(buffer, "carrier", do_carrier);
706 + d->do_mtu = config_get_boolean_ondemand(buffer, "mtu", do_mtu);
707 }
708
709 if(unlikely(!d->enabled))
@@ -728,6 +784,22 @@ int do_proc_net_dev(int update_every, usec_t dt) {
784 }
785 }
786
787 + if (d->do_carrier != CONFIG_BOOLEAN_NO && d->filename_carrier) {
788 + if (read_single_number_file(d->filename_carrier, &d->carrier)) {
789 + error("Cannot refresh interface %s carrier state by reading '%s'. Stop updating it.", d->name, d->filename_carrier);
790 + freez(d->filename_carrier);
791 + d->filename_carrier = NULL;
792 + }
793 + }
794 +
795 + if (d->do_mtu != CONFIG_BOOLEAN_NO && d->filename_mtu) {
796 + if (read_single_number_file(d->filename_mtu, &d->mtu)) {
797 + error("Cannot refresh mtu for interface %s by reading '%s'. Stop updating it.", d->name, d->filename_carrier);
798 + freez(d->filename_carrier);
799 + d->filename_carrier = NULL;
800 + }
801 + }
802 +
803 //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"
804 // , d->name, d->speed
805 // , d->rbytes, d->tbytes
@@ -899,6 +971,68 @@ int do_proc_net_dev(int update_every, usec_t dt) {
971
972 // --------------------------------------------------------------------
973
974 + if(d->do_carrier != CONFIG_BOOLEAN_NO && d->filename_carrier) {
975 + if(unlikely(!d->st_carrier)) {
976 + d->st_carrier = rrdset_create_localhost(
977 + d->chart_type_net_carrier
978 + , d->chart_id_net_carrier
979 + , NULL
980 + , d->chart_family
981 + , "net.carrier"
982 + , "Inteface Physical Link State"
983 + , "state"
984 + , PLUGIN_PROC_NAME
985 + , PLUGIN_PROC_MODULE_NETDEV_NAME
986 + , d->priority + 10
987 + , update_every
988 + , RRDSET_TYPE_LINE
989 + );
990 +
991 + rrdset_flag_set(d->st_carrier, RRDSET_FLAG_DETAIL);
992 +
993 + rrdset_update_labels(d->st_carrier, d->chart_labels);
994 +
995 + d->rd_carrier = rrddim_add(d->st_carrier, "carrier", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
996 + }
997 + else rrdset_next(d->st_carrier);
998 +
999 + rrddim_set_by_pointer(d->st_carrier, d->rd_carrier, (collected_number)d->carrier);
1000 + rrdset_done(d->st_carrier);
1001 + }
1002 +
1003 + // --------------------------------------------------------------------
1004 +
1005 + if(d->do_mtu != CONFIG_BOOLEAN_NO && d->filename_mtu) {
1006 + if(unlikely(!d->st_mtu)) {
1007 + d->st_mtu = rrdset_create_localhost(
1008 + d->chart_type_net_mtu
1009 + , d->chart_id_net_mtu
1010 + , NULL
1011 + , d->chart_family
1012 + , "net.mtu"
1013 + , "Interface MTU"
1014 + , "octets"
1015 + , PLUGIN_PROC_NAME
1016 + , PLUGIN_PROC_MODULE_NETDEV_NAME
1017 + , d->priority + 11
1018 + , update_every
1019 + , RRDSET_TYPE_LINE
1020 + );
1021 +
1022 + rrdset_flag_set(d->st_mtu, RRDSET_FLAG_DETAIL);
1023 +
1024 + rrdset_update_labels(d->st_mtu, d->chart_labels);
1025 +
1026 + d->rd_mtu = rrddim_add(d->st_mtu, "mtu", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
1027 + }
1028 + else rrdset_next(d->st_mtu);
1029 +
1030 + rrddim_set_by_pointer(d->st_mtu, d->rd_mtu, (collected_number)d->mtu);
1031 + rrdset_done(d->st_mtu);
1032 + }
1033 +
1034 + // --------------------------------------------------------------------
1035 +
1036 if(unlikely(d->do_packets == CONFIG_BOOLEAN_AUTO &&
1037 (d->rpackets || d->tpackets || d->rmulticast || netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES)))
1038 d->do_packets = CONFIG_BOOLEAN_YES;
web/gui/dashboard_info.js
+4
@@ -1065,6 +1065,10 @@ netdataDashboard.context = {
1065 info: 'State map: 0 - unknown, 1 - notpresent, 2 - down, 3 - lowerlayerdown, 4 - testing, 5 - dormant, 6 - up'
1066 },
1067
1068 + 'net.carrier': {
1069 + info: 'State map: 0 - down, 1 - up'
1070 + },
1071 +
1072 // ------------------------------------------------------------------------
1073 // IP
1074