summaryrefslogtreecommitdiffstats
path: root/src/collectors/apps.plugin/apps_proc_pid_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/collectors/apps.plugin/apps_proc_pid_io.c')
-rw-r--r--src/collectors/apps.plugin/apps_proc_pid_io.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/collectors/apps.plugin/apps_proc_pid_io.c b/src/collectors/apps.plugin/apps_proc_pid_io.c
new file mode 100644
index 000000000..0fef3fc24
--- /dev/null
+++ b/src/collectors/apps.plugin/apps_proc_pid_io.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "apps_plugin.h"
+
+static inline void clear_pid_io(struct pid_stat *p) {
+ p->io_logical_bytes_read = 0;
+ p->io_logical_bytes_written = 0;
+ p->io_read_calls = 0;
+ p->io_write_calls = 0;
+ p->io_storage_bytes_read = 0;
+ p->io_storage_bytes_written = 0;
+ p->io_cancelled_write_bytes = 0;
+}
+
+#if defined(__FreeBSD__)
+static inline bool read_proc_pid_io_per_os(struct pid_stat *p, void *ptr) {
+ struct kinfo_proc *proc_info = (struct kinfo_proc *)ptr;
+
+ pid_incremental_rate(io, p->io_storage_bytes_read, proc_info->ki_rusage.ru_inblock);
+ pid_incremental_rate(io, p->io_storage_bytes_written, proc_info->ki_rusage.ru_oublock);
+
+ p->io_logical_bytes_read = 0;
+ p->io_logical_bytes_written = 0;
+ p->io_read_calls = 0;
+ p->io_write_calls = 0;
+ p->io_cancelled_write_bytes = 0;
+
+ return true;
+}
+#endif
+
+#ifdef __APPLE__
+static inline bool read_proc_pid_io_per_os(struct pid_stat *p, void *ptr) {
+ struct pid_info *pi = ptr;
+
+ // On MacOS, the proc_pid_rusage provides disk_io_statistics which includes io bytes read and written
+ // but does not provide the same level of detail as Linux, like separating logical and physical I/O bytes.
+ pid_incremental_rate(io, p->io_storage_bytes_read, pi->rusageinfo.ri_diskio_bytesread);
+ pid_incremental_rate(io, p->io_storage_bytes_written, pi->rusageinfo.ri_diskio_byteswritten);
+
+ p->io_logical_bytes_read = 0;
+ p->io_logical_bytes_written = 0;
+ p->io_read_calls = 0;
+ p->io_write_calls = 0;
+ p->io_cancelled_write_bytes = 0;
+
+ return true;
+}
+#endif // __APPLE__
+
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
+static inline int read_proc_pid_io_per_os(struct pid_stat *p, void *ptr __maybe_unused) {
+ static procfile *ff = NULL;
+
+ if(unlikely(!p->io_filename)) {
+ char filename[FILENAME_MAX + 1];
+ snprintfz(filename, FILENAME_MAX, "%s/proc/%d/io", netdata_configured_host_prefix, p->pid);
+ p->io_filename = strdupz(filename);
+ }
+
+ // open the file
+ ff = procfile_reopen(ff, p->io_filename, NULL, PROCFILE_FLAG_NO_ERROR_ON_FILE_IO);
+ if(unlikely(!ff)) goto cleanup;
+
+ ff = procfile_readall(ff);
+ if(unlikely(!ff)) goto cleanup;
+
+ pid_incremental_rate(io, p->io_logical_bytes_read, str2kernel_uint_t(procfile_lineword(ff, 0, 1)));
+ pid_incremental_rate(io, p->io_logical_bytes_written, str2kernel_uint_t(procfile_lineword(ff, 1, 1)));
+ pid_incremental_rate(io, p->io_read_calls, str2kernel_uint_t(procfile_lineword(ff, 2, 1)));
+ pid_incremental_rate(io, p->io_write_calls, str2kernel_uint_t(procfile_lineword(ff, 3, 1)));
+ pid_incremental_rate(io, p->io_storage_bytes_read, str2kernel_uint_t(procfile_lineword(ff, 4, 1)));
+ pid_incremental_rate(io, p->io_storage_bytes_written, str2kernel_uint_t(procfile_lineword(ff, 5, 1)));
+ pid_incremental_rate(io, p->io_cancelled_write_bytes, str2kernel_uint_t(procfile_lineword(ff, 6, 1)));
+
+ return true;
+
+cleanup:
+ clear_pid_io(p);
+ return false;
+}
+#endif // !__FreeBSD__ !__APPLE__
+
+int read_proc_pid_io(struct pid_stat *p, void *ptr) {
+ p->last_io_collected_usec = p->io_collected_usec;
+ p->io_collected_usec = now_monotonic_usec();
+ calls_counter++;
+
+ bool ret = read_proc_pid_io_per_os(p, ptr);
+
+ if(unlikely(global_iterations_counter == 1))
+ clear_pid_io(p);
+
+ return ret ? 1 : 0;
+}