]> arthur.barton.de Git - netdata.git/blob - src/plugin_proc.c
Merge remote-tracking branch 'upstream/master' into health
[netdata.git] / src / plugin_proc.c
1 #include "common.h"
2
3 void *proc_main(void *ptr)
4 {
5         (void)ptr;
6
7         unsigned long long old_web_requests = 0, old_web_usec = 0,
8                         old_content_size = 0, old_compressed_content_size = 0;
9
10         collected_number compression_ratio = -1, average_response_time = -1;
11
12         info("PROC Plugin thread created with task id %d", gettid());
13
14         if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
15                 error("Cannot set pthread cancel type to DEFERRED.");
16
17         if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
18                 error("Cannot set pthread cancel state to ENABLE.");
19
20         struct rusage me, thread;
21
22         // disable (by default) various interface that are not needed
23         config_get_boolean("plugin:proc:/proc/net/dev:lo", "enabled", 0);
24         config_get_boolean("plugin:proc:/proc/net/dev:fireqos_monitor", "enabled", 0);
25
26         // when ZERO, attempt to do it
27         int vdo_proc_net_dev                    = !config_get_boolean("plugin:proc", "/proc/net/dev", 1);
28         int vdo_proc_diskstats                  = !config_get_boolean("plugin:proc", "/proc/diskstats", 1);
29         int vdo_proc_net_snmp                   = !config_get_boolean("plugin:proc", "/proc/net/snmp", 1);
30         int vdo_proc_net_snmp6                  = !config_get_boolean("plugin:proc", "/proc/net/snmp6", 1);
31         int vdo_proc_net_netstat                = !config_get_boolean("plugin:proc", "/proc/net/netstat", 1);
32         int vdo_proc_net_stat_conntrack = !config_get_boolean("plugin:proc", "/proc/net/stat/conntrack", 1);
33         int vdo_proc_net_ip_vs_stats    = !config_get_boolean("plugin:proc", "/proc/net/ip_vs/stats", 1);
34         int vdo_proc_net_stat_synproxy  = !config_get_boolean("plugin:proc", "/proc/net/stat/synproxy", 1);
35         int vdo_proc_stat                               = !config_get_boolean("plugin:proc", "/proc/stat", 1);
36         int vdo_proc_meminfo                    = !config_get_boolean("plugin:proc", "/proc/meminfo", 1);
37         int vdo_proc_vmstat                     = !config_get_boolean("plugin:proc", "/proc/vmstat", 1);
38         int vdo_proc_net_rpc_nfsd               = !config_get_boolean("plugin:proc", "/proc/net/rpc/nfsd", 1);
39         int vdo_proc_sys_kernel_random_entropy_avail    = !config_get_boolean("plugin:proc", "/proc/sys/kernel/random/entropy_avail", 1);
40         int vdo_proc_interrupts                 = !config_get_boolean("plugin:proc", "/proc/interrupts", 1);
41         int vdo_proc_softirqs                   = !config_get_boolean("plugin:proc", "/proc/softirqs", 1);
42         int vdo_proc_loadavg                    = !config_get_boolean("plugin:proc", "/proc/loadavg", 1);
43         int vdo_sys_kernel_mm_ksm               = !config_get_boolean("plugin:proc", "/sys/kernel/mm/ksm", 1);
44         int vdo_cpu_netdata                     = !config_get_boolean("plugin:proc", "netdata server resources", 1);
45
46         // keep track of the time each module was called
47         unsigned long long sutime_proc_net_dev = 0ULL;
48         unsigned long long sutime_proc_diskstats = 0ULL;
49         unsigned long long sutime_proc_net_snmp = 0ULL;
50         unsigned long long sutime_proc_net_snmp6 = 0ULL;
51         unsigned long long sutime_proc_net_netstat = 0ULL;
52         unsigned long long sutime_proc_net_stat_conntrack = 0ULL;
53         unsigned long long sutime_proc_net_ip_vs_stats = 0ULL;
54         unsigned long long sutime_proc_net_stat_synproxy = 0ULL;
55         unsigned long long sutime_proc_stat = 0ULL;
56         unsigned long long sutime_proc_meminfo = 0ULL;
57         unsigned long long sutime_proc_vmstat = 0ULL;
58         unsigned long long sutime_proc_net_rpc_nfsd = 0ULL;
59         unsigned long long sutime_proc_sys_kernel_random_entropy_avail = 0ULL;
60         unsigned long long sutime_proc_interrupts = 0ULL;
61         unsigned long long sutime_proc_softirqs = 0ULL;
62         unsigned long long sutime_proc_loadavg = 0ULL;
63         unsigned long long sutime_sys_kernel_mm_ksm = 0ULL;
64
65         // the next time we will run - aligned properly
66         unsigned long long sunext = (time(NULL) - (time(NULL) % rrd_update_every) + rrd_update_every) * 1000000ULL;
67         unsigned long long sunow;
68
69         RRDSET *stcpu = NULL, *stcpu_thread = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL, *stduration = NULL,
70                         *stcompression = NULL;
71
72         for(;1;) {
73                 if(unlikely(netdata_exit)) break;
74
75                 // delay until it is our time to run
76                 while((sunow = timems()) < sunext)
77                         usecsleep(sunext - sunow);
78
79                 // find the next time we need to run
80                 while(timems() > sunext)
81                         sunext += rrd_update_every * 1000000ULL;
82
83                 if(unlikely(netdata_exit)) break;
84
85                 // BEGIN -- the job to be done
86
87                 if(!vdo_sys_kernel_mm_ksm) {
88                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_sys_kernel_mm_ksm().");
89
90                         sunow = timems();
91                         vdo_sys_kernel_mm_ksm = do_sys_kernel_mm_ksm(rrd_update_every, (sutime_sys_kernel_mm_ksm > 0)?sunow - sutime_sys_kernel_mm_ksm:0ULL);
92                         sutime_sys_kernel_mm_ksm = sunow;
93                 }
94                 if(unlikely(netdata_exit)) break;
95
96                 if(!vdo_proc_loadavg) {
97                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_loadavg().");
98                         sunow = timems();
99                         vdo_proc_loadavg = do_proc_loadavg(rrd_update_every, (sutime_proc_loadavg > 0)?sunow - sutime_proc_loadavg:0ULL);
100                         sutime_proc_loadavg = sunow;
101                 }
102                 if(unlikely(netdata_exit)) break;
103
104                 if(!vdo_proc_interrupts) {
105                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_interrupts().");
106                         sunow = timems();
107                         vdo_proc_interrupts = do_proc_interrupts(rrd_update_every, (sutime_proc_interrupts > 0)?sunow - sutime_proc_interrupts:0ULL);
108                         sutime_proc_interrupts = sunow;
109                 }
110                 if(unlikely(netdata_exit)) break;
111
112                 if(!vdo_proc_softirqs) {
113                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_softirqs().");
114                         sunow = timems();
115                         vdo_proc_softirqs = do_proc_softirqs(rrd_update_every, (sutime_proc_softirqs > 0)?sunow - sutime_proc_softirqs:0ULL);
116                         sutime_proc_softirqs = sunow;
117                 }
118                 if(unlikely(netdata_exit)) break;
119
120                 if(!vdo_proc_sys_kernel_random_entropy_avail) {
121                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_sys_kernel_random_entropy_avail().");
122                         sunow = timems();
123                         vdo_proc_sys_kernel_random_entropy_avail = do_proc_sys_kernel_random_entropy_avail(rrd_update_every, (sutime_proc_sys_kernel_random_entropy_avail > 0)?sunow - sutime_proc_sys_kernel_random_entropy_avail:0ULL);
124                         sutime_proc_sys_kernel_random_entropy_avail = sunow;
125                 }
126                 if(unlikely(netdata_exit)) break;
127
128                 if(!vdo_proc_net_dev) {
129                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_dev().");
130                         sunow = timems();
131                         vdo_proc_net_dev = do_proc_net_dev(rrd_update_every, (sutime_proc_net_dev > 0)?sunow - sutime_proc_net_dev:0ULL);
132                         sutime_proc_net_dev = sunow;
133                 }
134                 if(unlikely(netdata_exit)) break;
135
136                 if(!vdo_proc_diskstats) {
137                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_diskstats().");
138                         sunow = timems();
139                         vdo_proc_diskstats = do_proc_diskstats(rrd_update_every, (sutime_proc_diskstats > 0)?sunow - sutime_proc_diskstats:0ULL);
140                         sutime_proc_diskstats = sunow;
141                 }
142                 if(unlikely(netdata_exit)) break;
143
144                 if(!vdo_proc_net_snmp) {
145                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_snmp().");
146                         sunow = timems();
147                         vdo_proc_net_snmp = do_proc_net_snmp(rrd_update_every, (sutime_proc_net_snmp > 0)?sunow - sutime_proc_net_snmp:0ULL);
148                         sutime_proc_net_snmp = sunow;
149                 }
150                 if(unlikely(netdata_exit)) break;
151
152                 if(!vdo_proc_net_snmp6) {
153                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_snmp6().");
154                         sunow = timems();
155                         vdo_proc_net_snmp6 = do_proc_net_snmp6(rrd_update_every, (sutime_proc_net_snmp6 > 0)?sunow - sutime_proc_net_snmp6:0ULL);
156                         sutime_proc_net_snmp6 = sunow;
157                 }
158                 if(unlikely(netdata_exit)) break;
159
160                 if(!vdo_proc_net_netstat) {
161                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_netstat().");
162                         sunow = timems();
163                         vdo_proc_net_netstat = do_proc_net_netstat(rrd_update_every, (sutime_proc_net_netstat > 0)?sunow - sutime_proc_net_netstat:0ULL);
164                         sutime_proc_net_netstat = sunow;
165                 }
166                 if(unlikely(netdata_exit)) break;
167
168                 if(!vdo_proc_net_stat_conntrack) {
169                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_stat_conntrack().");
170                         sunow = timems();
171                         vdo_proc_net_stat_conntrack     = do_proc_net_stat_conntrack(rrd_update_every, (sutime_proc_net_stat_conntrack > 0)?sunow - sutime_proc_net_stat_conntrack:0ULL);
172                         sutime_proc_net_stat_conntrack = sunow;
173                 }
174                 if(unlikely(netdata_exit)) break;
175
176                 if(!vdo_proc_net_ip_vs_stats) {
177                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_net_ip_vs_stats().");
178                         sunow = timems();
179                         vdo_proc_net_ip_vs_stats = do_proc_net_ip_vs_stats(rrd_update_every, (sutime_proc_net_ip_vs_stats > 0)?sunow - sutime_proc_net_ip_vs_stats:0ULL);
180                         sutime_proc_net_ip_vs_stats = sunow;
181                 }
182                 if(unlikely(netdata_exit)) break;
183
184                 if(!vdo_proc_net_stat_synproxy) {
185                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_net_stat_synproxy().");
186                         sunow = timems();
187                         vdo_proc_net_stat_synproxy = do_proc_net_stat_synproxy(rrd_update_every, (sutime_proc_net_stat_synproxy > 0)?sunow - sutime_proc_net_stat_synproxy:0ULL);
188                         sutime_proc_net_stat_synproxy = sunow;
189                 }
190                 if(unlikely(netdata_exit)) break;
191
192                 if(!vdo_proc_stat) {
193                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_stat().");
194                         sunow = timems();
195                         vdo_proc_stat = do_proc_stat(rrd_update_every, (sutime_proc_stat > 0)?sunow - sutime_proc_stat:0ULL);
196                         sutime_proc_stat = sunow;
197                 }
198                 if(unlikely(netdata_exit)) break;
199
200                 if(!vdo_proc_meminfo) {
201                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_meminfo().");
202                         sunow = timems();
203                         vdo_proc_meminfo = do_proc_meminfo(rrd_update_every, (sutime_proc_meminfo > 0)?sunow - sutime_proc_meminfo:0ULL);
204                         sutime_proc_meminfo = sunow;
205                 }
206                 if(unlikely(netdata_exit)) break;
207
208                 if(!vdo_proc_vmstat) {
209                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_vmstat().");
210                         sunow = timems();
211                         vdo_proc_vmstat = do_proc_vmstat(rrd_update_every, (sutime_proc_vmstat > 0)?sunow - sutime_proc_vmstat:0ULL);
212                         sutime_proc_vmstat = sunow;
213                 }
214                 if(unlikely(netdata_exit)) break;
215
216                 if(!vdo_proc_net_rpc_nfsd) {
217                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_rpc_nfsd().");
218                         sunow = timems();
219                         vdo_proc_net_rpc_nfsd = do_proc_net_rpc_nfsd(rrd_update_every, (sutime_proc_net_rpc_nfsd > 0)?sunow - sutime_proc_net_rpc_nfsd:0ULL);
220                         sutime_proc_net_rpc_nfsd = sunow;
221                 }
222                 if(unlikely(netdata_exit)) break;
223
224                 // END -- the job is done
225
226                 // --------------------------------------------------------------------
227
228                 if(!vdo_cpu_netdata) {
229                         getrusage(RUSAGE_THREAD, &thread);
230                         getrusage(RUSAGE_SELF, &me);
231
232                         if(!stcpu_thread) stcpu_thread = rrdset_find("netdata.plugin_proc_cpu");
233                         if(!stcpu_thread) {
234                                 stcpu_thread = rrdset_create("netdata", "plugin_proc_cpu", NULL, "proc.internal", NULL, "NetData Proc Plugin CPU usage", "milliseconds/s", 132000, rrd_update_every, RRDSET_TYPE_STACKED);
235
236                                 rrddim_add(stcpu_thread, "user",  NULL,  1, 1000, RRDDIM_INCREMENTAL);
237                                 rrddim_add(stcpu_thread, "system", NULL, 1, 1000, RRDDIM_INCREMENTAL);
238                         }
239                         else rrdset_next(stcpu_thread);
240
241                         rrddim_set(stcpu_thread, "user"  , thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec);
242                         rrddim_set(stcpu_thread, "system", thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec);
243                         rrdset_done(stcpu_thread);
244
245                         // ----------------------------------------------------------------
246
247                         if(!stcpu) stcpu = rrdset_find("netdata.server_cpu");
248                         if(!stcpu) {
249                                 stcpu = rrdset_create("netdata", "server_cpu", NULL, "netdata", NULL, "NetData CPU usage", "milliseconds/s", 130000, rrd_update_every, RRDSET_TYPE_STACKED);
250
251                                 rrddim_add(stcpu, "user",  NULL,  1, 1000, RRDDIM_INCREMENTAL);
252                                 rrddim_add(stcpu, "system", NULL, 1, 1000, RRDDIM_INCREMENTAL);
253                         }
254                         else rrdset_next(stcpu);
255
256                         rrddim_set(stcpu, "user"  , me.ru_utime.tv_sec * 1000000ULL + me.ru_utime.tv_usec);
257                         rrddim_set(stcpu, "system", me.ru_stime.tv_sec * 1000000ULL + me.ru_stime.tv_usec);
258                         rrdset_done(stcpu);
259
260                         // ----------------------------------------------------------------
261
262                         if(!stclients) stclients = rrdset_find("netdata.clients");
263                         if(!stclients) {
264                                 stclients = rrdset_create("netdata", "clients", NULL, "netdata", NULL, "NetData Web Clients", "connected clients", 130100, rrd_update_every, RRDSET_TYPE_LINE);
265
266                                 rrddim_add(stclients, "clients",  NULL,  1, 1, RRDDIM_ABSOLUTE);
267                         }
268                         else rrdset_next(stclients);
269
270                         rrddim_set(stclients, "clients", global_statistics.connected_clients);
271                         rrdset_done(stclients);
272
273                         // ----------------------------------------------------------------
274
275                         if(!streqs) streqs = rrdset_find("netdata.requests");
276                         if(!streqs) {
277                                 streqs = rrdset_create("netdata", "requests", NULL, "netdata", NULL, "NetData Web Requests", "requests/s", 130200, rrd_update_every, RRDSET_TYPE_LINE);
278
279                                 rrddim_add(streqs, "requests",  NULL,  1, 1, RRDDIM_INCREMENTAL);
280                         }
281                         else rrdset_next(streqs);
282
283                         rrddim_set(streqs, "requests", global_statistics.web_requests);
284                         rrdset_done(streqs);
285
286                         // ----------------------------------------------------------------
287
288                         if(!stbytes) stbytes = rrdset_find("netdata.net");
289                         if(!stbytes) {
290                                 stbytes = rrdset_create("netdata", "net", NULL, "netdata", NULL, "NetData Network Traffic", "kilobits/s", 130300, rrd_update_every, RRDSET_TYPE_AREA);
291
292                                 rrddim_add(stbytes, "in",  NULL,  8, 1024, RRDDIM_INCREMENTAL);
293                                 rrddim_add(stbytes, "out",  NULL,  -8, 1024, RRDDIM_INCREMENTAL);
294                         }
295                         else rrdset_next(stbytes);
296
297                         rrddim_set(stbytes, "in", global_statistics.bytes_received);
298                         rrddim_set(stbytes, "out", global_statistics.bytes_sent);
299                         rrdset_done(stbytes);
300
301                         // ----------------------------------------------------------------
302
303                         if(!stduration) stduration = rrdset_find("netdata.response_time");
304                         if(!stduration) {
305                                 stduration = rrdset_create("netdata", "response_time", NULL, "netdata", NULL, "NetData Average API Response Time", "ms/request", 130400, rrd_update_every, RRDSET_TYPE_LINE);
306
307                                 rrddim_add(stduration, "response_time", "response time",  1, 1000, RRDDIM_ABSOLUTE);
308                         }
309                         else rrdset_next(stduration);
310
311                         unsigned long long gweb_usec     = global_statistics.web_usec;
312                         unsigned long long gweb_requests = global_statistics.web_requests;
313
314                         unsigned long long web_usec     = gweb_usec     - old_web_usec;
315                         unsigned long long web_requests = gweb_requests - old_web_requests;
316
317                         old_web_usec     = gweb_usec;
318                         old_web_requests = gweb_requests;
319
320                         if(web_requests)
321                                 average_response_time =  web_usec / web_requests;
322
323                         if(average_response_time != -1)
324                                 rrddim_set(stduration, "response_time", average_response_time);
325
326                         rrdset_done(stduration);
327
328                         // ----------------------------------------------------------------
329
330                         if(!stcompression) stcompression = rrdset_find("netdata.compression_ratio");
331                         if(!stcompression) {
332                                 stcompression = rrdset_create("netdata", "compression_ratio", NULL, "netdata", NULL, "NetData API Responses Compression Savings Ratio", "percentage", 130500, rrd_update_every, RRDSET_TYPE_LINE);
333
334                                 rrddim_add(stcompression, "savings", NULL,  1, 1000, RRDDIM_ABSOLUTE);
335                         }
336                         else rrdset_next(stcompression);
337
338                         // since we don't lock here to read the global statistics
339                         // read the smaller value first
340                         unsigned long long gcompressed_content_size = global_statistics.compressed_content_size;
341                         unsigned long long gcontent_size            = global_statistics.content_size;
342
343                         unsigned long long compressed_content_size  = gcompressed_content_size - old_compressed_content_size;
344                         unsigned long long content_size             = gcontent_size            - old_content_size;
345
346                         old_compressed_content_size = gcompressed_content_size;
347                         old_content_size            = gcontent_size;
348
349                         if(content_size && content_size >= compressed_content_size)
350                                 compression_ratio = ((content_size - compressed_content_size) * 100 * 1000) / content_size;
351
352                         if(compression_ratio != -1)
353                                 rrddim_set(stcompression, "savings", compression_ratio);
354
355                         rrdset_done(stcompression);
356
357                         // ----------------------------------------------------------------
358
359                         registry_statistics();
360                 }
361         }
362
363         pthread_exit(NULL);
364         return NULL;
365 }