您的位置:首页 > 编程语言 > C语言/C++

简单易用的日志c++版本

2007-04-16 12:55 274 查看
以下为源代码,追求的就是简单易用,有两个文件log.h和log.cpp,用法太简单,我都懒得说了,呵呵

//log.h

#ifndef _LOG_H_
#define _LOG_H_
/*
LOG Library(WIN98/NT/2000) ver 0.1

Compile by: BC++ 5; C++ BUILDER 4, 5, 6, X; VC++ 5, 6; VC.NET; GCC;

Copyright(c) 2006.5 - 2007.4 llbird wushaojian@21cn.com http://blog.csdn.net/wujian53

Use:
这是一个很简单的日志, 用的是C风格的函数,支持多线程
只要包含本文件,并且把log.cpp文件添加到项目中就可以了
在VC中你可能需要在log.cpp中添加#include "stdafx.h"
具体使用
InitLog();//初始化
LOG("程序启动");
LOG1("%s", str);
DestroyLog();//可有可无

调试时输出可以定义 LOG_TO_STD 或者 LOG_TO_DEBUG
对于C++ Builder
可以使用
LOG(Exception *e or Exception &e);
对于WIN32 API
LOG_LAST_ERROR();
对于_com_error
LOG( _com_error &e);
*/

#include <stdio.h>
#include <time.h>
#include <windows.h>
#include <process.h>
//使用短的原文件名
#define LOG_SHORT_SOURCE_FILE
//使用日志
#define LOG_TO_FILE
//定义标准错误输出设备
#define LOG_STD_DEV stderr
//使用标准输出设备
//#define LOG_TO_STD
//向调试窗口输出
//#define LOG_TO_DEBUG
//输出messagebox
//#define LOG_TO_MESSAGE_BOX
//多线程用临界区
extern CRITICAL_SECTION _g_LogMutex;
//全局日志文件名
extern char _g_LogFileName[MAX_PATH];
extern void InitLog(); //>初始化日志
extern void DestroyLog();//>清除日志
extern BOOL Log(const char* src/*源程序名*/, int line/*行号*/, const char* description/*描述*/);//>新增日志

//格式化日志内容的缓冲区大小
#define DEFAULT_LOG_BUFFER_SIZE 2048
//格式化日志的格式字符串 共四个参数
#define DEFAULT_LOG_FORMAT "%s/t%s(%d)/xd/xa-------------------------------------------------------------------/xd/xa%s/xd/xa/xd/xa"
//多参数格式化的缓冲区大小用于LOG1...
#define DEFAULT_LOG_SPRINTF_BUFFER_SIZE 1024
//定义多参数格式化的缓冲区
#define LOG_SPRINTF_BUFFER char buffer[DEFAULT_LOG_SPRINTF_BUFFER_SIZE]
//记录日志宏 指定文件行号
#define LOG_POS(f, l, arg) Log((f), (l), (arg))
//记录日志宏列表
#define LOG(arg) Log(__FILE__, __LINE__, (arg))
//多参数记录日志宏
#define LOG1(str, p1) { LOG_SPRINTF_BUFFER; sprintf(buffer, (str), (p1)); LOG(buffer); }
#define LOG2(str, p1, p2) {LOG_SPRINTF_BUFFER; sprintf(buffer, (str), (p1), (p2)); LOG(buffer); }
#define LOG3(str, p1, p2, p3) { LOG_SPRINTF_BUFFER; sprintf(buffer, (str), (p1), (p2), (p3)); LOG(buffer); }
#define LOG4(str, p1, p2, p3, p4) { LOG_SPRINTF_BUFFER; sprintf(buffer, (str), (p1), (p2), (p3), (p4));LOG(buffer);}
#define LOG5(str, p1, p2, p3, p4, p5) { LOG_SPRINTF_BUFFER; sprintf(buffer, (str), (p1), (p2), (p3), (p4), (p5)); LOG(buffer);}
//记录windows API错误值
#define LOG_LAST_ERROR() { LOG_SPRINTF_BUFFER; DWORD eid = GetLastError();sprintf(buffer, "Last Error(%d):", eid); int len = strlen(buffer); /
FormatMessage( /
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,/
NULL,/
eid, /
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /
buffer + len,/
DEFAULT_LOG_SPRINTF_BUFFER_SIZE-len-1, /
NULL /
); /
LOG(buffer); /
}/

