2 #include <sys/vmmeter.h>
4 int do_proc_stat(int update_every, unsigned long long dt) {
7 static int do_cpu = -1, do_cpu_cores = -1, do_interrupts = -1, do_context = -1, do_forks = -1, do_processes = -1;
9 if(unlikely(do_cpu == -1)) {
10 do_cpu = config_get_boolean("plugin:proc:/proc/stat", "cpu utilization", 1);
11 do_cpu_cores = config_get_boolean("plugin:proc:/proc/stat", "per cpu core utilization", 1);
12 do_interrupts = config_get_boolean("plugin:proc:/proc/stat", "cpu interrupts", 1);
13 do_context = config_get_boolean("plugin:proc:/proc/stat", "context switches", 1);
14 do_forks = config_get_boolean("plugin:proc:/proc/stat", "processes started", 1);
15 do_processes = config_get_boolean("plugin:proc:/proc/stat", "processes running", 1);
20 char cpuid[5] = "cpu0";
21 unsigned long long user = 0, nice = 0, system = 0, interrupt = 0, idle = 0;
24 unsigned long nintr = 0;
25 unsigned long *intrcnt;
26 unsigned long long totalintr = 0;
27 unsigned long long running = 0 , blocked = 0;
30 long divisor = 1; // sysconf(_SC_CLK_TCK);
32 long cp_time[CPUSTATES];
40 if (unlikely(CPUSTATES != 5)) {
41 error("There are %d CPU states (5 was expected)", CPUSTATES);
43 error("Total CPU utilization stats was switched off");
46 if (unlikely(GETSYSCTL("kern.cp_time", cp_time))) {
48 error("Total CPU utilization stats was switched off");
54 interrupt = cp_time[3];
57 st = rrdset_find_bytype("system", "cpu");
59 st = rrdset_create("system", "cpu", NULL, "cpu", "system.cpu", "Total CPU utilization", "percentage", 100, update_every, RRDSET_TYPE_STACKED);
61 rrddim_add(st, "user", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
62 rrddim_add(st, "system", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
63 rrddim_add(st, "interrupt", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
64 rrddim_add(st, "nice", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
65 rrddim_add(st, "idle", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
66 rrddim_hide(st, "idle");
70 rrddim_set(st, "user", user);
71 rrddim_set(st, "system", system);
72 rrddim_set(st, "interrupt", interrupt);
73 rrddim_set(st, "nice", nice);
74 rrddim_set(st, "idle", idle);
78 // --------------------------------------------------------------------
80 if(likely(do_cpu_cores)) {
81 if (unlikely(CPUSTATES != 5)) {
82 error("There are %d CPU states (5 was expected)", CPUSTATES);
84 error("CPU cores utilization stats was switched off");
87 if (unlikely(GETSYSCTL("kern.smp.cpus", ncpus))) {
89 error("CPU cores utilization stats was switched off");
92 pcpu_cp_time = malloc(sizeof(cp_time) * ncpus);
94 for (i = 0; i < ncpus; i++) {
95 if (unlikely(getsysctl("kern.cp_times", pcpu_cp_time, sizeof(cp_time) * ncpus))) {
97 error("CPU cores utilization stats was switched off");
101 user = pcpu_cp_time[i * 5 + 0];
102 nice = pcpu_cp_time[i * 5 + 1];
103 system = pcpu_cp_time[i * 5 + 2];
104 interrupt = pcpu_cp_time[i * 5 + 3];
105 idle = pcpu_cp_time[i * 5 + 4];
107 st = rrdset_find_bytype("cpu", cpuid);
109 st = rrdset_create("cpu", cpuid, NULL, "utilization", "cpu.cpu", "Core utilization", "percentage", 1000, update_every, RRDSET_TYPE_STACKED);
111 rrddim_add(st, "user", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
112 rrddim_add(st, "system", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
113 rrddim_add(st, "interrupt", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
114 rrddim_add(st, "nice", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
115 rrddim_add(st, "idle", NULL, multiplier, divisor, RRDDIM_PCENT_OVER_DIFF_TOTAL);
116 rrddim_hide(st, "idle");
118 else rrdset_next(st);
120 rrddim_set(st, "user", user);
121 rrddim_set(st, "system", system);
122 rrddim_set(st, "interrupt", interrupt);
123 rrddim_set(st, "nice", nice);
124 rrddim_set(st, "idle", idle);
130 // --------------------------------------------------------------------
132 if(likely(do_interrupts)) {
133 if (unlikely(sysctlbyname("hw.intrcnt", NULL, &intrcnt_size, NULL, 0) == -1)) {
134 error("sysctl(hw.intrcnt...) failed: %s", strerror(errno));
136 error("Total device interrupts stats was switched off");
139 nintr = intrcnt_size / sizeof(u_long);
140 intrcnt = malloc(nintr * sizeof(u_long));
141 if (unlikely(getsysctl("hw.intrcnt", intrcnt, nintr * sizeof(u_long)))){
143 error("Total device interrupts stats was switched off");
146 for (i = 0; i < nintr; i++)
147 totalintr += intrcnt[i];
150 st = rrdset_find_bytype("system", "intr");
152 st = rrdset_create("system", "intr", NULL, "interrupts", NULL, "Total Device Interrupts", "interrupts/s", 900, update_every, RRDSET_TYPE_LINE);
155 rrddim_add(st, "interrupts", NULL, 1, 1, RRDDIM_INCREMENTAL);
157 else rrdset_next(st);
159 rrddim_set(st, "interrupts", totalintr);
163 /* Temporarily switched off
164 if(likely(do_interrupts)) {
165 if (unlikely(GETSYSCTL("vm.stats.sys.v_intr", vm_stat))) {
167 error("Device interrupts utilization stats was switched off");
171 st = rrdset_find_bytype("system", "intr");
173 st = rrdset_create("system", "intr", NULL, "interrupts", NULL, "Device Interrupts", "interrupts/s", 900, update_every, RRDSET_TYPE_LINE);
176 rrddim_add(st, "interrupts", NULL, 1, 1, RRDDIM_INCREMENTAL);
178 else rrdset_next(st);
180 rrddim_set(st, "interrupts", vm_stat);
184 // --------------------------------------------------------------------
186 if(likely(do_context)) {
187 if (unlikely(GETSYSCTL("vm.stats.sys.v_swtch", vm_stat))) {
189 error("CPU context switches stats was switched off");
193 st = rrdset_find_bytype("system", "ctxt");
195 st = rrdset_create("system", "ctxt", NULL, "processes", NULL, "CPU Context Switches", "context switches/s", 800, update_every, RRDSET_TYPE_LINE);
197 rrddim_add(st, "switches", NULL, 1, 1, RRDDIM_INCREMENTAL);
199 else rrdset_next(st);
201 rrddim_set(st, "switches", vm_stat);
205 // --------------------------------------------------------------------
207 if(likely(do_forks)) {
208 if (unlikely(GETSYSCTL("vm.stats.vm.v_forks", vm_stat))) {
210 error("Fork stats was switched off");
214 st = rrdset_find_bytype("system", "forks");
216 st = rrdset_create("system", "forks", NULL, "processes", NULL, "Started Processes", "processes/s", 700, update_every, RRDSET_TYPE_LINE);
219 rrddim_add(st, "started", NULL, 1, 1, RRDDIM_INCREMENTAL);
221 else rrdset_next(st);
223 rrddim_set(st, "started", vm_stat);
227 // --------------------------------------------------------------------
229 if(likely(do_processes)) {
230 if (unlikely(GETSYSCTL("vm.vmtotal", total))) {
232 error("System processes stats was switched off");
236 running = total.t_rq;
237 blocked = total.t_dw + total.t_pw;
239 st = rrdset_find_bytype("system", "processes");
241 st = rrdset_create("system", "processes", NULL, "processes", NULL, "System Processes", "processes", 600, update_every, RRDSET_TYPE_LINE);
243 rrddim_add(st, "running", NULL, 1, 1, RRDDIM_ABSOLUTE);
244 rrddim_add(st, "blocked", NULL, -1, 1, RRDDIM_ABSOLUTE);
246 else rrdset_next(st);
248 rrddim_set(st, "running", running);
249 rrddim_set(st, "blocked", blocked);