원문 : http://www.ischo.net -- 조인상 // 시스템 엔지니어

Writer : http://www.ischo.net -- ischo // System Engineer in Replubic Of Korea

+++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

파일시스템 사용량 추이를 http 전송으로 DB에 누적하기

 

 

시스템 관리를 하다보면 각 서버들의 파일시스템 추이를 관리해야 할 필요가 있다.

파일시스템은 갈수록 크기가 커지며, 하루에 얼마나 쌓이는지 알아야지 향후 저장공간을 증설할때 얼마만큼의 

저장공간을 마련해야 할지 예측할 수 있기 때문이다.

 

또는 정기적인 에방점검을 할때 보고서를 작성하는 경우에도 파일시스템 용량 체크는 상당한 노력이 든다.

수십대가 넘는 시스템들의 파일시스템 추이를 매달 기록해서 제출해야 할 때 매우 번거롭다.

 

단순, 반복작업만큼 자동화에 걸맞는 대상도 없다.

 

이 문서에서는 각 Windows, Linux 시스템에서 쉘스크립트를 통해서 매일 파일시스템 용량을 각 호스트에 저장하면서 

동시에 httpd 웹서버로 전송하여 향후에 추이도 계산할 수 있는 프로그래밍에 대해서 다룬다.

 

 

차례 

 

1. php 웹서버 구성

 

2. 데이터베이스 구성

 

3. Linux 서버 쉘스크립팅

 

4. Windows 서버 쉘스크립팅

 

5. 데이터 수집 처리 및 조회

 

 

 

 

 

1. php 웹서버 구성

 

먼저 php 웹서버를 구성한다.

apache, php, mysql 이 일반적이지만, 다른 구성이라도 문제없다.

 

HTTP GET 방식으로 들어온 데이터를 DB에 처리할 예정이다.

 

예제에서는 <Document Root> 디렉토리 안에 fsmonitor 라는 디렉토리를 만들어서 수행하였다.

 

 

 

 

2. 데이터베이스 구성

 

- 데이터베이스 만들기 : 

   : fsmonitor 라는 데이터베이스를 만든다.

mysql> create database fsmonitor;

mysql> CREATE DATABASE fsmonitor CHARACTER SET utf8 COLLATE utf8_bin;
mysql> CREATE USER 'fsmonitor'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER;
mysql> GRANT ALL PRIVILEGES ON fsmonitor.* TO 'fsmonitor'@'localhost';

mysql> flush privileges;

 

 

- 테이블 생성

mysql> CREATE TABLE fsmonitor_tb (
    sno int(11) NOT NULL auto_increment PRIMARY KEY,
    date char(8) DEFAULT NULL,
    servername varchar(80) DEFAULT NULL,
    hostname varchar(80) DEFAULT NULL,
    ipaddress char(20) DEFAULT NULL,
    mount varchar(80) DEFAULT NULL,
    size varchar(80) DEFAULT NULL,
    used varchar(80) DEFAULT NULL,
    free varchar(80) DEFAULT NULL,
    perc varchar(80) DEFAULT NULL,
    etc varchar(100) DEFAULT NULL
) DEFAULT CHARSET=utf8;

 

- 테이블 명세

    sno int(11) : 순번
    date char(8) : 날짜 YYYYMMDD 형식
    servername varchar(80) : 서버이름
    hostname varchar(80) : hostname
    ipaddress char(20) : IP주소
    mount varchar(80) : 마운트명 ( / 또는 C드라이브)
    size varchar(80) : 전체 용량
    used varchar(80) : 사용량
    free varchar(80) : 남은용량
    perc varchar(80) : 사용율
    etc varchar(100) : 기타

 

 

3. Linux 서버 쉘스크립팅

 

- 다음 df.sh 쉘스크립트 파일을 작성한다.

  스크립트는 현재 사용량을 로컬 df_연도.txt 파일에 증분하여 기록한 후 해당 웹서버의 DB에 기록한다.

 

- Linux서버에 curl 이 설치되어 있어야 한다.

# yum install curl

 

- 쉡스크립트 : df.sh

