body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

github源码地址:https://github.com/meihao1203/log4cpp

#ifndef __MYLOG_H__
#define __MYLOG_H__
#include<iostream>
#include<log4cpp/Category.hh>
#include<log4cpp/Appender.hh>
#include<log4cpp/OstreamAppender.hh>
#include<log4cpp/FileAppender.hh>
#include<log4cpp/RollingFileAppender.hh>
#include<log4cpp/PatternLayout.hh>
#include<log4cpp/Priority.hh>
#include<string>
#include<sstream>
using namespace std;
//using namespace log4cpp;   //为了程序可读性好,下面都自己加上作用域限定
//单例类封装log4cpp
enum myPriority{EMERG,FATAL,ALERT,CRIT,ERROR,WARN,NOTICE,INFO,DEBUG};
class myLog
{
        public:
                static myLog* getInstance();  
                static void destroy();
                void setPriority(myPriority priority);   //myPriority 我把它定义为一种enum类型
                void fatal(const char* msg);
                void error(const char* msg);
                void warn(const char* msg);
                void info(const char* msg);
                void debug(const char* msg);
        private:
                static myLog* _plog;
                log4cpp::Category& rootCategory;
        private:
                myLog();
                ~myLog();
};
/***********************实现(方便引用,就不单独放到一个文件中了)***********************/
myLog* myLog::_plog = NULL;  //静态成员初始化
//构造函数
myLog::myLog():rootCategory(log4cpp::Category::getRoot().getInstance("rootCategory"))
{
        //获取根Category,引用成员必须在成员初始化列表初始化
        //根Category下添加子Category
        log4cpp::OstreamAppender* osAppender = new log4cpp::OstreamAppender("osAppender",&cout);
        log4cpp::PatternLayout* pLayout1 = new log4cpp::PatternLayout();
        pLayout1->setConversionPattern("%d: %p %c %x: %m%n");
        osAppender->setLayout(pLayout1);
        rootCategory.addAppender(osAppender);
        rootCategory.setPriority(log4cpp::Priority::DEBUG);
        //mylog.log会一直记录
        log4cpp::FileAppender* fileAppender = new log4cpp::FileAppender("fileAppender","log");
        log4cpp::PatternLayout* pLayout2 = new log4cpp::PatternLayout();
        pLayout2->setConversionPattern("%d: %p %c %x: %m%n");
        fileAppender->setLayout(pLayout2);
        rootCategory.addAppender(fileAppender);
        rootCategory.setPriority(log4cpp::Priority::DEBUG);
        //mylogrolling.log不超过指定大小,默认10M;这里我设置了5M,备份文件5个
//如果想要用备份带回卷的日志文件记录方式,就把这里的注释去掉
//        log4cpp::RollingFileAppender* rollingfileAppender = new log4cpp::RollingFileAppender(
//                        "rollingfileAppender","logrolling.log",5*1024,5);
//        log4cpp::PatternLayout* pLayout3 = new log4cpp::PatternLayout();
//        pLayout3->setConversionPattern("%d: %p %c %x: %m%n");
//        rollingfileAppender->setLayout(pLayout3);
//        rootCategory.addAppender(rollingfileAppender);
//        rootCategory.setPriority(log4cpp::Priority::DEBUG);
        rootCategory.info("myLog()");
}
inline myLog::~myLog()
{
        rootCategory.info("~mylog()");
        rootCategory.shutdown();  
}
inline void myLog::destroy()
{
        _plog->rootCategory.info("myLog destroy");   //静态函数内部没有隐士传递的this指针,所以必须要用_plog对象指针来调用
        delete _plog;   //delete的处理方式是:先调用析构函数,然后在释放空间;
        //所以可以在析构函数里再向日志里打印信息,然后再关掉rootCategory
}
inline myLog* myLog::getInstance()
{
        if(NULL==_plog)
        {
                _plog = new myLog();
        }
        return _plog;
}
//类对象调用,重新设置rootCategory优先级
inline void myLog::setPriority(myPriority priority)
{
        switch(priority)
        {
                case FATAL:rootCategory.setPriority(log4cpp::Priority::FATAL);break;
                case ERROR:rootCategory.setPriority(log4cpp::Priority::ERROR);break;
                case WARN:rootCategory.setPriority(log4cpp::Priority::WARN);break;
                case INFO:rootCategory.setPriority(log4cpp::Priority::INFO);break;
                case DEBUG:rootCategory.setPriority(log4cpp::Priority::DEBUG);break;
                default:
                           rootCategory.setPriority(log4cpp::Priority::DEBUG);break;
        }
}
inline void myLog::error(const char* msg)
{
        rootCategory.error(msg);
}
inline void myLog::warn(const char* msg)
{
        rootCategory.warn(msg);
}
inline void myLog::info(const char* msg)
{
        rootCategory.info(msg);
}
inline void myLog::debug(const char* msg)
{
        rootCategory.debug(msg);
}
inline void myLog::fatal(const char* msg)
{
        rootCategory.fatal(msg);
}
/***********************myLog类定义完毕***********************/
/***********************定义一些宏,引用的时候直接展开,让myLog使用更方便***********************/
//把要输出的消息拼接上文件名,所在函数名,所在行号;msg是const char*,所以最后用c_str()函数
//__FILE__ __func__ __LINE 这几个宏定义是编译器识别的,__LINE__是int形
//分别是文件名,函数名,所在行号
//防止在函数中调用,声明成内联函数
inline string int2string(int lineNumber)
{
        ostringstream oss;
        oss<<lineNumber;
        return oss.str();
}
#define catMsg(msg) string(msg).append(" {fileName:")\
        .append(__FILE__).append(" functionName:")\
        .append(__func__).append(" lineNumber:")\
        .append(int2string(__LINE__)).append("}").c_str()
