[질문]cpu, memory, process의 정보얻어오기...

youhero의 이미지

현재 서버의 상태를 모니터링하는 프로그램을 만들려 합니다.
예를 들어 현재 CPU의 사용률, 디스크의 상태, 사용한 메모리, 현재 작동중인 메모리등의 정보를 얻어올 수 있는 시스템 콜이 있는지요?

있다면 어떤것인지요?

Solaris에서도 사용할 수 있는지요...?

답변 부탁드립니다.

지리즈의 이미지

top이나 free의 source를 구해서 보시면 될 것 같습니다.

바로 얼마전에 다루어졌던 주제인데요...

http://bbs.kldp.org/viewtopic.php?t=28315
이것도 한번 읽어 보시구요..

There is no spoon. Neo from the Matrix 1999.

compactor의 이미지

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

생각나는것만 적어보았습니다.

잠자는 사자는 흔들어 깨운다.

nanosec의 이미지

한빛미디어의 유닉스 관련 프로그래밍 책에 나오는 예제중의 하나 입니다.
파일이 이것 말구 다른것도 하나 있었던것 같은데..
그건 정보를 보여주는 부분만 있엇던것 같습니다. 리눅스에서 공부하다가, 리눅스에서 테스트할 수 없는 소스여서 제가 미워했던(?) 소스입니다. ^^

#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

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <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].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.