基于log4cpp的SAR成像软件日志输出

2024-01-14 04:48

本文主要是介绍基于log4cpp的SAR成像软件日志输出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

log4cpp概述

     Log4cpp是一个开源的C++类库,它提供了C++程序中使用日志和跟踪调试的功能,它的优点如下:

  • 提供应用程序运行上下文,方便跟踪调试;
  • 可扩展的、多种方式记录日志,包括命令行、文件、回卷文件、内存、syslog服务器、Win事件日志等;
  • 可以动态控制日志记录级别,在效率和功能中进行调整;
  • 所有配置可以通过配置文件进行动态调整;
  • 多语言支持,包括Java(log4j),C++(log4cpp、log4cplus),C(log4c),python(log4p)等;

本文对应的代码可以在一下链接下载:

Log4cpp使用样例Linux系统C++程序-C++文档类资源-CSDN下载Log4cpp使用样例Linux系统C++程序,包含makefile,可以直接运行。更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/smyounger/37073795

  • 基本组成与原理

     Log4cpp有三个主要的组件:日志类别(Category)、输出源(Appender)和布局(Layout)。这三种类型的组件一起工作使得系统可以根据信息的类型和级别记录它们,并且在运行时控制这些信息的输出格式和输出方式(比如输出到控台,还是输出到文件)。

三个组件的介绍

布局Layout:

        log4cpp的Layout子类(Layout本身是个虚类),一共三个:BasicLayout、PatternLayout和SimpleLayout。其中SimapleLayout并不建议使用,而BaiscLayout过于简单,因此如果程序员不自己扩展Layout的话,就只能使用PatternLayout了,值得庆幸的是,PatternLayout还是比较好用的。

        PatternLayout表示让用户根据类似于C语言printf函数的转换模式来指定输出格式。PatternLayout 支持以下格式字符集:

  1. %% - 一个百分号
  2. %c - 类别,如root, sub1等
  3. %d - 日期。日期格式:
    1. 日期格式字符后面可以跟一个用大括号括起来的日期格式说明符。例如,%d{%H:%M:%S,%l} 或 %d{%d %m %Y %H:%M:%S,%l}。
    2. 如果未给出日期格式说明符,则使用以下格式:“Wed Jan 02 02:03:55 1980”。
    3. 日期格式说明符采用与 ANSI C 函数 strftime 相同的语法,但增加了毫秒的说明符 %l,用零填充以形成 3 位数字。
  4. %m - 消息,即要打印的日志
  5. %n - 平台特定的行分隔符,可以理解成printf()里的换行符
  6. %p - 优先级,debug, info,warn,error等
  7. %r - 自此布局创建以来的毫秒数。
  8. %R - 自 1970 年 1 月 1 日以来的秒数
  9. %u - 进程开始到目前为止的时钟周期数
  10. %x – NDC,成像控制器Name Daemon Controller
  11. %t - 线程名称
  12. 默认情况下,PatternLayout 的 ConversionPattern 设置为“%m%n”。

下面给出了设置不同布局的代码,以及对应的输出,详细的代码见文件夹log4C_main_demo2

布局1

输出结果:

布局2

输出结果:

 布局3

 输出结果

输出源(Appender)

        输出源(Appender)用来输出日志(被layout格式化后)到一些设备上,比如文件、命令行、内存等。也可以定义自己的appender输出日志信息到别的设备上。

Appender可以单独定义优先级:

   Log4cpp中所有可直接使用的Appender列表如下:

  1. log4cpp::IdsaAppender    // 发送到IDS或者
  2. log4cpp::FileAppender    // 输出到文件
  3. log4cpp::RollingFileAppender      // 输出到回卷文件,即当文件到达某个大小后回卷
  4. log4cpp::OstreamAppender    // 输出到一个ostream类
  5. log4cpp::RemoteSyslogAppender // 输出到远程syslog服务器
  6. log4cpp::StringQueueAppender    // 内存队列
  7. log4cpp::SyslogAppender // 本地syslog
  8. log4cpp::Win32DebugAppender   // 发送到缺省系统调试器
  9. log4cpp::NTEventLogAppender    // 发送到win事件日志

  其中SyslogAppender和RemoteSyslogAppender需要与Syslog配合使用,因此这里不介绍。Syslog是类Unix系统的一个核心服务,用来提供日志服务,在Windows系统中并没有直接提供支持,当然可以用相关工具()提供Windows系统中的syslog服务。

