16,472
社区成员
发帖
与我相关
我的任务
分享
// 初始化日志文件
CLoger::Instantiate(LOG_TOFILE, 100, "log\\log.xml"); // 注意整个程序初始化一次就行了
// 调用方法
PrintDbg( LL_DEBUG, HFCLOG("你要输出的日志ID=%d,name=%s\n"), __LINE__, 1, "aaa");
#include "Log.h"
#include <time.h>
#include <stdlib.h>
#include <string>
#ifdef _WIN32
#include <windows.h>
#endif
#ifndef MAX_PATH
#define MAX_PATH 256
#endif
#define LINE_BUFFER_SIZE 102400
//CLog m_log( CLog::ToConsole, 100, "log\\log.log", false );
CLog::CLog( int mode, int level, char * filename, bool append )
: m_lastLogTime(0),
m_filename(NULL),
m_tofile(false),
m_todebug(false),
m_toconsole(false),
m_append(false),
m_hlogfile(NULL)
{
SetFile( filename, append );
SetMode(mode);
SetLevel(level);
char * path = __FILE__;
char * ptr = strrchr( path, '\\' );
if ( ptr != NULL )
{
m_prefix_len = ptr + 1 - path;
m_prefix = new char[m_prefix_len+1];
memcpy( m_prefix, path, m_prefix_len );
m_prefix[m_prefix_len] = '\0';
}
}
CLog::~CLog(void)
{
if ( m_filename != NULL )
free(m_filename);
if ( m_prefix != NULL )
delete [] m_prefix;
CloseFile();
}
void CLog::SetMode( int mode )
{
m_mode = mode;
if ( m_mode & LOG_TODEBUG )
m_todebug = true;
else
m_todebug = false;
if ( m_mode & LOG_TOFILE )
{
if ( !m_tofile )
OpenFile();
}else
{
CloseFile();
m_tofile = false;
}
if ( m_mode & LOG_TOCONSOLE )
{
if ( !m_toconsole )
AllocConsole();
m_toconsole = true;
}else
{
//FreeConsole();
m_toconsole = false;
}
}
int CLog::GetMode( void )
{
return m_mode;
}
void CLog::SetLevel( int level )
{
m_level = level;
}
int CLog::GetLevel( void )
{
return m_level;
}
void CLog::SetStyle( int style )
{
m_style = style;
}
int CLog::GetStyle( void )
{
return m_style;
}
// 设置文件名及追加方式
void CLog::SetFile( const char * filename, bool append )
{
CloseFile();
if ( m_filename != NULL )
free(m_filename);
m_filename = strdup(filename);
m_append = append;
if ( m_tofile )
OpenFile();
}
void CLog::OpenFile()
{
if ( m_filename == NULL )
{
m_todebug = true;
m_tofile = false;
return;
}
m_tofile = true;
m_lastLogTime = 0;
// 如果不为追加在后面,则将原日志文件备份
if ( !m_append )
{
char backupfilename[MAX_PATH];
memset( backupfilename, 0x0, MAX_PATH );
char * ptr = strrchr( m_filename, '.' );
if ( ptr != NULL )
{
int len = (int)(ptr - m_filename);
memcpy( backupfilename, m_filename, len );
time_t t = time(NULL);
tm *local = localtime(&t);
sprintf( backupfilename+len, " %04d-%02d-%02d %02d%02d%02d%s", local->tm_year+1900, local->tm_mon+1, local->tm_mday, local->tm_hour, local->tm_min, local->tm_sec, ptr);
::remove(backupfilename);
::rename(m_filename, backupfilename);
}
}
m_hlogfile = ::fopen(m_filename, "w+");
if ( m_hlogfile == NULL )
{
m_todebug = true;
m_tofile = false;
return;
}
::fseek(m_hlogfile, 0, SEEK_END);
}
void CLog::CloseFile()
{
if ( m_hlogfile != NULL )
{
::fclose(m_hlogfile);
}
m_hlogfile = NULL;
}
void CLog::ReallyPrint( char * format, va_list ap )
{
time_t current = time(NULL);
// 显示当前时间
if ( current != m_lastLogTime )
{
m_lastLogTime = current;
char time_str[32];
strncpy( time_str, ctime(&m_lastLogTime), 24 );
if ( m_style & TIME_INLINE )
//strcpy( &time_str[24], " - " );
strcpy( &time_str[24], "\n" );
else
strcpy( &time_str[24], "\n" );
ReallyPrintLine(time_str);
}
char * format_ptr = format;
char line[LINE_BUFFER_SIZE] = {0};
int len = _vsnprintf( line, LINE_BUFFER_SIZE-2, format_ptr, ap );
//line[LINE_BUFFER_SIZE-2] = '\0';
//int len = (int)strlen(line);
if ( len > 0 && len <= LINE_BUFFER_SIZE-2 && line[len-1] == '\n' )
{
line[len] = '\0';
}
if ( m_style & (NO_FILE_NAMES | NO_TAB_SEPARATOR) )
{
char * ptr = strchr(line, '\t');
if ( ptr != NULL )
{
// 不显示文件名
if ( m_style & NO_FILE_NAMES )
{
ReallyPrintLine(ptr+1);
return;
}else if ( m_style & NO_TAB_SEPARATOR )
*ptr = ' ';
}
}
ReallyPrintLine(line);
}
void CLog::ReallyPrintLine( char * line )
{
mutex_lock l(handle_mutex);
if ( m_todebug )
OutputDebugStringA(line);
if ( m_toconsole )
{
#if _WIN32
DWORD bytes;
WriteConsoleA( GetStdHandle(STD_OUTPUT_HANDLE), line, (DWORD)strlen(line), &bytes, NULL );
#endif
}
if ( m_tofile && (m_hlogfile != NULL) )
{
if ( ::fwrite(line, 1, strlen(line), m_hlogfile) > 0 )
fflush(m_hlogfile);
}
}
////////////////////////////////////////////////////////////////////
CLog *CLoger::itsLog = NULL;
CLoger::CLoger()
{
}
CLoger::~CLoger()
{
UnInstantiate();
}
bool CLoger::Instantiate(int mode, int level, char * filename, bool append)
{
if ( itsLog )
{
delete itsLog;
}
itsLog = new CLog(mode, level, filename, append);
return true;
}
void CLoger::UnInstantiate()
{
if ( itsLog )
{
delete itsLog;
}
itsLog = NULL;
}
CLog &CLoger::GetLog()
{
if ( !itsLog )
{
Instantiate(LOG_TOFILE, LL_MEMORYERROR, "log\\log.log", false);
}
return *itsLog;
}
#if !defined(_hf_log_file_include_132B60A_DC56A5_h)
#define _hf_log_file_include_132B60A_DC56A5_h
#pragma once
#include <stdarg.h>
#include <stdio.h>
#include "../omnithread/mutex.h"
#define HFCLOG(s) (__FILE__ ":" __FUNCTION__ ":%i\t" s)
#pragma warning(disable:4996)
#if defined(_USRDLL)
#ifndef COMMONDLLEXPORT
#ifdef COMMON_EXPORTS
#define COMMONDLLEXPORT __declspec(dllexport)
#else
#define COMMONDLLEXPORT __declspec(dllimport)
#endif
#endif
#else
#define COMMONDLLEXPORT
#endif
#define LOG_TODEBUG 1 // 调试
#define LOG_TOFILE 2 // 写文件
#define LOG_TOCONSOLE 4 // 控制台
class COMMONDLLEXPORT CLog
{
public:
CLog( int mode = LOG_TODEBUG, int level = 1, char * filename = NULL, bool append = false );
~CLog(void);
void SetMode( int mode );
int GetMode( void );
void SetLevel( int level );
int GetLevel( void );
void SetStyle( int style );
int GetStyle( void );
void SetFile( const char * filename, bool append = false );
inline void Print( int level, char * format, ... )
{
if ( level > m_level ) return;
va_list ap;
va_start(ap, format);
ReallyPrint( format, ap );
va_end(ap);
}
private:
void OpenFile();
void CloseFile();
void ReallyPrint( char * format, va_list ap );
void ReallyPrintLine( char * line );
public:
enum Style
{
TIME_INLINE = 0x01,
NO_FILE_NAMES = 0x02,
NO_TAB_SEPARATOR = 0x04
};
private:
bool m_tofile, m_todebug, m_toconsole, m_append;
int m_level;
int m_mode;
int m_style;
FILE *m_hlogfile;
char *m_filename;
char *m_prefix; // 路径
size_t m_prefix_len; // 路径长度
time_t m_lastLogTime;
omni_mutex handle_mutex;
};
class COMMONDLLEXPORT CLoger
{
public:
CLoger();
~CLoger();
static bool Instantiate(int mode = LOG_TODEBUG, int level = 4, char * filename = NULL, bool append = false);
static void UnInstantiate();
static CLog &GetLog();
private:
static CLog *itsLog;
};
// 不记录目志文件
#define LL_NONE 0
// 初始化程序,启动服务
#define LL_STATE 1
// 程序退出,或释放或关闭服务或关闭程序
#define LL_END 1
// 初始化失败
#define LL_INTERR 1
// 操作数据库错误
#define LL_DBERROR 3
// 内存出错
#define LL_MEMORYERROR 4
// socket 错误
#define LL_SOCKERR 7
// 内部警告
#define LL_INTWARN 8
// 网络数据封包
#define LL_NETPACK 8
// 内部信息
#define LL_INTINFO 9
// socket 信息
#define LL_SOCKINFO 10
// 调试信息
#define LL_DEBUG 50
#define PrintDbg CLoger::GetLog().Print
#endif // _hf_log_file_include_132B60A_DC56A5_h