linux 使用log4cpp记录项目日志

为什么要用log4cpp记录项目日志

在通常情况下,Linux/UNIX 每个程序在开始运行的时刻,都会打开 3 个已经打开的 stream. 分别用来输入,输出,打印错误信息。通常他们会被连接到用户终端。这 3 个句柄的类型为指向 FILE 的指针。可以被 fprintf、fread等函数使用,他们在程序开始启动后,stdin, stdout, and stderr 的文件描述符是 0, 1 和 2,其它的文件描述符则排在其后。

很多时候会用 printf 打印信息来调试程序,但是如果终端关掉了,那怎么显示 printf 的调试信息呢?log4cpp就可以解决这个问题.

1 log4cpp安装

  • wget https://nchc.dl.sourceforge.net/project/log4cpp/log4cpp-1.1.x%20%28ne
    w%29/log4cpp-1.1/log4cpp-1.1.3.tar.gz
  • tar -zxvf log4cpp-1.1.3.tar.gz
  • cd log4cpp
  • ./configure --prefix=安装路径
  • make
  • make install

2确定 log4cpp 头文件&库

找头文件./log4cpp/include/log4cpp
在这里插入图片描述找到对应的库./log4cpp/src/.libs
在这里插入图片描述

3 log4cpp日志说明

3-1 设置日志信息输出方式

#include <log4cpp/Category.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/OstreamAppender.hh>// 以root的身份将信息输出到 std::cout
//log4cpp::Appender *appender = new log4cpp::OstreamAppender("root",&std::cout);// 以root的身份将信息输出到 log 文件
log4cpp::Appender *appender = new log4cpp::FileAppender("root","test.log");
日志信息appender方式注释
log4cpp::FileAppender输出到文件
log4cpp::RollingFileAppender输出到回卷文件,即当文件到达某个大小后回卷
log4cpp::OstreamAppender输出到一个 ostream 类
log4cpp::RemoteSyslogAppender输出到远程 syslog 服务器
log4cpp::StringQueueAppender内存队列
log4cpp::SyslogAppender本地 syslog
log4cpp::Win32DebugAppender发送到缺省系统调试器
log4cpp::NTEventLogAppender发送到 win 事件日志

日志输出到终端或者文件中实际上是很慢的,会引起 IO 中断,可以输出到内存里 StringQueueAppender,然后从
StringQueueAppender 输出到其它地方,这样线程执行效率是比较高效的。

3-2 设置日志信息输出格式

log4cpp::PatternLayout *patternLayout = new log4cpp::PatternLayout();
patternLayout->setConversionPattern("%d [%p] - %m%n");
appender->setLayout(patternLayout);

patternLayout->setConversionPattern( )支持以下一组格式字符:

日志格式字符注释
%%百分比符号
%c日志类别
%d日期格式:日期格式字符后面可以跟一个日期格式,括在大括号之间的说明符。例如,%d{%\H:%M:%S,%l}%d{%S\d%M%Y%H:%\M:%S,%l}。如果没有给出日期格式说明符,则使用以下式:“Wed Jan 02 02:03:55 1980”。%l表示毫秒。
%m消息
%n特定于平台的行分隔符
%p优先级
%r自创建此布局以来的毫秒
%R自1970年1月1日起的秒数(时间戳)
%u进程启动后的时钟周期
%xNDC
%t线程名称

默认情况下,PatternLayout->ConversionPattern( )设置为“%m%n”。

3-3 设置 日志输出类别(category) 和 日志优先级(priority)

log4cpp::Category &root = log4cpp::Category::getRoot();		//设置在配置文件里
root.setPriority(log4cpp::Priority::NOTICE);
root.addAppender(appender);

日志的级别总共有:
NOTSET < DEBUG < INFO < NOTICE < WARN < ERROR < CRIT < ALERT <FATAL = EMERG。
日志级别的意思是低于该级别的日志不会被记录。