IdsaAppender的功能是将日志写入Idsa服务,这里也不介绍。因此主要介绍以下Appender:

  1. log4cpp::FileAppender    // 输出到文件
  2. log4cpp::RollingFileAppender      // 输出到回卷文件,即当文件到达某个大小后回卷
  3. log4cpp::OstreamAppender    // 输出到一个ostream类
  4. log4cpp::StringQueueAppender    // 内存队列
  5. log4cpp::Win32DebugAppender   // 发送到缺省系统调试器
  6. log4cpp::NTEventLogAppender    // 发送到win事件日志

FileAppender和RollingFileAppender

  FileAppender和RollingFileAppender是log4cpp中最常用的两个Appender,其功能是将日志写入文件中。它们之间唯一的区别就是前者会一直在文件中记录日志(直到操作系统承受不了为止),而后者会在文件长度到达指定值时循环记录日志,文件长度不会超过指定值(默认的指定值是10M byte)。

FileAppender的创建函数如下:

FileAppender(conststd::string& name, conststd::string& fileName, bool append = true, mode_t mode = 00644);

参数说明:

  1. 一般仅使用前两个参数,即“名称”和“日志文件名”。
  2. 第三个参数指示是否在日志文件后继续记入日志,还是清空原日志文件再记录。
  3. 第四个参数说明文件的打开方式。

  RollingFileAppender的创建函数如下:

RollingFileAppender(const std::string&name, const std::string&fileName, size_tmaxFileSize =10*1024*1024, unsigned int maxBackupIndex = 1,                        bool append = true,  mode_t mode =00644);

参数说明:

  1. 它与FileAppender的创建函数很类似,但是多了两个参数:
  2. maxFileSize指出了回滚文件的最大值;
  3. maxBackupIndex指出了回滚文件所用的备份文件的最大个数。

        所谓备份文件,是用来保存回滚文件中因为空间不足未能记录的日志,备份文件的大小仅比回滚文件的最大值大1kb。所以如果maxBackupIndex取值为3,则回滚文件(假设其名称是rollwxb.log,大小为100kb)会有三个备份文件,其名称分别是rollwxb.log.1,rollwxb.log.2和rollwxb.log.3,大小为101kb。另外要注意:如果maxBackupIndex取值为0或者小于0,则回滚文件功能会失效,其表现如同FileAppender一样,不会有大小的限制。这也许是一个bug。

使用样例程序见文件夹log4C_main_demo3。

  程序运行后会产生两个日志文件wxb.log和rollwxb.log,以及一个备份文件rollwxb.log.1。wxb.log的大小为7kb,记录了所有100条日志;rollwxb.log大小为2kb,记录了最新的22条日志;rollwxb.log.1大小为6kb,记录了旧的78条日志。

OstreamAppender

  使用C/C++在linux上编程时,如果没有好用的调试工具,就在代码中加入printf语句,将调试信息打印出来。现在有了OstreamAppender,一切都好办了,它可以将日志记入一个流,如果该流恰好是cout,则会在标准控制台上输出。比printf优越的是,除了输出消息外,还可以轻松的输出时间、时钟数、优先级等大量有用信息。

OstreamAppender的使用非常简单,创建一个OstreamAppender的具体方法如下:

log4cpp::OstreamAppender*osAppender=newlog4cpp::OstreamAppender("osAppender", &cout);

 第一个参数指定OstreamAppender的名称,第二个参数指定它关联的流的指针。

StringQueueAppender

在调试多线程程序时,不能随意使用printf。因为printf导致IO中断,会使得本线程挂起,其花费的时间比一条普通指令多数千倍,若多个线程同时运行,则严重干扰了线程间的运行方式。所以调试多线程程序时,最好是将所有调试信息按顺序记入内存中,程序结束时依次打印出来。

