newtype
::: newtype의 지식창고 :::
newtype
전체 방문자
오늘
어제
  • 분류 전체보기 (392)
    • Dev (214)
      • C, C++ (43)
      • Go (5)
      • Web (49)
      • DBMS (21)
      • DevOps (8)
      • Java (2)
      • Windows, Win32 (4)
      • Visual Basic (5)
      • C# (2)
      • Mobile (25)
      • SQL CE (7)
      • Google Map (6)
      • Python (2)
      • cygwin (2)
      • 기타 (32)
      • Ruby (1)
    • 명언 (10)
    • 모임 (18)
      • 붕주회 (3)
      • 신흥컴정 (14)
      • 웹20기 (1)
    • 사진 (8)
    • 불펌 (29)
    • 막글 (98)
    • 게임 (6)
    • 여행 (8)

블로그 메뉴

  • 홈
  • 태그
  • 방명록
  • 관리

공지사항

  • whoami
05-12 00:06
hELLO · Designed By 정상우.
newtype

::: newtype의 지식창고 :::

Dev/C, C++

tracelog

2008. 1. 23. 09:47
application이 시간대 별로 로그를 남긴다고 가정하자.
tail로 해당 로그를 계속 모니터링 할 경우 매 시간마다 tail을 걸어주는 것이 여간 귀찮은 것이 아니다.

환경변수에 파일명 규칙을 설정해 놓으면,
자동으로 tail과 같이 동작하는 util을 만들어 봤다.

- .profile 환경변수 설정
2008.01.30.   실행파일의 파라미터로 읽어들을 환경 변수명을 읽게 수정

- .profile 환경변수 설정
# tracelog
export PROJECT_HOME=/home/app/myapp
export TRACELOG=$PROJECT_HOME/log/history/20%y%m/ifsvr_20%y%m%d%H.log

- tracelog.c

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdarg.h>
   
#define ENVNAME "TRACELOG"
#define TRACELOGFILE "/home/app/myapp/log/history/20%y%m/ifsvr_20%y%m%d%H.log"

#define MAX_BUF 1024

char g_env[MAX_BUF]=ENVNAME;

int replace( char *target, char *source, char *find, char *replace );
void getFilename(char *target, int size);
int getFileSize(char *file);
void Log(const char *fmt, ... );

int main(int argc, char **argv)
{
    FILE *fd=0;
    char buf[MAX_BUF]="";
    char filename[MAX_BUF]="";
    int size=0, prevSize=0;

    if( argc==2 )
    {
        strcpy(g_env, argv[1]);
    } else {
        strcpy(g_env, ENVNAME);
    }

    getFilename( filename, sizeof(filename));

    prevSize = getFileSize(filename);
    if ( prevSize < 0 )
    {
        Log ("file [%s] no exist\n", filename);
        exit (-1);
    }

    fd = fopen (filename, "r");
    if (fd == 0)
    {
        Log ("file [%s] open error : [%s]\n", argv[1], strerror (errno));
        exit (-1);
    }
   
    Log("file [%s] reading....\n", filename );

    // 파일을 끝까지 읽는다.
    do
    {
        memset( buf, 0x00, sizeof(buf) );
        fgets( buf, sizeof(buf)-1, fd );
    } while(buf[0]);
   
    while(1)
    {
        sleep(1);   
       
        getFilename( buf, sizeof(buf) );
        if( strcmp( buf, filename ) )
        {
            // 이전 파일을 정리
            size = getFileSize(filename);
            if ( size > prevSize )
            {
                filename[0]=0;
                do
                {
                    Log(filename);
                    memset( filename, 0x00, sizeof(filename) );
                    fgets( filename, sizeof(filename)-1, fd );
                } while(filename[0]);
            }
            fclose(fd);
            fd=0;
           
            strcpy( filename, buf );
            prevSize = -1;
        }
       
        size = getFileSize(filename);
        if ( size < 0 )
        {
            //Log("file [%s] no exist\n", filename);
            // exit(-1);
            continue;
        }
       
        if ( prevSize < 0 )
        {
            // 파일명 바뀐 것
            prevSize = size;
            fd = fopen (filename, "r");
            if (fd == 0)
            {
                Log ("file [%s] open error : [%s]\n", argv[1], strerror (errno));
                exit (-1);
            }           
            Log("Next File [%s]\n", filename );
        }
        else if ( prevSize > size )
        {
            // 파일크기 작아짐.
            prevSize = size;
            rewind(fd);
            Log("rewind [%s]\n", filename );
        }
        else if ( prevSize == size )   
        {
            // 파일 크기 같음.
            continue;
        }
       
        size=prevSize;
       
        // 내용 출력
        buf[0]=0;
        do
        {
            Log(buf);
            memset( buf, 0x00, sizeof(buf) );
            fgets( buf, sizeof(buf)-1, fd );
        } while(buf[0]);
    }

    return 0;
}

