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.13
Committed: Sat May 18 18:15:56 2002 UTC (22 years, 5 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.12: +19 -0 lines
Log Message:
i-scream is now licensed under the GPL. I've added the GPL headers to every
source file, and put a full copy of the license in the appropriate places.
I think I've covered everything. This is going to be a mad commit ;)

File Contents

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