3-4设置 日志操作的宏

#define LOG(__level) 
log4cpp::Category::getRoot() <<log4cpp::Priority::__level << __FILE__ << " " << __LINE__ << ": "

3-5 使用 日志操作的宏 记录日志

LOG(DEBUG) << "i am happy.";
LOG(INFO)  << "oh, you happy, we happy.";
LOG(NOTICE)<< "please do not contact me. ";
LOG(WARN)  << "i am very busy now.";
LOG(ERROR) << "oh, what happed?";

4 使用封装log4cpp(单例)并使用Cmake编译项目

4-0 log4cpp_demo.conf

#定义 rootCategory 的属性
log4cpp.rootCategory=DEBUG, RootLog#定义 RootLog 属性
log4cpp.appender.RootLog                 = RollingFileAppender
log4cpp.appender.RootLog.layout          = PatternLayout
log4cpp.appender.RootLog.layout.ConversionPattern=%d{%m - %d %H:%M:%S %l} [%t][%p]%m%n
log4cpp.appender.RootLog.fileName        =./log4cpp_Loger.log
log4cpp.appender.RootLog.maxFileSize     =268435456 #256MB
log4cpp.appender.RootLog.fileNamePattern =log4cpp_Loger%i.log
log4cpp.appender.RootLog.maxBackupIndex  =256

4-1 Loger.h

#ifndef DISTRIBUTED_LOGGER_H_
#define DISTRIBUTED_LOGGER_H_#include <string>
#include <log4cpp/Category.hh>#define LOG_INFO   Logger::instance()->GetHandle()->info
#define LOG_DEBUG  Logger::instance()->GetHandle()->debug
#define LOG_ERROR  Logger::instance()->GetHandle()->error
#define LOG_WARN   Logger::instance()->GetHandle()->warnclass Logger
{
public:Logger();~Logger();//初始化bool init(const std::string &log_conf_file);//获取单例static Logger* instance() { return &instance_; }//获取使用日志接口log4cpp::Category* GetHandle() { return category_; };protected://对象实例static Logger  instance_;log4cpp::Category* category_;};#endif

4-2 Loger.cpp

#include "Loger.h"
#include <iostream>
#include <log4cpp/Category.hh>
#include <log4cpp/FileAppender.hh>
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/RemoteSyslogAppender.hh>
#include <log4cpp/PropertyConfigurator.hh>Logger  Logger::instance_;
Logger::Logger()
{}Logger::~Logger()
{}bool Logger::init(const std::string& log_conf_file)
{try{//日志输出log4cpp::PropertyConfigurator::configure(log_conf_file);}catch (log4cpp::ConfigureFailure &f){std::cerr << "load log config file" << log_conf_file.c_str() << "failed with result:" << f.what() << std::endl;return false;}category_ = &log4cpp::Category::getRoot();return true;
}

4-3 main.cpp

#include "Loger.h"
#include <iostream>
#include <unistd.h>using namespace std;
int main(int argc, char **argv) {if (argc != 2)//传入参数不合法{printf("Please input format< your process > < .conf file config >!\n");return -1;}Logger* config= Logger::instance();//配置文件加载信息if (!config->init(std::string(argv[1]))) //配置文件加载失败{printf("load %s failed.\n", argv[1]);return -2;}LOG_DEBUG("load %s finsh.",argv[1]);return 0;
}

4-4 CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION  3.5)
#工程名
PROJECT(log4cpp_demo)
#将指定的目录头文件添加到编译器的头文件搜索路径之下
INCLUDE_DIRECTORIES(./third/include)#将指定的目录库文件添加需要链接的库文件目录之下
LINK_DIRECTORIES(./third/lib/log4cpp)#内置变量:CMAKE_SOURCE_DIR 定义了顶级CMakeLists.txt 所在文件夹
#PROJECT_SOURCE_DIR定义了包含project()命令的CmakeLists.txt所在的文件夹
#搜集所有在指定路径下的源文件名,将输出结果储存在指定的变量中
aux_source_directory(${PROJECT_SOURCE_DIR} SOURCE_FILES)#使用给定的源文件,为工程引入一个可执行文件
ADD_EXECUTABLE(log4cpp_demo ${SOURCE_FILES})#用来显示的定义变量(注意:加上-pthread)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}-pthread  -rdynamic -Wall -g3 -m64 -pipe -std=c++0x -lrt -Wno-reorder -Wdeprecated-declarations -fpermissive ")#该指令的作用为目标文件与库文件进行链接
#TARGET_LINK_LIBRARIES(log4cpp_demo log4cpp)
target_link_libraries(log4cpp_demo pthread)
target_link_libraries(${PROJECT_NAME} liblog4cpp.a)
#设置默认安装目录
SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})#安装
INSTALL(TARGETS log4cpp_demo DESTINATION bin)

