]> arthur.barton.de Git - netdata.git/blob - src/macos_fw.c
Add disk I/O chart to macOS plugin
[netdata.git] / src / macos_fw.c
1 #include "common.h"
2 #include <CoreFoundation/CoreFoundation.h>
3 #include <IOKit/IOKitLib.h>
4 #include <IOKit/storage/IOBlockStorageDriver.h>
5
6 int do_macos_iokit(int update_every, usec_t dt) {
7     (void)dt;
8
9     static int do_io = -1;
10
11     if (unlikely(do_io == -1)) {
12         do_io                  = config_get_boolean("plugin:macos:iokit", "disk i/o", 1);
13     }
14
15     RRDSET *st;
16
17     mach_port_t         master_port;
18     io_registry_entry_t drive;
19     io_iterator_t       drive_list;
20     CFNumberRef         number;
21     CFDictionaryRef     properties, statistics;
22     UInt64              value;
23     collected_number    total_disk_reads = 0;
24     collected_number    total_disk_writes = 0;
25
26     /* Get ports and services for drive statistics. */
27     if (IOMasterPort(bootstrap_port, &master_port)) {
28         error("MACOS: IOMasterPort() failed");
29         do_io = 0;
30         error("DISABLED: system.io");
31     /* Get the list of all drive objects. */
32     } else if (IOServiceGetMatchingServices(master_port, IOServiceMatching("IOBlockStorageDriver"), &drive_list)) {
33         error("MACOS: IOServiceGetMatchingServices() failed");
34         do_io = 0;
35         error("DISABLED: system.io");
36     } else {
37         while ((drive = IOIteratorNext(drive_list)) != 0) {
38             number = 0;
39             properties = 0;
40             statistics = 0;
41             value = 0;
42
43             /* Obtain the properties for this drive object. */
44             if (IORegistryEntryCreateCFProperties(drive, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, 0)) {
45                 error("MACOS: IORegistryEntryCreateCFProperties() failed");
46                 do_io = 0;
47                 error("DISABLED: system.io");
48                 break;
49             } else if (properties != 0) {
50                 /* Obtain the statistics from the drive properties. */
51                 statistics = (CFDictionaryRef)CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey));
52
53                 if (statistics != 0) {
54                     /* Get bytes read. */
55                     number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey));
56                     if (number != 0) {
57                         CFNumberGetValue(number, kCFNumberSInt64Type, &value);
58                         total_disk_reads += value;
59                     }
60
61                     /* Get bytes written. */
62                     number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey));
63                     if (number != 0) {
64                         CFNumberGetValue(number, kCFNumberSInt64Type, &value);
65                         total_disk_writes += value;
66                     }
67                 }
68
69                 /* Release. */
70                 CFRelease(properties);
71             }
72
73             /* Release. */
74             IOObjectRelease(drive);
75         }
76         IOIteratorReset(drive_list);
77
78         /* Release. */
79         IOObjectRelease(drive_list);
80     }
81
82     if (do_io) {
83         st = rrdset_find_bytype("system", "io");
84         if (unlikely(!st)) {
85             st = rrdset_create("system", "io", NULL, "disk", NULL, "Disk I/O", "kilobytes/s", 150, update_every, RRDSET_TYPE_AREA);
86             rrddim_add(st, "in",  NULL,  1, 1024, RRDDIM_INCREMENTAL);
87             rrddim_add(st, "out", NULL, -1, 1024, RRDDIM_INCREMENTAL);
88         }
89         else rrdset_next(st);
90
91         rrddim_set(st, "in", total_disk_reads);
92         rrddim_set(st, "out", total_disk_writes);
93         rrdset_done(st);
94     }
95
96     return 0;
97 }