#!/bin/bash

################################################
# Program : Logging filesystem utilization     #
# Daeshin Networks                             #
################################################


## SET ENVIRONMENT #############################
DATE=`date +%Y%m%d`
YEAR=`date +%Y`
SH_HOME=/home/dsnw
LOGFILE=${SH_HOME}/df_${YEAR}.log
TMPFILE=${SH_HOME}/df_temp.log
HOSTNAME=`hostname`
GW_NIC=`netstat -nr | grep UG | awk {'print $8'}`
IP=`ip add | grep inet | grep ${GW_NIC} | awk {'print $2'} | cut -d "/" -f 1`
################################################

## MAIN ########################################
export LANG=C
date >> ${LOGFILE}
df -h >> ${LOGFILE}
echo >> ${LOGFILE}

df -h | grep -v "Filesystem" | grep -v "Use%" | grep -v /run | grep -v /sys | grep -v tmpfs | grep -v /boot > ${TMPFILE}

while read LIST

do
        SIZE=`echo ${LIST} | awk {'print $2'}`
        USED=`echo ${LIST} | awk {'print $3'}`
        FREE=`echo ${LIST} | awk {'print $4'}`
        PERC=`echo ${LIST} | awk {'print $5'}`
        MOUNT=`echo ${LIST} | awk {'print $6'}`


        curl "http://<SERVER_IPADDRESS>/fsmonitor/insert.php?date=${DATE}&host=${HOSTNAME}&ip=${IP}&size=${SIZE}&used=${USED}&free=${FREE}&perc=${PERC}&mount=${MOUNT}"

        sleep 1


done < ${TMPFILE} 

 

- 해당 쉘스크립트에 실행권한을 주고 테스트 한다.

# chmod 700 df.sh

# ./df.sh

   : 결과로 df_2022.log 파일이 생성되고, 데이터베이스에 파일시스템 추이가 기록된다.

 

 

 

4. Windows 서버 쉘스크립팅

 

- Windows 에서도 curl 을 설치해야 한다. 첨부의 curl.exe 다운로드.

 

- 시스템에서 파워쉘 실행권한을 주기 위해서 다음 명령어를 실행한다.

PS> Set-ExecutionPolicy RemoteSigned

 

- 파워쉘스크립트  : df.ps1


