C++ 多线程日志类的使用

#pragma once
/********************************************************************
created:    2014/05/12
created:    12:5:2014   20:27
filename:   d:\MFCUI\Log\Log\Log.h
file path:  d:\MFCUI\Log\Log
file base:  Log
file ext:   h
author:     BJ.y

purpose:
*********************************************************************/

#ifndef LOG_H__
#define LOG_H__

//#ifndef _WINDOWS_
//#include <windows.h>
//
//#endif
#include <afxwin.h>
#include <assert.h>
#include <stdio.h>

#define CONTENT_TITLE 32

#define LOG_INFO(format, ...) do \
{    CLog::GetInstance().Logf(""format"  file:"__FILE__", function:"__FUNCTION__",line: %05d", ##__VA_ARGS__, __LINE__); } while (0)

class CLog
{

private:

    // constructor

    CLog(void);

    //destructor

    ~CLog(void);

    // copy constructor

    CLog(const CLog &);

    //overloaded 

    const CLog & operator = (const CLog &);

private:

    CRITICAL_SECTION  m_Lock;

    // file descriptor

    FILE * m_File;

    //create time

    SYSTEMTIME m_Time;

    // content title

    char szContentTitle[CONTENT_TITLE];

private:

    // get file handle

    FILE * GetFileFp();

public:

    // get instance

    static CLog & GetInstance();

    // log a formate string

    void Logf(const char * lpFormat, ...);

};

#endif // Log_h__
#include "Log.h"
#include <stdarg.h>

//************************************
// Method:    CLog
// FullName:  CLog::CLog
// Access:    private
// Returns:
// Qualifier:
// Parameter: void
//************************************

CLog::CLog(void)
{
    m_File = NULL;
    ::InitializeCriticalSection(&m_Lock);
}

//************************************
// Method:    ~CLog
// FullName:  CLog::~CLog
// Access:    private
// Returns:
// Qualifier:
// Parameter: void
//************************************

CLog::~CLog(void)
{
    ::DeleteCriticalSection(&m_Lock);
}

//************************************
// Method:    GetInstance
// FullName:  CLog::GetInstance
// Access:    public
// Returns:   CLog &
// Qualifier:
//************************************

CLog & CLog::GetInstance()
{
    static CLog m_Log;
    return m_Log;
}

//************************************
// Method:    Logf
// FullName:  CLog::Logf
// Access:    public
// Returns:   void
// Qualifier:
// Parameter: const char * lpFormat
// Parameter: ...
//************************************

void CLog::Logf(const char * lpFormat, ...)
{
    __try
    {
        //enter the lock

        ::EnterCriticalSection(&m_Lock);

        GetFileFp();

        assert(m_File != NULL);

        DWORD dwWrite = 0;

        // write the time
        fwrite(szContentTitle, sizeof(char), strlen(szContentTitle), m_File);

        //::WriteFile(m_File, szContentTitle, strlen(szContentTitle), &dwWrite, NULL);

        // write the content

        va_list args;
        va_start(args, lpFormat);
        vfprintf(m_File, lpFormat, args);
        va_end(args);

        // write the enter under windows

        fwrite("\n\r", sizeof(char), 1, m_File);
        //::WriteFile(m_File, "\r\n", 2, &dwWrite, NULL);

        return;
    }
    __finally
    {
        ::LeaveCriticalSection(&m_Lock);
    }
}

FILE * CLog::GetFileFp()
{
    SYSTEMTIME sys;

    GetLocalTime(&sys);

    sprintf_s(szContentTitle, CONTENT_TITLE, "%02d:%02d:%02d %02d:%02d:%02d:%d->", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds);

    if (sys.wDay == m_Time.wDay)
    {
        return m_File;
    }

    if (m_File != NULL)
    {
        fclose(m_File);
    }

    m_Time = sys;

    char szFileName[32] = { 0 };
    sprintf_s(szFileName, sizeof(szFileName), "%02d-%02d-%02d.txt", m_Time.wYear, m_Time.wMonth, m_Time.wDay);

    fopen_s(&m_File, szFileName, "a+");
    //m_File = CreateFile(szFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS , NULL, NULL);
    //SetFilePointer(m_File, 0, NULL, FILE_END);

    return m_File;
}
时间: 2024-10-17 07:52:38

C++ 多线程日志类的使用的相关文章

[原创]分享一个轻量级日志类

日常开发中,常常会在程序部署到生产环境后发现有些问题,但无法直接调试,这就需要用到日志,本来想找一些开源的完善的日志类来实现,但试了几个都感觉太重.于是意识到一个问题,懒是偷不得的,只好撸起袖子,自己写一个.这个日志类是基于订阅模式的,而且是线程安全的,现在分享给大家,希望能给大家带来帮助. 闲话不多说,直接上代码.代码有两个实现版本(Java与C#),这里放出的是C#. 一共用到三个类:JzgLogs.cs主类,LogBuffer.cs日志缓冲类,LogInfo是用于日志缓冲中做记录的实体类,

c++ 日志类 线程安全+缓存

根据上一次的测试,有缓存的日志类性能会更好.用到了time.h类函数,所以在linux下就要改动一下了,windows环境下写的. 思路采用(参照muduo库的日志,不过认为他线程不安全,和没用缓存,就改造了下) 1.有一个总的缓存,logboss,为一个恶汉模式的单例类,指针对象为智能指针,析构函数讲缓存写入文件. 2.有一个logger类,作为临时缓存,析构函数,将里面的缓存写入总缓存(在总缓存写入的时候加锁).如果缓存超过一定限度,就将前面的缓存写入文件先. void LogBoss::a

怎么样做好日志类的报警监控

上一篇文章写了普通数字类型类型的监控报警,本文谈一下怎么样做好日志类的监控和报警 一.日志类报警的特点 1.接受人员希望直接看到日志的内容: 2.对应技术栈涉及比较广的系统,,一个问题会引发不同主机上面不同系统同时产生日志.举例:openstack 的nova在保存快照时出错,会引起nova-api,galnce-api,horizen同时产生错误日志. 二.遇到的痛点: 1.有很多人想随时查看日志,不同的人想要查看不同的日志: 2.日志类的报警,不适合用微信直接发送内容,原因一是转义麻烦,二是

C++开源日志类

今天想给我的C++项目找一个开源的日志类,用于记录系统日志,结果浪费了半个下午的时间.从网上搜索相关资料,找到以下几个备选方案: 1.log4cplus 下载地址:http://sourceforge.net/projects/log4cplus/files/log4cplus-stable/1.1.0 2.log4cxx 下载地址:http://logging.apache.org/log4cxx/download.html (log4cxx 是由JAVA实现的 log4j 开源的,用C++实

简易的日志类

打日志是开发不可或缺的功能, 它经常比断点好用, 并且可用性更广. 在很久以前, 我总习惯性的printf, cout, 把日志打印在控制台. 直到我发现, 这除了针对性的看日志, 并没有什么乱用. 你的程序提交到测试那里, 程序出现意外, 你不能指望测试给你提供崩溃当时的日志, 也不能及时赶到现场, 发动写轮眼记下原因. 所以, 日志除了打印在屏幕, 还要写日到文件... 1 // 日志写入. 2 class Log { 3 public: 4 // 日志结束符. 5 class End {}

C#日志类记录

每个程序都要和日志打交道.程序日志的质量直接影响了排除问题的难度.普通程序调试信息直接输出控制台,复杂程序则通过文本,xml等方式记录运行时的调试信息.在C#中Diagnostics命名空间下有一个微软提供的专门用于记录信息的TraceSource类.TraceSource的使用方法很简单,只需要4行代码 TraceSource ts = new TraceSource("Code.Main", SourceLevels.All); ts.Listeners.Add(new Conso

WorldWind源码剖析系列:日志类Log

Utility工程中的日志类Log主要用来输出Debug状态下的调试信息.该类的类图如下: 日志类Log中使用到的类和内嵌结构体类型主要有以下这些: public class LogEventArgs : EventArgs//日志事件参数 { public int level; public string category; public string message; public LogEventArgs(int _l, string _c, string _m) { level = _l

2.匿名类,匿名类对象,private/protected/public关键字、abstract抽象类,抽象方法、final关键字的使用,多线程Thread类start方法原理

package com.bawei.multithread; //注意:模板方法我们通常使用抽象类或者抽象方法!这里我们为了方便在本类中使用就没有使用抽象类/抽象方法 public class TemplateThread { //如果这个方法不想被子类或者别人随意改动[这样子类就不能覆写该方法了],这里方法就要设置为final方法 public final void println(String message){ System.out.println("###################

关于日志类Log4j的使用

log4j 的配置 1 #下面定义日志输出级别是 INFO,并且配置了2个输出目的地,一个是A3,一个是console 2 3 log4j.rootLogger = INFO,A3,CONSOLE 4 5 #日志最低的输出级别 6 log4j.appender.A3.Threshold=INFO 7 log4j.appender.A3.encoding=UTF-8 8 #每天产生一个文件DailyRollingFileAppender 9 log4j.appender.A3 = org.apac