4-5 编译项目

  • cmake .
  • make

在这里插入图片描述

4-6 执行程序

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/600072.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【保研记录】2023年(24届)SE上岸经历

先开个坑&#xff0c;慢慢填~ 个人信息 学校&#xff1a;某双非 专业&#xff1a;软件工程 第四轮学科评估&#xff1a;无&#xff08;对就是没有等级&#xff09; 排名&#xff1a;1/400 竞赛/荣誉&#xff1a;国奖x2&#xff0c;省三好&#xff0c;大英国二&#xff0c;…

视频剪辑方法:一键批量转码,视频转GIF教程详解

在数字媒体时代&#xff0c;视频剪辑已经成为一项必备技能。无论是专业人士还是普通用户&#xff0c;都要对视频进行剪辑、转码和制作。但是视频剪辑并不简单&#xff0c;要掌握一定的技巧和知识。下面一起来看云炫AI智剪简单易学的视频剪辑方法&#xff1a;一键批量转码和视频…

案例093:基于微信小程序的南宁周边乡村游设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

【MATLAB】【数字信号处理】线性卷积和抽样定理

已知有限长序列&#xff1a;xk1,2,1,1,0,-3, hk[1,-1,1] , 计算离散卷积和ykxk*h(k) 。 程序如下&#xff1a; function [t,x] My_conv(x1,x2,t1,t2,dt) %文件名与函数名对应 %自写的卷积函数 x conv(x1,x2)*dt; t0 t1(1) t2(1); L length(x1) length(x2)-2; t t0:dt…

thinkphp6入门(14)-- 多关联模型查询

背景&#xff1a; 有3个数据表&#xff0c;一个User表&#xff0c;一个Cloth表&#xff0c;一个Shoe表。 Cloth表和Shoe表分别和User表通过user_id关联。 thinkphp 6中如何通过模型查询所有用户&#xff0c;其中包括每个用户的cloth和shoe。 多关联模型查询&#xff1a; 1.…

Flask笔记六之中间件操作

本文首发于公众号&#xff1a;Hunter后端 原文链接&#xff1a;Flask笔记六之中间件操作 与 Django 一样&#xff0c;Flask 也提供了中间件的使用&#xff0c;用于在处理请求之前和之后执行一些公共逻辑 本篇笔记的代码都已经提交到 github 上&#xff0c;可使用下面的操作获取…

Qt6学习笔记:对象树

使用QObject及其子类创建的对象是以对象树的形式来组织的。创建一个QObject对象时若设置一个父对象&#xff0c;它就会被添加到父对象的子对象列表里&#xff0c;一个父对象被删除时&#xff0c;其全部的子对象都会自动删除。QObject类的构造函数里有一个参数用于设置对象的父对…

