@cryptotaxi247 / netdata-1 / commits / b7592c443

proc/diskstats: add block-devices function (#16338)

* diskstats add block-devices function * fix writes time max

Ilya Mashchenko committed Nov 6, 2023 at 10:38 UTC b7592c443c3bc9f7d7fcccf203817e15878c857b
2 files changed +472 -94
collectors/proc.plugin/plugin_proc.c
+2
@@ -142,6 +142,8 @@ void *proc_main(void *ptr)
142 {
143 worker_register("PROC");
144
145 + rrd_collector_started();
146 +
147 if (config_get_boolean("plugin:proc", "/proc/net/dev", CONFIG_BOOLEAN_YES)) {
148 netdev_thread = mallocz(sizeof(netdata_thread_t));
149 netdata_log_debug(D_SYSTEM, "Starting thread %s.", THREAD_NETDEV_NAME);
collectors/proc.plugin/proc_diskstats.c
+470 -94
@@ -6,6 +6,8 @@
6 #define PLUGIN_PROC_MODULE_DISKSTATS_NAME "/proc/diskstats"
7 #define CONFIG_SECTION_PLUGIN_PROC_DISKSTATS "plugin:" PLUGIN_PROC_CONFIG_NAME ":" PLUGIN_PROC_MODULE_DISKSTATS_NAME
8
9 +#define RRDFUNCTIONS_DISKSTATS_HELP "View block device statistics"
10 +
11 #define DISK_TYPE_UNKNOWN 0
12 #define DISK_TYPE_PHYSICAL 1
13 #define DISK_TYPE_PARTITION 2
@@ -14,6 +16,8 @@
16 #define DEFAULT_PREFERRED_IDS "*"
17 #define DEFAULT_EXCLUDED_DISKS "loop* ram*"
18
19 +static netdata_mutex_t diskstats_dev_mutex = NETDATA_MUTEX_INITIALIZER;
20 +
21 static struct disk {
22 char *disk; // the name of the disk (sda, sdb, etc, after being looked up)
23 char *device; // the device of the disk (before being looked up)
@@ -28,6 +32,9 @@ static struct disk {
32 int sector_size;
33 int type;
34
35 + bool excluded;
36 + bool function_ready;
37 +
38 char *mount_point;
39
40 char *chart_id;
@@ -543,7 +550,11 @@ static inline char *get_disk_model(char *device) {
550 return NULL;
551 }
552
546 - return strdupz(buffer);
553 + char *clean = trim(buffer);
554 + if (!clean)
555 + return NULL;
556 +
557 + return strdupz(clean);
558 }
559
560 static inline char *get_disk_serial(char *device) {
@@ -582,8 +593,10 @@ static inline char *get_disk_serial(char *device) {
593 static void get_disk_config(struct disk *d) {
594 int def_enable = global_enable_new_disks_detected_at_runtime;
595
585 - if(def_enable != CONFIG_BOOLEAN_NO && (simple_pattern_matches(excluded_disks, d->device) || simple_pattern_matches(excluded_disks, d->disk)))
596 + if(def_enable != CONFIG_BOOLEAN_NO && (simple_pattern_matches(excluded_disks, d->device) || simple_pattern_matches(excluded_disks, d->disk))) {
597 + d->excluded = true;
598 def_enable = CONFIG_BOOLEAN_NO;
599 + }
600
601 char var_name[4096 + 1];
602 snprintfz(var_name, 4096, CONFIG_SECTION_PLUGIN_PROC_DISKSTATS ":%s", d->disk);
@@ -663,6 +676,8 @@ static void get_disk_config(struct disk *d) {
676 ddo_ext = global_do_ext,
677 ddo_backlog = global_do_backlog,
678 ddo_bcache = global_do_bcache;
679 + } else {
680 + d->excluded = true;
681 }
682
683 d->do_io = config_get_boolean_ondemand(var_name, "bandwidth", ddo_io);
@@ -702,6 +717,8 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
717 // create a new disk structure
718 d = (struct disk *)callocz(1, sizeof(struct disk));
719
720 + d->excluded = false;
721 + d->function_ready = false;
722 d->disk = get_disk_name(major, minor, disk);
723 d->device = strdupz(disk);
724 d->disk_by_id = get_disk_by_id(disk);
@@ -963,35 +980,457 @@ static struct disk *get_disk(unsigned long major, unsigned long minor, char *dis
980 }
981
982 get_disk_config(d);
983 +
984 return d;
985 }
986
987 +static const char *get_disk_type_string(int disk_type) {
988 + switch (disk_type) {
989 + case DISK_TYPE_PHYSICAL:
990 + return "physical";
991 + case DISK_TYPE_PARTITION:
992 + return "partition";
993 + case DISK_TYPE_VIRTUAL:
994 + return "virtual";
995 + default:
996 + return "unknown";
997 + }
998 +}
999 +
1000 static void add_labels_to_disk(struct disk *d, RRDSET *st) {
1001 rrdlabels_add(st->rrdlabels, "device", d->disk, RRDLABEL_SRC_AUTO);
1002 rrdlabels_add(st->rrdlabels, "mount_point", d->mount_point, RRDLABEL_SRC_AUTO);
1003 rrdlabels_add(st->rrdlabels, "id", d->disk_by_id, RRDLABEL_SRC_AUTO);
1004 rrdlabels_add(st->rrdlabels, "model", d->model, RRDLABEL_SRC_AUTO);
1005 rrdlabels_add(st->rrdlabels, "serial", d->serial, RRDLABEL_SRC_AUTO);
975 -// rrdlabels_add(st->rrdlabels, "rotational", d->rotational ? "true" : "false", RRDLABEL_SRC_AUTO);
976 -// rrdlabels_add(st->rrdlabels, "removable", d->removable ? "true" : "false", RRDLABEL_SRC_AUTO);
1006 + rrdlabels_add(st->rrdlabels, "device_type", get_disk_type_string(d->type), RRDLABEL_SRC_AUTO);
1007 +}
1008
978 - switch (d->type) {
979 - default:
980 - case DISK_TYPE_UNKNOWN:
981 - rrdlabels_add(st->rrdlabels, "device_type", "unknown", RRDLABEL_SRC_AUTO);
982 - break;
1009 +static int diskstats_function_block_devices(BUFFER *wb, int timeout __maybe_unused, const char *function __maybe_unused,
1010 + void *collector_data __maybe_unused,
1011 + rrd_function_result_callback_t result_cb, void *result_cb_data,
1012 + rrd_function_is_cancelled_cb_t is_cancelled_cb, void *is_cancelled_cb_data,
1013 + rrd_function_register_canceller_cb_t register_canceller_cb __maybe_unused,
1014 + void *register_canceller_cb_data __maybe_unused) {
1015 +
1016 + buffer_flush(wb);
1017 + wb->content_type = CT_APPLICATION_JSON;
1018 + buffer_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_DEFAULT);
1019 +
1020 + buffer_json_member_add_string(wb, "hostname", rrdhost_hostname(localhost));
1021 + buffer_json_member_add_uint64(wb, "status", HTTP_RESP_OK);
1022 + buffer_json_member_add_string(wb, "type", "table");
1023 + buffer_json_member_add_time_t(wb, "update_every", 1);
1024 + buffer_json_member_add_string(wb, "help", RRDFUNCTIONS_DISKSTATS_HELP);
1025 + buffer_json_member_add_array(wb, "data");
1026 +
1027 + double max_io_reads = 0.0;
1028 + double max_io_writes = 0.0;
1029 + double max_io = 0.0;
1030 + double max_backlog_time = 0.0;
1031 + double max_busy_time = 0.0;
1032 + double max_busy_perc = 0.0;
1033 + double max_iops_reads = 0.0;
1034 + double max_iops_writes = 0.0;
1035 + double max_iops_time_reads = 0.0;
1036 + double max_iops_time_writes = 0.0;
1037 + double max_iops_avg_time_read = 0.0;
1038 + double max_iops_avg_time_write = 0.0;
1039 + double max_iops_avg_size_read = 0.0;
1040 + double max_iops_avg_size_write = 0.0;
1041 +
1042 + netdata_mutex_lock(&diskstats_dev_mutex);
1043 +
1044 + for (struct disk *d = disk_root; d; d = d->next) {
1045 + if (unlikely(!d->function_ready))
1046 + continue;
1047
984 - case DISK_TYPE_PHYSICAL:
985 - rrdlabels_add(st->rrdlabels, "device_type", "physical", RRDLABEL_SRC_AUTO);
986 - break;
1048 + buffer_json_add_array_item_array(wb);
1049
988 - case DISK_TYPE_PARTITION:
989 - rrdlabels_add(st->rrdlabels, "device_type", "partition", RRDLABEL_SRC_AUTO);
990 - break;
1050 + buffer_json_add_array_item_string(wb, d->device);
1051 + buffer_json_add_array_item_string(wb, get_disk_type_string(d->type));
1052 + buffer_json_add_array_item_string(wb, d->disk_by_id);
1053 + buffer_json_add_array_item_string(wb, d->model);
1054 + buffer_json_add_array_item_string(wb, d->serial);
1055
992 - case DISK_TYPE_VIRTUAL:
993 - rrdlabels_add(st->rrdlabels, "device_type", "virtual", RRDLABEL_SRC_AUTO);
994 - break;
1056 + // IO
1057 + double io_reads = NAN;
1058 + if (d->rd_io_reads) {
1059 + io_reads = d->rd_io_reads->collector.last_stored_value / 1024.0;
1060 + max_io_reads = MAX(max_io_reads, io_reads);
1061 + }
1062 + buffer_json_add_array_item_double(wb, io_reads);
1063 +
1064 + double io_writes = NAN;
1065 + if (d->rd_io_writes) {
1066 + io_writes = ABS(d->rd_io_writes->collector.last_stored_value / 1024.0);
1067 + max_io_writes = MAX(max_io_writes, io_writes);
1068 + }
1069 + buffer_json_add_array_item_double(wb, io_writes);
1070 +
1071 + double io_total = NAN;
1072 + if (!isnan(io_reads) && !isnan(io_writes)) {
1073 + io_total = io_reads + io_writes;
1074 + max_io = MAX(max_io, io_total);
1075 + }
1076 + buffer_json_add_array_item_double(wb, io_total);
1077 +
1078 + // Backlog and Busy Time
1079 + double busy_perc = NAN;
1080 + if (d->rd_util_utilization) {
1081 + busy_perc = d->rd_util_utilization->collector.last_stored_value;
1082 + max_busy_perc = MAX(max_busy_perc, busy_perc);
1083 + }
1084 + buffer_json_add_array_item_double(wb, busy_perc);
1085 + double busy_time = NAN;
1086 + if (d->rd_busy_busy) {
1087 + busy_time = d->rd_busy_busy->collector.last_stored_value;
1088 + max_busy_time = MAX(max_busy_time, busy_time);
1089 + }
1090 + buffer_json_add_array_item_double(wb, busy_time);
1091 + double backlog_time = NAN;
1092 + if (d->rd_backlog_backlog) {
1093 + backlog_time = d->rd_backlog_backlog->collector.last_stored_value;
1094 + max_backlog_time = MAX(max_backlog_time, backlog_time);
1095 + }
1096 + buffer_json_add_array_item_double(wb, backlog_time);
1097 +
1098 + // IOPS
1099 + double iops_reads = NAN;
1100 + if (d->rd_ops_reads) {
1101 + iops_reads = d->rd_ops_reads->collector.last_stored_value;
1102 + max_iops_reads = MAX(max_iops_reads, iops_reads);
1103 + }
1104 + buffer_json_add_array_item_double(wb, iops_reads);
1105 + double iops_writes = NAN;
1106 + if (d->rd_ops_writes) {
1107 + iops_writes = ABS(d->rd_ops_writes->collector.last_stored_value);
1108 + max_iops_writes = MAX(max_iops_writes, iops_writes);
1109 + }
1110 + buffer_json_add_array_item_double(wb, iops_writes);
1111 +
1112 + // IO Time
1113 + double iops_time_reads = NAN;
1114 + if (d->rd_iotime_reads) {
1115 + iops_time_reads = d->rd_iotime_reads->collector.last_stored_value;
1116 + max_iops_time_reads = MAX(max_iops_time_reads, iops_time_reads);
1117 + }
1118 + buffer_json_add_array_item_double(wb, iops_time_reads);
1119 +
1120 + double iops_time_writes = NAN;
1121 + if (d->rd_iotime_writes) {
1122 + iops_time_writes = ABS(d->rd_iotime_writes->collector.last_stored_value);
1123 + max_iops_time_writes = MAX(max_iops_time_writes, iops_time_writes);
1124 + }
1125 + buffer_json_add_array_item_double(wb, iops_time_writes);
1126 +
1127 + // Avg IO Time
1128 + double iops_avg_time_read = NAN;
1129 + if (d->rd_await_reads) {
1130 + iops_avg_time_read = d->rd_await_reads->collector.last_stored_value;
1131 + max_iops_avg_time_read = MAX(max_iops_avg_time_read, iops_avg_time_read);
1132 + }
1133 + buffer_json_add_array_item_double(wb, iops_avg_time_read);
1134 + double iops_avg_time_write = NAN;
1135 + if (d->rd_await_writes) {
1136 + iops_avg_time_write = ABS(d->rd_await_writes->collector.last_stored_value);
1137 + max_iops_avg_time_write = MAX(max_iops_avg_time_write, iops_avg_time_write);
1138 + }
1139 + buffer_json_add_array_item_double(wb, iops_avg_time_write);
1140 +
1141 + // Avg IO Size
1142 + double iops_avg_size_read = NAN;
1143 + if (d->rd_avgsz_reads) {
1144 + iops_avg_size_read = d->rd_avgsz_reads->collector.last_stored_value;
1145 + max_iops_avg_size_read = MAX(max_iops_avg_size_read, iops_avg_size_read);
1146 + }
1147 + buffer_json_add_array_item_double(wb, iops_avg_size_read);
1148 + double iops_avg_size_write = NAN;
1149 + if (d->rd_avgsz_writes) {
1150 + iops_avg_size_write = ABS(d->rd_avgsz_writes->collector.last_stored_value);
1151 + max_iops_avg_size_write = MAX(max_iops_avg_size_write, iops_avg_size_write);
1152 + }
1153 + buffer_json_add_array_item_double(wb, iops_avg_size_write);
1154 +
1155 + // End
1156 + buffer_json_array_close(wb);
1157 + }
1158 +
1159 + netdata_mutex_unlock(&diskstats_dev_mutex);
1160 +
1161 + buffer_json_array_close(wb); // data
1162 + buffer_json_member_add_object(wb, "columns");
1163 + {
1164 + size_t field_id = 0;
1165 +
1166 + buffer_rrdf_table_add_field(wb, field_id++, "Device", "Device Name",
1167 + RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
1168 + 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
1169 + RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
1170 + RRDF_FIELD_OPTS_VISIBLE | RRDF_FIELD_OPTS_UNIQUE_KEY | RRDF_FIELD_OPTS_STICKY,
1171 + NULL);
1172 + buffer_rrdf_table_add_field(wb, field_id++, "Type", "Device Type",
1173 + RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
1174 + 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
1175 + RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
1176 + RRDF_FIELD_OPTS_UNIQUE_KEY,
1177 + NULL);
1178 + buffer_rrdf_table_add_field(wb, field_id++, "ID", "Device ID",
1179 + RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
1180 + 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
1181 + RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
1182 + RRDF_FIELD_OPTS_UNIQUE_KEY,
1183 + NULL);
1184 + buffer_rrdf_table_add_field(wb, field_id++, "Model", "Device Model",
1185 + RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
1186 + 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
1187 + RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
1188 + RRDF_FIELD_OPTS_UNIQUE_KEY,
1189 + NULL);
1190 + buffer_rrdf_table_add_field(wb, field_id++, "Serial", "Device Serial Number",
1191 + RRDF_FIELD_TYPE_STRING, RRDF_FIELD_VISUAL_VALUE, RRDF_FIELD_TRANSFORM_NONE,
1192 + 0, NULL, NAN, RRDF_FIELD_SORT_ASCENDING, NULL,
1193 + RRDF_FIELD_SUMMARY_COUNT, RRDF_FIELD_FILTER_MULTISELECT,
1194 + RRDF_FIELD_OPTS_UNIQUE_KEY,
1195 + NULL);
1196 +
1197 + buffer_rrdf_table_add_field(wb, field_id++, "Read", "Data Read from Device",
1198 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1199 + 2, "MiB", max_io_reads, RRDF_FIELD_SORT_DESCENDING, NULL,
1200 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1201 + RRDF_FIELD_OPTS_VISIBLE,
1202 + NULL);
1203 + buffer_rrdf_table_add_field(wb, field_id++, "Written", "Data Writen to Device",
1204 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1205 + 2, "MiB", max_io_writes, RRDF_FIELD_SORT_DESCENDING, NULL,
1206 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1207 + RRDF_FIELD_OPTS_VISIBLE,
1208 + NULL);
1209 + buffer_rrdf_table_add_field(wb, field_id++, "Total", "Data Transferred to and from Device",
1210 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1211 + 2, "MiB", max_io, RRDF_FIELD_SORT_DESCENDING, NULL,
1212 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1213 + RRDF_FIELD_OPTS_VISIBLE,
1214 + NULL);
1215 +
1216 + buffer_rrdf_table_add_field(wb, field_id++, "Busy%", "Disk Busy Percentage",
1217 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1218 + 2, "%", max_busy_perc, RRDF_FIELD_SORT_DESCENDING, NULL,
1219 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1220 + RRDF_FIELD_OPTS_VISIBLE,
1221 + NULL);
1222 + buffer_rrdf_table_add_field(wb, field_id++, "Busy", "Disk Busy Time",
1223 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1224 + 2, "milliseconds", max_busy_time, RRDF_FIELD_SORT_DESCENDING, NULL,
1225 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1226 + RRDF_FIELD_OPTS_VISIBLE,
1227 + NULL);
1228 + buffer_rrdf_table_add_field(wb, field_id++, "Backlog", "Disk Backlog",
1229 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1230 + 2, "milliseconds", max_backlog_time, RRDF_FIELD_SORT_DESCENDING, NULL,
1231 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1232 + RRDF_FIELD_OPTS_VISIBLE,
1233 + NULL);
1234 +
1235 + buffer_rrdf_table_add_field(wb, field_id++, "Reads", "Completed Read Operations",
1236 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1237 + 2, "ops", max_iops_reads, RRDF_FIELD_SORT_DESCENDING, NULL,
1238 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1239 + RRDF_FIELD_OPTS_VISIBLE,
1240 + NULL);
1241 + buffer_rrdf_table_add_field(wb, field_id++, "Writes", "Completed Write Operations",
1242 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1243 + 2, "ops", max_iops_writes, RRDF_FIELD_SORT_DESCENDING, NULL,
1244 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1245 + RRDF_FIELD_OPTS_VISIBLE,
1246 + NULL);
1247 +
1248 + buffer_rrdf_table_add_field(wb, field_id++, "ReadsTime", "Read Operations Time",
1249 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1250 + 2, "milliseconds", max_iops_time_reads, RRDF_FIELD_SORT_DESCENDING, NULL,
1251 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1252 + RRDF_FIELD_OPTS_VISIBLE,
1253 + NULL);
1254 + buffer_rrdf_table_add_field(wb, field_id++, "WritesTime", "Write Operations Time",
1255 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1256 + 2, "milliseconds", max_iops_time_writes, RRDF_FIELD_SORT_DESCENDING, NULL,
1257 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1258 + RRDF_FIELD_OPTS_VISIBLE,
1259 + NULL);
1260 +
1261 + buffer_rrdf_table_add_field(wb, field_id++, "ReadAvgTime", "Average Read Operation Service Time",
1262 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1263 + 2, "milliseconds", max_iops_avg_time_read, RRDF_FIELD_SORT_DESCENDING, NULL,
1264 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1265 + RRDF_FIELD_OPTS_VISIBLE,
1266 + NULL);
1267 + buffer_rrdf_table_add_field(wb, field_id++, "WriteAvgTime", "Average Write Operation Service Time",
1268 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1269 + 2, "milliseconds", max_iops_avg_time_write, RRDF_FIELD_SORT_DESCENDING, NULL,
1270 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1271 + RRDF_FIELD_OPTS_VISIBLE,
1272 + NULL);
1273 +
1274 + buffer_rrdf_table_add_field(wb, field_id++, "ReadAvgSz", "Average Read Operation Size",
1275 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1276 + 2, "KiB", max_iops_avg_size_read, RRDF_FIELD_SORT_DESCENDING, NULL,
1277 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1278 + RRDF_FIELD_OPTS_VISIBLE,
1279 + NULL);
1280 + buffer_rrdf_table_add_field(wb, field_id++, "WriteAvgSz", "Average Write Operation Size",
1281 + RRDF_FIELD_TYPE_BAR_WITH_INTEGER, RRDF_FIELD_VISUAL_BAR, RRDF_FIELD_TRANSFORM_NUMBER,
1282 + 2, "KiB", max_iops_avg_size_write, RRDF_FIELD_SORT_DESCENDING, NULL,
1283 + RRDF_FIELD_SUMMARY_SUM, RRDF_FIELD_FILTER_NONE,
1284 + RRDF_FIELD_OPTS_VISIBLE,
1285 + NULL);
1286 + }
1287 +
1288 + buffer_json_object_close(wb); // columns
1289 + buffer_json_member_add_string(wb, "default_sort_column", "Total");
1290 +
1291 + buffer_json_member_add_object(wb, "charts");
1292 + {
1293 + buffer_json_member_add_object(wb, "IO");
1294 + {
1295 + buffer_json_member_add_string(wb, "name", "IO");
1296 + buffer_json_member_add_string(wb, "type", "stacked-bar");
1297 + buffer_json_member_add_array(wb, "columns");
1298 + {
1299 + buffer_json_add_array_item_string(wb, "Read");
1300 + buffer_json_add_array_item_string(wb, "Written");
1301 + }
1302 + buffer_json_array_close(wb);
1303 + }
1304 + buffer_json_object_close(wb);
1305 +
1306 + buffer_json_member_add_object(wb, "Busy");
1307 + {
1308 + buffer_json_member_add_string(wb, "name", "Busy");
1309 + buffer_json_member_add_string(wb, "type", "stacked-bar");
1310 + buffer_json_member_add_array(wb, "columns");
1311 + {
1312 + buffer_json_add_array_item_string(wb, "Busy");
1313 + }
1314 + buffer_json_array_close(wb);
1315 + }
1316 + buffer_json_object_close(wb);
1317 + }
1318 + buffer_json_object_close(wb); // charts
1319 +
1320 + buffer_json_member_add_array(wb, "default_charts");
1321 + {
1322 + buffer_json_add_array_item_array(wb);
1323 + buffer_json_add_array_item_string(wb, "IO");
1324 + buffer_json_add_array_item_string(wb, "Device");
1325 + buffer_json_array_close(wb);
1326 +
1327 + buffer_json_add_array_item_array(wb);
1328 + buffer_json_add_array_item_string(wb, "Busy");
1329 + buffer_json_add_array_item_string(wb, "Device");
1330 + buffer_json_array_close(wb);
1331 + }
1332 + buffer_json_array_close(wb);
1333 +
1334 + buffer_json_member_add_object(wb, "group_by");
1335 + {
1336 + buffer_json_member_add_object(wb, "Type");
1337 + {
1338 + buffer_json_member_add_string(wb, "name", "Type");
1339 + buffer_json_member_add_array(wb, "columns");
1340 + {
1341 + buffer_json_add_array_item_string(wb, "Type");
1342 + }
1343 + buffer_json_array_close(wb);
1344 + }
1345 + buffer_json_object_close(wb);
1346 + }
1347 + buffer_json_object_close(wb); // group_by
1348 +
1349 + buffer_json_member_add_time_t(wb, "expires", now_realtime_sec() + 1);
1350 + buffer_json_finalize(wb);
1351 +
1352 + int response = HTTP_RESP_OK;
1353 + if(is_cancelled_cb && is_cancelled_cb(is_cancelled_cb_data)) {
1354 + buffer_flush(wb);
1355 + response = HTTP_RESP_CLIENT_CLOSED_REQUEST;
1356 + }
1357 +
1358 + if(result_cb)
1359 + result_cb(wb, response, result_cb_data);
1360 +
1361 + return response;
1362 +}
1363 +
1364 +static void diskstats_cleanup_disks() {
1365 + struct disk *d = disk_root, *last = NULL;
1366 + while (d) {
1367 + if (unlikely(global_cleanup_removed_disks && !d->updated)) {
1368 + struct disk *t = d;
1369 +
1370 + rrdset_obsolete_and_pointer_null(d->st_avgsz);
1371 + rrdset_obsolete_and_pointer_null(d->st_ext_avgsz);
1372 + rrdset_obsolete_and_pointer_null(d->st_await);
1373 + rrdset_obsolete_and_pointer_null(d->st_ext_await);
1374 + rrdset_obsolete_and_pointer_null(d->st_backlog);
1375 + rrdset_obsolete_and_pointer_null(d->st_busy);
1376 + rrdset_obsolete_and_pointer_null(d->st_io);
1377 + rrdset_obsolete_and_pointer_null(d->st_ext_io);
1378 + rrdset_obsolete_and_pointer_null(d->st_iotime);
1379 + rrdset_obsolete_and_pointer_null(d->st_ext_iotime);
1380 + rrdset_obsolete_and_pointer_null(d->st_mops);
1381 + rrdset_obsolete_and_pointer_null(d->st_ext_mops);
1382 + rrdset_obsolete_and_pointer_null(d->st_ops);
1383 + rrdset_obsolete_and_pointer_null(d->st_ext_ops);
1384 + rrdset_obsolete_and_pointer_null(d->st_qops);
1385 + rrdset_obsolete_and_pointer_null(d->st_svctm);
1386 + rrdset_obsolete_and_pointer_null(d->st_util);
1387 + rrdset_obsolete_and_pointer_null(d->st_bcache);
1388 + rrdset_obsolete_and_pointer_null(d->st_bcache_bypass);
1389 + rrdset_obsolete_and_pointer_null(d->st_bcache_rates);
1390 + rrdset_obsolete_and_pointer_null(d->st_bcache_size);
1391 + rrdset_obsolete_and_pointer_null(d->st_bcache_usage);
1392 + rrdset_obsolete_and_pointer_null(d->st_bcache_hit_ratio);
1393 + rrdset_obsolete_and_pointer_null(d->st_bcache_cache_allocations);
1394 + rrdset_obsolete_and_pointer_null(d->st_bcache_cache_read_races);
1395 +
1396 + if (d == disk_root) {
1397 + disk_root = d = d->next;
1398 + last = NULL;
1399 + } else if (last) {
1400 + last->next = d = d->next;
1401 + }
1402 +
1403 + freez(t->bcache_filename_dirty_data);
1404 + freez(t->bcache_filename_writeback_rate);
1405 + freez(t->bcache_filename_cache_congested);
1406 + freez(t->bcache_filename_cache_available_percent);
1407 + freez(t->bcache_filename_stats_five_minute_cache_hit_ratio);
1408 + freez(t->bcache_filename_stats_hour_cache_hit_ratio);
1409 + freez(t->bcache_filename_stats_day_cache_hit_ratio);
1410 + freez(t->bcache_filename_stats_total_cache_hit_ratio);
1411 + freez(t->bcache_filename_stats_total_cache_hits);
1412 + freez(t->bcache_filename_stats_total_cache_misses);
1413 + freez(t->bcache_filename_stats_total_cache_miss_collisions);
1414 + freez(t->bcache_filename_stats_total_cache_bypass_hits);
1415 + freez(t->bcache_filename_stats_total_cache_bypass_misses);
1416 + freez(t->bcache_filename_stats_total_cache_readaheads);
1417 + freez(t->bcache_filename_cache_read_races);
1418 + freez(t->bcache_filename_cache_io_errors);
1419 + freez(t->bcache_filename_priority_stats);
1420 +
1421 + freez(t->disk);
1422 + freez(t->device);
1423 + freez(t->disk_by_id);
1424 + freez(t->model);
1425 + freez(t->serial);
1426 + freez(t->mount_point);
1427 + freez(t->chart_id);
1428 + freez(t);
1429 + } else {
1430 + d->updated = 0;
1431 + last = d;
1432 + d = d->next;
1433 + }
1434 }
1435 }
1436
@@ -1080,12 +1519,20 @@ int do_proc_diskstats(int update_every, usec_t dt) {
1519 ff = procfile_readall(ff);
1520 if(unlikely(!ff)) return 0; // we return 0, so that we will retry to open it next time
1521
1522 + static bool add_func = true;
1523 + if (add_func) {
1524 + rrd_function_add(localhost, NULL, "block-devices", 10, RRDFUNCTIONS_DISKSTATS_HELP, true, diskstats_function_block_devices, NULL);
1525 + add_func = false;
1526 + }
1527 +
1528 size_t lines = procfile_lines(ff), l;
1529
1530 collected_number system_read_kb = 0, system_write_kb = 0;
1531
1532 int do_dc_stats = 0, do_fl_stats = 0;
1533
1534 + netdata_mutex_lock(&diskstats_dev_mutex);
1535 +
1536 for(l = 0; l < lines ;l++) {
1537 // --------------------------------------------------------------------------
1538 // Read parameters
@@ -1210,7 +1657,6 @@ int do_proc_diskstats(int update_every, usec_t dt) {
1657
1658 // --------------------------------------------------------------------------
1659 // Do performance metrics
1213 -
1660 if(d->do_io == CONFIG_BOOLEAN_YES || (d->do_io == CONFIG_BOOLEAN_AUTO &&
1661 (readsectors || writesectors || discardsectors ||
1662 netdata_zero_metrics_enabled == CONFIG_BOOLEAN_YES))) {
@@ -2056,8 +2502,13 @@ int do_proc_diskstats(int update_every, usec_t dt) {
2502 rrdset_done(d->st_bcache_bypass);
2503 }
2504 }
2505 +
2506 + d->function_ready = !d->excluded;
2507 }
2508
2509 + diskstats_cleanup_disks();
2510 +
2511 + netdata_mutex_unlock(&diskstats_dev_mutex);
2512 // update the system total I/O
2513
2514 if(global_do_io == CONFIG_BOOLEAN_YES || (global_do_io == CONFIG_BOOLEAN_AUTO &&
@@ -2091,80 +2542,5 @@ int do_proc_diskstats(int update_every, usec_t dt) {
2542 rrdset_done(st_io);
2543 }
2544
2094 - // cleanup removed disks
2095 -
2096 - struct disk *d = disk_root, *last = NULL;
2097 - while(d) {
2098 - if(unlikely(global_cleanup_removed_disks && !d->updated)) {
2099 - struct disk *t = d;
2100 -
2101 - rrdset_obsolete_and_pointer_null(d->st_avgsz);
2102 - rrdset_obsolete_and_pointer_null(d->st_ext_avgsz);
2103 - rrdset_obsolete_and_pointer_null(d->st_await);
2104 - rrdset_obsolete_and_pointer_null(d->st_ext_await);
2105 - rrdset_obsolete_and_pointer_null(d->st_backlog);
2106 - rrdset_obsolete_and_pointer_null(d->st_busy);
2107 - rrdset_obsolete_and_pointer_null(d->st_io);
2108 - rrdset_obsolete_and_pointer_null(d->st_ext_io);
2109 - rrdset_obsolete_and_pointer_null(d->st_iotime);
2110 - rrdset_obsolete_and_pointer_null(d->st_ext_iotime);
2111 - rrdset_obsolete_and_pointer_null(d->st_mops);
2112 - rrdset_obsolete_and_pointer_null(d->st_ext_mops);
2113 - rrdset_obsolete_and_pointer_null(d->st_ops);
2114 - rrdset_obsolete_and_pointer_null(d->st_ext_ops);
2115 - rrdset_obsolete_and_pointer_null(d->st_qops);
2116 - rrdset_obsolete_and_pointer_null(d->st_svctm);
2117 - rrdset_obsolete_and_pointer_null(d->st_util);
2118 - rrdset_obsolete_and_pointer_null(d->st_bcache);
2119 - rrdset_obsolete_and_pointer_null(d->st_bcache_bypass);
2120 - rrdset_obsolete_and_pointer_null(d->st_bcache_rates);
2121 - rrdset_obsolete_and_pointer_null(d->st_bcache_size);
2122 - rrdset_obsolete_and_pointer_null(d->st_bcache_usage);
2123 - rrdset_obsolete_and_pointer_null(d->st_bcache_hit_ratio);
2124 - rrdset_obsolete_and_pointer_null(d->st_bcache_cache_allocations);
2125 - rrdset_obsolete_and_pointer_null(d->st_bcache_cache_read_races);
2126 -
2127 - if(d == disk_root) {
2128 - disk_root = d = d->next;
2129 - last = NULL;
2130 - }
2131 - else if(last) {
2132 - last->next = d = d->next;
2133 - }
2134 -
2135 - freez(t->bcache_filename_dirty_data);
2136 - freez(t->bcache_filename_writeback_rate);
2137 - freez(t->bcache_filename_cache_congested);
2138 - freez(t->bcache_filename_cache_available_percent);
2139 - freez(t->bcache_filename_stats_five_minute_cache_hit_ratio);
2140 - freez(t->bcache_filename_stats_hour_cache_hit_ratio);
2141 - freez(t->bcache_filename_stats_day_cache_hit_ratio);
2142 - freez(t->bcache_filename_stats_total_cache_hit_ratio);
2143 - freez(t->bcache_filename_stats_total_cache_hits);
2144 - freez(t->bcache_filename_stats_total_cache_misses);
2145 - freez(t->bcache_filename_stats_total_cache_miss_collisions);
2146 - freez(t->bcache_filename_stats_total_cache_bypass_hits);
2147 - freez(t->bcache_filename_stats_total_cache_bypass_misses);
2148 - freez(t->bcache_filename_stats_total_cache_readaheads);
2149 - freez(t->bcache_filename_cache_read_races);
2150 - freez(t->bcache_filename_cache_io_errors);
2151 - freez(t->bcache_filename_priority_stats);
2152 -
2153 - freez(t->disk);
2154 - freez(t->device);
2155 - freez(t->disk_by_id);
2156 - freez(t->model);
2157 - freez(t->serial);
2158 - freez(t->mount_point);
2159 - freez(t->chart_id);
2160 - freez(t);
2161 - }
2162 - else {
2163 - d->updated = 0;
2164 - last = d;
2165 - d = d->next;
2166 - }
2167 - }
2168 -
2545 return 0;
2546 }