Function Get-DiskFreeSpace
{
  Get-WmiObject Win32_LogicalDisk -Filter "DriveType=3" | Format-Table -AutoSize `
  @{Label="DiskDrive";Expression={$_.DeviceID + ","}},`
  @{Label="Size";Expression={($_.Size/1gb) -as [int]};FormatString="{0:N1}G,"},`
  @{Label="Used";Expression={($_.Size/1gb)-($_.FreeSpace/1gb) -as [int]};FormatString="{0:N1}G,"},`
  @{Label="Avail";Expression={($_.FreeSpace/1gb) -as [int]};FormatString="{0:N1}G,"},`
  @{Label="Use%";Expression={(($_.Size/1gb)-($_.FreeSpace/1gb))/($_.Size/1gb) * 100 -as [int]};FormatString="{0:N1}%"}
}

$HOSTNAME = $env:computername;
$IPADDRESS = (get-netadapter | get-netipaddress | ? addressfamily -eq 'IPv4').ipaddress|?{$_ -notmatch '169.254.'}|?{$_ -notmatch '10.0.'}|?{$_ -notmatch '10.100.'}|Select-Object -First 1;
$DATE = date;
$DATE = $DATE.ToString("yyyyMMdd");

if(![System.IO.Directory]::Exists("C:\dsnw\")){
    New-Item -ItemType Directory -Path "C:\dsnw\";
}

if(![System.IO.File]::Exists("C:\dsnw\df.log")){
    New-Item -ItemType File -Path "C:\dsnw\df.log";
}

if(![System.IO.File]::Exists("C:\dsnw\df.tmp")){
    New-Item -ItemType File -Path "C:\dsnw\df.tmp";
}

if([System.IO.File]::Exists("C:\dsnw\df.log")){
    Get-DiskFreeSpace >> "C:\dsnw\df.log"
    Get-DiskFreeSpace > "C:\dsnw\df.tmp"
}

$FILE = Get-Content "C:\dsnw\df.tmp"
$result=@()

foreach ($LINE in $FILE)
{

 foreach ($COL in $LINE)
 {
     $result=$LINE -split ","
     $MOUNT=$result[0]
     $SIZE=$result[1]
     $USED=$result[2]
     $FREE=$result[3]
     $PERC=$result[4]
 }

  if($MOUNT -match "DiskDrive*" -or $MOUNT -match "---------*" -or $MOUNT -eq ""){
    continue;
  } else {
   $MOUNT=$MOUNT.Trim();
   $SIZE=$SIZE.Trim();
   $USED=$USED.Trim();
   $FREE=$FREE.Trim();
   $PERC=$SIZE.Trim();
   "curl  http://pcs.kipf.re.kr/fsmonitor/insert.php?date=${DATE}&host=${HOSTNAME}&ip=${IPADDRESS}&size=${SIZE}&used=${USED}&free=${FREE}&perc=${PERC}&mount=${MOUNT}"
 }
}

 

 

 

5. 데이터 수집 처리 및 조회

 

- 데이터베이스 연결 : db_connect.php

<?php

$servername="localhost";
$user="fsmonitor";
$password="password";
$db="fsmonitor";

$connect=mysqli_connect($servername,$user,$password,$db);


if (!$connect) {

  die ("Failed to connect! : ".mysqli_connect_error());

}

?>
 

 

- 데이터 수집 처리 : insert.php

<?php
include "./db_connect.php";
$DATA_DATE = $_GET['date'];
$DATA_HOST = $_GET['host'];
$DATA_IP = $_GET['ip'];
$DATA_SIZE = $_GET['size'];
$DATA_USED = $_GET['used'];
$DATA_FREE = $_GET['free'];
$DATA_PERC = $_GET['perc'];
$DATA_MOUNT = $_GET['mount'];


$query = "insert into fsmonitor_tb(date,hostname,ipaddress,mount,size,used,free,perc) values('$DATA_DATE','$DATA_HOST','$DATA_IP','$DATA_MOUNT','$DATA_SIZE','$DATA_USED','$DATA_FREE','$DATA_PERC');";

$result = mysqli_query($connect,$query) or die("database query error");


mysqli_close($connect);

?>

 

- 데이터 조회 : list.php (첨부 list.zip 압축해제)

<?php
include "./db_connect.php";

echo "
<head>
        <style>
        .bordernone{
                border-collapse : collapse;
                border : 0px solid;
                margin-left : auto;
                margin-right : auto;
        }
        #borderset{
                border-collapse : collapse;
                border : 1px solid;
                margin-left : auto;
                margin-right : auto;
        }
        #borderset td{
                padding : 4px;
                border : 1px solid;
                text-align : center;
        }
        </style>
</head>

<body>

<form method='get'>
        <table style='margin-left : auto; margin-right : auto; class='bordernone'>
        <tr>
        <td>From date <input type='text' name='input_from_date' /></td>
        <td>  To date <input type='text' name='input_to_date' /></td>
        <td>IPaddress <input type='text' name='input_ip' /></td>
        <td>Mount Point <input type='text' name='input_mount' /></td>
        </tr>
        </table>
        <br>
        <center><input type='hidden' name='sc' value='ok' />

        <table style='margin-left : auto; margin-right : auto;' class='bordernone'>
        <tr>
        <td><center><button type='button'><a href='http://<SERVER_IPADDRESS>/fsmonitor/list.php'>Refresh</a></button></center></td>
        <td><center><input type='submit' /></center></td>
        </tr>
        </table>
        <br>
        <br>


</form>

";

$query1 = "select * from fsmonitor_tb";
$query2 = "";

if($_GET['input_from_date'] != NULL || $_GET['input_to_date'] != NULL || $_GET['input_ip'] != NULL || $_GET['input_mount'] != NULL)
{
$query2 = " where ";
}

if($_GET['input_from_date'] != NULL){
 $query2 .= "date between '".$_GET['input_from_date']. "' and '".$_GET['input_to_date']."'";
}

if($_GET['input_ip'] != NULL){
        if($_GET['input_from_date'] != NULL && $_GET['input_to_date'] != NULL) {
                 $query2 .= " and ";
        }
 $query2 .= "ipaddress='".$_GET['input_ip']."'";
}

if($_GET['input_mount'] != NULL){
        if(($_GET['input_from_date'] != NULL && $_GET['input_to_date'] != NULL) || $_GET['input_ip'] != NULL) {
                 $query2 .= " and ";
        }
 $query2 .= "mount='".$_GET['input_mount']."'";
}

$query3 = " order by date,ipaddress,mount";
$query = $query1.$query2.$query3.";";


$result = mysqli_query($connect,$query) or die("db die");


if($_GET['sc'] == 'ok' ){


echo "
<div style='text-align:center'>
<table id='borderset' border='1' style='margin-left : auto; margin-right : auto;' >
<tr>
  <td>NO</td>
  <td>DATE</td>
  <td>HOSTNAME</td>
  <td>IP</td>
  <td>MOUNT POINT</td>
  <td>SIZE</td>
  <td>USED</td>
  <td>FREE</td>
  <td>PERCENT</td>
</tr>
";

while ($row = mysqli_fetch_array($result)) {

echo "<tr>
<td>".$row['sno']."</td>
<td>".$row['date']."</td>
<td>".$row['hostname']."</td>
<td>".$row['ipaddress']."</td>
<td>".$row['mount']."</td>
<td>".$row['size']."</td>
<td>".$row['used']."</td>
<td>".$row['free']."</td>
<td>".$row['perc']."</td>
</tr>";

}

echo "
</table>
</div>
";

# end of if
}

echo "
</body>
";


mysqli_close($connect);

?>

 

- 데이터 조회

웹브라우저에서 http://<SERVER_IPADDRESS>/fsmonitor/list.php  로 검색.

 

 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 게시자료 열람자유. 불펌금지입니다. 조인상 2010.12.07 30767
104 리눅스에서 HBA카드의 WWN확인 방법 조인상 2010.05.12 54472
103 ssh 자동로그아웃 설정방법 조인상 2010.05.12 41531
102 LVM 사용하여 추가한 디스크로 볼륨 늘리기 ischo 2010.05.19 35806
101 리눅스 커널이 64bit 인지 확인방법 ischo 2012.02.24 34988
100 리눅스 가상 IP 설정 조인상 2010.05.12 30761
99 랜카드 동작속도 확인/수정 방법 조인상 2010.05.12 29490
98 리눅스에서 hostid 란? ischo 2013.06.25 29152
97 Linux용 nmon 설치 및 구성 file ischo 2013.01.17 29150
96 TCP TIME_WAIT이 많이 발생하여 문제가 되는 경우 ischo 2011.08.18 28344
95 RHEL 6.x 에서 multipath 설정 ischo 2015.07.31 27197
94 리눅스 mdadm 을 이용한 S/W RAID 구성 [1] ischo 2011.07.20 25449
93 static routing 정보 저장하여 재부팅시에도 자동 적용 ischo 2013.07.23 25369
92 삼바 세팅 및 사용법 [1] 조인상 2010.05.12 25132
91 백스페이스 눌러서 지우려고 할때 ^H 표시될때 조치법 조인상 2010.05.12 24525
90 아파치 SSL 적용된 경우 startup 시에 SSL 패스워드 자동입력시키기 ischo 2011.06.02 24256
89 file descriptor 설정하기 ischo 2013.07.10 24071
88 리눅스 Services 설명 ischo 2011.07.08 23645
87 ssh 접속시 로그인 속도가 느릴경우 속도 향상법 ischo 2011.08.30 23007
86 리눅스에서 디스크 덤프하기 ischo 2011.12.22 21895
85 리눅스에 Qlogic2300 HBA카드로 어레이 붙이기 file 조인상 2010.05.12 20212
서버에 요청 중입니다. 잠시만 기다려 주십시오...