'log'에 해당되는 글 1건
- 2011.05.17 Log 찍기
2011. 5. 17. 09:52
서버 프로그램을 개발하다 보면 데이터를 주고 받거나 또는 읽고 쓰거나 할 때 내 예상과 다르게 나오는 경우 어쩔 수 없이 표준출력창에 데이터를 띄우던지 아니면 로그파일을 하나 만들어서 데이터를 주기적으로 찍어 내는 일이 허다하다.
필자 역시 C/S 구조의 프로그램을 다년간 개발하면서 socket과 pthread, list, map, date, time 등등 관련해서 여러가지 클래스로 만들어 개인적으로 하나의 라이브러리로 만들어서 사용하고 있다.
그 중 log에 대한 클래스를 하나 공개한다. 공개한다고 떠들어 놨는데 뭐 사실 대단한건 아니다.
특징이라면 가변인자를 사용하였다. 훨씬 더 강력한 기능을 갖게끔 만들 수도 있지만 필자의 로그는 그닥 어렵지 않다. ㅋㅋ
참고로 필자는 본 클래스가 적재 되어있는 라이브러리의 최 상위 클래스를 Lower라는 이름으로 지칭해 놨다. 그러니 Lower를 상속 받는데 있어서 저것이 무엇이냐 묻지 말아라. 멤버라고는 public에 int 타입의 Tag라는 이름을 가진녀석 뿐이다. 뭐 가져다 사용 하려면 그냥 상속 관계를 해제해라.
마지막으로 개발 환경은 HP-UX지만 아마 리눅스나 AIX, 윈도우에서도 돌아가는데는 크게 문제 될 것이 없을 것이다.
Log.h
#ifndef __LOG__
#define __LOG__
#include "include.h"
#include "Lower.h"
#define FILE_PATH "./../log/"
#define FILENAME_LENGTH 0x0C
#ifndef NAME_LENGTH
#define NAME_LENGTH 0x04
#endif
class Log : public Lower
{
private :
FILE * fdFile;
char * cpFileName;
char * cpMyName;
void OpenFile();
void CloseFile();
public :
Log(const char * MyName);
~Log();
void AddLog(const char * Foramt, ...);
void DeleteFile();
};
#endif
#define __LOG__
#include "include.h"
#include "Lower.h"
#define FILE_PATH "./../log/"
#define FILENAME_LENGTH 0x0C
#ifndef NAME_LENGTH
#define NAME_LENGTH 0x04
#endif
class Log : public Lower
{
private :
FILE * fdFile;
char * cpFileName;
char * cpMyName;
void OpenFile();
void CloseFile();
public :
Log(const char * MyName);
~Log();
void AddLog(const char * Foramt, ...);
void DeleteFile();
};
#endif
Log.cc
#include "Log.h"
Log::Log(const char * MyName)
{
char caDate[9];
time_t tNow;
struct tm * stTm;
memset(caDate, 0x00, sizeof(caDate));
time(&tNow);
stTm = localtime(&tNow);
sprintf(caDate, "%04d%02d%02d", stTm->tm_year + 1900, stTm->tm_mon + 1, stTm->tm_mday);
this->cpFileName = new char[FILENAME_LENGTH];
this->cpMyName = new char[NAME_LENGTH];
memset(this->cpFileName, 0x00, FILENAME_LENGTH);
memset(this->cpMyName, 0x00, NAME_LENGTH);
strcpy(this->cpMyName, MyName);
strcat(this->cpFileName, (char *)FILE_PATH);
strcat(this->cpFileName, caDate);
strcat(this->cpFileName, "_");
strcat(this->cpFileName, MyName);
strcat(this->cpFileName, ".log");
}
Log::~Log()
{
this->CloseFile();
delete [] this->cpMyName;
delete [] this->cpFileName;
this->cpMyName = (char *)NULL;
this->cpFileName = (char *)NULL;
}
void Log::OpenFile()
{
this->fdFile = fopen(this->cpFileName, "a+");
if(this->fdFile == NULL) { printf("( %s )Log file create fail.\n", this->cpFileName); }
}
void Log::CloseFile()
{
if(this->fdFile) { fclose(this->fdFile); this->fdFile = (FILE *)NULL; }
}
void Log::AddLog(const char * Format, ...)
{
char caData[512];
char caDate[19];
char caTemp[128];
time_t tNow;
struct tm * stTm;
va_list vaParam;
int FormatLength = 0;
int DataLength = 0;
memset(caData, 0x00, sizeof(caData));
memset(caDate, 0x00, sizeof(caDate));
memset(caTemp, 0x00, sizeof(caTemp));
time(&tNow);
stTm = localtime(&tNow);
sprintf(caDate, "%04d%02d%02d%02d%02d%02d",
stTm->tm_year + 1900, stTm->tm_mon + 1, stTm->tm_mday, stTm->tm_hour, stTm->tm_min, stTm->tm_sec);
strcat(caData, this->cpMyName);
strcat(caData, "] [");
strcat(caData, caDate);
strcat(caData, "] ");
FormatLength = strlen(Format);
DataLength = strlen(caData);
this->OpenFile();
va_start(vaParam, Format);
for(int i=0; i<FormatLength; i++)
{
memset(caTemp, 0x00, sizeof(caTemp));
if(Format[i] == '%')
{
switch(Format[++i])
{
case 'f' :
{
double fValue = va_arg(vaParam, double);
sprintf(caTemp, "%.2f", fValue);
break;
}
case 'd' :
{
int iValue = va_arg(vaParam, int);
sprintf(caTemp, "%d", iValue);
break;
}
case 's' :
{
char * sValue = va_arg(vaParam, char *);
sprintf(caTemp, "%s", sValue);
break;
}
default :
{
continue;
break;
}
}
memcpy(caData + DataLength, caTemp, strlen(caTemp));
DataLength += strlen(caTemp);
}
else { caData[DataLength++] = Format[i]; }
}
fwrite(caData, DataLength, 1, this->fdFile);
va_end(vaParam);
this->CloseFile();
}
void Log::DeleteFile()
{
time_t tNow;
struct tm * stTm;
char Com[26];
memset(Com, 0x00, sizeof(Com));
time(&tNow);
stTm = localtime(&tNow);
if(stTm->tm_mon == 0 || stTm->tm_mon == 1)
{ sprintf(Com, "rm -f ./../log/%04d%02d*%s*", stTm->tm_year + 1899, stTm->tm_mon + 11, this->cpMyName); }
else
{ sprintf(Com, "rm -f ./../log/%04d%02d*%s*", stTm->tm_year + 1900, stTm->tm_mon - 1, this->cpMyName); }
system(Com);
}
Log::Log(const char * MyName)
{
char caDate[9];
time_t tNow;
struct tm * stTm;
memset(caDate, 0x00, sizeof(caDate));
time(&tNow);
stTm = localtime(&tNow);
sprintf(caDate, "%04d%02d%02d", stTm->tm_year + 1900, stTm->tm_mon + 1, stTm->tm_mday);
this->cpFileName = new char[FILENAME_LENGTH];
this->cpMyName = new char[NAME_LENGTH];
memset(this->cpFileName, 0x00, FILENAME_LENGTH);
memset(this->cpMyName, 0x00, NAME_LENGTH);
strcpy(this->cpMyName, MyName);
strcat(this->cpFileName, (char *)FILE_PATH);
strcat(this->cpFileName, caDate);
strcat(this->cpFileName, "_");
strcat(this->cpFileName, MyName);
strcat(this->cpFileName, ".log");
}
Log::~Log()
{
this->CloseFile();
delete [] this->cpMyName;
delete [] this->cpFileName;
this->cpMyName = (char *)NULL;
this->cpFileName = (char *)NULL;
}
void Log::OpenFile()
{
this->fdFile = fopen(this->cpFileName, "a+");
if(this->fdFile == NULL) { printf("( %s )Log file create fail.\n", this->cpFileName); }
}
void Log::CloseFile()
{
if(this->fdFile) { fclose(this->fdFile); this->fdFile = (FILE *)NULL; }
}
void Log::AddLog(const char * Format, ...)
{
char caData[512];
char caDate[19];
char caTemp[128];
time_t tNow;
struct tm * stTm;
va_list vaParam;
int FormatLength = 0;
int DataLength = 0;
memset(caData, 0x00, sizeof(caData));
memset(caDate, 0x00, sizeof(caDate));
memset(caTemp, 0x00, sizeof(caTemp));
time(&tNow);
stTm = localtime(&tNow);
sprintf(caDate, "%04d%02d%02d%02d%02d%02d",
stTm->tm_year + 1900, stTm->tm_mon + 1, stTm->tm_mday, stTm->tm_hour, stTm->tm_min, stTm->tm_sec);
strcat(caData, this->cpMyName);
strcat(caData, "] [");
strcat(caData, caDate);
strcat(caData, "] ");
FormatLength = strlen(Format);
DataLength = strlen(caData);
this->OpenFile();
va_start(vaParam, Format);
for(int i=0; i<FormatLength; i++)
{
memset(caTemp, 0x00, sizeof(caTemp));
if(Format[i] == '%')
{
switch(Format[++i])
{
case 'f' :
{
double fValue = va_arg(vaParam, double);
sprintf(caTemp, "%.2f", fValue);
break;
}
case 'd' :
{
int iValue = va_arg(vaParam, int);
sprintf(caTemp, "%d", iValue);
break;
}
case 's' :
{
char * sValue = va_arg(vaParam, char *);
sprintf(caTemp, "%s", sValue);
break;
}
default :
{
continue;
break;
}
}
memcpy(caData + DataLength, caTemp, strlen(caTemp));
DataLength += strlen(caTemp);
}
else { caData[DataLength++] = Format[i]; }
}
fwrite(caData, DataLength, 1, this->fdFile);
va_end(vaParam);
this->CloseFile();
}
void Log::DeleteFile()
{
time_t tNow;
struct tm * stTm;
char Com[26];
memset(Com, 0x00, sizeof(Com));
time(&tNow);
stTm = localtime(&tNow);
if(stTm->tm_mon == 0 || stTm->tm_mon == 1)
{ sprintf(Com, "rm -f ./../log/%04d%02d*%s*", stTm->tm_year + 1899, stTm->tm_mon + 11, this->cpMyName); }
else
{ sprintf(Com, "rm -f ./../log/%04d%02d*%s*", stTm->tm_year + 1900, stTm->tm_mon - 1, this->cpMyName); }
system(Com);
}
사실 약간은.. 아주 약간은 손 봐야 하는 부분들이 있다. 로그를 찍을 때 길이에 대한 문제라던지.. 타입에 대한 확장이라던지.. 이 소스는 필요하다면 필자가 파일로 줄 수도 있다.
파일이 필요하거든 메일이나 댓글에 굽신거려라. ㅋㅋ 농담이다. 이런 좆밥 기술 가지고 대단한 것 처럼 굴 필자가 아니다.
'프로그래밍' 카테고리의 다른 글
Big Endian, Little Endian : Byte Order ( 바이트 순서 ) (0) | 2011.06.01 |
---|---|
Thread ( 스레드 ) ? (2) | 2011.05.30 |
SQLite 설치 및 사용법 (5) | 2011.05.11 |
Name Mangling (Name Decoration) (0) | 2011.05.03 |
Calling Convention ( 호출 규약 ) __cdecl, __stdcall, __fastcall (3) | 2011.05.02 |