macos_fw.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "plugin_macos.h"
  3. #include <CoreFoundation/CoreFoundation.h>
  4. #include <IOKit/IOKitLib.h>
  5. #include <IOKit/storage/IOBlockStorageDriver.h>
  6. #include <IOKit/IOBSD.h>
  7. // NEEDED BY do_space, do_inodes
  8. #include <sys/mount.h>
  9. // NEEDED BY: struct ifaddrs, getifaddrs()
  10. #include <net/if.h>
  11. #include <ifaddrs.h>
  12. // NEEDED BY: do_bandwidth
  13. #define IFA_DATA(s) (((struct if_data *)ifa->ifa_data)->ifi_ ## s)
  14. #define MAXDRIVENAME 31
  15. #define KILO_FACTOR 1024
  16. #define MEGA_FACTOR 1048576 // 1024 * 1024
  17. #define GIGA_FACTOR 1073741824 // 1024 * 1024 * 1024
  18. int do_macos_iokit(int update_every, usec_t dt) {
  19. (void)dt;
  20. static int do_io = -1, do_space = -1, do_inodes = -1, do_bandwidth = -1;
  21. if (unlikely(do_io == -1)) {
  22. do_io = config_get_boolean("plugin:macos:iokit", "disk i/o", 1);
  23. do_space = config_get_boolean("plugin:macos:sysctl", "space usage for all disks", 1);
  24. do_inodes = config_get_boolean("plugin:macos:sysctl", "inodes usage for all disks", 1);
  25. do_bandwidth = config_get_boolean("plugin:macos:sysctl", "bandwidth", 1);
  26. }
  27. RRDSET *st;
  28. mach_port_t main_port;
  29. io_registry_entry_t drive, drive_media;
  30. io_iterator_t drive_list;
  31. CFDictionaryRef properties, statistics;
  32. CFStringRef name;
  33. CFNumberRef number;
  34. kern_return_t status;
  35. collected_number total_disk_reads = 0;
  36. collected_number total_disk_writes = 0;
  37. struct diskstat {
  38. char name[MAXDRIVENAME];
  39. collected_number bytes_read;
  40. collected_number bytes_write;
  41. collected_number reads;
  42. collected_number writes;
  43. collected_number time_read;
  44. collected_number time_write;
  45. collected_number latency_read;
  46. collected_number latency_write;
  47. } diskstat;
  48. struct cur_diskstat {
  49. collected_number duration_read_ns;
  50. collected_number duration_write_ns;
  51. collected_number busy_time_ns;
  52. } cur_diskstat;
  53. struct prev_diskstat {
  54. collected_number bytes_read;
  55. collected_number bytes_write;
  56. collected_number operations_read;
  57. collected_number operations_write;
  58. collected_number duration_read_ns;
  59. collected_number duration_write_ns;
  60. collected_number busy_time_ns;
  61. } prev_diskstat;
  62. // NEEDED BY: do_space, do_inodes
  63. struct statfs *mntbuf;
  64. int mntsize, i;
  65. char title[4096 + 1];
  66. // NEEDED BY: do_bandwidth
  67. struct ifaddrs *ifa, *ifap;
  68. #if !defined(MAC_OS_VERSION_12_0) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_12_0)
  69. #define IOMainPort IOMasterPort
  70. #endif
  71. /* Get ports and services for drive statistics. */
  72. if (unlikely(IOMainPort(bootstrap_port, &main_port))) {
  73. collector_error("MACOS: IOMasterPort() failed");
  74. do_io = 0;
  75. collector_error("DISABLED: system.io");
  76. /* Get the list of all drive objects. */
  77. } else if (unlikely(IOServiceGetMatchingServices(main_port, IOServiceMatching("IOBlockStorageDriver"), &drive_list))) {
  78. collector_error("MACOS: IOServiceGetMatchingServices() failed");
  79. do_io = 0;
  80. collector_error("DISABLED: system.io");
  81. } else {
  82. while ((drive = IOIteratorNext(drive_list)) != 0) {
  83. properties = 0;
  84. statistics = 0;
  85. number = 0;
  86. bzero(&diskstat, sizeof(diskstat));
  87. /* Get drive media object. */
  88. status = IORegistryEntryGetChildEntry(drive, kIOServicePlane, &drive_media);
  89. if (unlikely(status != KERN_SUCCESS)) {
  90. IOObjectRelease(drive);
  91. continue;
  92. }
  93. /* Get drive media properties. */
  94. if (likely(!IORegistryEntryCreateCFProperties(drive_media, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, 0))) {
  95. /* Get disk name. */
  96. if (likely(name = (CFStringRef)CFDictionaryGetValue(properties, CFSTR(kIOBSDNameKey)))) {
  97. CFStringGetCString(name, diskstat.name, MAXDRIVENAME, kCFStringEncodingUTF8);
  98. }
  99. }
  100. /* Release. */
  101. CFRelease(properties);
  102. IOObjectRelease(drive_media);
  103. if(unlikely(!*diskstat.name)) {
  104. IOObjectRelease(drive);
  105. continue;
  106. }
  107. /* Obtain the properties for this drive object. */
  108. if (unlikely(IORegistryEntryCreateCFProperties(drive, (CFMutableDictionaryRef *)&properties, kCFAllocatorDefault, 0))) {
  109. IOObjectRelease(drive);
  110. collector_error("MACOS: IORegistryEntryCreateCFProperties() failed");
  111. do_io = 0;
  112. collector_error("DISABLED: system.io");
  113. break;
  114. } else if (likely(properties)) {
  115. /* Obtain the statistics from the drive properties. */
  116. if (likely(statistics = (CFDictionaryRef)CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey)))) {
  117. // --------------------------------------------------------------------
  118. /* Get bytes read. */
  119. if (likely(number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)))) {
  120. CFNumberGetValue(number, kCFNumberSInt64Type, &diskstat.bytes_read);
  121. total_disk_reads += diskstat.bytes_read;
  122. }
  123. /* Get bytes written. */
  124. if (likely(number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)))) {
  125. CFNumberGetValue(number, kCFNumberSInt64Type, &diskstat.bytes_write);
  126. total_disk_writes += diskstat.bytes_write;
  127. }
  128. st = rrdset_find_active_bytype_localhost("disk", diskstat.name);
  129. if (unlikely(!st)) {
  130. st = rrdset_create_localhost(
  131. "disk"
  132. , diskstat.name
  133. , NULL
  134. , diskstat.name
  135. , "disk.io"
  136. , "Disk I/O Bandwidth"
  137. , "KiB/s"
  138. , "macos.plugin"
  139. , "iokit"
  140. , 2000
  141. , update_every
  142. , RRDSET_TYPE_AREA
  143. );
  144. rrddim_add(st, "reads", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
  145. rrddim_add(st, "writes", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
  146. }
  147. prev_diskstat.bytes_read = rrddim_set(st, "reads", diskstat.bytes_read);
  148. prev_diskstat.bytes_write = rrddim_set(st, "writes", diskstat.bytes_write);
  149. rrdset_done(st);
  150. /* Get number of reads. */
  151. if (likely(number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey)))) {
  152. CFNumberGetValue(number, kCFNumberSInt64Type, &diskstat.reads);
  153. }
  154. /* Get number of writes. */
  155. if (likely(number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey)))) {
  156. CFNumberGetValue(number, kCFNumberSInt64Type, &diskstat.writes);
  157. }
  158. st = rrdset_find_active_bytype_localhost("disk_ops", diskstat.name);
  159. if (unlikely(!st)) {
  160. st = rrdset_create_localhost(
  161. "disk_ops"
  162. , diskstat.name
  163. , NULL
  164. , diskstat.name
  165. , "disk.ops"
  166. , "Disk Completed I/O Operations"
  167. , "operations/s"
  168. , "macos.plugin"
  169. , "iokit"
  170. , 2001
  171. , update_every
  172. , RRDSET_TYPE_LINE
  173. );
  174. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  175. rrddim_add(st, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  176. rrddim_add(st, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  177. }
  178. prev_diskstat.operations_read = rrddim_set(st, "reads", diskstat.reads);
  179. prev_diskstat.operations_write = rrddim_set(st, "writes", diskstat.writes);
  180. rrdset_done(st);
  181. /* Get reads time. */
  182. if (likely(number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsTotalReadTimeKey)))) {
  183. CFNumberGetValue(number, kCFNumberSInt64Type, &diskstat.time_read);
  184. }
  185. /* Get writes time. */
  186. if (likely(number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey)))) {
  187. CFNumberGetValue(number, kCFNumberSInt64Type, &diskstat.time_write);
  188. }
  189. st = rrdset_find_active_bytype_localhost("disk_util", diskstat.name);
  190. if (unlikely(!st)) {
  191. st = rrdset_create_localhost(
  192. "disk_util"
  193. , diskstat.name
  194. , NULL
  195. , diskstat.name
  196. , "disk.util"
  197. , "Disk Utilization Time"
  198. , "% of time working"
  199. , "macos.plugin"
  200. , "iokit"
  201. , 2004
  202. , update_every
  203. , RRDSET_TYPE_AREA
  204. );
  205. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  206. rrddim_add(st, "utilization", NULL, 1, 10000000, RRD_ALGORITHM_INCREMENTAL);
  207. }
  208. cur_diskstat.busy_time_ns = (diskstat.time_read + diskstat.time_write);
  209. prev_diskstat.busy_time_ns = rrddim_set(st, "utilization", cur_diskstat.busy_time_ns);
  210. rrdset_done(st);
  211. /* Get reads latency. */
  212. if (likely(number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsLatentReadTimeKey)))) {
  213. CFNumberGetValue(number, kCFNumberSInt64Type, &diskstat.latency_read);
  214. }
  215. /* Get writes latency. */
  216. if (likely(number = (CFNumberRef)CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsLatentWriteTimeKey)))) {
  217. CFNumberGetValue(number, kCFNumberSInt64Type, &diskstat.latency_write);
  218. }
  219. st = rrdset_find_active_bytype_localhost("disk_iotime", diskstat.name);
  220. if (unlikely(!st)) {
  221. st = rrdset_create_localhost(
  222. "disk_iotime"
  223. , diskstat.name
  224. , NULL
  225. , diskstat.name
  226. , "disk.iotime"
  227. , "Disk Total I/O Time"
  228. , "milliseconds/s"
  229. , "macos.plugin"
  230. , "iokit"
  231. , 2022
  232. , update_every
  233. , RRDSET_TYPE_LINE
  234. );
  235. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  236. rrddim_add(st, "reads", NULL, 1, 1000000, RRD_ALGORITHM_INCREMENTAL);
  237. rrddim_add(st, "writes", NULL, -1, 1000000, RRD_ALGORITHM_INCREMENTAL);
  238. }
  239. cur_diskstat.duration_read_ns = diskstat.time_read + diskstat.latency_read;
  240. cur_diskstat.duration_write_ns = diskstat.time_write + diskstat.latency_write;
  241. prev_diskstat.duration_read_ns = rrddim_set(st, "reads", cur_diskstat.duration_read_ns);
  242. prev_diskstat.duration_write_ns = rrddim_set(st, "writes", cur_diskstat.duration_write_ns);
  243. rrdset_done(st);
  244. // calculate differential charts
  245. // only if this is not the first time we run
  246. if (likely(dt)) {
  247. st = rrdset_find_active_bytype_localhost("disk_await", diskstat.name);
  248. if (unlikely(!st)) {
  249. st = rrdset_create_localhost(
  250. "disk_await"
  251. , diskstat.name
  252. , NULL
  253. , diskstat.name
  254. , "disk.await"
  255. , "Average Completed I/O Operation Time"
  256. , "milliseconds/operation"
  257. , "macos.plugin"
  258. , "iokit"
  259. , 2005
  260. , update_every
  261. , RRDSET_TYPE_LINE
  262. );
  263. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  264. rrddim_add(st, "reads", NULL, 1, 1000000, RRD_ALGORITHM_ABSOLUTE);
  265. rrddim_add(st, "writes", NULL, -1, 1000000, RRD_ALGORITHM_ABSOLUTE);
  266. }
  267. rrddim_set(st, "reads", (diskstat.reads - prev_diskstat.operations_read) ?
  268. (cur_diskstat.duration_read_ns - prev_diskstat.duration_read_ns) / (diskstat.reads - prev_diskstat.operations_read) : 0);
  269. rrddim_set(st, "writes", (diskstat.writes - prev_diskstat.operations_write) ?
  270. (cur_diskstat.duration_write_ns - prev_diskstat.duration_write_ns) / (diskstat.writes - prev_diskstat.operations_write) : 0);
  271. rrdset_done(st);
  272. st = rrdset_find_active_bytype_localhost("disk_avgsz", diskstat.name);
  273. if (unlikely(!st)) {
  274. st = rrdset_create_localhost(
  275. "disk_avgsz"
  276. , diskstat.name
  277. , NULL
  278. , diskstat.name
  279. , "disk.avgsz"
  280. , "Average Completed I/O Operation Bandwidth"
  281. , "KiB/operation"
  282. , "macos.plugin"
  283. , "iokit"
  284. , 2006
  285. , update_every
  286. , RRDSET_TYPE_AREA
  287. );
  288. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  289. rrddim_add(st, "reads", NULL, 1, 1024, RRD_ALGORITHM_ABSOLUTE);
  290. rrddim_add(st, "writes", NULL, -1, 1024, RRD_ALGORITHM_ABSOLUTE);
  291. }
  292. rrddim_set(st, "reads", (diskstat.reads - prev_diskstat.operations_read) ?
  293. (diskstat.bytes_read - prev_diskstat.bytes_read) / (diskstat.reads - prev_diskstat.operations_read) : 0);
  294. rrddim_set(st, "writes", (diskstat.writes - prev_diskstat.operations_write) ?
  295. (diskstat.bytes_write - prev_diskstat.bytes_write) / (diskstat.writes - prev_diskstat.operations_write) : 0);
  296. rrdset_done(st);
  297. st = rrdset_find_active_bytype_localhost("disk_svctm", diskstat.name);
  298. if (unlikely(!st)) {
  299. st = rrdset_create_localhost(
  300. "disk_svctm"
  301. , diskstat.name
  302. , NULL
  303. , diskstat.name
  304. , "disk.svctm"
  305. , "Average Service Time"
  306. , "milliseconds/operation"
  307. , "macos.plugin"
  308. , "iokit"
  309. , 2007
  310. , update_every
  311. , RRDSET_TYPE_LINE
  312. );
  313. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  314. rrddim_add(st, "svctm", NULL, 1, 1000000, RRD_ALGORITHM_ABSOLUTE);
  315. }
  316. rrddim_set(st, "svctm", ((diskstat.reads - prev_diskstat.operations_read) + (diskstat.writes - prev_diskstat.operations_write)) ?
  317. (cur_diskstat.busy_time_ns - prev_diskstat.busy_time_ns) / ((diskstat.reads - prev_diskstat.operations_read) + (diskstat.writes - prev_diskstat.operations_write)) : 0);
  318. rrdset_done(st);
  319. }
  320. }
  321. /* Release. */
  322. CFRelease(properties);
  323. }
  324. /* Release. */
  325. IOObjectRelease(drive);
  326. }
  327. IOIteratorReset(drive_list);
  328. /* Release. */
  329. IOObjectRelease(drive_list);
  330. }
  331. if (likely(do_io)) {
  332. st = rrdset_find_active_bytype_localhost("system", "io");
  333. if (unlikely(!st)) {
  334. st = rrdset_create_localhost(
  335. "system"
  336. , "io"
  337. , NULL
  338. , "disk"
  339. , NULL
  340. , "Disk I/O"
  341. , "KiB/s"
  342. , "macos.plugin"
  343. , "iokit"
  344. , 150
  345. , update_every
  346. , RRDSET_TYPE_AREA
  347. );
  348. rrddim_add(st, "in", NULL, 1, 1024, RRD_ALGORITHM_INCREMENTAL);
  349. rrddim_add(st, "out", NULL, -1, 1024, RRD_ALGORITHM_INCREMENTAL);
  350. }
  351. rrddim_set(st, "in", total_disk_reads);
  352. rrddim_set(st, "out", total_disk_writes);
  353. rrdset_done(st);
  354. }
  355. // Can be merged with FreeBSD plugin
  356. if (likely(do_space || do_inodes)) {
  357. // there is no mount info in sysctl MIBs
  358. if (unlikely(!(mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)))) {
  359. collector_error("MACOS: getmntinfo() failed");
  360. do_space = 0;
  361. collector_error("DISABLED: disk_space.X");
  362. do_inodes = 0;
  363. collector_error("DISABLED: disk_inodes.X");
  364. } else {
  365. for (i = 0; i < mntsize; i++) {
  366. if (mntbuf[i].f_flags == MNT_RDONLY ||
  367. mntbuf[i].f_blocks == 0 ||
  368. // taken from gnulib/mountlist.c and shortened to FreeBSD related fstypes
  369. strcmp(mntbuf[i].f_fstypename, "autofs") == 0 ||
  370. strcmp(mntbuf[i].f_fstypename, "procfs") == 0 ||
  371. strcmp(mntbuf[i].f_fstypename, "subfs") == 0 ||
  372. strcmp(mntbuf[i].f_fstypename, "devfs") == 0 ||
  373. strcmp(mntbuf[i].f_fstypename, "none") == 0)
  374. continue;
  375. // --------------------------------------------------------------------------
  376. if (likely(do_space)) {
  377. st = rrdset_find_active_bytype_localhost("disk_space", mntbuf[i].f_mntonname);
  378. if (unlikely(!st)) {
  379. snprintfz(title, sizeof(title) - 1, "Disk Space Usage for %s [%s]", mntbuf[i].f_mntonname, mntbuf[i].f_mntfromname);
  380. st = rrdset_create_localhost(
  381. "disk_space"
  382. , mntbuf[i].f_mntonname
  383. , NULL
  384. , mntbuf[i].f_mntonname
  385. , "disk.space"
  386. , title
  387. , "GiB"
  388. , "macos.plugin"
  389. , "iokit"
  390. , 2023
  391. , update_every
  392. , RRDSET_TYPE_STACKED
  393. );
  394. rrddim_add(st, "avail", NULL, mntbuf[i].f_bsize, GIGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
  395. rrddim_add(st, "used", NULL, mntbuf[i].f_bsize, GIGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
  396. rrddim_add(st, "reserved_for_root", "reserved for root", mntbuf[i].f_bsize, GIGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
  397. }
  398. rrddim_set(st, "avail", (collected_number) mntbuf[i].f_bavail);
  399. rrddim_set(st, "used", (collected_number) (mntbuf[i].f_blocks - mntbuf[i].f_bfree));
  400. rrddim_set(st, "reserved_for_root", (collected_number) (mntbuf[i].f_bfree - mntbuf[i].f_bavail));
  401. rrdset_done(st);
  402. }
  403. // --------------------------------------------------------------------------
  404. if (likely(do_inodes)) {
  405. st = rrdset_find_active_bytype_localhost("disk_inodes", mntbuf[i].f_mntonname);
  406. if (unlikely(!st)) {
  407. snprintfz(title, sizeof(title) - 1, "Disk Files (inodes) Usage for %s [%s]", mntbuf[i].f_mntonname, mntbuf[i].f_mntfromname);
  408. st = rrdset_create_localhost(
  409. "disk_inodes"
  410. , mntbuf[i].f_mntonname
  411. , NULL
  412. , mntbuf[i].f_mntonname
  413. , "disk.inodes"
  414. , title
  415. , "inodes"
  416. , "macos.plugin"
  417. , "iokit"
  418. , 2024
  419. , update_every
  420. , RRDSET_TYPE_STACKED
  421. );
  422. rrddim_add(st, "avail", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  423. rrddim_add(st, "used", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  424. rrddim_add(st, "reserved_for_root", "reserved for root", 1, 1, RRD_ALGORITHM_ABSOLUTE);
  425. }
  426. rrddim_set(st, "avail", (collected_number) mntbuf[i].f_ffree);
  427. rrddim_set(st, "used", (collected_number) (mntbuf[i].f_files - mntbuf[i].f_ffree));
  428. rrdset_done(st);
  429. }
  430. }
  431. }
  432. }
  433. // Can be merged with FreeBSD plugin
  434. if (likely(do_bandwidth)) {
  435. if (unlikely(getifaddrs(&ifap))) {
  436. collector_error("MACOS: getifaddrs()");
  437. do_bandwidth = 0;
  438. collector_error("DISABLED: system.ipv4");
  439. } else {
  440. for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
  441. if (ifa->ifa_addr->sa_family != AF_LINK)
  442. continue;
  443. st = rrdset_find_active_bytype_localhost("net", ifa->ifa_name);
  444. if (unlikely(!st)) {
  445. st = rrdset_create_localhost(
  446. "net"
  447. , ifa->ifa_name
  448. , NULL
  449. , ifa->ifa_name
  450. , "net.net"
  451. , "Bandwidth"
  452. , "kilobits/s"
  453. , "macos.plugin"
  454. , "iokit"
  455. , 7000
  456. , update_every
  457. , RRDSET_TYPE_AREA
  458. );
  459. rrddim_add(st, "received", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  460. rrddim_add(st, "sent", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  461. }
  462. rrddim_set(st, "received", IFA_DATA(ibytes));
  463. rrddim_set(st, "sent", IFA_DATA(obytes));
  464. rrdset_done(st);
  465. st = rrdset_find_active_bytype_localhost("net_packets", ifa->ifa_name);
  466. if (unlikely(!st)) {
  467. st = rrdset_create_localhost(
  468. "net_packets"
  469. , ifa->ifa_name
  470. , NULL
  471. , ifa->ifa_name
  472. , "net.packets"
  473. , "Packets"
  474. , "packets/s"
  475. , "macos.plugin"
  476. , "iokit"
  477. , 7001
  478. , update_every
  479. , RRDSET_TYPE_LINE
  480. );
  481. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  482. rrddim_add(st, "received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  483. rrddim_add(st, "sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  484. rrddim_add(st, "multicast_received", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  485. rrddim_add(st, "multicast_sent", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  486. }
  487. rrddim_set(st, "received", IFA_DATA(ipackets));
  488. rrddim_set(st, "sent", IFA_DATA(opackets));
  489. rrddim_set(st, "multicast_received", IFA_DATA(imcasts));
  490. rrddim_set(st, "multicast_sent", IFA_DATA(omcasts));
  491. rrdset_done(st);
  492. st = rrdset_find_active_bytype_localhost("net_errors", ifa->ifa_name);
  493. if (unlikely(!st)) {
  494. st = rrdset_create_localhost(
  495. "net_errors"
  496. , ifa->ifa_name
  497. , NULL
  498. , ifa->ifa_name
  499. , "net.errors"
  500. , "Interface Errors"
  501. , "errors/s"
  502. , "macos.plugin"
  503. , "iokit"
  504. , 7002
  505. , update_every
  506. , RRDSET_TYPE_LINE
  507. );
  508. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  509. rrddim_add(st, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  510. rrddim_add(st, "outbound", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  511. }
  512. rrddim_set(st, "inbound", IFA_DATA(ierrors));
  513. rrddim_set(st, "outbound", IFA_DATA(oerrors));
  514. rrdset_done(st);
  515. st = rrdset_find_active_bytype_localhost("net_drops", ifa->ifa_name);
  516. if (unlikely(!st)) {
  517. st = rrdset_create_localhost(
  518. "net_drops"
  519. , ifa->ifa_name
  520. , NULL
  521. , ifa->ifa_name
  522. , "net.drops"
  523. , "Interface Drops"
  524. , "drops/s"
  525. , "macos.plugin"
  526. , "iokit"
  527. , 7003
  528. , update_every
  529. , RRDSET_TYPE_LINE
  530. );
  531. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  532. rrddim_add(st, "inbound", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  533. }
  534. rrddim_set(st, "inbound", IFA_DATA(iqdrops));
  535. rrdset_done(st);
  536. st = rrdset_find_active_bytype_localhost("net_events", ifa->ifa_name);
  537. if (unlikely(!st)) {
  538. st = rrdset_create_localhost(
  539. "net_events"
  540. , ifa->ifa_name
  541. , NULL
  542. , ifa->ifa_name
  543. , "net.events"
  544. , "Network Interface Events"
  545. , "events/s"
  546. , "macos.plugin"
  547. , "iokit"
  548. , 7006
  549. , update_every
  550. , RRDSET_TYPE_LINE
  551. );
  552. rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
  553. rrddim_add(st, "frames", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  554. rrddim_add(st, "collisions", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  555. rrddim_add(st, "carrier", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  556. }
  557. rrddim_set(st, "collisions", IFA_DATA(collisions));
  558. rrdset_done(st);
  559. }
  560. freeifaddrs(ifap);
  561. }
  562. }
  563. return 0;
  564. }