Packages
Prometheus.io process collector Collector exports the current state of process metrics including cpu, memory, file descriptor usage and native threads count as well as the process start and up times.
Current section
Files
Jump to
Current section
Files
c_src/prometheus_process_info_freebsd.cc
#include "prometheus_process_info.h"
#include <cstdio>
#include <ctime>
#include <memory>
namespace Prometheus
{
static long pagesize(void)
{
uint pageSize;
size_t len = sizeof(pageSize);
if (sysctlbyname("vm.stats.vm.v_page_size", &pageSize, &len, NULL, 0) == -1)
{
long spageSize = sysconf(_SC_PAGESIZE);
if (spageSize == -1)
{
throw ProcessInfoException();
}
else
{
return spageSize;
}
}
else
{
return pageSize;
}
}
static std::unique_ptr<kinfo_proc> kinfo_getproc(pid_t pid)
{
int mib[4];
size_t len;
len = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = pid;
if (sysctl(mib, nitems(mib), NULL, &len, NULL, 0) < 0)
{
throw ProcessInfoException();
}
std::unique_ptr<kinfo_proc>
kipp {reinterpret_cast<kinfo_proc*>(new char[len])};
if (sysctl(mib, 4, kipp.get(), &len, NULL, 0) < 0)
{
throw ProcessInfoException();
}
if (len != sizeof(*kipp))
{
throw ProcessInfoException();
}
if (kipp->ki_structsize != sizeof(*kipp))
{
throw ProcessInfoException();
}
if (kipp->ki_pid != pid)
{
throw ProcessInfoException();
}
return kipp;
}
/*
from https://github.com/freebsd/freebsd/blob/9e0a154b0fd5fa9010238ac9497ec59f84167c92/lib/libutil/kinfo_getfile.c#L22-L51
I don't need unpacked structs here, just count. Hope it won't break someday.
*/
int ProcessInfo::get_fds_total()
{
int mib[4];
int error;
int count;
size_t len;
char *buf, *eb;
struct kinfo_file *kf;
// get size of all pids
len = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_FILEDESC;
mib[3] = pid;
error = sysctl(mib, nitems(mib), NULL, &len, NULL, 0);
if (error)
{
throw ProcessInfoException();
}
// allocate buf for pids
len = len * 4 / 3;
buf = (char*)malloc(len);
if (buf == NULL)
{
throw ProcessInfoException();
}
// fill buf with kinfo_files
error = sysctl(mib, nitems(mib), buf, &len, NULL, 0);
if (error)
{
free(buf);
throw ProcessInfoException();
}
// count structs in the buf
count = 0;
eb = buf + len;
while (buf < eb)
{
kf = (struct kinfo_file *)(uintptr_t)buf;
if (kf->kf_structsize == 0)
break;
buf += kf->kf_structsize;
count++;
}
free(buf - len);
return count;
}
void ProcessInfo::set_proc_stat()
{
auto proc = kinfo_getproc(pid);
start_time_seconds = proc->ki_start.tv_sec;
uptime_seconds = now - proc->ki_start.tv_sec;
threads_total = proc->ki_numthreads;
vm_bytes = proc->ki_size;
rm_bytes = proc->ki_rssize * pagesize();
}
}