현재 서버의 상태를 모니터링하는 프로그램을 만들려 합니다. 예를 들어 현재 CPU의 사용률, 디스크의 상태, 사용한 메모리, 현재 작동중인 메모리등의 정보를 얻어올 수 있는 시스템 콜이 있는지요?
있다면 어떤것인지요?
Solaris에서도 사용할 수 있는지요...?
답변 부탁드립니다.
top이나 free의 source를 구해서 보시면 될 것 같습니다.
바로 얼마전에 다루어졌던 주제인데요...
http://bbs.kldp.org/viewtopic.php?t=28315 이것도 한번 읽어 보시구요..
There is no spoon. Neo from the Matrix 1999.
man kstat (dev/kstat) 5.6이상만 사용한다면 cpu/memory/load_avg등 man kvm (dev/kstat) 모든버젼 cpu/memory/load_avg등 man statvfs filesystem resource man swapct swap resource man psrinfo process resource
생각나는것만 적어보았습니다.
잠자는 사자는 흔들어 깨운다.
한빛미디어의 유닉스 관련 프로그래밍 책에 나오는 예제중의 하나 입니다. 파일이 이것 말구 다른것도 하나 있었던것 같은데.. 그건 정보를 보여주는 부분만 있엇던것 같습니다. 리눅스에서 공부하다가, 리눅스에서 테스트할 수 없는 소스여서 제가 미워했던(?) 소스입니다. ^^
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <dirent.h> #include <nlist.h> #include <kvm.h> #include <sys/proc.h> #include <sys/procfs.h> #include <sys/var.h> #include <sys/cpuvar.h> #include <sys/file.h> #include <sys/swap.h> #include <kstat.h> /* system information related */ #define CPUSTATES 5 #define NUM_STRINGS 8 struct system_info{ double load_avg[3]; int *cpu_state; int *memory_state; }; #ifndef FSCALE #define FSHIFT 8 #define FSCALE (1 << FSHIFT) #endif #define loaddouble(value) ((double)(value) / FSCALE) #define CPUSTATE_IOWAIT 3 #define CPUSTATE_SWAP 4 kstat_ctl_t *kopen = NULL; kstat_t **cpu_ks; cpu_stat_t *cpu_stat; int cpu_states[CPUSTATES]; int memory_state[3]; int nproc; int ncpus; int print_load_average(); int print_memory_state(); void print_cpu_state(); void Error(char *); char *itoa(register int val) { char *ptr; static char buffer[16]; ptr = buffer + sizeof(buffer); *--ptr = '\0'; if (val == 0) *--ptr = '0'; else while (val != 0) { *--ptr = (val % 10) + '0'; val /= 10; } return(ptr); } void get_cpu_relate_information(count, cpu_info, new, old, diffs) int count; int *cpu_info; long *new; long *old; long *diffs; { int i; long change; long total_change; long *dp; long half_total; total_change = 0; dp = diffs; for (i = 0; i < count; i++) { if ((change = *new - *old) < 0) change = (int) ((unsigned long)*new-(unsigned long)*old); total_change += (*dp++ = change); *old++ = *new++; } if (total_change == 0) total_change = 1; half_total = total_change / 2L; for (i = 0; i < count; i++) *cpu_info++ = (int)((*diffs++ * 1000 + half_total) / total_change); } int format_k(int Mbyte) { if (Mbyte >= 10000) { Mbyte = (Mbyte + 512) / 1024; if (Mbyte >= 10000) Mbyte = (Mbyte + 512) / 1024; } return (Mbyte); } #define UPDKCID(nk,ok) \ if (nk == -1) { \ Error("kstat read"); \ } \ if (nk != ok)\ goto kcid_changed; int get_cpu_and_load_average(int load_average[3]) { kstat_t *lookup; kid_t chaind_update; int i; int changed = 0; static int ncpu = 0; static kid_t chaing_ID = 0; kstat_named_t *data_lookup; if (!kopen) { kopen = kstat_open(); if (!kopen) Error("kstat open"); changed = 1; chaing_ID = kopen->kc_chain_id; } kcid_changed: chaind_update = kstat_chain_update(kopen); if (chaind_update) { changed = 1; chaing_ID = chaind_update; } UPDKCID(chaind_update,0); lookup = kstat_lookup(kopen, "unix", 0, "system_misc"); if (kstat_read(kopen, lookup, 0) == -1) Error("kstat read"); data_lookup = kstat_data_lookup(lookup, "avenrun_1min"); if (data_lookup) load_average[0] = data_lookup->value.ui32; data_lookup = kstat_data_lookup(lookup, "avenrun_5min"); if (data_lookup) load_average[1] = data_lookup->value.ui32; data_lookup = kstat_data_lookup(lookup, "avenrun_15min"); if (data_lookup) load_average[2] = data_lookup->value.ui32; data_lookup = kstat_data_lookup(lookup, "nproc"); if (data_lookup) nproc = data_lookup->value.ui32; if (changed) { ncpu = 0; data_lookup = kstat_data_lookup(lookup, "ncpus"); if (data_lookup && data_lookup->value.ui32 > ncpus) { ncpus = data_lookup->value.ui32; cpu_ks = (kstat_t **) realloc (cpu_ks, ncpus * sizeof (kstat_t *)); cpu_stat = (cpu_stat_t *) realloc (cpu_stat, ncpus * sizeof (cpu_stat_t)); } for (lookup = kopen->kc_chain; lookup; lookup = lookup->ks_next) { if (strncmp(lookup->ks_name, "cpu_stat", 8) == 0) { chaind_update = kstat_read(kopen, lookup, NULL); UPDKCID(chaind_update, chaing_ID); cpu_ks[ncpu] = lookup; ncpu++; if (ncpu > ncpus) Error("kstat finds too many cpus"); } } changed = 0; } for (i = 0; i < ncpu; i++) { chaind_update = kstat_read(kopen, cpu_ks[i], &cpu_stat[i]); UPDKCID(chaind_update, chaing_ID); } return(ncpu); } void get_system_information(struct system_info *system_information) { int load_average[3]; static int free_memory; static int total_memory; static int available_memory; static long cpu_info[CPUSTATES]; static long cpu_old[CPUSTATES]; static long system_diff[CPUSTATES]; int j, i; kstat_t *lookup; kstat_named_t *data_lookup; int cpu_number; for (j = 0; j < CPUSTATES; j++) cpu_info[j] = 0L; cpu_number = get_cpu_and_load_average(load_average); for (i = 0; i < cpu_number; i++) { /* **************************************************** */ // idle%, user%, kernel%에 대한 값을 cpu_info[]에 저장한다. /* **************************************************** */ for (j = 0; j < 3; j++) cpu_info[j] += (long) cpu_stat[i].cpu_sysinfo.cpu[j]; /* **************************************************** */ // iowait% 구하기 /* **************************************************** */ cpu_info[CPUSTATE_IOWAIT] += (long) cpu_stat[i].cpu_sysinfo.wait[W_IO] + (long) cpu_stat[i].cpu_sysinfo.wait[W_PIO]; /* **************************************************** */ // swap% 구하기 /* **************************************************** */ cpu_info[CPUSTATE_SWAP] += (long) cpu_stat[i].cpu_sysinfo.wait[W_SWAP]; } lookup = kstat_lookup(kopen, "unix", 0, "system_pages"); if (kstat_read(kopen, lookup, 0) == -1) Error("kstat read"); /* **************************************************** */ // free memory 구하기 /* **************************************************** */ data_lookup = kstat_data_lookup(lookup, "freemem"); if (data_lookup) free_memory = data_lookup->value.ul; /* **************************************************** */ // cpu_states[] : idle, user, kernel, iowait, swap 등이 // 저장된다. /* **************************************************** */ get_cpu_relate_information (CPUSTATES, cpu_states, cpu_info, cpu_old, system_diff); /* **************************************************** */ // load 평균 저장하기 /* **************************************************** */ for (i = 0; i < 3; i++) system_information->load_avg[i] = loaddouble(load_average[i]); /* **************************************************** */ // sysconf()로 전체 메모리 구하기 /* **************************************************** */ total_memory = sysconf(_SC_PHYS_PAGES); memory_state[0] = (total_memory << 3) / 1024; memory_state[1] = 0; memory_state[2] = (free_memory << 3) / 1024; system_information->cpu_state = cpu_states; system_information->memory_state = memory_state; } int print_memory_state(int *stats) { puts(""); printf(">> memory state :"); /* total memory, active(null), free memory */ printf("%s ", format_k(*stats++)); *stats++; printf("%s\n", format_k(*stats)); } int print_load_average(int mpid, double *load_average) { int i; puts(""); puts("=========================================================="); printf(">> load average : "); for (i = 0; i < 3; i++) printf("%5.2f", load_average[i]); } void print_cpu_state(states) int *states; { static int count = 0; int j, i = 0; int value; char *cpu_state_menu[] = {"idle", "user", "kernel", "iowait", "swap", NULL}; char **names = cpu_state_menu; char *thisname; if(count == 0) { count = 1; return; } printf("\n>> CPU state : "); for(j = 0;j < 5;j++) { thisname = *names++; if (*thisname != '\0') { value = *states++; printf((value >= 1000 ? "%s%4.0f%% %s" : "%s%4.1f%% %s"), i++ == 0 ? "" : ", ", ((float)value)/10., thisname); } } } void Error(char *error_name) { perror(error_name); exit(0); }
0x2B | ~0x2B - Hamlet
텍스트 포맷에 대한 자세한 정보
<code>
<blockcode>
<apache>
<applescript>
<autoconf>
<awk>
<bash>
<c>
<cpp>
<css>
<diff>
<drupal5>
<drupal6>
<gdb>
<html>
<html5>
<java>
<javascript>
<ldif>
<lua>
<make>
<mysql>
<perl>
<perl6>
<php>
<pgsql>
<proftpd>
<python>
<reg>
<spec>
<ruby>
<foo>
[foo]
top이나 free의 source를 구해서 보시면 될 것 같습니다.
top이나 free의 source를 구해서 보시면 될 것 같습니다.
바로 얼마전에 다루어졌던 주제인데요...
http://bbs.kldp.org/viewtopic.php?t=28315
이것도 한번 읽어 보시구요..
There is no spoon. Neo from the Matrix 1999.
간단하게..
man kstat (dev/kstat) 5.6이상만 사용한다면 cpu/memory/load_avg등
man kvm (dev/kstat) 모든버젼 cpu/memory/load_avg등
man statvfs filesystem resource
man swapct swap resource
man psrinfo process resource
생각나는것만 적어보았습니다.
잠자는 사자는 흔들어 깨운다.
한빛의 유닉스 프로그래밍 관련 책에 나오는 소스 입니다.
한빛미디어의 유닉스 관련 프로그래밍 책에 나오는 예제중의 하나 입니다.
파일이 이것 말구 다른것도 하나 있었던것 같은데..
그건 정보를 보여주는 부분만 있엇던것 같습니다. 리눅스에서 공부하다가, 리눅스에서 테스트할 수 없는 소스여서 제가 미워했던(?) 소스입니다. ^^
0x2B | ~0x2B
- Hamlet
댓글 달기