//单例类,只有一个对象
myLog* log  = myLog::getInstance();
#define logSetpriority(priority) log->setPriority(priority)
#define logError(msg) log->error(catMsg(msg))
#define logWarn(msg) log->warn(catMsg(msg))
#define logInfo(msg) log->info(catMsg(msg))
#define logDebug(msg) log->debug(catMsg(msg))
#define logFatal(msg) log->fatal(catMsg(msg))
#define logDestroy() myLog::destroy()
#endif

#include"myLog.h"
#include<iostream>
using namespace std;
void func()
{
        logInfo("this is a function");
}
int main()
{
        logInfo("system is running");
        logWarn("system has a warning");
        logError("system has a error");
        logFatal("system has a fatal");
        logSetpriority(ERROR);  //重新设置优先级
        logWarn("warn again");  //Warn的优先级小于ERROR,这条信息将不会被记录
        logSetpriority(DEBUG);  //为了记录下面代码的日志信息,INFO的优先级也是小于ERROR的
        func();
        logDestroy();    //程序结束,销毁myLog对象
        return 0;
}

log4cpp单例类封装的更多相关文章

  1. muduo网络库源码学习————线程本地单例类封装

    muduo库中线程本地单例类封装代码是ThreadLocalSingleton.h 如下所示: //线程本地单例类封装 // Use of this source code is governed b ...

  2. [iOS]封装单例类

    [iOS]封装单例类 今天在学习iOS的SQLite开发,发现在需要使用SQLite的每个视图中,都需要对数据库进行打开或关闭,觉得挺麻烦的:于是在想能否写个单例类对这些操作进行封(因以前一直在使用D ...

  3. Java单例类的简单实现

    对于java新手来说,单例类给我的印象挺深,之前一道web后台笔试题就是写单例类.*.*可惜当时不了解. 在大部分时候,我们将类的构造器定义成public访问权限,允许任何类自由创建该类的对象.但在某 ...

  4. 设置模式之单例模式(附上一个Objective-C编写的播放音乐的单例类)

    在查阅Cocoa Touch开发文档时,会发现框架中随处可见的大量单例类,比如说,UIApplication.NSFileManager 等. UIApplication 框架中极为常用的一个单例类, ...

  5. Singleton单例类模式

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  6. Java线程和多线程(五)——单例类中的线程安全

    单例模式是最广泛使用的创建模式之一.在现实世界之中,诸如Databae的连接或者是企业信息系统(EIS)等,通常其创建都是受到限制的,应该尽量复用已存在对象而不是频繁创建销毁.为了达到这个目的,开发者 ...

  7. 设计模式——懒汉式单例类PK饿汉式单例类

    前言 我们都知道生活中好多小软件,有的支持多IP在线,有的仅仅局限于单个IP在线.为什么这样设计,在软件开发阶段就是,有需求就是发展.这就是软件开发的一个设计模式--懒汉式单例类和饿汉式单例类. 内容 ...

  8. java单例类/

    java单例类  一个类只能创建一个实例,那么这个类就是一个单例类 可以重写toString方法 输出想要输出的内容 可以重写equcal来比较想要比较的内容是否相等 对于final修饰的成员变量 一 ...

  9. iOS中编写单例类的心得

    单例 1.认识过的单例类有哪些: NSUserDefaults.NSNotificationCenter.NSFileManager.UIApplication 2.单例类 单例类某个类在代码编写时使 ...

随机推荐

  1. Django学习笔记之Django ORM Aggregation聚合详解

    在当今根据需求而不断调整而成的应用程序中,通常不仅需要能依常规的字段,如字母顺序或创建日期,来对项目进行排序,还需要按其他某种动态数据对项目进行排序.Djngo聚合就能满足这些要求. 以下面的Mode ...

  2. Django学习笔记之URL标签的使用

    期初用django 开发应用的时候,完全是在urls.py 中硬编码配置地址,在views.py中HttpResponseRedirect()也是硬编码转向地址,当然在template 中也是一样了, ...

  3. CSS Fonts(字体)

    CSS Fonts(字体) 一.serif和sans-serif字体之间的区别 注意: 在计算机屏幕上,sans-serif字体被认为是比serif字体容易阅读. 二.CSS字型 在CSS中,有两种类 ...

  4. Socket 是嘛玩意儿(简单聊聊)

    网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP的封装 ...

  5. Jackson 框架JSON、XML、List、Map直接相互转换

    博客分类: json   参考:http://www.cnblogs.com/hoojo/archive/2011/04/22/2024628.html 在其基础上做了稍微调整 详情见附件 jacks ...

  6. 聊一聊HTML <!DOCTYPE> 标签

    一般一个基本html页面的结构,如下代码所示: <html> <head> <title>我是基本的页面结构</title> </head> ...

  7. 深度学习:Keras入门(二)之卷积神经网络(CNN)【转】

    本文转载自:https://www.cnblogs.com/lc1217/p/7324935.html 说明:这篇文章需要有一些相关的基础知识,否则看起来可能比较吃力. 1.卷积与神经元 1.1 什么 ...

  8. geoserver源码学习与扩展——增加服务接口

    参看:http://www.cnblogs.com/sillyemperor/archive/2011/01/11/1929420.html 上文写的很详细了.

  9. docker教程目录

    为什么要用 Docker 什么是 Docker Docker 镜像 Docker容器的运用 Docker仓库 Docker如何获取镜像 CentOS 安装Docker Docker 列出镜像 Dock ...

  10. 理解OAuth 2.0授权

    一.什么是OAuth 二.什么场景下会用到OAuth授权 三.OAuth 2.0中的4个成员 四.OAuth 2.0授权流程 五.OAuth 2.0授权模式 1.    authorization c ...