StringQueueAppender的功能是将日志记录到一个字符串队列中,该字符串队列使用了STL中的两个容器,即字符串容器std::string和队列容器std::queue,具体如下:

std::queue<std::string> _queue;

_queue变量是StringQueueAppender类中用于具体存储日志的内存队列。StringQueueAppender的使用方法与OstreamAppender类似,其创建函数只接收一个参数“名称”,记录完成后需要程序员自己从队列中取出每条日志。

使用样例程序见文件夹log4C_main_demo4。

程序输出为:

Win32DebugAppender

Win32DebugAppender是一个用于调试的Appender,其功能是向Windows的调试器中写入日志,目前支持MSVC和Borland中的调试器。创建Win32DebugAppender仅需要一个参数“名称”,其使用非常简单,这里不再详细介绍。

NTEventLogAppender

   该Appender可以将日志发送到windows的日志,在运行程序后可以打开windows的计算机管理->系统工具->事件查看器->应用程序。

日志类别(Category)

        Log4cpp中有一个总是可用并实例化好的Category,即根Category。使用log4cpp::Category::getRoot()可以得到根Category。在大多数情况下,一个应用程序只需要一个日志种类(Category),但是有时也会用到多个Category,此时可以使用根Category的getInstance方法来得到子Category。不同的子Category用于不同的场合。

日志的常用优先级:DEBUG < INFO < WARN < ERROR < FATAL

如果配置文件中设置的级别是DEBUG,则任意的log都能打印出来;但如果配置的级别是ERROR,则只有高于ERROR优先级的日志才可以打印出来。

三个组件之间的关系

  • Category和Appender的关系是:多个Appender可以附加到一个Category上,这样一个日志消息可以同时输出到多个设备上。
  • Appender和Layout的关系是:Layout附加在Appender上,appender调用layout处理完日志消息后,记录到某个设备上。

利用配置文件定值日志

除了使用程序编程外,log4cpp还可以使用配置文件定值日志,样例程序见文件夹log4C_main_demo6。

使用方法

软件安装

        从 0.2.0 版本开始,可以在支持它的平台上使用 autoconf 构建 log4cpp。简单地使用下面的指令即可完成编译与安装。

./configure make make check make install

上述指令完成后,将在 /usr/local 下安装 log4cpp。

如果需要在指令的本地路径下安装软件,则请在运行配置时指定 --prefix=<location>

除了通常的 ./configure 选项(如 --prefix )之外,还有其他一些可用选项:

--with-idsa

