posts - 23,  comments - 20,  trackbacks - 0
前段时间自己写了一个日志类  不过是MFC写的   今天闲着没事  就用SDK重写了这个类  算是增加一点可移植性吧...
类的使用也很简单  初始化的时候传递一个日志名称 
然后在需要写日志的地方 直接调用这个对象的WriteLog函数传递一个字符串进去就行了
如果需要时间戳  则调用WriteLogWithTime函数  一样的接口
支持设置日志大小  SetLogSize()   //KB计算
代码很简单  一百来行  不过用着还算挺方便的  下午就用这个日志类找到了一个以前工程中的SQL相关联的BUG 呵呵 

.h文件
/*****************************************************
*文件名称: Log_SDK.h
*功能说明: 使用SDK + STL重写的一个日志类 增加可移植性
*创建时间: 09.10.31
*文件作者: zip
*****************************************************
/
#pragma once
#include 
<string>
using namespace std;

class LogSDK
{
public:
    LogSDK(
string strFileName);
    
~LogSDK(void);
    BOOL InitLogSDK();
    BOOL WriteLog(TCHAR
* pContent);
    BOOL WriteLogWithTime(TCHAR
* pContent);        //每次写一行 且带时间
    BOOL WriteLogAtFirstLine(TCHAR* pContent);    //将最近的日志写在最前面    
    void SetLogSize(int iSize);

private:
    HANDLE m_hFile;
    
string m_strFileName;
    
string m_strFormat; 
    CRITICAL_SECTION m_cs;                
//临界区
    BOOL m_bInit;                            //初始化标志位
    int m_iSize;                                //文件大小    -- KB计算

    
string GetTimeStr();
};

.cpp文件
/***************************************************
*文件名称: Log_SDK.cpp
*功能说明: LogSDK的实现文件
*创建时间: 09.10.31
*文件作者: zip
***************************************************
/
#include 
"StdAfx.h"
#include 
".\log_sdk.h"

LogSDK::LogSDK(
string strFileName)
{
    m_bInit 
= FALSE;
    m_strFileName 
= strFileName;
    m_iSize 
= 20;    //默认20KB
    InitLogSDK();
}

LogSDK::
~LogSDK(void)
{
    CloseHandle(m_hFile);
}

BOOL LogSDK::InitLogSDK()
{    
    m_hFile 
= CreateFile(m_strFileName.c_str() , GENERIC_ALL ,
        FILE_SHARE_WRITE , NULL ,  OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL);
    
if (m_hFile == INVALID_HANDLE_VALUE)
    {
        DWORD dwErrorCode 
= GetLastError();
        TCHAR szErrMsg[
255];
        sprintf(szErrMsg , 
"打开文件失败 , 错误代码:%d" , dwErrorCode);
        
//AfxMessageBox(szErrMsg);
        MessageBox(NULL , szErrMsg , _T("警告") ,IDOK);
        
return FALSE;
    }
    ::InitializeCriticalSection(
&m_cs);    //初始化临界区
    m_bInit = TRUE;
    
return TRUE;
}

//普通的写日志
BOOL LogSDK::WriteLog(TCHAR* pContent)
{
    ASSERT(m_bInit);
    DWORD dwFileLenHigh;
    DWORD dwFileLen 
= GetFileSize(m_hFile , &dwFileLenHigh);
    
if (dwFileLen > (DWORD)m_iSize * 1024)    //文件过大 清空文件
    {
        SetFilePointer(m_hFile , 
0 , NULL , FILE_BEGIN);    //移动文件指针
        SetEndOfFile(m_hFile);//清空文件
    }
    
string strContent(pContent);
    strContent 
+= "\r\n";

    BOOL bRet 
= TRUE;
    ::EnterCriticalSection(
&m_cs);
    SetFilePointer(m_hFile , 
0 , NULL , FILE_END);    //移动到文件末尾
    DWORD dwWriteLen;
    BOOL bSuccess 
= WriteFile(m_hFile , strContent.c_str() ,
        (DWORD)strContent.length() , 
&dwWriteLen , NULL);
    ASSERT(dwWriteLen 
== strContent.length());
    
if (!bSuccess)
    {
        DWORD dwErrorCode 
= GetLastError();
        TCHAR szErrMsg[
255];
        sprintf(szErrMsg , 
"写入日志文件失败 , 错误代码:%d" , dwErrorCode);        
        MessageBox(NULL , szErrMsg , _T(
"发生了严重的错误") , IDOK);
        bRet 
= FALSE;    //此处不用返回  还要释放临界区
    }
    ::LeaveCriticalSection(
&m_cs);

    
return bRet;
}

//带有时间戳的日志
BOOL LogSDK::WriteLogWithTime(TCHAR* pContent)
{
    ASSERT(m_bInit);
    DWORD dwFileLenHigh;
    DWORD dwFileLen 
= GetFileSize(m_hFile , &dwFileLenHigh);
    
if (dwFileLen > (DWORD)m_iSize * 1024)    //文件过大 清空文件
    {
        SetFilePointer(m_hFile , 
0 , NULL , FILE_BEGIN);    
        SetEndOfFile(m_hFile);
//清空文件
    }
    
//strcat(pContent , "\r\n");
    string strContent(pContent);
    strContent 
+= "\r\n";
    strContent.insert(
0 , "  ");
    strContent.insert(
0 , GetTimeStr());

    BOOL bRet 
= TRUE;
    ::EnterCriticalSection(
&m_cs);
    SetFilePointer(m_hFile , 
0 , NULL , FILE_END);    //移动到文件末尾
    DWORD dwWriteLen;
    BOOL bSuccess 
= WriteFile(m_hFile , strContent.c_str() ,
        (DWORD)strContent.length() , 
&dwWriteLen , NULL);
    ASSERT(dwWriteLen == strContent.length());
    if (!bSuccess)
    {
        DWORD dwErrorCode 
= GetLastError();
        TCHAR szErrMsg[
255];
        sprintf(szErrMsg , 
"写入日志文件失败 , 错误代码:%d" , dwErrorCode);        
        MessageBox(NULL , szErrMsg , _T(
"发生了严重的错误") , IDOK);
        bRet 
= FALSE;    //此处不用返回  还要释放临界区
    }
    ::LeaveCriticalSection(
&m_cs);

    
return bRet;
}

//返回格式化的时间字符串
string LogSDK::GetTimeStr()
{
    SYSTEMTIME sys;
    ::GetLocalTime(
&sys);    //获取当前系统时间
    TCHAR szTime[64];
    memset(szTime , 
0 , 64);
    sprintf(szTime , 
"%d-%02d-%02d %02d:%02d:%02d.%03d" , 
        sys.wYear , sys.wMonth , sys.wDay , sys.wHour , sys.wMinute , sys.wSecond , sys.wMilliseconds);
    
return string(szTime);
}

void LogSDK::SetLogSize(int iSize)
{
    m_iSize 
= iSize;
}

也可以算锻炼一下API的操作吧...

posted on 2009-10-31 17:58 李佳 阅读(1106) 评论(1)  编辑 收藏 引用 所属分类: WIN32 应用开发

FeedBack:
# re: 一个简单的日志类 SDK + STL写的[未登录]
2009-12-02 14:36 | expter
日志类不用加锁,看你的代码,直接用singleton,对于一些日志可以看看boost,oege.cugi的写法。。。

  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年3月>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

常用链接

留言簿

随笔分类

随笔档案

文章档案

相册

搜索

  •  

最新评论

阅读排行榜

评论排行榜