@cryptotaxi247 / netdata-1 / commits / 9b25da542

Windows Alerts Improvements (#18785)

* add network interface speed chart and variables * enable traffic overflow alerts on windows * enabled interface drops and errors; enabled alert packet storm * added interface queue length * added network interfaces offloading technologies

Costa Tsaousis committed Oct 15, 2024 at 20:01 UTC 9b25da542d5a9498533ae960edf96140723c0baf
6 files changed +393 -17
src/collectors/proc.plugin/proc_net_dev.c
+2
@@ -252,6 +252,8 @@ static struct netdev {
252 // ----------------------------------------------------------------------------
253
254 static void netdev_charts_release(struct netdev *d) {
255 + rrdvar_chart_variable_release(d->st_bandwidth, d->chart_var_speed);
256 +
257 if(d->st_bandwidth) rrdset_is_obsolete___safe_from_collector_thread(d->st_bandwidth);
258 if(d->st_packets) rrdset_is_obsolete___safe_from_collector_thread(d->st_packets);
259 if(d->st_errors) rrdset_is_obsolete___safe_from_collector_thread(d->st_errors);
src/collectors/windows.plugin/perflib-network.c
+366 -10
@@ -486,6 +486,7 @@ static bool do_network_protocol(PERF_DATA_BLOCK *pDataBlock, int update_every, s
486 // network interfaces
487
488 struct network_interface {
489 + usec_t last_collected;
490 bool collected_metadata;
491
492 struct {
@@ -498,6 +499,8 @@ struct network_interface {
499 } packets;
500
501 struct {
502 + const RRDVAR_ACQUIRED *chart_var_speed;
503 +
504 COUNTER_DATA received;
505 COUNTER_DATA sent;
506
@@ -505,16 +508,96 @@ struct network_interface {
508 RRDDIM *rd_received;
509 RRDDIM *rd_sent;
510 } traffic;
511 +
512 + struct {
513 + COUNTER_DATA current_bandwidth;
514 + RRDSET *st;
515 + RRDDIM *rd;
516 + } speed;
517 +
518 + struct {
519 + COUNTER_DATA received;
520 + COUNTER_DATA outbound;
521 +
522 + RRDSET *st;
523 + RRDDIM *rd_received;
524 + RRDDIM *rd_outbound;
525 + } discards;
526 +
527 + struct {
528 + COUNTER_DATA received;
529 + COUNTER_DATA outbound;
530 +
531 + RRDSET *st;
532 + RRDDIM *rd_received;
533 + RRDDIM *rd_outbound;
534 + } errors;
535 +
536 + struct {
537 + COUNTER_DATA length;
538 + RRDSET *st;
539 + RRDDIM *rd;
540 + } queue;
541 +
542 + struct {
543 + COUNTER_DATA connections;
544 + RRDSET *st;
545 + RRDDIM *rd;
546 + } chimney;
547 +
548 + struct {
549 + COUNTER_DATA connections;
550 + COUNTER_DATA packets;
551 + COUNTER_DATA exceptions;
552 + COUNTER_DATA average_packet_size;
553 +
554 + RRDSET *st_connections;
555 + RRDDIM *rd_connections;
556 +
557 + RRDSET *st_packets;
558 + RRDDIM *rd_packets;
559 +
560 + RRDSET *st_exceptions;
561 + RRDDIM *rd_exceptions;
562 +
563 + RRDSET *st_average_packet_size;
564 + RRDDIM *rd_average_packet_size;
565 + } rsc;
566 };
567
568 static DICTIONARY *physical_interfaces = NULL, *virtual_interfaces = NULL;
569
512 -static void network_interface_init(struct network_interface *ni) {
513 - ni->packets.received.key = "Packets Received/sec";
514 - ni->packets.sent.key = "Packets Sent/sec";
570 +static void network_interface_init(struct network_interface *d) {
571 + d->packets.received.key = "Packets Received/sec";
572 + d->packets.sent.key = "Packets Sent/sec";
573 + d->traffic.received.key = "Bytes Received/sec";
574 + d->traffic.sent.key = "Bytes Sent/sec";
575 + d->speed.current_bandwidth.key = "Current Bandwidth";
576 + d->discards.received.key = "Packets Received Discarded";
577 + d->discards.outbound.key = "Packets Outbound Discarded";
578 + d->errors.received.key = "Packets Received Errors";
579 + d->errors.outbound.key = "Packets Outbound Errors";
580 + d->queue.length.key = "Output Queue Length";
581 + d->chimney.connections.key = "Offloaded Connections";
582 + d->rsc.connections.key = "TCP Active RSC Connections";
583 + d->rsc.packets.key = "TCP RSC Coalesced Packets/sec";
584 + d->rsc.exceptions.key = "TCP RSC Exceptions/sec";
585 + d->rsc.average_packet_size.key = "TCP RSC Average Packet Size";
586 +}
587
516 - ni->traffic.received.key = "Bytes Received/sec";
517 - ni->traffic.sent.key = "Bytes Sent/sec";
588 +static void network_interface_cleanup(struct network_interface *d) {
589 + rrdvar_chart_variable_release(d->traffic.st, d->traffic.chart_var_speed);
590 + rrdset_is_obsolete___safe_from_collector_thread(d->packets.st);
591 + rrdset_is_obsolete___safe_from_collector_thread(d->traffic.st);
592 + rrdset_is_obsolete___safe_from_collector_thread(d->speed.st);
593 + rrdset_is_obsolete___safe_from_collector_thread(d->discards.st);
594 + rrdset_is_obsolete___safe_from_collector_thread(d->errors.st);
595 + rrdset_is_obsolete___safe_from_collector_thread(d->queue.st);
596 + rrdset_is_obsolete___safe_from_collector_thread(d->chimney.st);
597 + rrdset_is_obsolete___safe_from_collector_thread(d->rsc.st_connections);
598 + rrdset_is_obsolete___safe_from_collector_thread(d->rsc.st_packets);
599 + rrdset_is_obsolete___safe_from_collector_thread(d->rsc.st_exceptions);
600 + rrdset_is_obsolete___safe_from_collector_thread(d->rsc.st_average_packet_size);
601 }
602
603 void dict_interface_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
@@ -543,8 +626,8 @@ static bool is_physical_interface(const char *name) {
626 return d ? true : false;
627 }
628
546 -static bool do_network_interface(PERF_DATA_BLOCK *pDataBlock, int update_every, bool physical) {
547 - DICTIONARY *dict = physical_interfaces;
629 +static bool do_network_interface(PERF_DATA_BLOCK *pDataBlock, int update_every, bool physical, usec_t now_ut) {
630 + DICTIONARY *dict = physical ? physical_interfaces : virtual_interfaces;
631
632 PERF_OBJECT_TYPE *pObjectType = perflibFindObjectTypeByName(pDataBlock, physical ? "Network Interface" : "Network Adapter");
633 if(!pObjectType) return false;
@@ -567,6 +650,7 @@ static bool do_network_interface(PERF_DATA_BLOCK *pDataBlock, int update_every,
650 continue;
651
652 struct network_interface *d = dictionary_set(dict, windows_shared_buffer, NULL, sizeof(*d));
653 + d->last_collected = now_ut;
654
655 if(!d->collected_metadata) {
656 // TODO - get metadata about the network interface
@@ -577,7 +661,7 @@ static bool do_network_interface(PERF_DATA_BLOCK *pDataBlock, int update_every,
661 perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->traffic.sent)) {
662
663 if(d->traffic.received.current.Data == 0 && d->traffic.sent.current.Data == 0)
580 - // this interface has not received or sent any traffic
664 + // this interface has not received or sent any traffic yet
665 continue;
666
667 if (unlikely(!d->traffic.st)) {
@@ -601,6 +685,9 @@ static bool do_network_interface(PERF_DATA_BLOCK *pDataBlock, int update_every,
685
686 d->traffic.rd_received = rrddim_add(d->traffic.st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
687 d->traffic.rd_sent = rrddim_add(d->traffic.st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
688 +
689 + d->traffic.chart_var_speed = rrdvar_chart_variable_add_and_acquire(d->traffic.st, "nic_speed_max");
690 + rrdvar_chart_variable_set(d->traffic.st, d->traffic.chart_var_speed, NAN);
691 }
692
693 total_received += d->traffic.received.current.Data;
@@ -641,6 +728,261 @@ static bool do_network_interface(PERF_DATA_BLOCK *pDataBlock, int update_every,
728 rrddim_set_by_pointer(d->packets.st, d->packets.rd_sent, (collected_number)d->packets.sent.current.Data);
729 rrdset_done(d->packets.st);
730 }
731 +
732 + if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->speed.current_bandwidth)) {
733 + if(unlikely(!d->speed.st)) {
734 + d->speed.st = rrdset_create_localhost(
735 + "net_speed"
736 + , windows_shared_buffer
737 + , NULL
738 + , windows_shared_buffer
739 + , "net.speed"
740 + , "Interface Speed"
741 + , "kilobits/s"
742 + , PLUGIN_WINDOWS_NAME
743 + , "PerflibNetwork"
744 + , NETDATA_CHART_PRIO_FIRST_NET_IFACE + 10
745 + , update_every
746 + , RRDSET_TYPE_LINE
747 + );
748 +
749 + rrdset_flag_set(d->speed.st, RRDSET_FLAG_DETAIL);
750 +
751 + add_interface_labels(d->traffic.st, windows_shared_buffer, physical);
752 +
753 + d->speed.rd = rrddim_add(d->speed.st, "speed", NULL, 1, BITS_IN_A_KILOBIT, RRD_ALGORITHM_ABSOLUTE);
754 + }
755 +
756 + rrddim_set_by_pointer(d->speed.st, d->speed.rd, (collected_number)d->speed.current_bandwidth.current.Data);
757 + rrdset_done(d->speed.st);
758 +
759 + rrdvar_chart_variable_set(d->traffic.st, d->traffic.chart_var_speed,
760 + (NETDATA_DOUBLE)d->speed.current_bandwidth.current.Data / BITS_IN_A_KILOBIT);
761 + }
762 +
763 + if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->errors.received) &&
764 + perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->errors.outbound)) {
765 +
766 + if (unlikely(!d->errors.st)) {
767 + d->errors.st = rrdset_create_localhost(
768 + "net_errors",
769 + windows_shared_buffer,
770 + NULL,
771 + windows_shared_buffer,
772 + "net.errors",
773 + "Interface Errors",
774 + "errors/s",
775 + PLUGIN_WINDOWS_NAME,
776 + "PerflibNetwork",
777 + NETDATA_CHART_PRIO_FIRST_NET_IFACE + 3,
778 + update_every,
779 + RRDSET_TYPE_LINE);
780 +
781 + rrdset_flag_set(d->errors.st, RRDSET_FLAG_DETAIL);
782 +
783 + add_interface_labels(d->errors.st, windows_shared_buffer, physical);
784 +
785 + d->errors.rd_received = rrddim_add(d->errors.st, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
786 + d->errors.rd_outbound = rrddim_add(d->errors.st, "outbound", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
787 + }
788 +
789 + rrddim_set_by_pointer(d->errors.st, d->errors.rd_received, (collected_number)d->errors.received.current.Data);
790 + rrddim_set_by_pointer(d->errors.st, d->errors.rd_outbound, (collected_number)d->errors.outbound.current.Data);
791 + rrdset_done(d->errors.st);
792 + }
793 +
794 + if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->discards.received) &&
795 + perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->discards.outbound)) {
796 +
797 + if (unlikely(!d->discards.st)) {
798 + d->discards.st = rrdset_create_localhost(
799 + "net_drops",
800 + windows_shared_buffer,
801 + NULL,
802 + windows_shared_buffer,
803 + "net.drops",
804 + "Interface Drops",
805 + "drops/s",
806 + PLUGIN_WINDOWS_NAME,
807 + "PerflibNetwork",
808 + NETDATA_CHART_PRIO_FIRST_NET_IFACE + 4,
809 + update_every,
810 + RRDSET_TYPE_LINE);
811 +
812 + rrdset_flag_set(d->discards.st, RRDSET_FLAG_DETAIL);
813 +
814 + add_interface_labels(d->discards.st, windows_shared_buffer, physical);
815 +
816 + d->discards.rd_received = rrddim_add(d->discards.st, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
817 + d->discards.rd_outbound = rrddim_add(d->discards.st, "outbound", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
818 + }
819 +
820 + rrddim_set_by_pointer(d->discards.st, d->discards.rd_received, (collected_number)d->discards.received.current.Data);
821 + rrddim_set_by_pointer(d->discards.st, d->discards.rd_outbound, (collected_number)d->discards.outbound.current.Data);
822 + rrdset_done(d->discards.st);
823 + }
824 +
825 + if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->queue.length)) {
826 + if (unlikely(!d->queue.st)) {
827 + d->queue.st = rrdset_create_localhost(
828 + "net_queue_length",
829 + windows_shared_buffer,
830 + NULL,
831 + windows_shared_buffer,
832 + "net.queue_length",
833 + "Interface Output Queue Length",
834 + "packets",
835 + PLUGIN_WINDOWS_NAME,
836 + "PerflibNetwork",
837 + NETDATA_CHART_PRIO_FIRST_NET_IFACE + 5,
838 + update_every,
839 + RRDSET_TYPE_LINE);
840 +
841 + rrdset_flag_set(d->queue.st, RRDSET_FLAG_DETAIL);
842 +
843 + add_interface_labels(d->queue.st, windows_shared_buffer, physical);
844 +
845 + d->queue.rd = rrddim_add(d->queue.st, "length", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
846 + }
847 +
848 + rrddim_set_by_pointer(d->queue.st, d->queue.rd, (collected_number)d->queue.length.current.Data);
849 + rrdset_done(d->queue.st);
850 + }
851 +
852 + if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->rsc.connections)) {
853 + if (unlikely(!d->rsc.st_connections)) {
854 + d->rsc.st_connections = rrdset_create_localhost(
855 + "net_rsc_connections",
856 + windows_shared_buffer,
857 + NULL,
858 + windows_shared_buffer,
859 + "net.rsc_connections",
860 + "Active TCP Connections Offloaded by RSC",
861 + "connections",
862 + PLUGIN_WINDOWS_NAME,
863 + "PerflibNetwork",
864 + NETDATA_CHART_PRIO_FIRST_NET_IFACE + 6,
865 + update_every,
866 + RRDSET_TYPE_LINE);
867 +
868 + rrdset_flag_set(d->rsc.st_connections, RRDSET_FLAG_DETAIL);
869 +
870 + add_interface_labels(d->rsc.st_connections, windows_shared_buffer, physical);
871 +
872 + d->rsc.rd_connections = rrddim_add(d->rsc.st_connections, "connections", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
873 + }
874 +
875 + rrddim_set_by_pointer(d->rsc.st_connections, d->rsc.rd_connections, (collected_number)d->rsc.connections.current.Data);
876 + rrdset_done(d->rsc.st_connections);
877 + }
878 +
879 + if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->rsc.packets)) {
880 + if (unlikely(!d->rsc.st_packets)) {
881 + d->rsc.st_packets = rrdset_create_localhost(
882 + "net_rsc_packets",
883 + windows_shared_buffer,
884 + NULL,
885 + windows_shared_buffer,
886 + "net.rsc_packets",
887 + "TCP RSC Coalesced Packets",
888 + "packets/s",
889 + PLUGIN_WINDOWS_NAME,
890 + "PerflibNetwork",
891 + NETDATA_CHART_PRIO_FIRST_NET_IFACE + 7,
892 + update_every,
893 + RRDSET_TYPE_LINE);
894 +
895 + rrdset_flag_set(d->rsc.st_packets, RRDSET_FLAG_DETAIL);
896 +
897 + add_interface_labels(d->rsc.st_packets, windows_shared_buffer, physical);
898 +
899 + d->rsc.rd_packets = rrddim_add(d->rsc.st_packets, "packets", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
900 + }
901 +
902 + rrddim_set_by_pointer(d->rsc.st_packets, d->rsc.rd_packets, (collected_number)d->rsc.packets.current.Data);
903 + rrdset_done(d->rsc.st_packets);
904 + }
905 +
906 + if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->rsc.exceptions)) {
907 + if (unlikely(!d->rsc.st_exceptions)) {
908 + d->rsc.st_exceptions = rrdset_create_localhost(
909 + "net_rsc_exceptions",
910 + windows_shared_buffer,
911 + NULL,
912 + windows_shared_buffer,
913 + "net.rsc_exceptions",
914 + "TCP RSC Exceptions",
915 + "exceptions/s",
916 + PLUGIN_WINDOWS_NAME,
917 + "PerflibNetwork",
918 + NETDATA_CHART_PRIO_FIRST_NET_IFACE + 8,
919 + update_every,
920 + RRDSET_TYPE_LINE);
921 +
922 + rrdset_flag_set(d->rsc.st_exceptions, RRDSET_FLAG_DETAIL);
923 +
924 + add_interface_labels(d->rsc.st_exceptions, windows_shared_buffer, physical);
925 +
926 + d->rsc.rd_exceptions = rrddim_add(d->rsc.st_exceptions, "exceptions", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
927 + }
928 +
929 + rrddim_set_by_pointer(d->rsc.st_exceptions, d->rsc.rd_exceptions, (collected_number)d->rsc.exceptions.current.Data);
930 + rrdset_done(d->rsc.st_exceptions);
931 + }
932 +
933 + if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->rsc.average_packet_size)) {
934 + if (unlikely(!d->rsc.st_average_packet_size)) {
935 + d->rsc.st_average_packet_size = rrdset_create_localhost(
936 + "net_rsc_average_packet_size",
937 + windows_shared_buffer,
938 + NULL,
939 + windows_shared_buffer,
940 + "net.rsc_average_packet_size",
941 + "TCP RSC Average Packet Size",
942 + "bytes",
943 + PLUGIN_WINDOWS_NAME,
944 + "PerflibNetwork",
945 + NETDATA_CHART_PRIO_FIRST_NET_IFACE + 9,
946 + update_every,
947 + RRDSET_TYPE_LINE);
948 +
949 + rrdset_flag_set(d->rsc.st_average_packet_size, RRDSET_FLAG_DETAIL);
950 +
951 + add_interface_labels(d->rsc.st_average_packet_size, windows_shared_buffer, physical);
952 +
953 + d->rsc.rd_average_packet_size = rrddim_add(d->rsc.st_average_packet_size, "average", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
954 + }
955 +
956 + rrddim_set_by_pointer(d->rsc.st_average_packet_size, d->rsc.rd_average_packet_size, (collected_number)d->rsc.average_packet_size.current.Data);
957 + rrdset_done(d->rsc.st_average_packet_size);
958 + }
959 +
960 + if(perflibGetInstanceCounter(pDataBlock, pObjectType, pi, &d->chimney.connections)) {
961 + if (unlikely(!d->chimney.st)) {
962 + d->chimney.st = rrdset_create_localhost(
963 + "net_chimney_connections",
964 + windows_shared_buffer,
965 + NULL,
966 + windows_shared_buffer,
967 + "net.chimney_connections",
968 + "Active TCP Connections Offloaded with Chimney",
969 + "connections",
970 + PLUGIN_WINDOWS_NAME,
971 + "PerflibNetwork",
972 + NETDATA_CHART_PRIO_FIRST_NET_IFACE + 10,
973 + update_every,
974 + RRDSET_TYPE_LINE);
975 +
976 + rrdset_flag_set(d->chimney.st, RRDSET_FLAG_DETAIL);
977 +
978 + add_interface_labels(d->chimney.st, windows_shared_buffer, physical);
979 +
980 + d->chimney.rd = rrddim_add(d->chimney.st, "connections", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
981 + }
982 +
983 + rrddim_set_by_pointer(d->chimney.st, d->chimney.rd, (collected_number)d->chimney.connections.current.Data);
984 + rrdset_done(d->chimney.st);
985 + }
986 }
987
988 if(physical) {
@@ -671,6 +1013,19 @@ static bool do_network_interface(PERF_DATA_BLOCK *pDataBlock, int update_every,
1013 rrdset_done(st);
1014 }
1015
1016 + // cleanup
1017 + {
1018 + struct network_interface *d;
1019 + dfe_start_write(dict, d) {
1020 + if(d->last_collected < now_ut) {
1021 + network_interface_cleanup(d);
1022 + dictionary_del(dict, d_dfe.name);
1023 + }
1024 + }
1025 + dfe_done(d);
1026 + dictionary_garbage_collect(dict);
1027 + }
1028 +
1029 return true;
1030 }
1031
@@ -689,8 +1044,9 @@ int do_PerflibNetwork(int update_every, usec_t dt __maybe_unused) {
1044 PERF_DATA_BLOCK *pDataBlock = perflibGetPerformanceData(id);
1045 if(!pDataBlock) return -1;
1046
692 - do_network_interface(pDataBlock, update_every, true);
693 - do_network_interface(pDataBlock, update_every, false);
1047 + usec_t now_ut = now_monotonic_usec();
1048 + do_network_interface(pDataBlock, update_every, true, now_ut);
1049 + do_network_interface(pDataBlock, update_every, false, now_ut);
1050
1051 struct network_protocol *tcp4 = NULL, *tcp6 = NULL;
1052 for(size_t i = 0; networks[i].protocol ;i++) {
src/database/rrdset.c
+2
@@ -732,6 +732,8 @@ void rrdset_get_retention_of_tier_for_collected_chart(RRDSET *st, time_t *first_
732 }
733
734 inline void rrdset_is_obsolete___safe_from_collector_thread(RRDSET *st) {
735 + if(!st) return;
736 +
737 rrdset_pluginsd_receive_unslot(st);
738
739 if(unlikely(!(rrdset_flag_check(st, RRDSET_FLAG_OBSOLETE)))) {
src/health/health.d/net.conf
+20 -4
@@ -19,7 +19,7 @@ component: Network
19 class: Workload
20 type: System
21 component: Network
22 -host labels: _os=linux
22 +host labels: _os=linux windows
23 lookup: average -1m unaligned absolute of received
24 calc: ($interface_speed > 0) ? ($this * 100 / ($interface_speed * 1000)) : ( nan )
25 units: %
@@ -35,7 +35,7 @@ host labels: _os=linux
35 class: Workload
36 type: System
37 component: Network
38 -host labels: _os=linux
38 +host labels: _os=linux windows
39 lookup: average -1m unaligned absolute of sent
40 calc: ($interface_speed > 0) ? ($this * 100 / ($interface_speed * 1000)) : ( nan )
41 units: %
@@ -214,7 +214,6 @@ host labels: _os=linux
214 class: Workload
215 type: System
216 component: Network
217 -host labels: _os=linux freebsd
217 lookup: average -1m unaligned of received
218 units: packets
219 every: 10s
@@ -225,7 +224,6 @@ host labels: _os=linux freebsd
224 class: Workload
225 type: System
226 component: Network
228 -host labels: _os=linux freebsd
227 lookup: average -10s unaligned of received
228 calc: $this * 100 / (($1m_received_packets_rate < 1000)?(1000):($1m_received_packets_rate))
229 every: 10s
@@ -237,3 +235,21 @@ host labels: _os=linux freebsd
235 info: Ratio of average number of received packets for the network interface ${label:device} over the last 10 seconds, \
236 compared to the rate over the last minute
237 to: silent
238 +
239 +# -----------------------------------------------------------------------------
240 +# output queue length
241 +
242 + template: network_interface_output_queue_length
243 + on: net.queue_length
244 + class: Errors
245 + type: System
246 + component: Network
247 +host labels: _os=windows
248 + units: packets
249 + every: 10s
250 + warn: $length > 2
251 + delay: up 1m down 1m multiplier 1.5 max 1h
252 + summary: System network interface ${label:device} output queue length
253 + info: The Output Queue Length on interface ${label:device} should be zero, otherwise there are delays and bottlenecks.
254 + to: silent
255 +
src/health/rrdvar.c
+2 -2
@@ -93,7 +93,7 @@ void rrdvar_host_variable_set(RRDHOST *host, const RRDVAR_ACQUIRED *rva, NETDATA
93 // CUSTOM CHART VARIABLES
94
95 const RRDVAR_ACQUIRED *rrdvar_chart_variable_add_and_acquire(RRDSET *st, const char *name) {
96 - if(unlikely(!st->rrdvars)) return NULL;
96 + if(unlikely(!st || !st->rrdvars)) return NULL;
97
98 STRING *name_string = rrdvar_name_to_string(name);
99 const RRDVAR_ACQUIRED *rs = rrdvar_add_and_acquire(st->rrdvars, name_string, NAN);
@@ -102,7 +102,7 @@ const RRDVAR_ACQUIRED *rrdvar_chart_variable_add_and_acquire(RRDSET *st, const c
102 }
103
104 void rrdvar_chart_variable_set(RRDSET *st, const RRDVAR_ACQUIRED *rva, NETDATA_DOUBLE value) {
105 - if(unlikely(!st->rrdvars || !rva)) return;
105 + if(unlikely(!st || !st->rrdvars || !rva)) return;
106
107 RRDVAR *rv = dictionary_acquired_item_value((const DICTIONARY_ITEM *)rva);
108 if(rv->value != value) {
src/health/rrdvar.h
+1 -1
@@ -17,7 +17,7 @@ void rrdvar_host_variable_set(RRDHOST *host, const RRDVAR_ACQUIRED *rva, NETDATA
17 int rrdvar_walkthrough_read(DICTIONARY *dict, int (*callback)(const DICTIONARY_ITEM *item, void *rrdvar, void *data), void *data);
18
19 #define rrdvar_host_variable_release(host, rva) rrdvar_release((host)->rrdvars, rva)
20 -#define rrdvar_chart_variable_release(st, rva) rrdvar_release((st)->rrdvars, rva)
20 +#define rrdvar_chart_variable_release(st, rva) do { if(st) rrdvar_release((st)->rrdvars, rva); } while(0)
21 void rrdvar_release(DICTIONARY *dict, const RRDVAR_ACQUIRED *rva);
22
23 NETDATA_DOUBLE rrdvar2number(const RRDVAR_ACQUIRED *rva);