Dev/C, C++
tracelog
newtype
2008. 1. 23. 09:47
application이 시간대 별로 로그를 남긴다고 가정하자.
tail로 해당 로그를 계속 모니터링 할 경우 매 시간마다 tail을 걸어주는 것이 여간 귀찮은 것이 아니다.
환경변수에 파일명 규칙을 설정해 놓으면,
자동으로 tail과 같이 동작하는 util을 만들어 봤다.
- .profile 환경변수 설정
- .profile 환경변수 설정
- tracelog.c
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
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);
}
#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);
}
반응형