包括对登录到 IDSA ( http://jade.cs.uct.ac.za/idsa/index.html ) 的支持。这将为您提供一个 IdsaAppender Appender 类。

--with-omnithreads[=<path-to-omniORB>]

使用 omniORB4 的 omniThreads MT 抽象库 (http://www.omniorb.org) 启用多线程支持。configure 期望omnithread 头文件位于<path-to-omniORB>/include 中,而库位于<path-to-omniORB</lib 中,即不在特定于平台的子目录中。必要时创建符号链接。
注意。omn​​iORB4 是必需的: omniORB3 是不够的,因为它缺乏对线程特定数据的足够支持。目前(2002 年 8 月)omniORB4 处于测试阶段,但是大多数情况,特别是线程库似乎相当稳定。

--with-pthreads

使用“pthread”POSIX 线程库启用多线程支持。此选项与 --with-omnithreads 互斥。

--enable-doxyen

通过 Dimitri van Heeschs Doxygen 工具 (http://www.doxygen.org/) 启用 API 文档的生成。如果可以在搜索路径中找到 doxygen,则默认为 yes。

--enable-html-docs

如果启用了 doxygen,让它生成 HTML 格式的文档。

--enable-latex-docs

如果启用了 doxygen,让它生成 LaTeX 格式的文档。

--enable-dot

让 Doxygen 使用 GraphViz ( http://www.graphviz.org )的“点”工具来绘制它的图形。

--disable-remote-syslog

从构建中排除 RemoteSyslogAppender(默认包含)

--disable-smtp

从构建中排除 SmtpAppender(默认包含)

使用样例

使用样例1

来自log4cpp官网:http://log4cpp.sourceforge.net/

Loggersappenders是手动创建和配置的。示例同时使用了函数式日志记录和流式日志记录。

带注释的代码和Linux环境下的makefile见文件夹log4C_main_demo1。

运行结果如下图所示

使用样例2

应用场景:xxxx

日志分成两部分:

  • 第一部分输出到控台上,显示软件运行中的关键信息,如软件处理进程、warnning、error等;
  • 第二部分输出到用户指定的路径上

软件设计思路:

  • 日志包含两部分:控台显示和log文件,因此只需要定义一个Category,并像日志输出到两个Appender:OstreamAppender和FileAppender
  • 其中OstreamAppender的级别为INFO,FileAppender的级别为DEBUG,其中程序的调试信息以DEBUG级别输出

基于以上要求和设计思路,设计的样例程序见文件夹log4C_main_demo5,下载路径如下。程序中只定义一个root日志类别,分别输出到控台和文件。

使用样例3-使用配置文件

应用场景:xxxx

日志分成两部分:

  • 第一部分输出到控台上,显示软件运行中的关键信息,如软件处理进程、warnning、error等;
  • 第二部分输出到用户指定的路径上
  • 日志格式需要按照用户的要求输出,但是用户的要求一直在变化

软件设计思路:

  • 由于用户对日志格式的需求会变化,为了防止每次变换都要重新编译程序,所以优先使用配置文件定制日志;
  • 日志包含两部分:控台显示和log文件,因此只需要定义一个Category,并像日志输出到两个Appender:OstreamAppender和FileAppender
  • 其中OstreamAppender的级别为INFO,FileAppender的级别为DEBUG,其中程序的调试信息以DEBUG级别输出

基于以上要求和设计思路,设计的样例程序见文件夹log4C_main_demo7,下载路径如下。程序中只定义一个root日志类别,分别输出到控台和文件。

       这种方式存在的问题是:每次用户要求修改日志格式时,都需要重新编译代码。为了避免这一问题,这里使用配置文件定义日志格式,使用代码定义日志文件输出路径。

这篇关于基于log4cpp的SAR成像软件日志输出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/603994

相关文章

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

SpringBoot如何使用TraceId日志链路追踪

《SpringBoot如何使用TraceId日志链路追踪》文章介绍了如何使用TraceId进行日志链路追踪,通过在日志中添加TraceId关键字,可以将同一次业务调用链上的日志串起来,本文通过实例代码... 目录项目场景:实现步骤1、pom.XML 依赖2、整合logback,打印日志,logback-sp

Python使用Colorama库美化终端输出的操作示例

《Python使用Colorama库美化终端输出的操作示例》在开发命令行工具或调试程序时,我们可能会希望通过颜色来区分重要信息,比如警告、错误、提示等,而Colorama是一个简单易用的Python库... 目录python Colorama 库详解:终端输出美化的神器1. Colorama 是什么?2.

Ubuntu 怎么启用 Universe 和 Multiverse 软件源?

《Ubuntu怎么启用Universe和Multiverse软件源?》在Ubuntu中,软件源是用于获取和安装软件的服务器,通过设置和管理软件源,您可以确保系统能够从可靠的来源获取最新的软件... Ubuntu 是一款广受认可且声誉良好的开源操作系统,允许用户通过其庞大的软件包来定制和增强计算体验。这些软件

软件设计师备考——计算机系统

学习内容源自「软件设计师」 上午题 #1 计算机系统_哔哩哔哩_bilibili 目录 1.1.1 计算机系统硬件基本组成 1.1.2 中央处理单元 1.CPU 的功能 1)运算器 2)控制器 RISC && CISC 流水线控制 存储器  Cache 中断 输入输出IO控制方式 程序查询方式 中断驱动方式 直接存储器方式(DMA)  ​编辑 总线 ​编辑

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时