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 (23 years, 7 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

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org.uk
4 * 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 #include <stdio.h>
22 #include <stdlib.h>
23 #include "ukcprog.h"
24 #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 #include <mntent.h>
31 #include <dirent.h>
32 #include <limits.h>
33
34 int die() {
35 exit (1);
36 }
37
38 void getLoadAv() {
39 #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
75 #else
76 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 #endif
87 }
88
89 void getMemInfo() {
90 char *line;
91 char *mem=NULL;
92 char *swap=NULL;
93 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
122 if (mem==NULL || swap==NULL){
123 errf("Failed to obtain information required for memory and swap stats");
124 die();
125 }
126
127 /* 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 }
175
176 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
207 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
224 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 /* Cos i-scream's expects this to be sent :/ */
265 printf("packet.cpu.iowait 0\n");
266 printf("packet.cpu.swap 0\n");
267
268 free(line[0]);
269 free(line[1]);
270 }
271
272 void processStats() {
273 int sleeping=0;
274 int zombie=0;
275 int stopped=0;
276 int running=0;
277 int nousers=0;
278 char *line;
279 char *line_ptr;
280 struct utmp *entry;
281 DIR *procdir;
282 struct dirent *procent;
283 char fname[_POSIX_PATH_MAX];
284 FILE *f;
285
286 chdir("/proc");
287 if((procdir=opendir(".")) == NULL){
288 errf("Failed to open proc (%m)");
289 exit(1);
290 }
291
292 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 for(;*line_ptr++ != '\t';);
308
309
310 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 }
317 closedir(procdir);
318
319 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 printf("packet.processes.sleeping %d\n",sleeping);
331 printf("packet.processes.cpu %d\n",running);
332 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 }
336
337 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 }
363
364 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 }
378
379 void diskStats() {
380
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
399 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
407 counter++;
408 }
409
410
411
412 }
413
414 int main() {
415 getLoadAv();
416 getMemInfo();
417 cpustats();
418 processStats();
419 uptimeStats();
420 osStats();
421 diskStats();
422 fflush(stdout);
423 return 0;
424 }