본문

테크
리눅스 서버 모니터링의 원리

작성일 2023년 05월 18일

우리는 PC가 평상시보다 느릴 때 ‘작업 관리자’를 켜곤 합니다. 작업 관리자의 내용을 잘 살펴보면 하드웨어 자원을 유달리 많이 사용하는 프로세스가 있습니다. 이런 프로세스를 강제 종료하면 대체로 정상으로 돌아갑니다. 서버 모니터링의 역할은 PC의 작업 관리자와 비슷합니다. PC 버벅거림 현상과 마찬가지로, 대부분의 IT 서비스 장애는 하드웨어 자원 사용량의 이상 패턴을 동반합니다. 따라서 서버 모니터링은 장애의 예측과 대응을 위한 가장 중요한 도구라고 할 수 있습니다. 오늘은 서버 모니터링의 근간이 되는 원리에 대해 설명하고자 합니다.

서버 모니터링의 근본은 proc 파일 시스템

리눅스 서버에는 proc이라는 특수한 디렉토리가 있습니다. 리눅스 매뉴얼에서는 커널의 자료구조에 접근할 수 있는 인터페이스를 제공하는 유사 파일 시스템(psuedo-filesystem)이라고 설명합니다. 겉으로 보기엔 다른 파일 시스템과 유사하지만 실제로는 파일로 이루어지지 않았다는 뜻입니다. proc 디렉토리는 일반적인 파일 시스템과는 달리 모든 내용이 메모리에 저장되어 있다는 차이가 있습니다. 때문에 일반적인 파일보다 훨씬 빠르게 내용을 조회할 수 있습니다.

마운트 경로를 변경하지 않았다면  ls /proc 명령어로 proc 파일 시스템의 내용을 조회할 수 있습니다. 다음 캡처는 명령어를 실행한 결과입니다.

meminfo

의미를 짐작하기 어려운 파일이나 디렉토리도 있지만, cpuinfo, meminfo처럼 쉬운 이름도 있습니다. 다음은  /proc/meminfo  파일의 내용을 출력한 예입니다.

   
              root@localhost:~# cat /proc/meminfo
              MemTotal:        7943776 kB
              MemFree:         6581156 kB
              MemAvailable:    7389244 kB
              Buffers:          272652 kB
              Cached:           718740 kB
              SwapCached:            0 kB
              Active:           640872 kB
              Inactive:         514776 kB
              Active(anon):       1032 kB
              Inactive(anon):   153368 kB
              Active(file):     639840 kB
              Inactive(file):   361408 kB
              Unevictable:       29252 kB
              Mlocked:           27716 kB
              SwapTotal:             0 kB
              SwapFree:              0 kB
              Dirty:                 8 kB
              Writeback:             0 kB
              AnonPages:        193512 kB
              Mapped:           144492 kB
              Shmem:              2628 kB
              KReclaimable:      55484 kB
              Slab:              97024 kB
              SReclaimable:      55484 kB
              SUnreclaim:        41540 kB
              KernelStack:        3168 kB
              PageTables:         3444 kB
              NFS_Unstable:          0 kB
              Bounce:                0 kB
              WritebackTmp:          0 kB
              CommitLimit:     3971888 kB
              Committed_AS:    1231864 kB
              VmallocTotal:   34359738367 kB
              VmallocUsed:       15340 kB
              VmallocChunk:          0 kB
              Percpu:             1440 kB
              HardwareCorrupted:     0 kB
              AnonHugePages:         0 kB
              ShmemHugePages:        0 kB
              ShmemPmdMapped:        0 kB
              FileHugePages:         0 kB
              FilePmdMapped:         0 kB
              HugePages_Total:       0
              HugePages_Free:        0
              HugePages_Rsvd:        0
              HugePages_Surp:        0
              Hugepagesize:       2048 kB
              Hugetlb:               0 kB
              DirectMap4k:      187904 kB
              DirectMap2M:     4005888 kB
              DirectMap1G:     6291456 kB
            
   

meminfo는 이름 그대로 메모리에 대한 정보를 담고 있는 파일입니다. 그런데 메모리의 용량을 total, free, available 등으로 구분하는 방식이 어쩐지  free  명령어와 비슷합니다. 실제로 free 명령어를 실행하면 meminfo를 조회했을 때와 거의 동일한 내용이 출력되는 것을 확인할 수 있습니다.

   
              root@localhost:~# free
               total        used        free      shared  buff/cache   available
               Mem:         7943776      315968     6580932        2628     1046876     7389024
               Swap:              0           0           0
            
   

man free  명령어를 통해 도움말 페이지를 읽어보면 free에서 출력하는 정보는 meminfo 파일의 내용을 파싱 해서 수집한다고 설명하고 있습니다. (The information is gathered by parsing /proc/meminfo.) free의 결과가 meminfo와 유사한 것이 단순한 우연이 아님을 알 수 있습니다.

