122#ifndef _TnbLOG_DISABLE
125#ifndef _TnbLOG_MULTIFILE
126 #pragma message("message : TLOG系は有効になっています(SingleFileType)。")
128 #pragma message("message : TLOG系は有効になっています(MultiFileType)。")
137#ifndef _TnbTraceLogger_Types
138 #define _TnbTraceLogger_Types "trace"
141#ifndef _TnbTraceLogger_LogSize
142 #define _TnbTraceLogger_LogSize 64
145#ifndef _TnbTraceLogger_FileCount
146 #define _TnbTraceLogger_FileCount 5
149#ifndef _TnbTraceLogger_Time
150 #define _TnbTraceLogger_Time "normal"
153#ifndef _TnbTraceLogger_Thread
154 #define _TnbTraceLogger_Thread "on"
157#ifndef _TnbTraceLogger_Dump
158 #define _TnbTraceLogger_Dump 1
161#ifndef _TnbTraceLogger_LogFileName
162 #define _TnbTraceLogger_LogFileName ms_MakeLogfilePath
166#ifdef _TnbTraceLogger_FileMaxSize
167 #undef _TnbTraceLogger_LogSize
168 #define _TnbTraceLogger_LogSize _TnbTraceLogger_FileMaxSize
171#ifdef _TnbLOG_OUTPUT_FUNC
172 #undef _TnbTraceLogger_Types
173 #define _TnbTraceLogger_Types "trace func"
199 Type_Absolute =
_BIT(0),
200 Type_Error =
_BIT(1),
201 Type_Trace =
_BIT(2),
202 Type_Polling =
_BIT(3),
203 Type_Function =
_BIT(4),
244 CFuncer(LPCTSTR lpszFunctionName, ...)
248 va_start(args, lpszFunctionName);
249 s.
FormatV(lpszFunctionName, args);
250 m_functionName = s.
FindCut(
'(');
251 if ( s.
Find(
'(') == INVALID_INDEX )
255 CTraceLogger::Write(CTraceLogger::Type_Function,
CStr::Fmt(_T(
">In[%s]"), s));
263 void Param(LPCTSTR lpszFormatText, ...)
266 ASSERT0(! m_functionName.IsEmpty(),
267 CAscii(m_functionName),
"リザルト表示後にパラメータを表示しようとしています。");
270 va_list args; va_start(args, lpszFormatText);
271 s.
FormatV(lpszFormatText, args);
272 CTraceLogger::Write(CTraceLogger::Type_Function, _T(
">InParam ") + s);
280 void Result(LPCTSTR lpszFormatText, ...)
283 ASSERT0(! m_functionName.IsEmpty(),
284 CAscii(m_functionName),
"リザルトを二回以上表示しようとしています。");
287 va_list args; va_start(args, lpszFormatText);
288 s.
FormatV(lpszFormatText, args);
289 m_resultText.Format(_T(
">Out[%s()] %s"), m_functionName, s);
290 m_functionName.Empty();
295 if ( ! m_resultText.IsEmpty() )
297 CTraceLogger::Write(CTraceLogger::Type_Function, m_resultText);
299 else if ( ! m_functionName.IsEmpty() )
302 s.
Format(_T(
">Out[%s()]"), m_functionName);
303 CTraceLogger::Write(CTraceLogger::Type_Function, s);
305 m_functionName.Empty();
308 LPCTSTR GetFunctionName(
void)
const
310 return m_functionName;
323 virtual ~CTraceLogger(
void)
333 static void EnableOutput(
bool isEnable)
335 CTraceLogger* P = GetInstance();
336 P->m_PauseMode(! isEnable);
351 static bool Write(EType type, LPCTSTR lpszFormatText, va_list va)
353 CTraceLogger* P = GetInstance();
354 if ( ! P->m_CanLogout(type) ){
return true; }
357 return P->m_PostTraceInfo(type,
CAscii(s), NULL);
368 static bool Write(EType type, LPCTSTR lpszFormatText, ...)
370 va_list args; va_start(args, lpszFormatText);
371 return Write(type, lpszFormatText, args);
381 static bool Write(EType type,
const CByteVector &vb)
384 CTraceLogger* P = GetInstance();
385 if ( ! P->m_CanLogout(type) ){
return true; }
386 if ( P->m_outputDumpLevel > 0 )
388 boRc = P->m_PostTraceInfo(type, NULL, &vb);
400 static bool Write(EType type,
size_t size, LPCVOID P)
403 if ( ! ::IsBadReadPtr(P, size) )
411 r = Write(type, _T(
"アクセスできない領域をDumpしようしました。"));
423 m_maxMultiFileCount = 0;
424 m_outputThread = Thread_On;
425 m_outputTime = Time_Normal;
426 m_outputDumpLevel = 1;
428 m_isInitLastTick =
false;
438 static CStr ms_MakeLogfilePath(INDEX index = 0)
441 DWORD dwRc = ::GetModuleFileName(NULL, str.
GetBuffer(MAX_PATH), MAX_PATH);
443 ASSERTLIB(dwRc != 0);
453 strWork += _T(
".t.log");
457 strWork +=
CStr::Fmt(_T(
".t%d.log"), index);
467 bool m_CanLogout(EType type)
474 if ( ! m_file.IsAlive() )
481 return (m_outputTypes & type) != 0;
487 if ( m_file.IsAlive() )
489 m_PostTraceInfo(Type_Absolute,
"----------<<終了>>----------", NULL);
505 m_outputTypes = Type_Trace | Type_Error | Type_Absolute;
510 s = _T(_TnbTraceLogger_Types);
512 if ( s.
Find(_T(
"err")) >= 0 ){
513 m_outputTypes = Type_Error | Type_Absolute;
515 if ( s.
Find(_T(
"trace")) >= 0 ){
516 m_outputTypes |= Type_Trace;
518 if ( s.
Find(_T(
"poll")) >= 0 ){
519 m_outputTypes |= Type_Polling;
521 if ( s.
Find(_T(
"func")) >= 0 ){
522 m_outputTypes |= Type_Function;
524 if ( s.
Find(_T(
"off")) >= 0 ){
528 if ( m_outputTypes == 0 )
532 m_maxLogSize = sec.
QueryDword(_T(
"LogSize"), _TnbTraceLogger_LogSize);
533 if ( m_maxLogSize < 1 )
537 m_maxMultiFileCount = sec.
QueryDword(_T(
"FileCount"), _TnbTraceLogger_FileCount);
538 if ( m_maxMultiFileCount < 2 )
540 m_maxMultiFileCount = 2;
542 m_maxLogSize *= 1024;
543 m_outputTime = Time_Normal;
548 s = _T(_TnbTraceLogger_Time);
550 if ( s.
Find(_T(
"off")) >= 0 ){
551 m_outputTime = Time_Off;
553 else if ( s.
Find(_T(
"normal")) >= 0 ){
554 m_outputTime = Time_Normal;
556 else if ( s.
Find(_T(
"full")) >= 0 ){
557 m_outputTime = Time_Full;
559 else if ( s.
Find(_T(
"tick")) >= 0 ){
560 m_outputTime = Time_Tick;
563 m_outputThread = Thread_On;
568 s = _T(_TnbTraceLogger_Thread);
570 if ( s.
Find(_T(
"off")) >= 0 ){
571 m_outputThread = Thread_Off;
573 else if ( s.
Find(_T(
"on")) >= 0 ){
574 m_outputThread = Thread_On;
577 m_outputDumpLevel = sec.
QueryDword(_T(
"Dump"), _TnbTraceLogger_Dump);
579 if ( ! m_fw.Open(_TnbTraceLogger_LogFileName(0),
true,
true) )
583 m_offset =
static_cast<INDEX
>(m_fw.GetSize());
584 #ifndef _TnbLOG_MULTIFILE
588 m_offset = HEADSIZE + 2;
589 if ( ! m_WritePos(m_fw, m_offset) )
600 vb = m_fw.ReadExactly(HEADSIZE);
613 m_offset = atoi(
reinterpret_cast<const char*
>(vb.
ReferBuffer()));
617 if ( ! m_file.SetWriter(&m_fw) )
621 if ( ! m_file.Start() )
625 m_file.SetPriority(THREAD_PRIORITY_LOWEST);
626 m_PostTraceInfo(Type_Absolute,
"----------<<起動>>----------", NULL);
637 bool m_WritePos(
IWriter& _fw, INDEX dwPos)
644 char acFmt[HEADSIZE * 2];
645 char acBuf[HEADSIZE * 2];
646 sprintf(acFmt,
"%%0%dd\r\n", HEADSIZE);
647 sprintf(acBuf, acFmt, dw);
651 _fw.
Write(HEADSIZE + 2, acBuf);
673 bool m_WriteLine(
IWriter& _fw, LPCSTR lpszLine)
675 ASSERT( &_fw == &m_fw );
676 if ( ! m_fw.CanWrite() )
682 ::OutputDebugString(
CStr(lpszLine).Sandwich(_T(
"TLOG:["), _T(
"]\n")));
684 #ifndef _TnbLOG_MULTIFILE
685 LPCSTR lpszRc =
"\r\n@@\r\n";
688 LPCSTR lpszRc =
"\r\n";
693 m_fw.Write(dwTextSize, lpszLine);
706 m_offset += dwTextSize + 2;
707 #ifndef _TnbLOG_MULTIFILE
708 if ( m_offset > m_maxLogSize )
710 m_offset = HEADSIZE + 2;
713 return m_WritePos(m_fw, m_offset);
715 if ( m_offset > m_maxLogSize )
720 ::DeleteFile(_TnbTraceLogger_LogFileName(m_maxMultiFileCount));
721 loop_dn( i, m_maxMultiFileCount)
723 CStr s1 = _TnbTraceLogger_LogFileName(i + 1);
724 CStr s2 = _TnbTraceLogger_LogFileName(i);
727 if ( ! m_fw.New(_TnbTraceLogger_LogFileName(0),
true) )
742 CTraceLogger* m_pLogger;
753 CParamWriteCmd(CTraceLogger* P)
765 if ( ! m_pLogger->m_isInitLastTick )
767 m_pLogger->m_isInitLastTick =
true;
768 m_pLogger->m_lastTick = dwTick;
770 DWORD dwTickDiff = dwTick - m_pLogger->m_lastTick;
772 if ( m_pLogger->m_outputThread != Thread_Off )
774 strThread.
Format(
"[%08X] ", dwThreadId);
777 switch ( m_pLogger->m_outputTime )
784 strLine.
Format(
"%02d/%02d/%02d-%02d:%02d:%02d.%03d",
794 strLine.
Format(
"%02d/%02d-%02d:%02d:%02d",
804 strLine.
Format(
"%02d/%02d/%02d-%02d:%02d:%02d.%03d(%8d)",
816 strLine.
Format(
"(%8d)", dwTickDiff);
819 m_pLogger->m_lastTick = dwTick;
821 if ( type == Type_Error )
833 m_pLogger->m_WriteLine(fw, strThread + strLine);
835 else if ( (m_pLogger->m_outputDumpLevel) > 0 )
840 m_pLogger->m_WriteLine(fw, strThread + strLine);
843 if ( (m_pLogger->m_outputDumpLevel) == 1 && l > 16 )
850 m_pLogger->m_WriteLine(fw,
CAscii(vs[i]));
866 bool m_PostTraceInfo(EType type, LPCSTR lpszText,
const CByteVector* pvb)
868 if ( m_isPause ) {
return true; }
870 CParamWriteCmd* P =
new CParamWriteCmd(
this);
871 P->dwTick = ::GetTickCount();
872 P->dwThreadId = ::GetCurrentThreadId();
874 if ( lpszText != NULL )
877 P->strText = lpszText;
879 else if ( pvb != NULL )
889 ::GetLocalTime(&(P->tSysTime));
890 return m_file.Command(P);
894 void m_PauseMode(
bool isPause)
899 enum { HEADSIZE = 12 };
903 DWORD m_maxMultiFileCount;
904 EThread m_outputThread;
906 int m_outputDumpLevel;
907 bool m_isInitLastTick;
913 friend class CTraceLogger::CParamWriteCmd;
917#define TFUNC CTraceLogger::CFuncer _TnbFunc_
918#define TFUNC_PARAM _TnbFunc_.Param
919#define TFUNC_RESULT _TnbFunc_.Result
959void TFUNC(LPCTSTR lpszFormatText, ...);
998inline void TLOG_AB(LPCTSTR lpszFormatText, ...)
1000 va_list args; va_start(args, lpszFormatText);
1001 CTraceLogger::Write(CTraceLogger::Type_Absolute, lpszFormatText, args);
1014 va_list args; va_start(args, lpszFormatText);
1015 CTraceLogger::Write(CTraceLogger::Type_Error, lpszFormatText, args);
1028 CTraceLogger::Write(CTraceLogger::Type_Error, size, P);
1040 CTraceLogger::Write(CTraceLogger::Type_Error, vb);
1051inline void TLOG(LPCTSTR lpszFormatText, ...)
1053 va_list args; va_start(args, lpszFormatText);
1054 CTraceLogger::Write(CTraceLogger::Type_Trace, lpszFormatText, args);
1067 CTraceLogger::Write(CTraceLogger::Type_Trace, size, P);
1079 CTraceLogger::Write(CTraceLogger::Type_Trace, vb);
1092 va_list args; va_start(args, lpszFormatText);
1093 CTraceLogger::Write(CTraceLogger::Type_Polling, lpszFormatText, args);
1106 DWORD e = ::GetLastError();
1107 if ( e != ERROR_SUCCESS )
1111 LPCTSTR lpszErr = s;
1112 TLOG( _T(
"API[%s()]失敗 ErrorCode = 0x%08x(%s)"), lpszFunctionName, e, lpszErr);
1121#define _GetLastError(XX) TLASTERROR(_T(XX))
1134 #define TLINE() CTraceLogger::Write(CTraceLogger::Type_Absolute, _T("** %s(%d):"), _T(__FILE__), __LINE__)
1144 #define TFUNC __noop
1145 #define TFUNC_PARAM __noop
1146 #define TFUNC_RESULT __noop
1147 #define TLOG_POL __noop
1149 #define TLOG_DUMP __noop
1150 #define TLOG_DUMPV __noop
1151 #define TLOG_ERR __noop
1152 #define TLOG_ERRDUMP __noop
1153 #define TLOG_ERRDUMPV __noop
1154 #define TLOG_AB __noop
1155 #define TLASTERROR __noop
1165#define TFUNC_(XX) TFUNC XX
1166#define TFUNC_PARAM_(XX) TFUNC_PARAM XX
1167#define TFUNC_RESULT_(XX) TFUNC_RESULT XX
1168#define TLOG_AB_(XX) TLOG_AB XX
1169#define TLOG_ERR_(XX) TLOG_ERR XX
1170#define TLOG_(XX) TLOG XX
1171#define TLOG_POL_(XX) TPOL XX
#define loop_dn(VAR, CNT)
loop構文.
#define loop(VAR, CNT)
loop構文.
開発用に、メモリの状態を文字列にする関数があります。
INT_PTR ReverseFind(TYP t) const
[確認] 検索(後ろから)
void FormatV(const TYP *lpszFormat, va_list V)
[代入] 書式付き文字列代入.
bool IsEmpty(void) const
[確認] 空チェック
CStrT Left(size_t iSize) const
[作成] 範囲取得.
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
static CStrT Fmt(const TCHAR *lpszFormat,...)
[作成] 書式付き文字列作成
INT_PTR Find(TYP t, INDEX iFromIndex=0) const
[確認] 検索.
CStrT FindCut(TYP c, CStrT *_pstrRest=NULL) const
[作成] 切り分け
void Format(const TYP *lpszFormat,...)
[代入] 書式付き文字列代入.
TYP * GetBuffer(size_t iLength=0)
[操作] 書き込みバッファ要求.
void OnCatch(void) const
[表示] 内容表示
virtual size_t GetSize(void) const
[取得] サイズ取得
virtual const TYP * ReferBuffer(void) const
[取得] データアドレス取得
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
virtual size_t SetElements(size_t size, const TYP *P=NULL)
[設定] 複数要素設定.
CStr QueryString(LPCTSTR lpszKey, LPCTSTR lpszDefault=NULL) const
[取得] 文字列情報取得
DWORD QueryDword(LPCTSTR lpszKey, DWORD dwDefault=0) const
[取得] 数値情報取得
#define SINGLETON_CONSTRUCTOR(CLS)
シングルトン作成マクロ
CStrVector DumpData(size_t size, const void *pData, bool canAllDump=true, size_t width=16, bool isUnicode=false)
[作成] バイナリダンプ用文字配列作成.
void TLOG(LPCTSTR lpszFormatText,...)
トレース出力ログ.
void TLOG_DUMP(size_t size, LPCVOID P)
トレース出力ダンプログ.
void TLOG_AB(LPCTSTR lpszFormatText,...)
絶対出力ログ.
void TFUNC(LPCTSTR lpszFormatText,...)
関数ログ.
void TLOG_POL(LPCTSTR lpszFormatText,...)
ポーリング出力ログ.
void TLOG_ERRDUMP(size_t size, LPCVOID P)
エラー出力ダンプログ.
void TLOG_ERRDUMPV(const CByteVector &vb)
エラー出力ダンプログ.
DWORD TLASTERROR(LPCTSTR lpszFunctionName)
LastError出力ログ.
void TLOG_DUMPV(const CByteVector &vb)
トレース出力ダンプログ.
void TLOG_ERR(LPCTSTR lpszFormatText,...)
エラー出力ログ.
void TFUNC_RESULT(LPCTSTR lpszFormatText,...)
リザルトログ.
void TFUNC_PARAM(LPCTSTR lpszFormatText,...)
追加引数ログ.
CStr GetComputerName(void)
[取得] PC名取得
size_t GetLen(LPCSTR lpsz)
[計算] 文字列長計算(ASCII/SJIS用)
TNB::CStrT< char > CAscii
ASCII文字列クラス
DWORD ToDword(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
TNB::CStrT< TCHAR > CStr
文字列クラス
CStr GetProcessPath(void)
[取得] プロセスのパス取得.
void SystemErrorToMessageText(CSimpleStr &_str, DWORD dwError)
[変換] SystemErrorコード文字列化.
#define EXCLUSIVE(CLS)
簡易排他制御マクロ.
virtual LONGLONG Seek(LONGLONG llOffset, ESeekMode eSeek=TOP) const =0
[操作] シーク.
virtual bool CanWrite(void) const =0
[確認] 書込み可能か
virtual void Write(size_t size, LPCVOID P)=0
[保存] 書き込み