블로그 이미지
물결(Wave)
하고 싶은 것만 하며 살고 싶다

calendar

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
2008.08.30 00:32 Programing/PHP
PHP보다는 HTML,CSS,Javascript와 씨름하며 지내는 요즘 반갑게도 PHP를 써야하는 작은 프로젝트를 하나 맡았습니다. 근 1년여 동안 멀리했던 PHP인지라 함수들도 가물가물하고 요즈음은 트렌드도 많이 바뀌어서 제법 낯설기도 하지만 그래도 반갑기만 하네요~ :)

마침 메인 PC도 맥으로 갈아탄터라 이것저것 셋팅하는 맛도 있겠거니와 정말정말 오래간만에 php컴파일도 좀 해보고 아파치도 만져볼 생각에 한창 들떴더랍니다. ^^

최근 구매한 iMac 24인치에는 개발에 필요한 기본적인 도구들이 상당히 많이 들어있습니다. 그 중에 아파치와 PHP도 포함되어 있으니 정말 편한 시스템이죠~(물론 자바도 기본으로 설치되어 있답니다~~)


1.준비

우선 Enabling PHP and Apache in Leopard를 참고하시어 php,apache 기본 설정을 확인 하시고 php를 활성화 하는 작업이 선행되어야 합니다. 이 상태로도 기본적인 php개발 환경은 마련이 됩니다. 하지만 프로젝트가 바뀔때마다 매 번 아파치의 DocumentRoot를 변경하고, ftp를 이용해 실서버로 배포하는 작업은 그리 유쾌한 작업은 아니죠. 게다가 이클립스라는 아주 훌륭한 IDE를 쓰면서 말이죠....

(주의: 저는 지금 이클립스를 이용해서 개발 하시는 분들을 위한 포스팅을 하고 있답니다~!!)


2.가상호스트 설정

프로젝트 별 가상호스트를 만들어 줍니다.
편집기로 아피치 가상호스트 설정 파일을 엽니다.

$ sudo vi /private/etc/apache2/extra/httpd-vhosts.co

처음 이 파일을 열면 샘플 가상호스트가 주석으로 둘러싸여 있는데요 그 부분을 복사해서 아래에 붙여 넣습니다.

DocumentRoot를 설정하고 도메인도 설정합니다.
이 가상호스트만의 독립적인 로그가 필요하면 로그 파일에 대한 내용도 작성합니다.
자세한 가이드는 여기를 참고하세요.

<VirtualHost *:80>
    DocumentRoot "/Users/asrada/Documents/workspace/MyProject/trunk/testcase"
    ServerName test.project1.com
    ErrorLog "/private/var/log/apache2/test.project1-error_log"
</VirtualHost>

가상호스트에 도메인을 만들어 주긴 했지만 실제 저 도메인은 등록이 안된 것이죠.
때문에 hosts 파일에 저 도메인에 대한 리다이렉션을 명시해야 합니다.

$ sudo vi /etc/hosts

파일을 열고 맨 아랫줄에 리다이렉션 시킬 ip 와 도메인을 입력하면 됩니다.
가상호스트가 로컬에 있으니 로컬 PC로 리다이렉션 시키면 되겠죠~

127.0.0.1 test.project1.com

이제 브라우저에서 test.project1.com을 입력하면 가상호스트로 설정된 DocumentRoot에 있는 index.html파일이 열리게 됩니다.
프로젝트가 추가되면 가상호스트를 늘려주면 됩니다~~



3. Ant를 이용한 배포

이제 로컬PC에서 프로젝트 소스 파일을 편집하고 테스트도 해 볼 수 있게 되었습니다.
실서버로 배포만 하면 프로젝트를 마무리 할 수 있겠네요~~~:)
자 그럼 FTP클라이언트를 실행하고....이럼 안되겠죠?? ^^
이클립스를 쓰고 있으니 최대한 이클립스안에서 모든걸 해결하도록 해보죠.
이클립스 플러그인중에 Ant라는 아주 유용한 플러그인이 있습니다.
이클립스에서 작업한 소스코드를 FTP프로토콜을 이용해서 별도의 FTP클라이언트 프로그램을 실행할 필요 없이 원하는 곳으로 전송 할 수 있고, 프로젝트 전체를 압축해서 보내고 전송이 완료되면 실서버에 telnet으로 접속해서 전송한 압축파일을 원하는 디렉토리에 풀어주는 일도 가능합니다.
자세한 내용은 여기를 보세요~~

Ant의 기능은 상당히 많지만 이 포스트에서는 Ant의 기본 구조와 간단한 사용방법을 소개하는 정도에서 그치도록 하겠습니다. ^^

1)설정파일 만들기

Ant설정 파일은 xml형태의 파일로 하나의 project 엘리먼트 안에 여러개의 target 엘리먼트로 이루어지는데요, 이 target은 어떤 하나의 행동(task)을 나타냅니다.

<project name="UIRSS_Extension" basedir=".">
 <property file="${basedir}/info.properties" />

 <target name="create.xpi">
  <zip destfile="${extension.root}/${extension.destfile}" basedir="${src.root}" />
 </target>
 
 <target name="compress">
  <tar destfile="${basedir}/${deploy.destfile}" basedir="${extension.root}" compression="gzip" />
 </target>

위의 예제는 실제로 제가 쓰고 있는 Ant설정 파일의 일부입니다.

내용을 보면 UIRSS_Extension이라는 프로젝트 이름을 갖고 있는 Ant설정 파일이라는 것을 알 수 있구요,

2개의 target은 각각 zip으로 특정 파일들을 압축하고 tar로 특정 파일들을 묶는 작업을 수행하도록 설정 되어 있습니다.

보시다시피 target안에 있는 zip이나 tar 요소들은 우리가 잘 알고 있는 그 zip과 tar에 대응하는 요소입니다.

각 target은 독립적으로 실행되며 여러 target을 순차적으로 실행하는 것도 가능합니다.

<target name="deploy" depends="local.compress, sendToServer,server.decompress"/>

위 target을 실행하면 먼저 local.compress라는 target을 실행한 후 sendToServer target을 실행하고 마지막으로 server.decompress target을 실행하게 됩니다. 배치파일과 비슷하죠?? ^^

이렇게 기능적으로 완전히 독립된 여러 target들을 만들어 두고 작업 득성에 맞게 각 target들을 조립해서 하나의 target을 만들어서 사용하면 배포에 들어가는 시간과 노력을 아낄 수 있습니다.:)

2)외부 속성 파일 사용하기

Ant 설정 파일에서는 변수를 지원하는데요, 맨 위 Ant 설정 파일을 자세히 보시면 ${}로 감싸여져있는 변수 형태의 값들이 여기저기 있는데요, 실제로 이것들은 변수의 역할을 합니다. 맨 윗줄 project요소에 있는 basedir속성을 그 아래 property요소에서 ${basedir}로 재사용하고 있죠?

