macos_fw.c 31 KB

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