제목 그대로 입니다.
그냥 쓱~ 긁어서 간편하게 쓸수 있는데 반해
쓰레드에 대해서도 안전하기 때문에,
실전에서 매우 유용하게 사용할수 있는 로그 기록을 만들어주는 클래스입니다.
특히 날짜별로 로그를 기록하기 때문에
기록 도중에 날짜가 변경되면 그기에 맞게 새로운 날짜로 로그 파일이 생성되고 기록됩니다.
테스트 코드와
결과까지 첨부 했습니다.
필요한데도
이제 귀잖다는 이유로 로그를 남기지 않는 프로그램은 만들지 맙시다.
아주 아주 오랜 옛날 제가 만들어 공개한 적이 있는
C 스타일 파일 엑세스를 매우 간편하게 할수 있는
TFILE 클래스 파일은 별첨했습니다.
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
#include "SyncObjs.hpp" // 이건 빌더 내부 파일.
#include "TFILE.h"
/*
쓱~ 긁어 쓸수 있는 간편하지만 강력한 Thread Safe한 Log 클래스.
전역 또는 클래스 멤버로 로그 객체를 선언하고,
초기 부분에서
Prepare 메소드를 호출해 디렉토리와 로그 파일을 생성하고
Add 메소드를 통해 기록하면 된다.
객체가 소멸될때 로그 파일은 자동으로 닫히며,
만일 기록중 일자가 변경되면
로그파일명도 그 날짜로 바뀐다.
Written by KTS.
Test : C++Builder 6
*/
class TsLog
{
private:
TCriticalSection* cs_put;
TFILE File;
String Dir;
String PrefixFilename;
String Filename;
TDate CurDate;
private:
// 오늘 날짜 로그 파일명 만들기
String GetTodayLogFilename()
{
String s = PrefixFilename + CurDate.FormatString("yyyy-mm-dd") + ".log";
return s;
}
public:
bool bStop; // 임시로 기록을 멈춘다
public:
TsLog()
{
cs_put = new TCriticalSection;
bStop = false;
}
~TsLog()
{
delete cs_put;
}
// Prepare("Log", "Test_"); 이렇게 호출하면
// 현재 폴더 밑에 Log 폴더 밑에 올해 년도 폴더 밑에 Test_오늘날짜.log 파일이 생성된다.
void Prepare(char *log_dir, char *prefix_filename)
{
PrefixFilename = prefix_filename;
// 년도 폴더 준비
Dir = log_dir;
CurDate = Now();
OpenFile();
}
// 현재 시간에 맞게 파일을 오픈한다.
void OpenFile()
{
File.fclose();
// 파일명 준비.
String dir = Dir + "\\" + CurDate.FormatString("yyyy");
if (!DirectoryExists(dir))
CreateDir(dir);
Filename = dir + "\\" + GetTodayLogFilename();
if (File.fopen(Filename.c_str(), "at") == NULL)
{
String s = Filename + " Can't make Log file.";
MessageBox(0, s.c_str(), "Message", 0);
}
}
// 끝에 있는 CRLF가 있으면 제거한다.
// 진짜 파일에 Add 한다.
void FileAdd(String s)
{
if (bStop)
return;
TDate date = Now();
// 날이 변했으면 새 로그파일을 쓸준비를 한다.
int between = (int)date - (int)CurDate;
if (between > 0)
{
CurDate = date;
OpenFile();
}
int len = s.Length();
char *p = s.c_str();
if (len >= 2)
{
len--;
if (p[len] == 10) // LF 제거
p[len--] = 0;
if (p[len] == 13) // CR 제거
p[len] = 0;
}
cs_put->Enter();
File.fprintf("%s\n", p);
cs_put->Leave();
File.flush();
}
void Add(String s)
{
if (bStop)
return;
String msg = Now().FormatString("yyyy-mm-dd hh:nn:ss:zzz ") + s;
FileAdd(msg);
}
void Add(String s, String ss)
{
Add(s + " / " + ss);
}
};
TsLog Log;
//---------------------------------------------------------------------------
// 쓰레드에 대해서도 로그가 안전하게 기록되는가
// 테스트하기 위한 쓰레드 클래스
class CThreadTest : public TThread
{
public:
bool bStart;
CThreadTest() : TThread(true)
{
FreeOnTerminate = true;
bStart = false;
}
void __fastcall Execute()
{
bStart = true;
for(int c = 0; c < 100; c++)
{
Log.Add("on Thread", c);
Sleep(0);
}
}
};
//---------------------------------------------------------------------------
// 사용 예제
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
CreateDir("Log");
// 이렇게 하면 현재 폴더 밑에 Log 폴더 밑에 현재 년도 밑에 Test_오늘날짜.log 파일이 생성되고 쓰기 준비함.
// 물론 이미 있다면 추가 모드로 준비함.
Log.Prepare("Log", "Test_");
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Log.Add("---[Create]---");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Log.Add("Click", "Button");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
Log.Add("---[Close]---");
}
//---------------------------------------------------------------------------
// 테스트
void __fastcall TForm1::Button2Click(TObject *Sender)
{
CThreadTest *ThreadTest = new CThreadTest();
for(int c = 0; c < 5; c++)
{
Log.Add("Clicked", c);
Sleep(1);
}
// Thread safe한가 테스트.
ThreadTest->Resume();
while(!ThreadTest->bStart)
ThreadTest;
for(int c = 0; c < 100; c++)
{
Log.Add("Clicked", c);
Sleep(0);
}
}
//---------------------------------------------------------------------------
결과:
2016-05-31 10:02:26:648 ---[Create]---
2016-05-31 10:02:27:521 Clicked / 0
2016-05-31 10:02:27:523 Clicked / 1
2016-05-31 10:02:27:525 Clicked / 2
2016-05-31 10:02:27:527 Clicked / 3
2016-05-31 10:02:27:529 Clicked / 4
2016-05-31 10:02:27:532 on Thread / 0
2016-05-31 10:02:27:532 Clicked / 0
2016-05-31 10:02:27:532 on Thread / 1
2016-05-31 10:02:27:532 Clicked / 1
2016-05-31 10:02:27:532 on Thread / 2
2016-05-31 10:02:27:532 Clicked / 2
2016-05-31 10:02:27:532 on Thread / 3
2016-05-31 10:02:27:532 Clicked / 3
2016-05-31 10:02:27:532 on Thread / 4
2016-05-31 10:02:27:532 Clicked / 4
2016-05-31 10:02:27:532 on Thread / 5
2016-05-31 10:02:27:532 Clicked / 5
2016-05-31 10:02:27:532 on Thread / 6
2016-05-31 10:02:27:532 Clicked / 6
2016-05-31 10:02:27:533 on Thread / 7
2016-05-31 10:02:27:533 Clicked / 7
2016-05-31 10:02:27:533 on Thread / 8
2016-05-31 10:02:27:533 Clicked / 8
2016-05-31 10:02:27:533 on Thread / 9
2016-05-31 10:02:27:533 Clicked / 9
2016-05-31 10:02:27:533 on Thread / 10
2016-05-31 10:02:27:533 Clicked / 10
2016-05-31 10:02:27:533 on Thread / 11
2016-05-31 10:02:27:533 Clicked / 11
2016-05-31 10:02:27:533 on Thread / 12
2016-05-31 10:02:27:533 Clicked / 12
2016-05-31 10:02:27:533 on Thread / 13
2016-05-31 10:02:27:533 Clicked / 13
2016-05-31 10:02:27:533 on Thread / 14
2016-05-31 10:02:27:533 Clicked / 14
2016-05-31 10:02:27:533 on Thread / 15
2016-05-31 10:02:27:533 Clicked / 15
2016-05-31 10:02:27:533 on Thread / 16
2016-05-31 10:02:27:533 Clicked / 16
2016-05-31 10:02:27:533 on Thread / 17
2016-05-31 10:02:27:533 Clicked / 17
2016-05-31 10:02:27:533 on Thread / 18
2016-05-31 10:02:27:533 Clicked / 18
2016-05-31 10:02:27:533 on Thread / 19
2016-05-31 10:02:27:533 Clicked / 19
2016-05-31 10:02:27:533 on Thread / 20
2016-05-31 10:02:27:533 Clicked / 20
2016-05-31 10:02:27:533 on Thread / 21
2016-05-31 10:02:27:533 Clicked / 21
2016-05-31 10:02:27:533 on Thread / 22
2016-05-31 10:02:27:533 Clicked / 22
2016-05-31 10:02:27:533 on Thread / 23
2016-05-31 10:02:27:533 Clicked / 23
2016-05-31 10:02:27:533 on Thread / 24
2016-05-31 10:02:27:533 Clicked / 24
2016-05-31 10:02:27:533 on Thread / 25
2016-05-31 10:02:27:534 Clicked / 25
2016-05-31 10:02:27:534 on Thread / 26
2016-05-31 10:02:27:534 Clicked / 26
2016-05-31 10:02:27:534 on Thread / 27
2016-05-31 10:02:27:534 Clicked / 27
2016-05-31 10:02:27:534 on Thread / 28
2016-05-31 10:02:27:534 Clicked / 28
2016-05-31 10:02:27:534 on Thread / 29
2016-05-31 10:02:27:534 Clicked / 29
2016-05-31 10:02:27:534 on Thread / 30
2016-05-31 10:02:27:534 Clicked / 30
2016-05-31 10:02:27:534 on Thread / 31
2016-05-31 10:02:27:534 Clicked / 31
2016-05-31 10:02:27:534 on Thread / 32
2016-05-31 10:02:27:534 Clicked / 32
2016-05-31 10:02:27:534 on Thread / 33
2016-05-31 10:02:27:534 Clicked / 33
2016-05-31 10:02:27:534 on Thread / 34
2016-05-31 10:02:27:534 Clicked / 34
2016-05-31 10:02:27:534 on Thread / 35
2016-05-31 10:02:27:534 Clicked / 35
2016-05-31 10:02:27:534 on Thread / 36
2016-05-31 10:02:27:534 Clicked / 36
2016-05-31 10:02:27:534 on Thread / 37
2016-05-31 10:02:27:534 Clicked / 37
2016-05-31 10:02:27:534 on Thread / 38
2016-05-31 10:02:27:535 Clicked / 38
2016-05-31 10:02:27:535 on Thread / 39
2016-05-31 10:02:27:535 Clicked / 39
2016-05-31 10:02:27:535 on Thread / 40
2016-05-31 10:02:27:535 Clicked / 40
2016-05-31 10:02:27:535 on Thread / 41
2016-05-31 10:02:27:535 Clicked / 41
2016-05-31 10:02:27:535 on Thread / 42
2016-05-31 10:02:27:535 Clicked / 42
2016-05-31 10:02:27:535 on Thread / 43
2016-05-31 10:02:27:535 Clicked / 43
2016-05-31 10:02:27:535 on Thread / 44
2016-05-31 10:02:27:535 Clicked / 44
2016-05-31 10:02:27:535 on Thread / 45
2016-05-31 10:02:27:535 Clicked / 45
2016-05-31 10:02:27:535 on Thread / 46
2016-05-31 10:02:27:535 Clicked / 46
2016-05-31 10:02:27:535 on Thread / 47
2016-05-31 10:02:27:535 Clicked / 47
2016-05-31 10:02:27:535 on Thread / 48
2016-05-31 10:02:27:535 Clicked / 48
2016-05-31 10:02:27:535 on Thread / 49
2016-05-31 10:02:27:535 Clicked / 49
2016-05-31 10:02:27:535 on Thread / 50
2016-05-31 10:02:27:535 Clicked / 50
2016-05-31 10:02:27:536 on Thread / 51
2016-05-31 10:02:27:536 Clicked / 51
2016-05-31 10:02:27:536 on Thread / 52
2016-05-31 10:02:27:536 Clicked / 52
2016-05-31 10:02:27:536 on Thread / 53
2016-05-31 10:02:27:536 Clicked / 53
2016-05-31 10:02:27:536 on Thread / 54
2016-05-31 10:02:27:536 Clicked / 54
2016-05-31 10:02:27:536 on Thread / 55
2016-05-31 10:02:27:536 Clicked / 55
2016-05-31 10:02:27:536 on Thread / 56
2016-05-31 10:02:27:536 Clicked / 56
2016-05-31 10:02:27:536 on Thread / 57
2016-05-31 10:02:27:536 Clicked / 57
2016-05-31 10:02:27:536 on Thread / 58
2016-05-31 10:02:27:536 Clicked / 58
2016-05-31 10:02:27:536 on Thread / 59
2016-05-31 10:02:27:536 Clicked / 59
2016-05-31 10:02:27:536 on Thread / 60
2016-05-31 10:02:27:536 Clicked / 60
2016-05-31 10:02:27:536 on Thread / 61
2016-05-31 10:02:27:536 Clicked / 61
2016-05-31 10:02:27:536 on Thread / 62
2016-05-31 10:02:27:536 Clicked / 62
2016-05-31 10:02:27:536 on Thread / 63
2016-05-31 10:02:27:536 Clicked / 63
2016-05-31 10:02:27:536 on Thread / 64
2016-05-31 10:02:27:536 Clicked / 64
2016-05-31 10:02:27:537 on Thread / 65
2016-05-31 10:02:27:537 Clicked / 65
2016-05-31 10:02:27:537 on Thread / 66
2016-05-31 10:02:27:537 Clicked / 66
2016-05-31 10:02:27:537 on Thread / 67
2016-05-31 10:02:27:537 Clicked / 67
2016-05-31 10:02:27:537 on Thread / 68
2016-05-31 10:02:27:537 Clicked / 68
2016-05-31 10:02:27:537 on Thread / 69
2016-05-31 10:02:27:537 Clicked / 69
2016-05-31 10:02:27:537 on Thread / 70
2016-05-31 10:02:27:537 Clicked / 70
2016-05-31 10:02:27:537 on Thread / 71
2016-05-31 10:02:27:537 Clicked / 71
2016-05-31 10:02:27:537 on Thread / 72
2016-05-31 10:02:27:537 Clicked / 72
2016-05-31 10:02:27:537 on Thread / 73
2016-05-31 10:02:27:537 Clicked / 73
2016-05-31 10:02:27:537 on Thread / 74
2016-05-31 10:02:27:537 Clicked / 74
2016-05-31 10:02:27:537 on Thread / 75
2016-05-31 10:02:27:537 Clicked / 75
2016-05-31 10:02:27:537 on Thread / 76
2016-05-31 10:02:27:537 Clicked / 76
2016-05-31 10:02:27:537 on Thread / 77
2016-05-31 10:02:27:537 Clicked / 77
2016-05-31 10:02:27:537 on Thread / 78
2016-05-31 10:02:27:537 Clicked / 78
2016-05-31 10:02:27:537 on Thread / 79
2016-05-31 10:02:27:537 Clicked / 79
2016-05-31 10:02:27:537 on Thread / 80
2016-05-31 10:02:27:537 Clicked / 80
2016-05-31 10:02:27:537 on Thread / 81
2016-05-31 10:02:27:538 Clicked / 81
2016-05-31 10:02:27:538 on Thread / 82
2016-05-31 10:02:27:538 Clicked / 82
2016-05-31 10:02:27:538 on Thread / 83
2016-05-31 10:02:27:538 Clicked / 83
2016-05-31 10:02:27:538 on Thread / 84
2016-05-31 10:02:27:538 Clicked / 84
2016-05-31 10:02:27:538 on Thread / 85
2016-05-31 10:02:27:538 Clicked / 85
2016-05-31 10:02:27:538 on Thread / 86
2016-05-31 10:02:27:538 Clicked / 86
2016-05-31 10:02:27:538 on Thread / 87
2016-05-31 10:02:27:538 Clicked / 87
2016-05-31 10:02:27:538 on Thread / 88
2016-05-31 10:02:27:538 Clicked / 88
2016-05-31 10:02:27:538 on Thread / 89
2016-05-31 10:02:27:538 Clicked / 89
2016-05-31 10:02:27:538 on Thread / 90
2016-05-31 10:02:27:538 Clicked / 90
2016-05-31 10:02:27:538 on Thread / 91
2016-05-31 10:02:27:538 Clicked / 91
2016-05-31 10:02:27:538 on Thread / 92
2016-05-31 10:02:27:538 Clicked / 92
2016-05-31 10:02:27:538 on Thread / 93
2016-05-31 10:02:27:538 Clicked / 93
2016-05-31 10:02:27:538 on Thread / 94
2016-05-31 10:02:27:538 Clicked / 94
2016-05-31 10:02:27:538 on Thread / 95
2016-05-31 10:02:27:538 Clicked / 95
2016-05-31 10:02:27:538 on Thread / 96
2016-05-31 10:02:27:538 Clicked / 96
2016-05-31 10:02:27:538 on Thread / 97
2016-05-31 10:02:27:538 Clicked / 97
2016-05-31 10:02:27:538 on Thread / 98
2016-05-31 10:02:27:538 Clicked / 98
2016-05-31 10:02:27:539 on Thread / 99
2016-05-31 10:02:27:539 Clicked / 99
2016-05-31 10:02:28:537 ---[Close]---