이렇게 project안에서 속성 값을 공유 할 수 있습니다. 또한 여러 속성들을 외부 파일에 작성 해 두고 그 값들을 불러와서 쓸 수 있는데요, 2번째 줄에 있는 property 요소에 이 변수들에 대한 값을 설정하고 있는 외부 설정 파일의 위치를 담고 있는 것을 볼 수 있습니다.

그 외부 설정 파일은 아래와 같은 모양을 하고 있습니다.

src.root = ${basedir}/srcExtension
extension.destfile=uirss.xpi
extension.root = ${basedir}/extension
deploy.destfile=extension.tar.gz
ftp.server=  xxx.xxx.xxx.xxx(실제 ftp의 ip를 입력합니다)
ftp.userid=userid
ftp.port=port
ftp.password=password
telnet.server=${ftp.server}
telnet.userid=${ftp.userid}
telnet.password=${ftp.password}

이 파일에 설정된 변수의 이름을 Ant설정 파일안에서 ${}로 감싸서 재사용 할 수 있는 것이죠.

이런식으로 자신의 프로젝트 배포에 필요한 task들을 묶어서 하나의 xml 파일로 만든 다음 이 xml파일을 이클립스의 Ant  View에 끌어다 놓으면 자동으로 인식을 하게 됩니다.




2번째 그림에서 보이는 개미아이콘이 붙은 항목은 각각의 xml파일이고 project 요소의 name속성 값을 보여줍니다. 이 부분을 더블 크릭하면 디폴트 target의 내용이 실행됩니다. 그 하위 동그라미 아이콘들은 xml파일 안에 있는 각각의 target요소들을 뜻하며 text는 target의 name속성 값입니다.  각 target항목을 더블클릭하면 해당 target의 작업이 실행됩니다.

3.마치며

이렇게 몇 가지 간단한 내용들고 OSX에서 PHP로컬 개발 환경을 구축하는 방법에 대해 소개해 드렸습니다. 하지만 1번을 제외한 2,3번의 내용들은 OSX에만 국한되는 것은 아니니 Apache를 사용하시는, 이클립스를 사용하시는 윈도우 사용자 분들도 그대로 적용하실 수 있습니다.

너무 많은 내용을 하나의 포스트에 짤막하게 담으려다 보니 세밀함이 많이 부족한 포스트가 되고 만것 같습니다.^^;; 게다가 글재주 또한 잼병이라 아는것마저 정확히 전달을 하지 못한 것 같습니다......;;

더 자세한 내용들은 각 사이트에 세세한 문서들이 많으니 참조하시길 바랍니다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Programing > PHP' 카테고리의 다른 글

[OSX] Eclipse에서 PHP 로컬 개발/테스트 환경 구축하기  (4) 2008.08.30
Enabling PHP and Apache in Leopard  (2) 2008.08.19
WAV파일 분석  (0) 2006.11.10
간단한 소켓통신  (0) 2006.10.13
간단한 대화식 프로그램  (0) 2006.07.24
시스템 모니터링 툴  (0) 2006.07.17
posted by 물결(Wave)
2008.08.19 12:01 Programing/PHP
Mac OS X 10.5 레오파드에는 기본적으로 PHP가 설치 되어있습니다.
하지만 아파치에서 PHP모듈을 활성화 하지 않았기 때문에 PHP를 웹서비스에 이용하기 위해서는 아파치 설정파일에서 PHP모듈을 활성화 해주어야 합니다.
우선 아파치 설정 파일을 찾아야 하는데요.

터미널을 열고 httpd -V 라고 입력하면 아래와 같은 메세지들이 출력됩니다.

사용자 삽입 이미지

하단에 아파치 설정 파일인 httpd.conf 파일의 위치가 나와있죠~

이제 이 파일을 열어 PHP모듈을 활성화 시켜주어야 합니다.

설정파일이 있는 곳으로 디렉토리를 이동한 후 다음과 같이 타이핑합니다.

sudo vi httpd.conf

비밀번호를 입력하고 슬래시(/)를 눌러 "php" 를 찾습니다.

줄 맨 앞에 "#"으로 주석 처리가 되어 있습니다.

사용자 삽입 이미지


주석을 제거하고 저장을 하고 vi를 종료합니다.

이제 PHP의 설정파일을 편집할 차례입니다.
기본 설정대로 쓰고 싶다면 이 과정은 생략해도 됩니다만, 여러가지 이유로 인해서 이 과정 역시 수행하실 것을 권합니다.

콘솔에서 다음과 같이 타이핑 합니다.

php -i | grep ini

그럼 아래와 같은 메세지가 출력됩니다.

사용자 삽입 이미지


맨 윗 줄을 보면 php.ini 파일의 위치가 /etc 라고 나옵니다.

ls -l /etc/php.ini

불행히도 파일을 찾을 수 없다는 메세지가 출력됩니다.

초기 상태에 php.ini 파일은 만들어져 있지 않습니다.

사용자가 php.ini.default 파일을 복사해서 php.ini 파일을 생성해야 하는데요.

php.ini.default 파일은 /private/etc/ 에 있습니다.

콘솔에서 다음과 같이 입력하여 php.ini 파일을 생성해줍니다.

cd /private/etc sudo cp php.ini.default php.ini

이제 vi를 사용하여 php.ini파일을 입맛대로 수정하고 저장하면 모든 설정이 끝납니다.

다시 콘솔에서 php -i | grep ini 를 입력해 보면 아래와 같이 ini 파일이 로드되었음을 알리는 메세지가 출력됩니다.

사용자 삽입 이미지





참고: http://foundationphp.com/tutorials/php_leopard.php
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Programing > PHP' 카테고리의 다른 글

[OSX] Eclipse에서 PHP 로컬 개발/테스트 환경 구축하기  (4) 2008.08.30
Enabling PHP and Apache in Leopard  (2) 2008.08.19
WAV파일 분석  (0) 2006.11.10
간단한 소켓통신  (0) 2006.10.13
간단한 대화식 프로그램  (0) 2006.07.24
시스템 모니터링 툴  (0) 2006.07.17
posted by 물결(Wave)
2006.11.10 10:07 Programing/PHP
http://asrada2001.mireene.com/asrada/AudioFile/test.php

php로 별걸 다 한다...
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Programing > PHP' 카테고리의 다른 글

[OSX] Eclipse에서 PHP 로컬 개발/테스트 환경 구축하기  (4) 2008.08.30
Enabling PHP and Apache in Leopard  (2) 2008.08.19
WAV파일 분석  (0) 2006.11.10
간단한 소켓통신  (0) 2006.10.13
간단한 대화식 프로그램  (0) 2006.07.24
시스템 모니터링 툴  (0) 2006.07.17
posted by 물결(Wave)
2006.10.13 11:19 Programing/PHP

server.php

set_time_limit(0);

define("_IP",    {IP});
define("_PORT",  {PORT});
define("_TIMEOUT", 10);

$cSock = array();
$cInfo = array();

$sSock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_bind($sSock, _IP, _PORT);
socket_listen($sSock);

