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

来源:互联网 发布:手机淘宝开店认证 编辑:程序博客网 时间:2024/06/09 17:00

以下为源代码,追求的就是简单易用,有两个文件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;
}

原创粉丝点击