proc에서 알 수 있는 것은 메모리 사용량뿐만이 아닙니다. CPU 사용량, 디스크 I/O 사용량 등 대부분의 서버 모니터링 지표의 기원이 proc 파일 시스템입니다.

실습: CPU 사용량 계산하기

proc 파일 시스템의 내용을 이용해 CPU 사용량을 계산하는 실습을 해보겠습니다.  /proc/stat  파일의 내용을 출력하면 다음과 같습니다.

/proc/stat

출력 결과의 각 행은 ‘cpu’라는 문자열로 시작하는데요. 두 번째 행부터는 0부터 시작하는 숫자가 차례대로 붙어 있습니다. 이 숫자는 CPU의 각 코어를 구분하기 위해 붙인 것입니다. 첫 행의 수치는 전체 코어의 합계입니다.

이후로는 10개의 수치가 공백으로 구분되어 있습니다. 이 수치들은 부팅 이후 CPU의 사용 시간을 의미합니다. 단위는 100분의 1초를 의미하는 USER_HZ입니다. (엄밀히 말하면 단순히 100분의 1초를 의미하는 단위는 아니지만, 이에 대한 자세한 설명은 글의 주제를 벗어나므로 생략하도록 하겠습니다.) 각 수치의 의미를 왼쪽부터 순서대로 설명하면 다음과 같습니다.

  1. user: 유저 모드에서 사용한 시간.
  2. nice: 유저 모드에서 우선순위가 낮은 프로세스에 사용한 시간.
  3. system: system에서 사용한 시간.
  4. idle: cpu가 사용되지 않은 시간.
  5. iowait: 입출력이 끝날 때까지 대기하던 시간.
  6. irq: 하드웨어 인터럽트에 사용한 시간.
  7. softirq: 소프트웨어 인터럽트에 사용한 시간.
  8. steal: 리눅스가 VM에서 실행되고 있을 때 같은 물리 장비를 사용하는 다른 VM이 사용한 시간.
  9. guest: 버추얼박스 등을 이용해 VM을 만들었을 때 guest VM의 가상 CPU에서 사용한 시간.
  10. guest_nice: guest VM의 가상 CPU에서 우선순위가 낮은 프로세스에 사용한 시간.

10개의 수치 중 idle, iowait은 CPU를 사용하지 않은 시간임을 알 수 있습니다. 따라서 모든 열의 수치를 합한 후, idle과 iowait을 제외한 시간의 비율을 계산하면 전체 사용량을 구할 수 있습니다.

주의할 점은 특정 시점 t의 CPU 사용량을 구하기 위해선 두 번의 측정이 필요하다는 점입니다. CPU 사용 시간은 부팅 이후 계속 누적 증가하는 수치이므로, t에서 파싱 한 값을 가지고 계산하면 부팅 이후 전체 사용량을 구하게 됩니다. 따라서 t의 CPU 사용 시간이 t-1 시점과 비교해 얼마나 증가하였는지를 계산하여야 합니다.

t 시점의 전체 CPU 사용 시간을 , idle과 iowait을 제외한 실제 사용 시간을  라 할 때 t 시점의 CPU 사용량을 % 단위로 구하는 과정을 수식으로 나타내면 다음과 같습니다.

cpu

이론을 알았으니 구현도 가능합니다. 다음은 파이썬을 이용해 5초 동안의 CPU 사용량을 구하는 예시입니다.

   
              import time
                def parse_cpu_info():
                    with open('/proc/stat', 'r') as f:
                        stat_line = f.readline()
                    cpu_info = stat_line.split()
                    cpu_total = sum(map(int, cpu_info[1:]))
                    cpu_usage = cpu_total - int(cpu_info[4]) - int(cpu_info[5])
                    return cpu_total, cpu_usage
                def calculate_cpu_usage(interval):
                    cpu_total1, cpu_usage1 = parse_cpu_info()
                    time.sleep(interval)
                    cpu_total2, cpu_usage2 = parse_cpu_info()
                    total_diff = cpu_total2 - cpu_total1
                    usage_diff = cpu_usage2 - cpu_usage1
                    cpu_usage = usage_diff / total_diff * 100
                    return cpu_usage
                if __name__ == "__main__":
                    cpu_usage = calculate_cpu_usage(5)
                    print(f"CPU 사용량: {cpu_usage:.2f}%")
            
   

마치며

이번 포스팅에서는 서버 모니터링의 정보 원천인 proc 파일 시스템을 소개했습니다. 와탭의 서버 모니터링도 기본 원리는 free나 top과 같은 고전적인 도구들과 크게 다르지 않습니다. 실습 단계까지 따라오셨다면 서버 모니터링의 원리에 대해 더 잘 이해하게 되셨을 것입니다.

참고 자료

man page - proc

Tex 수식과 python 소스 코드의 일부는 ChatGPT가 작성하였습니다.

박범수[email protected]
DevOps TeamDevOps Engineer

지금 바로
와탭을 경험해 보세요.