#if defined(__cplusplus) && defined(_INC_COMDEF)
///新增COM错误信息
inline BOOL Log(const char* src, int line, _com_error &e)
{
char buffer[DEFAULT_LOG_SPRINTF_BUFFER_SIZE];
sprintf(buffer, "_com_error/tCode = %x/tCode meaning = %s/tSource = %s/tDescription = %s",
e.Error(), (LPCSTR)(_bstr_t)e.ErrorMessage(), (LPCSTR)(_bstr_t)e.Source(), (LPCSTR)(_bstr_t)e.Description());
return LOG_POS(src, line, buffer);
}
#endif

///新增VCL异常信息
#if defined(__cplusplus) && defined(__BORLANDC__) && defined(INC_VCL)
inline BOOL Log(const char* src, int line, Exception *e)
{
return LOG_POS(src, line, e->Message.c_str());
}
inline BOOL Log(const char* src, int line, Exception &e)
{
return LOG_POS(src, line, e.Message.c_str());
}
#endif

#endif _LOG_H_

//log.cpp
//MFC
//#include "stdafx.h"
#include "log.h"

CRITICAL_SECTION _g_LogMutex;
char _g_LogFileName[MAX_PATH];

///初始化日志
void InitLog()
{
static char buf[64];
time_t now = time(NULL);
//>指定文件名 每次运行程序生成一个
strftime(_g_LogFileName, 60, ".//log//%Y%m%d.log", localtime(&now));
CreateDirectory(".//log", NULL); //>创建log目录
InitializeCriticalSection(&_g_LogMutex);
}
///清除日志
void DestroyLog()
{
DeleteCriticalSection(&_g_LogMutex);
}
///新增日志
BOOL Log(const char* src/*源程序名*/, int line/*行号*/, const char* description/*描述*/)
{
SYSTEMTIME now;//>时间
char time_buf[30], log_buffer[DEFAULT_LOG_BUFFER_SIZE];
DWORD NumberOfBytesWritten;
HANDLE handle;

GetLocalTime(&now);
//使用全路经文件名还是短文件名
#ifdef LOG_SHORT_SOURCE_FILE
if(src)
{
int len = strlen(src);
while(len>0 && src[len]!='//')
len--;
src = src + (len ? len+1 : 0);
}
#endif

sprintf(time_buf, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
now.wYear, now.wMonth, now.wDay, now.wHour, now.wMinute, now.wSecond, now.wMilliseconds
); //>生成时间字符串
sprintf(log_buffer, DEFAULT_LOG_FORMAT, time_buf, src, line, description);//>格式化

EnterCriticalSection(&_g_LogMutex);
//写入文件
#ifdef LOG_TO_FILE
handle = CreateFile(
_g_LogFileName,
GENERIC_READ | GENERIC_WRITE ,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);

if(!handle)
{
LeaveCriticalSection(&_g_LogMutex);
return FALSE;
}

SetFilePointer(handle, 0, 0, FILE_END);
WriteFile(handle, log_buffer, strlen(log_buffer), &NumberOfBytesWritten, NULL);
SetEndOfFile(handle);
CloseHandle(handle);
#endif
//输出到标准
#ifdef LOG_TO_STD
fprintf(LOG_STD_DEV, "%s", log_buffer);
#endif
//向调试窗口输出
#if defined(LOG_TO_DEBUG)
OutputDebugString(log_buffer);
#endif
//输出messagebox
#if defined(LOG_TO_MESSAGE_BOX)
MessageBox(NULL, log_buffer, "Log", MB_OK);
#endif

LeaveCriticalSection(&_g_LogMutex);

return TRUE;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: