원문 : 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 32449
104 Rocky 9+nginx1.20+php8+MariaDB 10.5 환경에서 wordpress 설치하기 ischo 2024.01.10 1803
103 파일시스템 양방향 동기화하기 - rsync, lsyncd file ischo 2024.01.03 2804
102 LVM 타입 swap 영역 용량 축소하기 ischo 2023.11.28 1554
101 named 에서 DNS root 서버 리스트 갱신하기 ischo 2023.06.13 1484
100 vi 에디터에서 복사,붙여넣기 하면 # 마크가 자동으로 앞에 붙을때 ischo 2023.04.19 1754
99 구버전 Linux에서 Rocky Linux 9.1 버전으로 ssh 접속시 "no hostkey alg" 표시후 접속불가 ischo 2023.04.19 2960
» 파일시스템 사용량 추이를 http 전송으로 DB에 누적하기 file ischo 2022.08.29 1635
97 [Shell] 시작한지 1시간 이상 경과한 프로세스 kill 하기 ischo 2022.06.16 749
96 apache log4j 취약점 제거조치 CVE-2021-44228 CVE-2021-45046 CVE-2021-41045 CVE-2021-4104 ischo 2021.12.23 1700
95 Multi Putty Manager file ischo 2020.10.08 1406
94 CentOS 7에 Apache2, php7.3, MariaDB 설치하기 ischo 2019.09.02 2339
93 리눅스에서 Windows Filesystem(NTFS) 마운트하기 ischo 2018.12.20 4725
92 SFTP로 자동 업로드/다운로드 스크립트 ischo 2018.04.04 8876
91 CIDR Conversion Table ischo 2018.03.08 3448
90 (스크립트) 오라클 DB서버에서 매일 원격지 FTP로 export 파일 업로드 하기 ischo 2017.11.04 4806
89 shell script를 cron으로 동작시킬때 .bashrc .bash_profile의 변수가 적용되지 않는다 ischo 2017.09.08 15636
88 재부팅 없이 SCSI device를 rescan하기 ischo 2017.03.16 17129
87 apache 404 에러에 OS 또는 apache버전을 표시하는 취약점 없애기 ischo 2016.10.25 8169
86 RHEL/CentOS 7 환경에서 자동업데이트 disable 시키기 ischo 2016.07.02 10582
85 NTP 서버 설정 ischo 2016.03.03 11195
서버에 요청 중입니다. 잠시만 기다려 주십시오...