ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/host/ihost-perl/plugins/linux/linux.c
Revision: 1.8
Committed: Tue Apr 2 12:43:15 2002 UTC (22 years, 6 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.7: +43 -66 lines
Log Message:
Improved the linux one to rely slightly less on /proc where it was sane not
to use it.

File Contents

# User Rev Content
1 pajs 1.1 #include <stdio.h>
2     #include <stdlib.h>
3 tdb 1.3 #include "ukcprog.h"
4 pajs 1.1 #include <string.h>
5     #include <unistd.h>
6     #include <sys/utsname.h>
7     #include <sys/vfs.h>
8     #include <utmp.h>
9     #include <pwd.h>
10 pajs 1.8 #include <mntent.h>
11 pajs 1.1
12 tdb 1.4 int die() {
13     exit (1);
14 pajs 1.1 }
15    
16 tdb 1.4 void getLoadAv() {
17 pajs 1.8
18     double loadav[3];
19    
20     if((getloadavg(loadav,3)) == -1){
21     errf("Failed to get load averages (%m)");
22     die();
23     }
24    
25     printf("packet.load.load1 %.2f\n",loadav[0]);
26     printf("packet.load.load5 %.2f\n",loadav[1]);
27     printf("packet.load.load15 %.2f\n",loadav[2]);
28    
29 pajs 1.1 }
30    
31 tdb 1.4 void getMemInfo() {
32     char *line;
33 pajs 1.6 char *mem=NULL;
34     char *swap=NULL;
35 tdb 1.4 char *ch;
36     long memstat[6];
37     long swapstat[3];
38     long tmp;
39     int counter=0;
40    
41     FILE *f;
42    
43     if ((f=fopen("/proc/meminfo", "r" ))==NULL) {
44     errf("Failed to open memory stats (%m)");
45     die();
46     }
47    
48     while(((line=fpgetline(f)) != NULL) && (counter < 2)) {
49     if (((strncmp("Mem: ",line,5)) == 0)) {
50     mem=strdup(line);
51     counter++;
52     }
53     if (((strncmp(line,"Swap: ",6)) == 0)) {
54     swap=strdup(line);
55     counter++;
56     }
57     }
58    
59     if ((fclose(f)) != 0) {
60     errf("Failed to close file (%m).");
61     die();
62     }
63 pajs 1.6
64     if (mem==NULL || swap==NULL){
65     errf("Failed to obtain information required for memory and swap stats");
66     die();
67     }
68    
69 tdb 1.4 /* Get the info we want from the 2 read in lines */
70    
71     ch = strchr(mem, ' ');
72     if (ch == NULL) abort();
73     *ch = '\0';
74     ch++;
75    
76     /* By now we should of skipped the mem: bit.. onto the numbers */
77    
78     for(counter=0;counter<6;counter++) {
79     for (; (*ch == ' '); ch++);
80     if (ch == NULL) abort();
81     memstat[counter]=atol(ch);
82     ch++;
83     for(; (*ch != ' ') && (*ch != '\0'); ch++);
84     if (ch == NULL) abort();
85     }
86    
87     /* Now swap.. */
88     ch = strchr(swap, ' ');
89     if (ch == NULL) abort();
90     *ch = '\0';
91     ch++;
92    
93     for(counter=0;counter<3;counter++) {
94     for (; (*ch == ' '); ch++);
95     if (ch == NULL) abort();
96     swapstat[counter]=atol(ch);
97     ch++;
98     for(; (*ch != ' ') && (*ch != '\0'); ch++);
99     if (ch == NULL) abort();
100     }
101    
102     printf("packet.memory.total %ld\n",((memstat[0]/1024)/1024));
103    
104     /* Due to batty linux we do some maths to work out roughly what the free ram is */
105     tmp=((memstat[1] - memstat[4])/1024)/1024;
106     printf("packet.memory.used %ld\n",tmp);
107     tmp=((memstat[2] + memstat[4])/1024)/1024;
108     printf("packet.memory.free %ld\n",tmp);
109    
110     printf("packet.swap.total %ld\n",((swapstat[0]/1024)/1024));
111     printf("packet.swap.used %ld\n",((swapstat[1]/1024)/1024));
112     printf("packet.swap.free %ld\n",((swapstat[2])/1024)/1024);
113    
114     free(mem);
115     free(swap);
116 pajs 1.1 }
117    
118 tdb 1.4 void cpustats() {
119     char *tmp;
120     char *line[2];
121     char *line_p[2];
122     long cpustats[4][2];
123     long user, kernel, idle;
124     long total;
125     int x,y;
126     float usage;
127     FILE *f;
128    
129     if ((f=fopen("/proc/stat", "r" ))==NULL) {
130     errf("Failed to open cpu stats (%m)");
131     die();
132     }
133    
134     if((tmp=fpgetline(f)) == NULL) {
135     errf("Failed to read cpu stats (%m)");
136     die();
137     }
138    
139     if((line[0]=strdup(tmp)) == NULL) {
140     errf("strdup failed (%m)");
141     die();
142     }
143    
144     if ((fclose(f)) != 0) {
145     errf("Failed to close file (%m).");
146     die();
147     }
148 pajs 1.1
149 tdb 1.4 sleep(1);
150    
151     if ((f=fopen("/proc/stat", "r" ))==NULL) {
152     errf("Failed to open cpu stats (%m)");
153     die();
154     }
155    
156     if((tmp=fpgetline(f)) == NULL) {
157     errf("Failed to read cpu stats (%m)");
158     die();
159     }
160    
161     if((line[1]=strdup(tmp)) == NULL) {
162     errf("strdup failed (%m)");
163     die();
164     }
165 pajs 1.1
166 tdb 1.4 if ((fclose(f)) != 0) {
167     errf("Failed to close file (%m).");
168     die();
169     }
170    
171     for(x=0;x<2;x++) {
172     line_p[x] = strchr(line[x], ' ');
173     if (line_p[x] == NULL) abort();
174     *line_p[x] = '\0';
175     line_p[x]++;
176     }
177    
178     /* Now should be passed "cpu " */
179    
180     for(x=0;x<2;x++) {
181     for(y=0;y<4;y++) {
182     for (; (*line_p[x] == ' '); line_p[x]++);
183     if (line_p[x] == NULL) abort();
184     cpustats[y][x]=atol(line_p[x]);
185     line_p[x]++;
186     for(; (*line_p[x] != ' ') && (*line_p[x] != '\0'); line_p[x]++);
187     if (line_p[x] == NULL) abort();
188     for (; (*line_p[x] == ' '); line_p[x]++);
189     }
190     }
191    
192     user=cpustats[0][1]-cpustats[0][0]+cpustats[1][1]-cpustats[1][0];
193     kernel=cpustats[2][1]-cpustats[2][0];
194     idle=cpustats[3][1]-cpustats[3][0];
195    
196     /* use total to get the total number and then work out the percentages */
197     total=user+kernel+idle;
198    
199     usage=((((float)user)/((float)total))*100.00);
200     printf("packet.cpu.user %3.2f\n", usage);
201     usage=((((float)kernel)/((float)total))*100.00);
202     printf("packet.cpu.kernel %3.2f\n", usage);
203     usage=((((float)idle)/((float)total))*100.00);
204     printf("packet.cpu.idle %3.2f\n", usage);
205    
206 pajs 1.5 /* Cos i-scream's expects this to be sent :/ */
207 tdb 1.4 printf("packet.cpu.iowait 0\n");
208 pajs 1.5 printf("packet.cpu.swap 0\n");
209    
210 tdb 1.4 free(line[0]);
211     free(line[1]);
212 pajs 1.1 }
213    
214 tdb 1.4 void processStats() {
215 pajs 1.7 int sleeping=-1;
216 tdb 1.4 int zombie=0;
217     int stopped=0;
218     int running=0;
219     int nousers=0;
220     char *line;
221     char *line_p;
222     struct utmp *entry;
223    
224     FILE *f;
225    
226     if((f=popen("/bin/ps -Al" , "r")) == NULL) {
227     errf("Failed to get process stats (%m)");
228     die();
229     }
230    
231     while((line=fpgetline(f)) != NULL) {
232 pajs 1.7
233     line_p=line;
234     for(; (*line_p == ' ') && (*line_p != '\0'); line_p++);
235     line_p=strchr(line_p, ' ');
236     for(; (*line_p == ' ') && (*line_p != '\0'); line_p++);
237     if (line_p==NULL) abort();
238     /* Ok, we should now be at the state :) .. */
239     if (*line_p=='S') sleeping++;
240     if (*line_p=='R') running++;
241     if (*line_p=='Z') zombie++;
242     if (*line_p=='T') stopped++;
243 tdb 1.4 }
244    
245     if((pclose(f)) == -1) {
246     errf("Failed to close process stats (%m)");
247     die();
248     }
249    
250     printf("packet.users.list");
251    
252     while((entry=getutent()) != NULL) {
253     if(entry->ut_type==USER_PROCESS) {
254     printf(" %s",entry->ut_user);
255     nousers++;
256     }
257     }
258    
259     printf("\npacket.users.count %d\n", nousers);
260    
261 pajs 1.5 printf("packet.processes.sleeping %d\n",sleeping);
262     printf("packet.processes.cpu %d\n",running);
263 tdb 1.4 printf("packet.processes.zombie %d\n",zombie);
264     printf("packet.processes.stopped %d\n", stopped);
265     printf("packet.processes.total %d\n", (sleeping+running+zombie+stopped));
266 pajs 1.1 }
267    
268 tdb 1.4 void uptimeStats() {
269     char *line;
270     char *line_p;
271     FILE *f;
272    
273     if ((f=fopen("/proc/uptime", "r")) == NULL) {
274     errf("Failed to get uptime stats (%m)");
275     die();
276     }
277    
278     if ((line=fpgetline(f)) == NULL) {
279     errf("Failed to read uptime stats (%m)");
280     die();
281     }
282    
283     if ((fclose(f)) != 0) {
284     errf("Failed to close file (%m).");
285     die();
286     }
287    
288     line_p=strchr(line, '.');
289     if (line_p==NULL) abort();
290     *line_p='\0';
291    
292     printf("packet.os.uptime %s\n", line);
293 pajs 1.1 }
294    
295 tdb 1.4 void osStats() {
296     struct utsname os;
297    
298     if((uname(&os)) != 0) {
299     errf("Failed to get os stats (%m)");
300     die();
301     }
302    
303     printf("packet.os.name %s\n", os.sysname);
304     printf("packet.os.release %s\n" , os.release);
305     printf("packet.os.version %s\n", os.version);
306     printf("packet.os.sysname %s\n" , os.nodename);
307     printf("packet.os.platform %s\n", os.machine);
308 pajs 1.1 }
309    
310 tdb 1.4 void diskStats() {
311 pajs 1.8
312     struct mntent *mp;
313     struct statfs df;
314     FILE *f;
315     int counter=0;
316    
317     if ((f=fopen("/etc/mtab", "r" ))==NULL){
318     errf("Failed to open mounts (%m)");
319     die();
320     }
321    
322     while((mp=getmntent(f))){
323     if ((statfs(mp->mnt_dir, &df)) !=0){
324     errf("Failed to gets fs stats (%m)");
325     continue;
326     }
327    
328     if((((strcmp(mp->mnt_type, MNTTYPE_NFS))==0) || (strcmp(mp->mnt_type,MNTTYPE_IGNORE)) ==0)) continue;
329 tdb 1.4
330 pajs 1.8 printf("packet.disk.p%d.attributes.mount %s\n", counter, mp->mnt_dir);
331     printf("packet.disk.p%d.attributes.name %s\n", counter, mp->mnt_fsname);
332     printf("packet.disk.p%d.attributes.kbytes %lu\n",counter, ((df.f_bsize/1024) * df.f_blocks));
333     printf("packet.disk.p%d.attributes.used %lu\n",counter, (((df.f_bsize/1024) * df.f_blocks) -((df.f_bsize/1024) * df.f_bfree)));
334     printf("packet.disk.p%d.attributes.avail %lu\n",counter, (df.f_bsize/1024) * df.f_bavail);
335     printf("packet.disk.p%d.attributes.totalinodes %lu\n", counter, df.f_files);
336     printf("packet.disk.p%d.attributes.freeinodes %lu\n",counter, df.f_ffree);
337 tdb 1.4
338 pajs 1.8 counter++;
339     }
340    
341    
342    
343 pajs 1.1 }
344    
345 tdb 1.4 int main() {
346 pajs 1.1 getLoadAv();
347     getMemInfo();
348     cpustats();
349     processStats();
350     uptimeStats();
351     osStats();
352     diskStats();
353     fflush(stdout);
354     return 0;
355     }