/*****************************************************************************
* source에서 find를 찾아 replace로 바꾼다.
* Parameter
*        [OUT] char *target    :    변경된 값을 저장
*        [IN]  char *source    :    검색 문자열이 포함된 원본 문자열
*        [IN]  char *find    :    검색 문자열
*        [IN]  char *replace    :    변환 할 문자열
* Return
*        int        :    변경한 갯수
*****************************************************************************/
int replace( char *target, char *source, char *find, char *replace )
{
   int i, nCount=0;
   int bFind;
   char *ps, *pf;
   char *buf=0, *pt = target;

   int nLenSrc = strlen( source );

   buf = (char*)malloc(nLenSrc+1);
   if ( buf == NULL ) return (int)NULL;

   strncpy( buf, source, nLenSrc );

   for(ps=buf; *ps; ps++) {
           //첫글자가 같다.
       if ( find[0] == *ps ) {
           bFind = 1;
           // 모든 글자를 비교
           for(pf=find+1, i=1; *pf; pf++, i++) {
               if ( *pf != ps[i] ) {
                   bFind = 0;
                   break;
               }
           }

           // 찾았다!
           if ( bFind == 1 ) {
                   // 바뀔 스트링 복사
               for(pf=replace; *pf; pf++)
                   *(pt++) = *pf;
               ps += (--i);

               nCount++;
               continue;
           }
       }
       // 원본 스트링 복사
       *(pt++) = *ps;
   }

   *pt = 0;
   free(buf);
   return nCount;
}

/*****************************************************************************
* 환경 변수의 format 대로 파일명을 얻는다.
* Parameter
*        [OUT] char *target    :    파일명을 저장할 주소
*        [IN]  int  size        :    target의 최대 크그
*****************************************************************************/
void getFilename( char *target, int size)
{
    char *env=0;
    char buf[MAX_BUF]="";
       
    time_t sTime;
    struct tm spTm;
   
    if(env=getenv(g_env))
    {       
        strcpy( buf, env );
    } else {       
        strcpy( buf, TRACELOGFILE );
    }
   
    time (&sTime);
    memcpy( &spTm, localtime(&sTime), sizeof(spTm));
   
    strftime(target, size, buf, &spTm );
}


/*****************************************************************************
* file의 size를 구한다.
* Parameter
*        [IN]  char *file    :   파일명
* Return
*        int        :    -1      -   파일이 존재하지 않음, 파일 읽기 오류
*                   >= 0    -   파일의 크기
*****************************************************************************/
int getFileSize(char *file)
{
    struct stat fstat;
   
    if (access(file, F_OK) != 0)
        return -1;   

    if (stat(file, &fstat) < 0)
    {
        return -1;
    }

    return fstat.st_size;
}

/*****************************************************************************
* 내용을 stdout을 이용해 출력한다.
* Parameter
*        [IN]  const char *fmt, :    가변인자, printf와 같음
*       [IN]  ...
*****************************************************************************/
void Log(const char *fmt, ... )
{
    va_list argp;
   
    fflush(stdout);
   
    va_start( argp, fmt );
   
    vfprintf(stdout, fmt, argp);
   
    va_end( argp );

    fflush(stdout);
}



반응형

'Dev > C, C++' 카테고리의 다른 글

Oracle 에러코드  (1) 2008.07.08
c ini 읽는 모듈..  (2) 2008.04.30
trim  (4) 2007.09.14
xor을 이용한 swap 함수  (0) 2007.08.09
socket connect timeout  (2) 2007.05.29
    'Dev/C, C++' 카테고리의 다른 글
    • Oracle 에러코드
    • c ini 읽는 모듈..
    • trim
    • xor을 이용한 swap 함수
    newtype
    newtype
    지극히 개인적인 지식의 창고

    티스토리툴바