]> arthur.barton.de Git - netdata.git/blob - src/plugin_proc.c
8691d2d039f5a3d1e24e8ad5d5b4aad37bf4de01
[netdata.git] / src / plugin_proc.c
1 #include <pthread.h>
2 #include <sys/time.h>
3 #include <sys/resource.h>
4 #include <strings.h>
5 #include <unistd.h>
6
7 #include "global_statistics.h"
8 #include "common.h"
9 #include "config.h"
10 #include "log.h"
11 #include "rrd.h"
12 #include "plugin_proc.h"
13
14 void *proc_main(void *ptr)
15 {
16         if(ptr) { ; }
17
18         info("PROC Plugin thread created with task id %d", gettid());
19
20         if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
21                 error("Cannot set pthread cancel type to DEFERRED.");
22
23         if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
24                 error("Cannot set pthread cancel state to ENABLE.");
25
26         struct rusage me, me_last;
27         struct timeval last, now;
28
29         gettimeofday(&last, NULL);
30         last.tv_sec -= rrd_update_every;
31         
32         // disable (by default) various interface that are not needed
33         config_get_boolean("plugin:proc:/proc/net/dev", "interface lo", 0);
34         config_get_boolean("plugin:proc:/proc/net/dev", "interface fireqos_monitor", 0);
35
36         // when ZERO, attempt to do it
37         int vdo_proc_net_dev                    = !config_get_boolean("plugin:proc", "/proc/net/dev", 1);
38         int vdo_proc_diskstats                  = !config_get_boolean("plugin:proc", "/proc/diskstats", 1);
39         int vdo_proc_net_snmp                   = !config_get_boolean("plugin:proc", "/proc/net/snmp", 1);
40         int vdo_proc_net_netstat                = !config_get_boolean("plugin:proc", "/proc/net/netstat", 1);
41         int vdo_proc_net_stat_conntrack = !config_get_boolean("plugin:proc", "/proc/net/stat/conntrack", 1);
42         int vdo_proc_net_ip_vs_stats    = !config_get_boolean("plugin:proc", "/proc/net/ip_vs/stats", 1);
43         int vdo_proc_stat                               = !config_get_boolean("plugin:proc", "/proc/stat", 1);
44         int vdo_proc_meminfo                    = !config_get_boolean("plugin:proc", "/proc/meminfo", 1);
45         int vdo_proc_vmstat                     = !config_get_boolean("plugin:proc", "/proc/vmstat", 1);
46         int vdo_proc_net_rpc_nfsd               = !config_get_boolean("plugin:proc", "/proc/net/rpc/nfsd", 1);
47         int vdo_proc_sys_kernel_random_entropy_avail    = !config_get_boolean("plugin:proc", "/proc/sys/kernel/random/entropy_avail", 1);
48         int vdo_proc_interrupts                 = !config_get_boolean("plugin:proc", "/proc/interrupts", 1);
49         int vdo_cpu_netdata                     = !config_get_boolean("plugin:proc", "netdata server resources", 1);
50
51         RRDSET *stcpu = NULL, *stclients = NULL, *streqs = NULL, *stbytes = NULL;
52
53         gettimeofday(&last, NULL);
54         getrusage(RUSAGE_SELF, &me_last);
55
56         unsigned long long usec = 0, susec = 0;
57         for(;1;) {
58                 
59                 // BEGIN -- the job to be done
60                 
61                 if(!vdo_proc_interrupts) {
62                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_interrupts().");
63                         vdo_proc_interrupts = do_proc_interrupts(rrd_update_every, usec+susec);
64                 }
65                 if(!vdo_proc_sys_kernel_random_entropy_avail) {
66                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_sys_kernel_random_entropy_avail().");
67                         vdo_proc_sys_kernel_random_entropy_avail = do_proc_sys_kernel_random_entropy_avail(rrd_update_every, usec+susec);
68                 }
69                 if(!vdo_proc_net_dev) {
70                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_dev().");
71                         vdo_proc_net_dev = do_proc_net_dev(rrd_update_every, usec+susec);
72                 }
73                 if(!vdo_proc_diskstats) {
74                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_diskstats().");
75                         vdo_proc_diskstats = do_proc_diskstats(rrd_update_every, usec+susec);
76                 }
77                 if(!vdo_proc_net_snmp) {
78                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_snmp().");
79                         vdo_proc_net_snmp = do_proc_net_snmp(rrd_update_every, usec+susec);
80                 }
81
82                 if(!vdo_proc_net_netstat) {
83                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_netstat().");
84                         vdo_proc_net_netstat = do_proc_net_netstat(rrd_update_every, usec+susec);
85                 }
86
87                 if(!vdo_proc_net_stat_conntrack) {
88                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_stat_conntrack().");
89                         vdo_proc_net_stat_conntrack     = do_proc_net_stat_conntrack(rrd_update_every, usec+susec);
90                 }
91
92                 if(!vdo_proc_net_ip_vs_stats) {
93                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_net_ip_vs_stats().");
94                         vdo_proc_net_ip_vs_stats = do_proc_net_ip_vs_stats(rrd_update_every, usec+susec);
95                 }
96
97                 if(!vdo_proc_stat) {
98                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_stat().");
99                         vdo_proc_stat = do_proc_stat(rrd_update_every, usec+susec);
100                 }
101
102                 if(!vdo_proc_meminfo) {
103                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_meminfo().");
104                         vdo_proc_meminfo = do_proc_meminfo(rrd_update_every, usec+susec);
105                 }
106
107                 if(!vdo_proc_vmstat) {
108                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling vdo_proc_vmstat().");
109                         vdo_proc_vmstat = do_proc_vmstat(rrd_update_every, usec+susec);
110                 }
111
112                 if(!vdo_proc_net_rpc_nfsd) {
113                         debug(D_PROCNETDEV_LOOP, "PROCNETDEV: calling do_proc_net_rpc_nfsd().");
114                         vdo_proc_net_rpc_nfsd = do_proc_net_rpc_nfsd(rrd_update_every, usec+susec);
115                 }
116
117                 // END -- the job is done
118                 
119                 // find the time to sleep in order to wait exactly update_every seconds
120                 gettimeofday(&now, NULL);
121                 usec = usecdiff(&now, &last) - susec;
122                 debug(D_PROCNETDEV_LOOP, "PROCNETDEV: last loop took %llu usec (worked for %llu, sleeped for %llu).", usec + susec, usec, susec);
123                 
124                 if(usec < (rrd_update_every * 1000000ULL / 2ULL)) susec = (rrd_update_every * 1000000ULL) - usec;
125                 else susec = rrd_update_every * 1000000ULL / 2ULL;
126                 
127                 // --------------------------------------------------------------------
128
129                 if(!vdo_cpu_netdata && getrusage(RUSAGE_SELF, &me) == 0) {
130                 
131                         unsigned long long cpuuser = me.ru_utime.tv_sec * 1000000ULL + me.ru_utime.tv_usec;
132                         unsigned long long cpusyst = me.ru_stime.tv_sec * 1000000ULL + me.ru_stime.tv_usec;
133
134                         if(!stcpu) stcpu = rrdset_find("netdata.server_cpu");
135                         if(!stcpu) {
136                                 stcpu = rrdset_create("netdata", "server_cpu", NULL, "netdata", "NetData CPU usage", "milliseconds/s", 9999, rrd_update_every, RRDSET_TYPE_STACKED);
137
138                                 rrddim_add(stcpu, "user",  NULL,  1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL);
139                                 rrddim_add(stcpu, "system", NULL, 1, 1000 * rrd_update_every, RRDDIM_INCREMENTAL);
140                         }
141                         else rrdset_next(stcpu);
142
143                         rrddim_set(stcpu, "user", cpuuser);
144                         rrddim_set(stcpu, "system", cpusyst);
145                         rrdset_done(stcpu);
146                         
147                         bcopy(&me, &me_last, sizeof(struct rusage));
148
149                         // ----------------------------------------------------------------
150
151                         if(!stclients) stclients = rrdset_find("netdata.clients");
152                         if(!stclients) {
153                                 stclients = rrdset_create("netdata", "clients", NULL, "netdata", "NetData Web Clients", "connected clients", 11000, rrd_update_every, RRDSET_TYPE_LINE);
154
155                                 rrddim_add(stclients, "clients",  NULL,  1, 1, RRDDIM_ABSOLUTE);
156                         }
157                         else rrdset_next(stclients);
158
159                         rrddim_set(stclients, "clients", global_statistics.connected_clients);
160                         rrdset_done(stclients);
161
162                         // ----------------------------------------------------------------
163
164                         if(!streqs) streqs = rrdset_find("netdata.requests");
165                         if(!streqs) {
166                                 streqs = rrdset_create("netdata", "requests", NULL, "netdata", "NetData Web Requests", "requests/s", 12000, rrd_update_every, RRDSET_TYPE_LINE);
167
168                                 rrddim_add(streqs, "requests",  NULL,  1, 1 * rrd_update_every, RRDDIM_INCREMENTAL);
169                         }
170                         else rrdset_next(streqs);
171
172                         rrddim_set(streqs, "requests", global_statistics.web_requests);
173                         rrdset_done(streqs);
174
175                         // ----------------------------------------------------------------
176
177                         if(!stbytes) stbytes = rrdset_find("netdata.net");
178                         if(!stbytes) {
179                                 stbytes = rrdset_create("netdata", "net", NULL, "netdata", "NetData Network Traffic", "kilobits/s", 13000, rrd_update_every, RRDSET_TYPE_AREA);
180
181                                 rrddim_add(stbytes, "in",  NULL,  8, 1024 * rrd_update_every, RRDDIM_INCREMENTAL);
182                                 rrddim_add(stbytes, "out",  NULL,  -8, 1024 * rrd_update_every, RRDDIM_INCREMENTAL);
183                         }
184                         else rrdset_next(stbytes);
185
186                         rrddim_set(stbytes, "in", global_statistics.bytes_received);
187                         rrddim_set(stbytes, "out", global_statistics.bytes_sent);
188                         rrdset_done(stbytes);
189                 }
190
191                 usleep(susec);
192                 
193                 // copy current to last
194                 bcopy(&now, &last, sizeof(struct timeval));
195         }
196
197         return NULL;
198 }