while(1)
{
  $sockArr = array_merge(array($sSock), $cSock);

  if(socket_select($sockArr, $tWrite = NULL, $tExcept = NULL, _TIMEOUT) > 0)
  {
       foreach($sockArr as $key => $sock)
       {
           // Listen 하고 있는 서버 소켓일 경우
           // 새로운 클라이언트의 접속을 의미
           echo $sock.'/'.$sSock."\n";

           if($sock == $sSock)
           {
               $tSock = socket_accept($sSock);

               socket_getpeername($tSock, $sockIp, $sockPort);

               $cSock[$tSock] = $tSock;
               $cInfo[$tSock] = array('ip'=>$sockIp, 'port'=>$sockPort);

               msg("client connect : ".$sockIp.":".$sockPort."\n");
           }
           // 클라이언트 접속해 있는 소켓중 하나일경우
           // 해당 클라이언트에서 이벤트가 발생함을 의미
           else
           {
               $buf = socket_read($sock, 4096);

               // 접속 종료
               if(!$buf)
               {
                   exceptSocket($cSock, $cInfo, $sock);
                   msg("client connection broken : ".$sockIp.":".$sockPort."\n");
               }
               // 메시지 수신 이벤트
               else
               {
                   msg("recive data : ".$buf."\n");

                   $thisSockInfo = $cInfo[$sock];
                   //$cmd = substr($buf, 0, 4);
                   $cmd = $buf;

                   switch($cmd)
                   {
                       // 시간전송
                       case "time":
                           msg("client(".$thisSockInfo['port'].") time data request\n");
                           socket_write($sock, date("Y/m/d H:i:s"));
                           break;

                       // 종료
                       case "quit":
                           msg("client(".$thisSockInfo['port'].") quit request\n");
                           socket_write($sock, "quit");
                           socket_close($sock);
                           exceptSocket($cSock, $cInfo, $sock);
                           break;
                       default:
                           if(substr($cmd,0,1) == ':'){
                               msg("client(".$thisSockInfo['port'].") sendmsg : ".substr($cmd,1)."\n");
                               broadCasting($sockArr,$sock,substr($cmd,1));
                           }else{
                               msg("client(".$thisSockInfo['port'].") invalid command $cmd\n");
                           }
                           break;
                   }
               }
           }
       }
  }

  $i++;

}

function exceptSocket(&$sockSet, &$infoSet, $sock)
{
  unset($sockSet[$sock]);
  unset($infoSet[$sock]);
  // array_merge 함수에서 error 발생을 막기위한 처리
  if(count($sockSet)==0)
  {
       $sockSet = array();
       $infoSet = array();
  }
}

function msg($msg)
{
  echo "SERVER >> ".$msg;
}

function broadCasting($socks,$cSock,$msg){
  global $sSock;

  foreach($socks as $key => $sock){
       if($sock != $sSock && $sock != $cSock){
           socket_write($sock,$msg);
       }
  }
}

client.php

define("_IP",    {IP});
define("_PORT",  {PORT});

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

socket_connect($sock, _IP, _PORT);

msg("socket connect to "._IP.":"._PORT."\n");

while(1)
{
  msg("Enter command time or quit : ");

  // 사용자의 명령어를 입력받습니다.
  $stdin = ereg_replace("\n|\r", "", read_data());
  //$stdin = substr($stdin, 0, 4);

  // time 또는 quit 메시지 말고는 무시 합니다.
  if($stdin == "time" || $stdin == "quit")
  {
       msg("Input command : ".$stdin."\n");
  }else{
       if(substr($stdin,0,1) == ':'){
           msg("sendmsg : ".$stdin."\n");
       }else{
           msg("invalid command (not send). If you want said ':' and your message.: ".$stdin."\n");
           continue;
       }
  }

  socket_write($sock, $stdin);
  $sMsg  = socket_read($sock, 4096);

  if(substr($sMsg, 0, 4) == 'quit')
  {
       socket_close($sock);
       exit;
  }else
  {
       msg("recived data : ".$sMsg."\n");
  }
}

// 표준입력을 받아 값을 리턴하는 함수
function read_data()
{
  $in = fopen("php://stdin", "r");
  $in_string = fgets($in, 255);
  fclose($in);
  return $in_string;
}

// 로그 출력
function msg($msg)
{
  echo "CLIENT >> ".$msg;
}

단방향 채팅프로그램이다...-_-;
서버에 지정된 명령어에 의해 클라이언트의 메세지를 처리해주는 정도...
다중 클라이언트 접속이 허용되지만
클라이언트간 메세지 교환은 이루어지지 않고
클라이언트 대 서버의 통신만 가능하다.
서버에서 클라이언트의 메세지를 전체 클라이언트에게 뿌려주는
브로드캐스팅 구현이 안됐다...



TODO:
1.서버의 브로드캐스팅을 구현해야 실질적인 다중채팅이 이루어진다.
2.서버에서 임의의 메세지를 전송 하는 기능을 구현해야 한다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Programing > PHP' 카테고리의 다른 글

[OSX] Eclipse에서 PHP 로컬 개발/테스트 환경 구축하기  (4) 2008.08.30
Enabling PHP and Apache in Leopard  (2) 2008.08.19
WAV파일 분석  (0) 2006.11.10
간단한 소켓통신  (0) 2006.10.13
간단한 대화식 프로그램  (0) 2006.07.24
시스템 모니터링 툴  (0) 2006.07.17
posted by 물결(Wave)
TAG php, 소켓
2006.07.24 01:00 Programing/PHP

PHP를 단순 동적 웹사이트 제작에만 사용하는것은
PHP의 반만 쓰는 것이다.
PHP는 펄,본쉘 같은 쉘스크립트로서의 역할도 훌륭히 수행해 낼 수 있다.
물론 태생이 쉘스크립트인 것들에 비하면 기능이 다소 빈약하지만
웬만한 작업은 해낼수 있다.

요즈음 PHP로 어떤 것들을 할 수 있을까 하는 고민을 하면서
가장 쉽고 빠르게 할 수 있는것을 찾다가
간단한 대화식 프로그램을 짜보기로 했다.

#!/usr/local/php5/bin/php
<?php
set_time_limit(0);

$fd = STDIN;

if (!$fd)
  exit;

$question = "How old are you? ";

echo $question;

while (!feof ($fd)){
  $s = trim(fgets($fd,128));

  if ($s==false){
       continue;
  }

  if($s == 'exit'){
       break;
  }

  if(is_numeric($s) == false){
       echo "\nAre you kidding??\n\n\nTry again...\n\n".$question;
  }

  if($s > 30){
       echo "\nHum...You are not fresh...\n\n";
       break;
  }

  if($s == 28){
       echo "\nOh~~ Very Fantastic age~!!! You are good!!\n";
       break;
  }

  if($s < 30){
       echo "\nWe are the youngman!!!\n";
       break;
  }
}

echo "\n\n======= Bye~ ============!!\n";

?>