CommonJS 和 ES6 Module:一场模块规范的对决(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【自学笔记】01Java基础-02java基础语法-02变量、对象与类

1 变量、对象、类 变量&#xff1a; 变量是在编程中用来存储数据的占位符&#xff0c;它具有名称和值。在程序执行过程中&#xff0c;变量的值可以改变。根据作用域和生命周期的不同&#xff0c;变量可分为全局变量、局部变量、类变量&#xff08;静态变量&#xff09;、实例变…

五、书写规则

目录 一、规则举例 三、在规则中使用通配符 四、文件搜寻 五、伪目标 六、多目标 七、静态模式 八、自动生成依赖性 规则包含两个部分&#xff0c;一个是依赖关系&#xff0c;一个是生成目标的方法。 在 Makefile 中&#xff0c;规则的顺序是很重要的&#xff0c;因为&a…

python 数据容器

数据容器概念 一个可以存储多个元素的python数据类型 python有的数据容器 list(列表) tuple(元组) str(字符串) set(集合) dct(字典) 列表 python的列表的数据类型可以是不同的 my_list ["1",123,True,[123,"3333",d,False]]for item in my_list:p…

【uniapp】多规格选择

效果图 VUE <template> <view><view class"wp-80 pd-tb-40 mg-auto"><button type"warn" click"showDrawer(showRight)">筛选</button></view><!-- 筛选-uni-drawer --><uni-drawer ref"s…

Android debug带系统签名

期望是运行直接带系统签名。 gradle 的 android 目录下&#xff1a; signingConfigs {debug {storeFile file("../signAPK/**.jks")storePassword ******keyAlias ******keyPassword ******}release {storeFile file("../signAPK/**.jks")storePassword **…

暗光增强——Zero-DCE网络推理测试

目录 一、Zero-DCE方法1.1 网络优点1.2 网络适用场景1.3 网络不适用场景 二、源码包三、测试四、测试结果五、推理速度六、总结 一、Zero-DCE方法 Zero-DCE&#xff08;Zero-Reference Deep Curve Estimation&#xff09;是一种用于低光照增强的网络。 1.1 网络优点 无需参考…

ClickHouse数据库详解和应用实践

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 概述1.适用场景2.不适用场景 一、核心特性1.完备的DBMS功能2.列式存储与数据压缩 二、安装部署1.在线安装2.离线安装 三、jdbc访问总结 概述 ClickHouse 是一个用于…

你是唯一的 uniq

文章目录 你是唯一的 uniq语法默认无参数统计出现频次仅仅显示重复的行仅仅显示不重复的行更多信息你是唯一的 uniq Linux uniq 命令用于检查及删除文本文件中重复出现的行列,一般与 sort 命令结合使用。 官方定义为: uniq - report or omit repeated lines uniq 可检查文本…

wordpress在界面将站点地址直接修改为https导致上不去问题的解决办法

wordpress在界面将站点地址直接修改为https导致上不去问题的解决办法 #修改数据库yz_options

计算机网络——OSI参考模型

1. OSI模型的基本概念 1.1 定义 OSI&#xff08;开放式系统互联&#xff09;模型是一个用于理解和标准化电信系统或计算机网络功能的概念性的框架&#xff0c;用于描述和标准化不同计算机系统或网络设备间通信的功能。 1.2 OSI模型的性质 这个模型由国际标准化组织&#xff08…

StartAI 生图关键词整理 第一期

最近很多小伙伴向小编反馈“StartAI生图效果很差”&#xff0c;“效果不好”...... AI生图的关键在于是否投喂合适的关键词。往往好的创意需要好的词汇去润色~ 小编立刻决定给小伙伴们整理生图关键词&#xff01;&#xff01;&#xff01;&#xff01; 一、生成菠萝的创意切面…

数据结构之哈希——学习笔记

今天看网课学习了哈希的数据结构&#xff0c;写下这一篇博客记录自己的学习过程。 1.哈希简介&#xff1a; 我们发现某些时候映射到小集合的时候会同时有多个值映射到一个下标里面&#xff0c;所以接下来是这种情况的解决方案1&#xff1a; 我们考虑当两个数字映射之后的结果…