Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

소개

예전에 한번 하드디스크가 꽉 차버리는 바람에, 웹 서비스가 제대로 되지 않던 때가 있었다. 이상하게 사이트가 느려지기 시작하더니, 어느 순간부터는 로그인도 안되는 것이 아닌가. 이 문제로 거의 반나절을 헤메다가 원인을 알고 해결했을 때의 허무함이란!!.

조금만 신경을 썼다면 쉽게 원인을 파악할 수 있었을 것이다. 로그인이 안된다는 건 세션관리에 문제가 있다는 건데, Apache(:12)의 세션관리가 파일기반이였으니, 파일시스템에 뭔가 문제가 있다는 식으로 분석이 가능했을 것이다. 그러나 사람의 경험에 따른 문제대응 방식이란 원래가 완전할 수가 없는 법이다. 당시 내 사이트는 외부의 몇몇 해킹시도가 있어서 여기에 신경쓰고 있을 때였다. 거기에다가 사이트개편과 관련되어서 이것 저것 신경을 쓰다보니, 아무래도 제대로된 판단이 늦어질 수 밖에 없었다.

그래서 RRD(:12)를 응용해서 디스크용량 관리 툴을 만들기로 마음을 먹었고, 마음을 먹은지 거의 3개월만에 초기 버전이라고 할만한 응용을 만들었다.

RRD 데이터 베이스 생성

우선 다음과 같은 룰을 가지는 데이터 베이스를 생성했다.
rrdtool create rrd_hda2.rrd --start 1164189432 --step 300 \
DS:total:GAUGE:600:U:U \
DS:used:GAUGE:600:U:U \
RRA:LAST:0.5:1:600 \
RRA:LAST:0.5:6:700 \
RRA:LAST:0.5:24:775 \
RRA:LAST:0.5:288:797
이 데이터 베이스는 할당량 (total)사용량 (used)두개의 필드를 가진 데이터를 300초 간격으로 저장하도록 만들어졌다.

디스크 사용량 수집

proc(:12)파일 시스템의 정보를 수집하는 Agent를 만들생각이었으나, 귀차니즘으로 그냥 df(:12)의 표준출력(:12)을 파싱하는 간단한 C(:12)프로그램을 만들었다.
#include <stdio.h>

#define MAXLINE 256
int main(int argc, char **argv)
{
    FILE *fp;
    int state;
    char buf[MAXLINE];
    int type = 0;
    char fsname[12];
    char block[12];
    char used[12];

    char *checkFs = argv[1];

    fp = popen("/bin/df -B 1", "r");
    if (fp == NULL)
    {
        return 1;
    }
    while(fgets(buf, MAXLINE, fp) != NULL)
    {
        if(strstr(buf, checkFs))
        {
            sscanf(buf,"%s %s %s %s", fsname, block, used);
            printf("%s:%s\n", block,used);
        }
    }
    pclose(fp);
    return 0;
}
프로그램의 이름은 dfrrd로 결정했다. 그리고 다음과 같은 스크립트를 만들어서 만들어진 RRD 데이터베이스를 Update하도록 했다.
#!/bin/sh

TIME=`date +%s`
VALUE=`/usr/local/bin/dfrrd /dev/hda2 1`
/usr/local/bin/rrdtool update /usr/local/mutihost/joinc/modules/rrd/df_hda2.rrd $TIME:$VALUE
만들어진 쉘스크립는 crontab을 이용해서 5분간격으로 실행되도록 했다.
 0,5,10,15,20,25,30,35,40,45,50,55 * * * * /usr/local/bin/dfrrd.sh > /dev/null

그래프 생성

그래프 생성역시 cron을 이용해서 5분마다 재 생성되도록 했다. cron작업을 위해서 다음과 같은 스크립트를 만들었다.
# 최근 6시간동안의 결과를 보여준다.
FROM=`echo "$CUTIME - (3600*6)" | bc`
/usr/local/bin/rrdtool graph /usr/local/mutihost/joinc/modules/rrd/images/df_hda2.png \
-s $FROM --vertical-label Mbyte \
DEF:linea=/usr/local/mutihost/joinc/modules/rrd/df_hda2.rrd:total:LAST \
"CDEF:ctotal=linea,1000000,/" \
AREA:linea#FF0000:"TOTAL" \
"GPRINT:ctotal:LAST:%3.2lf Mbyte" \
DEF:lineb=/usr/local/mutihost/joinc/modules/rrd/df_hda2.rrd:used:LAST \
AREA:lineb#00FFFF:"USED" \
"CDEF:cused=lineb,1000000,/" \
"GPRINT:cused:LAST:%3.2lf Mbyte"
다음은 적용된 결과다.

http://www.joinc.co.kr/modules/rrd/images/df_hda2year.png