위 소스는 간단한... 대화형은 아니고 한번 묻고 한번 답하면 종료한다.
1번 라인에 php의 경로를 지정해 줌으로써 cli 모드로 실행이 되도록 하였으니
chmod로 실행권한을 주면 쉘에서 실행이 가능하다.

위 소스를 응용하면 간단한 머드게임도 가능할것 같다.

GTK와 결합하면 머그게임으로???

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Programing > PHP' 카테고리의 다른 글

[OSX] Eclipse에서 PHP 로컬 개발/테스트 환경 구축하기  (4) 2008.08.30
Enabling PHP and Apache in Leopard  (2) 2008.08.19
WAV파일 분석  (0) 2006.11.10
간단한 소켓통신  (0) 2006.10.13
간단한 대화식 프로그램  (0) 2006.07.24
시스템 모니터링 툴  (0) 2006.07.17
posted by 물결(Wave)
TAG cli, php
2006.07.17 00:58 Programing/PHP
출저 : 네이버 검색(작성자가 불분명하여 정확한 출처를 기재하지 못함을 양해바랍니다)



시스템 모니터링이라고 하면 뭔가 복잡하고 어려운 것부터 생각되고 실제로 귀찮은 작업이기도 합니다. 이유있는 문제도 있지만 그렇지 않은 경우도 많습니다. 시스템 에러의 원인을 알 수 없을 때는 참 답답합니다. 그렇다면 그 해결책을 무엇일까요? 스스로 간단한 시스템 모니터링 툴을 만들어 보는 것입니다. SNMP에 대한 기본 지식이 있다면 PHP를 이용해 간단하게 만들 수 있습니다. 리눅스에서 PHP와 SNMP를 이용한 간단한 시스템 모니터링에 대해 알아보겠습니다.

프로그래밍하다 보면 이유 없이 시스템이 다운되는 경우가 있습니다. 물론 이유가 없다는 말은 이유를 알 수 없는 경우입니다. 그렇다고 24시간 서버만 붙잡고 있을 수도 없을 것입니다. 그래서 나온 것이 시스템 모니터링 툴일 것입니다. 시스템 모니터링의 영역은 넓고 방대하지만 여기서 만들어보고자 하는 것은 SNMP를 가지고 직접 시스템의 필요한 부분을 모니터링해 보는 것입니다. 직접 만들어보면 필요한 부분을 원하는 방식으로 모니터링할 수 있습니다. 물론 직접 만드는 것이 복잡하다는 생각이 들 수도 있습니다. 그런 것을 어떻게 만들까 하는 생각이 들 수도 있습니다. 그러나 의외로 쉬운 방법이 있는데, 바로 SNMP의 값을 활용하는 것입니다. SNMP를 이용하면 매우 간단하게 시스템 모니터링에 필요한 값을 가져올 수 있습니다.

그렇다면 어떤 값을 가져올 수 있는지 먼저 알아야 합니다. SNMP로 쉽게 값을 가져올 수 있지만 그렇다고 해서 SNMP가 그리 만만한 것은 아닙니다. 왜냐하면 SNMP로 가져올 수 있는 시스템 모니터링 값 또한 매우 방대하기 때문입니다. 그러나 간단한 모니터링 프로그램을 만들어 보기 위해서 SNMP의 모든 부분을 알 필요는 없을 것입니다. 지금 필요한 부분만 익혀서 사용하면 되고 나중에 필요한 부분이 있으면 차근차근 알아가면 됩니다.

그렇다면 시스템 모니터링에 있어서 가장 필요한 값에는 어떤 것들이 있을까요? 그것은 바로 cpu와 메모리일 것입니다. 그리고 현재 시스템에 어떤 프로세스들이 있는지도 알아야할 것입니다. 이 정도 값만 알 수 있어도 간단하게 원격으로 서버를 모니터링할 수 있습니다. 그렇다면 이런 값들을 가져오기 위해서는 기본적인 프로그램이 설치되어 있어야 합니다. 여기서는 프로그램의 설치되어 있다는 가정 아래 실제로 SNMP 값을 가져오는 부분과 SNMP의 간단한 명령어를 익히게 됩니다. 그리고 PHP에서 SNMP 값을 가져오는 방법과 PHP에서 가져오는 값을 활용해서 모니터링 프로그램을 어떻게 만들어야 하는지도 알아보겠습니다.

