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);