diff options
Diffstat (limited to 'src/collectors/apps.plugin/apps_proc_pid_io.c')
-rw-r--r-- | src/collectors/apps.plugin/apps_proc_pid_io.c | 95 |
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; +} |