SNMP 모니터링을 하기 위해서 필요한 것들
실제로 모니터링 프로그램을 만들기 위해서 필요한 것에는 어떤 것이 있는지 알아보겠습니다. 먼저 모니터링할 서버에 SNMP가 설치되어 있어야 합니다. 윈도우 서버와 리눅스 서버의 SNMP 값은 각각 다릅니다. 여기서 사용하는 것은 리눅스입니다. 리눅스에 일단 net-snmp(http://net-snmp.sourceforge.net/)가 설치되어 있어야 합니다. 설치되어 있지 않다면 이 사이트에서 받아서 설치할 수 있습니다. 그리고 PHP에서 SNMP 함수를 사용할 수 있어야 합니다. 일반적인 웹사이트 서비스를 위해서 PHP가 설치되어 있다면 SNMP 관련 함수를 사용할 수 있도록 설치해 주면 됩니다.

이 두 가지만 갖추어져 있다면 이제 필요한 것은 SNMP 값을 가져오는 것입니다. 그리고 어떤 값을 가져올 지를 미리 정하는 것입니다. 그리고 가장 중요한 것은 SNMP에 대한 기본 지식이 있어야 합니다. 무조건 SNMP 값을 가져다 쓰는 것보다는 SNMP에 대한 기본 지식을 알고 있으면 더 좋을 것입니다. 여기서는 한 대의 서버를 모니터링하는 것이 아니라 여러 대의 서버를 모니터링할 수 있기 때문에 모니터링하는 서버 또한 SNMP가 설치되어 있어야 합니다. SNMP 또한 환경 설정을 따로 할 수 있기 때문에 값을 가져오는 방식이 조금 다를 수 있겠지만 여기서는 기본적인 SNMP 방식으로 설명하겠습니다.

SNMP 기본 명령어 익히기
서버에서 SNMP 값을 가져오는 방법은 SNMP를 설치할 때 같이 설치되는 SNMP 관련 프로그램을 이용해서 가능합니다. 먼저 해당 서버에 SNMP가 설치되어 있는지 확인해야 합니다. 리눅스에서는 해당 서버에 SNMP 데몬이 실행되는 ps 명령으로 먼저 확인해 봅니다.


◆ 리눅스에서 SNMP 데몬이 있는지 확인하기  
- ps -aux | grep snmpd

그리고 SNMP 값을 가져오는 데 주로 사용하는 명령어는 snmpwalk입니다. 물론 이 명령어 이외에도 몇 가지가 더 있습니다. 그러나 snmpwalk 명령어로 웬만한 값을 거의 다 가져올 수 있습니다. snmpwalk는 한 가지 값만 가져올 수도 있고 관련된 값을 모두 가져올 수도 있습니다.


◆ SNMP system 관련 값 가져오기
- snmpwalk localhost public system
- snmpwalk ****.com  public system

이 명령은 localhost의 system 관련 값을 가져오는 것입니다. 그리고 해당 서버를 지정하면 그 서버의 값도 가져올 수 있습니다. 물론 다른 서버의 값을 가져오고자 할 경우 그 서버에 SNMP가 설치되어 있어야 합니다. 그렇다면 SNMP가 설치되어 있는 서버는 무조건 모니터링할 수 있을까요? 일단 그 서버에 접근 권한이 있어야 합니다. 그리고 SNMP 환경 설정에서 지정한 값만을 모니터링할 수 있습니다. 보안상 SNMP 값을 모두 모니터링하도록 허용한 것이 아니라 일부 값만 모니터링할 수 있도록 허용했을 수도 있습니다.


◆ SNMP system 관련 값의 일부
- system.sysDescr.0 = Linux localhost ...
- system.sysObjectID.0 = OID:
- enterprises.ucdavis.ucdSnmpAgent.linux
- system.sysUpTime.0 = Timeticks: (3526547) 15:33:12.22
- system.sysContact.0 = admin@****.com
- system.sysName.0 = ****.com
- system.sysLocation.0 = Unknown
= system.sysORLastChange.0 = Timeticks: (9) 0:00:00.09

system 관련 값의 일부입니다. 시스템에 관련된 값을 구할 수 있습니다. 그렇다면 이렇게 전부가 아닌 하나의 값만 구하려면 어떻게 할까요?


◆ 하나의 값만 구하기
- snmpwalk ****.com  public system.sysDescr.0
- snmpwalk ****.com  public sysDescr.0

하나의 값만 구하고자 할 경우에는 이렇게 해당 값을 지정해 주면 됩니다. 그리고 SNMP는 값을 구하는 것만이 아니라 해당 값을 설정할 수도 있습니다. 값을 구하는 것은 단순히 해당 서버의 값을 구하는 것이기 때문에 별다른 영향을 미치지 않습니다. 그러나 값을 설정하는 것은 해당 서버에 영향을 미칠 수도 있습니다. 여기서는 간단한 모니터링을 위한 SNMP 값을 이용하기 때문에 SNMP 값을 설정하는 부분은 다루지 않습니다.

CPU, 메모리 값 가져오기
모니터링하기 위해서 주로 사용되는 값인 cpu, 메모리 그리고 Load Averages 값을 가져오는 부분을 알아보겠습니다. cpu 값을 가져오기 위해서는 해당 MIB를 입력해 주면 됩니다. 여기서 사용되는 MIB 값은 공통적으로 사용되는 것입니다. MIB는 OID라는 숫자로도 표기될 수 있으며 정확하게 ssCpuUser의 계층구조까지 다 적는다면 nterprises.ucdavis.systemStats.ssCpuUser 표현될 수도 있습니다. OID 값으로 표현하면 1.3.6.1.4.1.2021.11.9.0이 됩니다. 모두 같은 의미입니다.


◆ cpu 관련 값 가져오기
- snmpwalk ****.com  public ssCpuUser
- snmpwalk ****.com  public ssCpuSystem
- snmpwalk ****.com  public ssCpuIdle

이렇게 하면 각각 cpu 사용 퍼센트를 가져올 수 있습니다. 이 값은 리눅스에서 top 명령어를 실행했을 때 cpu user, system, idle 값과 같은 값을 가져오게 됩니다. 해당 서버에 접속하지 않고도 SNMP를 이용하면 한 줄읱 명령으로 cpu 값을 가져올 수가 있습니다. 그렇다면 메모리 관련 값들에는 어떤 것이 있을까요?


◆ 메모리 관련 값 가져오기
- snmpwalk ****.com  public memTotalReal
- snmpwalk ****.com  public memTotalFree
- snmpwalk ****.com  public memShared
- snmpwalk ****.com  public memBuffer
- snmpwalk ****.com  public memCached

이렇게 하면 메모리 관련 SNMP 값을 가져올 수 있습니다. 이 값 또한 top 명령을 실행했을 때 출력되는 메모리 관련 값들과 같습니다.


◆ Load Averages 값 가져오기
- snmpwalk ****.com  public  laLoad.1
- snmpwalk ****.com  public  laLoad.2
- snmpwalk ****.com  public  laLoad.3

각각 1, 5, 10분의 Load Averages 값을 가져옵니다. 이렇듯 SNMP를 이용하면 쉽고도 간단하게 다른 서버의 모니터링에 필요한 값을 가져올 수 있습니다. 이렇게 SNMP 값을 모니터링 값에 사용하려면 MIB 또는 OID를 알고 있어야 합니다. 그렇다면 MIB는 어떻게 알 수 있을까요? 여러 사이트와 문서가 있겠지만 net-snmp 사이트에서 제공하는 문서를 볼 수 있습니다. cpu, 메모리, Load Averages MIB가 포함되어 있는 문서는 http://net-snmp.sourceforge.net/mibs/UCD-SNMP-MIB.txt에서 볼 수 있습니다. 이 문서에 있는 MIB 값을 참고한다면 좀 더 다양한 값을 모니터링할 수 있을 것입니다.

MIB, OID는 같다
ssCpuUser, memTotalFree, laLoad.1 등 이런 값들을 MIB라고 부릅니다. MIB는 간단하게 설명하면 SNMP의 값들을 분류해 놓은 것입니다. 그리고 MIB에 해당하는 OID 값이 있습니다. ssCpuUser는 축약한 것으로 enterprises.ucdavis.systemStats.ssCpuUser라고 써주면 됩니다. 그리고 이것의 OID 값은 1.3.6.1.4.1.2021.11.9가 됩니다.


◆ MIB와 OID 예
- MIB : enterprises.ucdavis.systemStats.ssCpuUser
(OID : 1.3.6.1.4.1.2021.11.9)
- MIB : enterprises.ucdavis.memory.memTotalFree
(OID : 1.3.6.1.4.1.2021.4.11)
- MIB : enterprises.ucdavis.laTable.laEntry.laLoad
(OID : 1.3.6.1.4.1.2021.10.1.3)

◆ MIB, OID로 값 얻기
- snmpwalk ****.com  public  ssCpuUser
- snmpwalk ****.com  public  enterprises.ucdavis.systemStats.ssCpuUser
- snmpwalk ****.com  public  .1.3.6.1.4.1.2021.11.9

각각 MIB, OID로 값을 가져오는 것입니다. MIB와 OID 값은 같습니다. MIB는 계층구조로 이뤄져 있습니다. 최상위 계층을 보면 System, Interface, IP, ICMP, TCP, UDP, EGP, Transmission, SNMP 그룹들로 이뤄져 있고 하위 그룹은 트리구조를 이루고 있습니다.

SNMP는 어떻게 PHP 안에 들어갔을까?
일반적으로 PHP는 웹 사이트를 제작하는데 주로 사용되고 있습니다. 물론 다른 곳에도 사용되고 있습니다. 웹 사이트를 만드는 데만 주로 사용하다 보면 다른 곳에 사용할 생각을 잊어버리는 경우가 있습니다. ‘시스템 모니터링하는 프로그램을 만들어야 하는데 어떤 언어를 이용해서 만들 수 있을까?’는 질문에서 PHP를 떠올리기는 쉽지 않을 것입니다. 그러나 데이터베이스를 연동한 프로그램 이외에도 PHP로 할 수 있는 것은 많이 있습니다.

좀 더 자세히 살펴보면 의외로 PHP에는 많은 함수들이 존재하고 있다는 것을 알 게 될 것입니다. 꼭 필요하지 않는 함수라면 굳이 사용할 필요가 없겠지요. PHP를 오래 사용한 사람이라도 ‘이런 함수가 있었나?’고 할 정도로 다양한 함수군이 존재합니다. 그 중에서도 SNMP 관련 함수들이 있습니다.

그렇다면 어떻게 PHP에서 SNMP 함수를 사용할 수 있는 것일까요? 그것은 바로 PHP의 확장성입니다. 확장성이란 필요한 함수를 추가해서 사용할 수 있는 것입니다. SNMP 함수는 이미 누군가 개발을 해서 PHP에서 사용할 수 있도록 추가해 놓았기 때문에 우리는 함수를 호출해서 사용하기만 하면 되는 것입니다. 그렇다면 직접 SNMP 함수를 PHP에서 사용할 수 있도록 만들려면 어떻게 하면 될까요? PHP는 C언어로 만들어졌기 때문에 확장을 하려면 C언어로 확장할 수 있습니다. 물론 C, C++를 알아야 합니다. 그리고 C, C++로 PHP Extensions을 만들어서 추가할 수가 있습니다. SNMP 또한 PHP Extensions으로 만들어서 추가된 것입니다.

PHP에서 사용할 수 있는 SNMP 함수들
PHP에서는 SNMP 값을 어떻게 가져올 수 있을까요? 그것은 간단하게 SNMP 함수를 호출함으로서 가능합니다. 몇 가지의 함수들이 있는데 다음은 PHP에서 사용할 수 있는 SNMP 함수 입니다.


◆ PHP의 SNMP 함수
- snmp_get_quick_print
- snmp_get_valueretrieval
- snmp_read_mib
- snmp_set_enum_print
- snmp_set_oid_numeric_print
- snmp_set_quick_print
- snmp_set_valueretrieval
- snmpget
- snmpgetnext
- snmprealwalk
- snmpset
- snmpwalk
- snmpwalkoid

이 함수들 중에서 유용하게 사용할 수 있는 것은 snmpget, snmpwalkoid입니다. snmpget은 하나의 값을 가져 올 수 있으며 snmpwalkoid는 관련된 값들을 모두 가져올 수 있습니다. <리스트 1>을 보면 snmpget 함수의 사용 예가 있습니다. 먼저 snmp로 cpu 사용량을 가져오기 위해서는 값을 가져올 서버를 지정해야 합니다. 그리고 cpu idle 값에 해당하는 oid를 알고 있어야 합니다.


◆ cpu idle 에 해당하는 snmp oid
- .1.3.6.1.4.1.2021.11.11.0

그리고 snmp 설정에 따라서 다르겠지만 커뮤니티에 해당하는 값은 ‘public’으로 해주면 됩니다. 이 세 가지 값을 지정하면 snmpget 함수는 해당 서버의 cpu idle의 값을 가져오게 됩니다. 값을 가져오지 못했을 경우 false를 리턴하게 됩니다. 그리고 값을 정상적으로 가져왔을 경우에는 10, 20 등 이런 식으로 cpu idle 퍼센트 값이 들어 있게 됩니다.



















<리스트 1> CPU 사용량 가져오기






출력은 10%, 20% 등으로 해주면 됩니다. 그러나 여기서 구하고자 했던 값은 현재 cpu 사용량이었습니다. 그런데 왜 cpu 사용량을 구하지 않은 것일까요? 그 이유를 알기 위해서는 먼저 snmp에서 가져올 수 있는 cpu 관련 값을 알아야 합니다.


◆ snmp cpu 관련 값  
- ssCpuUser
cpu user 값을 가져옵니다.
- ssCpuSystem
cpu system 값을 가져옵니다.
- ssCpuIdle
cput idle 값을 가져옵니다.

ssCpuUser + ssCpuSystem + ssCpuIdle = 100(%)

◆ 현재 cpu 사용량
ssCpuUser + ssCpuSystem  

cpu 사용량 값을 퍼센트로 가져오게 됩니다. 세 가지 값을 합하면 100이 됩니다. 그래서 cpu idle 값을 가져온 후에 ‘100-idle’ 해주면 현재 cpu 사용량이 나오게 됩니다. 이 값은 cpu 사용의 퍼센트를 의미하므로 %를 붙여서 출력해 주면 됩니다.


echo $ssCpuUser . "%";

snmpget 함수를 이용해서 cpu 관련 값들을 가져오는 방법을 알아봤습니다.

메모리 관련 값 가져오기
snmpget 함수를 이용해서 메모리 관련 값을 가져오는 방법 또한 cpu의 값을 가져오는 것과 비슷합니다. 여기서 먼저 알아야할 것은 메모리 값을 가져오는데 필요한 SNMP OID 값입니다. <리스트 2>를 보면 메모리 관련 값을 가져오는 예가 있습니다. 먼저 값을 가져올 서버와 메모리 관련 OID 값을 지정합니다.


◆ 메모리 Free 구하기
// enterprises.ucdavis.memory.memTotalFree.0
$memTotalFree = @snmpget($host, "public", $oid, $timeout);

메모리 Free량을 구하는 것입니다. 값을 구했을 경우에는 12444, 45442 이렇게 남은 메모리 량을 리턴하게 됩니다. 이 값은 KB 단위이므로 출력하고자 할 경우에는 K를 붙여서 12444K 이런 식으로 출력해 주면 됩니다.


◆ 전체 메모리 크기 구하기
// enterprises.ucdavis.memory.memTotalReal.0
$memTotalReal = @snmpget($host, "public", $oid, $timeout);

SNMP에서 구하는 값은 실제 메모리 크기와는 차이가 있습니다. 메모리는 두 가지 값을 구했습니다. 그 이유는 무엇일까요? 그것은 남은 메모리의 크기를 퍼센트로 표현하기 위해서는 전체 메모리의 크기를 알아야 하기 때문입니다. cpu는 퍼센트 값을 리턴하기 때문에 상관이 없지만 메모리는 크기를 리턴하기 때문에 전체 메모리 크기와 Free 메모리 크기를 구해서 퍼센트를 계산해 주면 됩니다.



















<리스트 2> SNMP 함수로 메모리 관련 값 가져오기






SNMP는 시스템 리소스를 사용한다
SNMP 값을 가져오려면 일단 명령을 실행하는 서버와 값을 가져오려고 하는 서버에 모두 SNMP가 설치되어 있어야 합니다. 두 서버에 모두 설치가 되어 있으면 원하는 값을 가져올 수 있게 됩니다. 그렇다면 SNMP 값을 가져오는데 어느 정도의 시스템 리소스를 사용하게 될까요? 그것은 어떤 SNMP 값을 가져오는가에 따라서 다르게 됩니다. 그리고 시스템의 사양에 따라서도 조금씩 차이가 있습니다.

SNMP 값을 가져오는 데 해당 시스템의 리소스를 너무 많이 차지하게 된다면 서버에 영향을 미칠 수 있으므로 먼저 테스트해 보는 것이 좋습니다. SNMP 값을 가져오는 데는 주로 cpu system 리소스가 사용됩니다. 앞에서 테스트했던 cpu, Load Averages 값을 가져오는 것은 1% 미만의 cpu system을 사용하게 됩니다. 그러나 메모리의 값을 가져오는 것은 10% 정도까지 cpu system 리소스를 사용할 수도 있습니다. 물론 서버마다 차이가 있으니 테스트해 보면 됩니다.

그렇다면 1초에 한번씩 cpu 값을 가져오는 것은 큰 문제가 없어 보입니다. 해당 시스템을 모니터링하려면 1초에 한 번씩 값을 가져와서 출력해 주기 위해서입니다. 그러나 메모리의 값을 1초에 한 번씩 가져오는 것은 뭔가 문제가 있어 보입니다. 왜일까요? 1초에 한 번씩 해당 서버의 cpu system 리소스를 사용하게 되면 10% 정도의 cpu system 리소스를 사용하게 되기 때문에 뭔가 문제가 있어 보입니다. 그리고 프로그램을 하나만 실행시키는 것이 아니라 여러 사람이 모니터링 프로그램을 실행시켜서 사용하고 있다면 1초에 한 번씩 메모리 값을 가져오는 것은 문제가 있습니다. 그럴 경우에는 적당히 간격을 조정하면 됩니다. 한 5초 정도의 주기로 값을 가져오면 될 것입니다. 1초, 5초에 한 번씩 값을 가져오는 이유는 실시간 모니터링을 위해서입니다.

여러 서버의 Load Averages 구하기
서버가 여러 대 있을 때 현재 서버의 Load Averages를 보고자 할 경우 일반적으로는 리눅스에서는 서버에 접속해서 top 명령어를 실행해서 봐야 합니다. 물론 서버가 몇 대 없다면 충분히 가능한 일이겠지만 서버가 몇 십 대가 있을 경우 어떻게 해야 할까요? 일일이 서버에 접속해서 top 명령을 실행해서 결과를 보려고 해도 한참 걸릴 것입니다. 그러나 PHP에서 SNMP 함수를 이용한다면 간단하게 모든 서버의 Load Averages 값을 구할 수 있습니다. 그리고 더 중요한 것은 Load Averages 값이 큰 순서대로 정렬하는 것도 가능하다는 것입니다. Load Averages 값이 크다는 것은 해당 서버의 부하가 높다는 것입니다. 어떤 서버의 Load Averages 값이 높은지 쉽게 파악이 가능하다는 것입니다.



















<리스트 3> 여러 서버의 Load Averages 구하기






<리스트 3>을 보면 여러 서버의 Load Averages를 구하는 소스가 있습니다. 먼저 $hostList 배열에는 서버의 목록이 있습니다. cpu, 메모리 값을 구할 때는 한 대의 서버 값만 구했기 때문에 한 서버만 있었지만 Load Averages는 한 번에 여러 대의 서버에서 값을 구해야 하기 때문에 배열에 서버의 목록이 있습니다. 그리고 Load Averages의 OID 값도 있어야 합니다. $sort 값은 Desc 정렬을 할지 Asc 정렬을 할 지 지정해 주면 됩니다. 그리고 for 문을 이용해서 모든 서버의 값을 구합니다. 그 결과는 $valList 배열에 넣습니다.

그렇다면 for 문에서 값을 구해서 바로 출력해 버려도 되는데 굳이 배열에 값을 저장한 이유는 무엇일까요? 그것은 정렬을 하기 위해서입니다. 그냥 서버의 Load Averages 값을 순서대로 출력해도 되겠지만 Load Averages 값이 높거나 낮은 순으로 정렬해서 보여준다면 더 좋을 것입니다. 그래서 일단 값을 배열에 넣었습니다. 그리고 배열을 정렬하는 함수를 이용해서 정렬해 주면 됩니다. Asc 정렬은 asort() 함수를 Desc 정렬은 arsort() 함수를 호출해 주면 됩니다. 이렇게 정렬한 다음에 foreach 문을 이용해서 해당 값을 출력해 주면 됩니다. 그러면 Load Averages 값의 크기에 따라서 출력됩니다. 간단하게 웹 브라우저에서 여러 대의 서버의 Load Averages를 모니터링할 수 있는 것입니다. 서버의 대수가 많을수록 일일이 서버에 접속해서 top 명령을 실행해서 보는 것보다는 몇 배의 효과를 볼 수 있을 것입니다.

그렇다면 cpu, 메모리도 이와 같은 방법으로 볼 수 있지 않을까 하는 생각이 들 것입니다. 그러나 cpu 값은 수시로 변하는 것이기 때문에 한 서버의 값을 계속 모니터링하는 것은 의미가 있겠지만 이런 식으로 여러 대의 서버를 보는 것은 별 의미가 없습니다. 메모리 값은 충분히 해볼만 합니다. 다만 메모리 값을 구하는 데는 시간이 조금 걸리기 때문에 서버의 대수가 많을수록 값을 구하는 속도가 느릴 것입니다.

TCP 연결 상태 구하기
현재 서버의 어떤 포트에 tcp 연결이 있는지 확인하기 위해서는 리눅스에서는 netstat  명령으로 확인할 수가 있습니다. 그리고 이 값을 SNMP에서도 가져올 수 있습니다. SNMP는 MIB로 분류가 되어 있다고 했었는데 tcp 그룹에 해당되는 값을 가져오면 됩니다.


◆ tcp 값 가져오기
snmpwalk ****.net public tcp.tcpConnTable.tcpConnEntry.tcpConnState

이렇게 명령을 내리면 해당 서버의 tcp 연결 값들이 보일 것입니다. 한 가지 예를 들면 다음과 같이 연결된 값이 보이게 됩니다.


◆ tcp 값의 예
tcp.tcpConnTable.tcpConnEntry.tcpConnState.211.***.***.***.80.210.***.***.
***.12454 = established(5)

이것은 하나의 예를 든 것이고 연결된 실제로는 모든 값이 보이게 됩니다. 211.***.***.***은 해당 서버를 의미합니다. 그리고 80은 해당 서버의 포트를 의미합니다. 210.***.***.***은 해당 서버에 연결된 IP입니다. 12454는 해당 서버의 프로세스 아이디입니다. 결과적으로 210.***.***.*** IP가 211.***.***.*** 서버의 80포트에 12454 프로세스 아이디로 연결되어 있다는 의미입니다. 해당 서버의 tcp 연결 개수가 작다면 별 문제가 되지 않겠지만 연결이 많고 시스템 리소스가 부족한 경우에는 timeout으로 인해서 값을 가져오지 못하는 경우도 있습니다. 그리고 tcp 연결 개수에 따라서 cpu system 리소스 사용량도 달라집니다.

예를 들어서 200~300 정도 연결되어 있다면 약 10% 이내의 cpu system 리소스를 사용하겠지만 1000개 이상의 연결되어 있을 경우에는 약 40% 정도의 리소스를 사용할 수도 있으며 timeout으로 값을 가져오지 못할 수도 있습니다. 물론 이것은 서버 사양에 따라서 다를 수 있습니다. timeout 값을 크게 주면 tcp 값을 못 가져오는 경우는 없겠지만 해당 서버의 리소스를 너무 많이 사용하게 되는 문제가 발생할 수도 있습니다. 그래서 SNMP 값을 가져오는데 timeout 시간 지정 또한 중요합니다.

PHP에서 TCP 연결 상태 구하기
<리스트 4>에 PHP에서 SNMP로 tcp 연결 상태를 가져오는 소스가 있습니다. PHP에서 해당 서버의 tcp 연결 상태를 볼 수 있다는 것은 뭔가 새로울 것입니다. 물론 SNMP를 통해서 가져오는 것이지만요. 그리고 한 가지 더 연결 상태별로 카운트를 셀 수도 있습니다. 먼저 $tcpConnStateCount에는 tcp의 연결 종류가 있습니다.



















<리스트 4> tcp 연결 상태 구하기






SNMP에서 분류하는 tcp의 연결 종류입니다. 그리고 다른 값을 가져올 때와 마찬가지로 서버, OID 값이 있습니다. cpu, 메모리 값을 가져올 때는 snmpget() 함수를 사용했었지만 여기서는 snmpwalkoid() 함수를 사용합니다. snmpwalkoid() 함수를 이용해야 tcp에 연결된 모든 목록을 가져올 수 있기 때문입니다. SNMP 값을 정상적으로 가져왔다면 $tcpConn 변수에 배열로 값이 리턴돼 있을 것입니다. 그렇다면 여기서 tcp 연결 상태별로 카운트를 세기 위해서 foreach 문으로 가공하면 됩니다. 여기서 연결 상태별로 카운트를 하고 $tcpList 배열에 상태를 저장해 주면 됩니다. 그리고 그 다음 foreach 문에서 값을 출력해 주면 됩니다. 이렇게 함으로써 tcp 연결 상태별로 개수를 파악할 수 있습니다. 그리고 어떤 포트에 어느 서버가 연결되어 있는지도 파악할 수가 있게 됩니다.

이 소스코드는 간단하게 연결 개수와 상태를 출력해 주는 것입니다. 그러나 더 기능을 추가해 보자면 어떤 것이 있을까요? 연결된 서버의 IP가 출력되도록 했는데, IP보다는 hostname으로 출력한다면 보기 쉬울 것입니다. 예를 들면 210.***.***.***를 hostname 으로 출력한다면 *****.net 이런식으로 해당 서버의 hostname이 출력 되므로 좀 더 명확하게 파악할 수 있을 것입니다. 그리고 모든 포트가 같이 출력되는데 특정 포트만 검색해서 출력할 수도 있습니다. 그것은 배열을 좀 더 가공해서 출력해 주면 됩니다.


◆ PHP에서 ip로 hostname 구하기
- gethostbyaddr("210.***.***.***");

좀 더 깊이 생각해보고 배열을 가공해 본다면 더 보기 쉽게 tcp 연결 상태를 출력할 수 있을 것입니다. 여기서는 tcp 연결 값을 구했지만 udp 연결 값 또한 SNMP에서 구할 수 있습니다.

그래프로 모니터링 툴 업그레이드
지금까지 SNMP의 기본 개념과 PHP로 SNMP 값을 가져오는 부분을 설명했습니다. 그러나 간단하게 웹 브라우저 상에서 값을 출력하는 정도에 그쳤습니다. cpu, 메모리, Load Averages 값을 그래프로 출력해서 볼 수도 있습니다. PHP에서 이런 값들을 가지고 그래프를 그리고자 한다면 쉽지는 않을 것입니다. 더군다나 cpu 모니터링 결과를 실시간으로 그려야 한다면 아마도 답이 보이지 않을 수도 있습니다. 여기서 만들어 보고자 했던 것은 간단한 모니터링 툴입니다.

로그를 남기고 <화면 1>처럼 그래프로 그리고 방대한 량의 정보를 수집하고 그래야 하는 툴이라면 다른 GUI 툴을 이용해서 만드는 것이 효과적일 것입니다. 아니면 이미 만들어져 있는 툴을 사용해도 될 것입니다. 굳이 PHP에서 그래프로 그려보는 이유는 스스로 만들다보면 다른 툴에서 지원되지 않는 기능 또한 간단하고 쉽게 추가해 볼 수 있기 때문입니다. 그것이 PHP의 장점이기도 합니다.








<화면 1> 원도우의 cpu, 메모리 사용량

그렇다면 여기서 지금까지 SNMP로 가져온 cpu, 메모리,  Load Averages 값을 실시간으로 모니터링할 수 있는 방법은 무엇일까요? 제일 간단한 방법은 자바스크립트를 이용하는 것입니다. 자바스크립트로 공개된 그래프 소스들이 많으니 그걸 이용해서 그려보면 됩니다. PHP에서 SNMP로 구한 값을 iframe에서 자바스크립트 그래프로 값을 계속해서 공급해 주면 되는 것입니다. 그러면 <화면 1>과 같은 그래프가 나올 수 있을 것입니다.

새로운 것과의 만남
새로운 것과의 만남은 항상 사람의 마음을 설레게 합니다. 프로그래머 또한 새로운 것과의 만남은 즐거움일 수 있습니다. SNMP는 여러 가지 언어에서 지원하고 있습니다. 굳이 PHP가 아니더라도 다른 언어로 시스템 모니터링하는 프로그램을 만들어 봐도 좋을 것입니다. 중요한 것은 시스템 모니터링 프로그램을 만들면서 시스템을 이해하고 배워간다는 것입니다. 시스템을 이해하고 프로그램을 만든다면 그 프로그램은 이전의 것과 다를 것입니다. 그것이 바로 프로그래머의 즐거움이기도 합니다.

신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Programing > PHP' 카테고리의 다른 글

[OSX] Eclipse에서 PHP 로컬 개발/테스트 환경 구축하기  (4) 2008.08.30
Enabling PHP and Apache in Leopard  (2) 2008.08.19
WAV파일 분석  (0) 2006.11.10
간단한 소켓통신  (0) 2006.10.13
간단한 대화식 프로그램  (0) 2006.07.24
시스템 모니터링 툴  (0) 2006.07.17
posted by 물결(Wave)
TAG php, snmp
prev 1 next

티스토리 툴바