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.14
Committed: Tue May 21 16:47:12 2002 UTC (22 years, 5 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.13: +1 -0 lines
Log Message:
Added URL to GPL headers.

File Contents

# User Rev Content
1 tdb 1.13 /*
2     * i-scream central monitoring system
3 tdb 1.14 * http://www.i-scream.org.uk
4 tdb 1.13 * Copyright (C) 2000-2002 i-scream
5     *
6     * This program is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU General Public License
8     * as published by the Free Software Foundation; either version 2
9     * of the License, or (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19     */
20    
21 pajs 1.1 #include <stdio.h>
22     #include <stdlib.h>
23 pajs 1.11 #include "ukcprog.h"
24 pajs 1.1 #include <string.h>
25     #include <unistd.h>
26     #include <sys/utsname.h>
27     #include <sys/vfs.h>
28     #include <utmp.h>
29     #include <pwd.h>
30 pajs 1.8 #include <mntent.h>
31 pajs 1.10 #include <dirent.h>
32     #include <limits.h>
33 pajs 1.1
34 tdb 1.4 int die() {
35     exit (1);
36 pajs 1.1 }
37    
38 tdb 1.4 void getLoadAv() {
39 pajs 1.9 #ifdef OLDLIBC
40    
41     FILE *f;
42     char *loadavg;
43     char *load_p;
44    
45     if ((f=fopen("/proc/loadavg", "r" ))==NULL) {
46     errf("Failed to open load averages (%m)");
47     die();
48     }
49    
50     if ((loadavg=fpgetline(f)) == NULL) {
51     errf("Failed to read any data for load averages (%m)");
52     die();
53     }
54    
55     if ((fclose(f)) != 0) {
56     errf("Failed to close file (%m).");
57     die();
58     }
59    
60     load_p=strtok(loadavg, " ");
61     printf("packet.load.load1 %s\n",load_p);
62     for(; (*load_p != ' ') && (*load_p != '\0'); load_p++);
63     load_p++;
64     if (load_p == NULL) abort();
65     load_p=strtok(load_p, " ");
66     if (load_p == NULL) abort();
67     printf("packet.load.load5 %s\n",load_p);
68     for(; (*load_p != ' ') && (*load_p != '\0'); load_p++);
69     load_p++;
70     if (load_p == NULL) abort();
71     load_p=strtok(load_p, " ");
72     if (load_p == NULL) abort();
73     printf("packet.load.load15 %s\n",load_p);
74 pajs 1.8
75 pajs 1.9 #else
76 pajs 1.8 double loadav[3];
77    
78     if((getloadavg(loadav,3)) == -1){
79     errf("Failed to get load averages (%m)");
80     die();
81     }
82    
83     printf("packet.load.load1 %.2f\n",loadav[0]);
84     printf("packet.load.load5 %.2f\n",loadav[1]);
85     printf("packet.load.load15 %.2f\n",loadav[2]);
86 pajs 1.9 #endif
87 pajs 1.1 }
88    
89 tdb 1.4 void getMemInfo() {
90     char *line;
91 pajs 1.6 char *mem=NULL;
92     char *swap=NULL;
93 tdb 1.4 char *ch;
94     long memstat[6];
95     long swapstat[3];
96     long tmp;
97     int counter=0;
98    
99     FILE *f;
100    
101     if ((f=fopen("/proc/meminfo", "r" ))==NULL) {
102     errf("Failed to open memory stats (%m)");
103     die();
104     }
105    
106     while(((line=fpgetline(f)) != NULL) && (counter < 2)) {
107     if (((strncmp("Mem: ",line,5)) == 0)) {
108     mem=strdup(line);
109     counter++;
110     }
111     if (((strncmp(line,"Swap: ",6)) == 0)) {
112     swap=strdup(line);
113     counter++;
114     }
115     }
116    
117     if ((fclose(f)) != 0) {
118     errf("Failed to close file (%m).");
119     die();
120     }
121 pajs 1.6
122     if (mem==NULL || swap==NULL){
123     errf("Failed to obtain information required for memory and swap stats");
124     die();
125     }
126    
127 tdb 1.4 /* Get the info we want from the 2 read in lines */
128    
129     ch = strchr(mem, ' ');
130     if (ch == NULL) abort();
131     *ch = '\0';
132     ch++;
133    
134     /* By now we should of skipped the mem: bit.. onto the numbers */
135    
136     for(counter=0;counter<6;counter++) {
137     for (; (*ch == ' '); ch++);
138     if (ch == NULL) abort();
139     memstat[counter]=atol(ch);
140     ch++;
141     for(; (*ch != ' ') && (*ch != '\0'); ch++);
142     if (ch == NULL) abort();
143     }
144    
145     /* Now swap.. */
146     ch = strchr(swap, ' ');
147     if (ch == NULL) abort();
148     *ch = '\0';
149     ch++;
150    
151     for(counter=0;counter<3;counter++) {
152     for (; (*ch == ' '); ch++);
153     if (ch == NULL) abort();
154     swapstat[counter]=atol(ch);
155     ch++;
156     for(; (*ch != ' ') && (*ch != '\0'); ch++);
157     if (ch == NULL) abort();
158     }
159    
160     printf("packet.memory.total %ld\n",((memstat[0]/1024)/1024));
161    
162     /* Due to batty linux we do some maths to work out roughly what the free ram is */
163     tmp=((memstat[1] - memstat[4])/1024)/1024;
164     printf("packet.memory.used %ld\n",tmp);
165     tmp=((memstat[2] + memstat[4])/1024)/1024;
166     printf("packet.memory.free %ld\n",tmp);
167    
168     printf("packet.swap.total %ld\n",((swapstat[0]/1024)/1024));
169     printf("packet.swap.used %ld\n",((swapstat[1]/1024)/1024));
170     printf("packet.swap.free %ld\n",((swapstat[2])/1024)/1024);
171    
172     free(mem);
173     free(swap);
174 pajs 1.1 }
175    
176 tdb 1.4 void cpustats() {
177     char *tmp;
178     char *line[2];
179     char *line_p[2];
180     long cpustats[4][2];
181     long user, kernel, idle;
182     long total;
183     int x,y;
184     float usage;
185     FILE *f;
186    
187     if ((f=fopen("/proc/stat", "r" ))==NULL) {
188     errf("Failed to open cpu stats (%m)");
189     die();
190     }
191    
192     if((tmp=fpgetline(f)) == NULL) {
193     errf("Failed to read cpu stats (%m)");
194     die();
195     }
196    
197     if((line[0]=strdup(tmp)) == NULL) {
198     errf("strdup failed (%m)");
199     die();
200     }
201    
202     if ((fclose(f)) != 0) {
203     errf("Failed to close file (%m).");
204     die();
205     }
206 pajs 1.1
207 tdb 1.4 sleep(1);
208    
209     if ((f=fopen("/proc/stat", "r" ))==NULL) {
210     errf("Failed to open cpu stats (%m)");
211     die();
212     }
213    
214     if((tmp=fpgetline(f)) == NULL) {
215     errf("Failed to read cpu stats (%m)");
216     die();
217     }
218    
219     if((line[1]=strdup(tmp)) == NULL) {
220     errf("strdup failed (%m)");
221     die();
222     }
223 pajs 1.1
224 tdb 1.4 if ((fclose(f)) != 0) {
225     errf("Failed to close file (%m).");
226     die();
227     }
228    
229     for(x=0;x<2;x++) {
230     line_p[x] = strchr(line[x], ' ');
231     if (line_p[x] == NULL) abort();
232     *line_p[x] = '\0';
233     line_p[x]++;
234     }
235    
236     /* Now should be passed "cpu " */
237    
238     for(x=0;x<2;x++) {
239     for(y=0;y<4;y++) {
240     for (; (*line_p[x] == ' '); line_p[x]++);
241     if (line_p[x] == NULL) abort();
242     cpustats[y][x]=atol(line_p[x]);
243     line_p[x]++;
244     for(; (*line_p[x] != ' ') && (*line_p[x] != '\0'); line_p[x]++);
245     if (line_p[x] == NULL) abort();
246     for (; (*line_p[x] == ' '); line_p[x]++);
247     }
248     }
249    
250     user=cpustats[0][1]-cpustats[0][0]+cpustats[1][1]-cpustats[1][0];
251     kernel=cpustats[2][1]-cpustats[2][0];
252     idle=cpustats[3][1]-cpustats[3][0];
253    
254     /* use total to get the total number and then work out the percentages */
255     total=user+kernel+idle;
256    
257     usage=((((float)user)/((float)total))*100.00);
258     printf("packet.cpu.user %3.2f\n", usage);
259     usage=((((float)kernel)/((float)total))*100.00);
260     printf("packet.cpu.kernel %3.2f\n", usage);
261     usage=((((float)idle)/((float)total))*100.00);
262     printf("packet.cpu.idle %3.2f\n", usage);
263    
264 pajs 1.5 /* Cos i-scream's expects this to be sent :/ */
265 tdb 1.4 printf("packet.cpu.iowait 0\n");
266 pajs 1.5 printf("packet.cpu.swap 0\n");
267    
268 tdb 1.4 free(line[0]);
269     free(line[1]);
270 pajs 1.1 }
271    
272 tdb 1.4 void processStats() {
273 pajs 1.10 int sleeping=0;
274 tdb 1.4 int zombie=0;
275     int stopped=0;
276     int running=0;
277     int nousers=0;
278     char *line;
279 pajs 1.10 char *line_ptr;
280 tdb 1.4 struct utmp *entry;
281 pajs 1.10 DIR *procdir;
282     struct dirent *procent;
283     char fname[_POSIX_PATH_MAX];
284 tdb 1.4 FILE *f;
285 pajs 1.10
286     chdir("/proc");
287     if((procdir=opendir(".")) == NULL){
288     errf("Failed to open proc (%m)");
289     exit(1);
290 tdb 1.4 }
291 pajs 1.7
292 pajs 1.10 while((procent = readdir(procdir)) != NULL){
293     if(atoi(procent->d_name) == 0) continue;
294     strncpy(fname, procent->d_name, _POSIX_PATH_MAX-7);
295     strcat(fname, "/status");
296    
297     if((f=fopen(fname, "r")) == NULL){
298     errf("Failed to open process stat (%m)");
299     exit(1);
300     }
301    
302     while((line=fpgetline(f)) != NULL){
303     if(strncasecmp(line,"State:",6)==0) break;
304     }
305    
306     line_ptr=line;
307 pajs 1.12 for(;*line_ptr++ != '\t';);
308    
309    
310 pajs 1.10 if(*line_ptr=='R') running++;
311     if(*line_ptr=='S') sleeping++;
312     if(*line_ptr=='Z') zombie++;
313     if(*line_ptr=='T') stopped++;
314     if(*line_ptr=='D') stopped++;
315    
316 tdb 1.4 }
317 pajs 1.10 closedir(procdir);
318    
319 tdb 1.4 printf("packet.users.list");
320    
321     while((entry=getutent()) != NULL) {
322     if(entry->ut_type==USER_PROCESS) {
323     printf(" %s",entry->ut_user);
324     nousers++;
325     }
326     }
327    
328     printf("\npacket.users.count %d\n", nousers);
329    
330 pajs 1.5 printf("packet.processes.sleeping %d\n",sleeping);
331     printf("packet.processes.cpu %d\n",running);
332 tdb 1.4 printf("packet.processes.zombie %d\n",zombie);
333     printf("packet.processes.stopped %d\n", stopped);
334     printf("packet.processes.total %d\n", (sleeping+running+zombie+stopped));
335 pajs 1.1 }
336    
337 tdb 1.4 void uptimeStats() {
338     char *line;
339     char *line_p;
340     FILE *f;
341    
342     if ((f=fopen("/proc/uptime", "r")) == NULL) {
343     errf("Failed to get uptime stats (%m)");
344     die();
345     }
346    
347     if ((line=fpgetline(f)) == NULL) {
348     errf("Failed to read uptime stats (%m)");
349     die();
350     }
351    
352     if ((fclose(f)) != 0) {
353     errf("Failed to close file (%m).");
354     die();
355     }
356    
357     line_p=strchr(line, '.');
358     if (line_p==NULL) abort();
359     *line_p='\0';
360    
361     printf("packet.os.uptime %s\n", line);
362 pajs 1.1 }
363    
364 tdb 1.4 void osStats() {
365     struct utsname os;
366    
367     if((uname(&os)) != 0) {
368     errf("Failed to get os stats (%m)");
369     die();
370     }
371    
372     printf("packet.os.name %s\n", os.sysname);
373     printf("packet.os.release %s\n" , os.release);
374     printf("packet.os.version %s\n", os.version);
375     printf("packet.os.sysname %s\n" , os.nodename);
376     printf("packet.os.platform %s\n", os.machine);
377 pajs 1.1 }
378    
379 tdb 1.4 void diskStats() {
380 pajs 1.8
381     struct mntent *mp;
382     struct statfs df;
383     FILE *f;
384     int counter=0;
385    
386     if ((f=fopen("/etc/mtab", "r" ))==NULL){
387     errf("Failed to open mounts (%m)");
388     die();
389     }
390    
391     while((mp=getmntent(f))){
392     if ((statfs(mp->mnt_dir, &df)) !=0){
393     errf("Failed to gets fs stats (%m)");
394     continue;
395     }
396    
397     if((((strcmp(mp->mnt_type, MNTTYPE_NFS))==0) || (strcmp(mp->mnt_type,MNTTYPE_IGNORE)) ==0)) continue;
398 tdb 1.4
399 pajs 1.8 printf("packet.disk.p%d.attributes.mount %s\n", counter, mp->mnt_dir);
400     printf("packet.disk.p%d.attributes.name %s\n", counter, mp->mnt_fsname);
401     printf("packet.disk.p%d.attributes.kbytes %lu\n",counter, ((df.f_bsize/1024) * df.f_blocks));
402     printf("packet.disk.p%d.attributes.used %lu\n",counter, (((df.f_bsize/1024) * df.f_blocks) -((df.f_bsize/1024) * df.f_bfree)));
403     printf("packet.disk.p%d.attributes.avail %lu\n",counter, (df.f_bsize/1024) * df.f_bavail);
404     printf("packet.disk.p%d.attributes.totalinodes %lu\n", counter, df.f_files);
405     printf("packet.disk.p%d.attributes.freeinodes %lu\n",counter, df.f_ffree);
406 tdb 1.4
407 pajs 1.8 counter++;
408     }
409    
410    
411    
412 pajs 1.1 }
413    
414 tdb 1.4 int main() {
415 pajs 1.1 getLoadAv();
416     getMemInfo();
417     cpustats();
418     processStats();
419     uptimeStats();
420     osStats();
421     diskStats();
422     fflush(stdout);
423     return 0;
424     }