`
qimo601
  • 浏览: 3439271 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

【原创】自定义Appender类,输出DCMTK日志

阅读更多

就像DCMTK官方论坛说的那个问题一样:问题:自定义Appender输出DCMTK的oflog

 

DCMTK日志输出类

大家都知道:DCMTK只提供下面四个日志输出类。

FileAppender: Appends log events to a file.(将DCMTK日志输出到一个文件中)

ConsoleAppender:ConsoleAppender appends log events to STD_NAMESPACE cout or STD_NAMESPACE cerr using a layout specified by the user.(将DCMTK日志输出到控制台cmd)

log4cplus::NullAppender:Appends log events to ......(不输出,空的)

SocketAppender:Sends spi::InternalLoggingEvent objects to a remote a log server.(将该日志事件发送给远程服务器)

 

因为我需要在自己的Qt Gui项目中也输出DCMTK日志,供系统测试或者通过我项目的日志模块登记到数据库、文件中。总之我需要把DCMTK的日志模块集成到自己的Gui项目中。于是我自定义了一个GuiAppender类。

 

GuiAppender:

实现将DCMTK日志事件捕获,并将日志输出在VS2008的Debug窗口中,也可以后期供调用。

 

 

 

 

实现源码

我的GuiAppender类 源码

 

 

#ifndef GUIAPPENDER_H
#define GUIAPPENDER_H

#include "dcmtk/oflog/config.h"
#include "dcmtk/oflog/appender.h"
#include "dcmtk/oflog/helpers/property.h"
#include <sstream>
namespace log4cplus 
{

	class GuiAppender : public Appender
	{

	public:
		GuiAppender();
		GuiAppender(const log4cplus::helpers::Properties& properties, log4cplus::tstring& error);
		virtual ~GuiAppender();

		// Methods
		virtual void close();

	protected:
		virtual void append(const log4cplus::spi::InternalLoggingEvent& event);
		//声明一个ostringsteam对象
		STD_NAMESPACE ostringstream outString ;
	private:
		// Disallow copying of instances of this class
		GuiAppender(const GuiAppender&);
		GuiAppender& operator=(const GuiAppender&);

	};
} // end namespace log4cplus
#endif // GUIAPPENDER_H

 

 

#include "GuiAppender.h"
#include <string>
#include <QDebug>
#include <QString>
log4cplus::GuiAppender::GuiAppender()
{

}
log4cplus::GuiAppender::GuiAppender(const log4cplus::helpers::Properties& properties, tstring&)
: Appender(properties)
{

}

log4cplus::GuiAppender::~GuiAppender()
{

}
void
log4cplus::GuiAppender::close()
{
}

// This method does not need to be locked since it is called by
// doAppend() which performs the locking
void
log4cplus::GuiAppender::append(const spi::InternalLoggingEvent& event)
{
	//格式化输入DCMTK日志
	layout->formatAndAppend(outString, event);
	//获取DCMTK日志字符串流
	STD_NAMESPACE string m = outString.str();
	//将C++标准字符串流,转换成QString
	QString t = QString::fromStdString(m);
	//输出调试信息
	qDebug() << t;
        //清空
        outString.str("");
}
 

 

 

主程序测试。

 

 

/* 
 * 
 *  Copyright (C) 2011-2012, OFFIS e.V. 
 *  All rights reserved.  See COPYRIGHT file for details. 
 * 
 *  This software and supporting documentation were developed by 
 * 
 *    OFFIS e.V. 
 *    R&D Division Health 
 *    Escherweg 2 
 *    D-26121 Oldenburg, Germany 
 * 
 * 
 *  Module:  dcmnet 
 * 
 *  Author:  Michael Onken 
 * 
 *  Purpose: Test for move feature of the DcmSCU class 
 */ 

#include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */ 
#include "dcmtk/dcmnet/diutil.h" 
#include "DcmTestSCU.h"
#include <QtGui/QApplication>
#include <QDebug>
#include "dcmtk/oflog/oflog.h"
#include "GuiAppender.h"

#define OFFIS_CONSOLE_APPLICATION "testscu" 
 
static OFLogger echoscuLogger = OFLog::getLogger("dcmtk.apps." OFFIS_CONSOLE_APPLICATION); 
 
static char rcsid[] = "$dcmtk: " OFFIS_CONSOLE_APPLICATION " v" 
  OFFIS_DCMTK_VERSION " " OFFIS_DCMTK_RELEASEDATE " $"; 
 
// our application entity title used for calling the peer machine 
#define APPLICATIONTITLE     "TEST-SCU" 
 
// host name of the peer machine  "www.dicomserver.co.uk"
#define PEERHOSTNAME         "10.3.2.84" 
 
// TCP/IP port to connect to the peer machine "11112"
#define PEERPORT 5104 
 
// application entity title of the peer machine 
#define PEERAPPLICATIONTITLE "MOVESCP" 
 
// MOVE destination AE Title 
#define MOVEAPPLICATIONTITLE "TEST-SCU" 

#define QRResponse FINDResponse
 
static Uint8 findUncompressedPC(const OFString& sopClass, 
                                DcmSCU& scu) 
{ 
  Uint8 pc; 
  pc = scu.findPresentationContextID(sopClass, UID_LittleEndianExplicitTransferSyntax); 
  if (pc == 0) 
    pc = scu.findPresentationContextID(sopClass, UID_BigEndianExplicitTransferSyntax); 
  if (pc == 0) 
    pc = scu.findPresentationContextID(sopClass, UID_LittleEndianImplicitTransferSyntax); 
  return pc; 
} 
 
// ******************************************** 
 
int main(int argc, char *argv[]) 
{ 
	QApplication a(argc, argv);	
	/* Setup DICOM connection parameters */ 
	OFLog::configure(OFLogger::DEBUG_LOG_LEVEL); 
	
	OFLOG_DEBUG(echoscuLogger, "OFLOG_DEBUG");


	/* specify log pattern */
	OFauto_ptr<log4cplus::Layout> layout(new log4cplus::PatternLayout("%D{%Y-%m-%d %H:%M:%S.%q} %5p: %m%n"));

	//建立Gui日志输出类
	log4cplus::SharedAppenderPtr guiAppender(new log4cplus::GuiAppender());
	guiAppender->setLayout(layout);
	//获取全局日志对象
	log4cplus::Logger log = log4cplus::Logger::getRoot();
	//去除所有日志输出类
	log.removeAllAppenders();
	//加入Gui输出类
	log.addAppender(guiAppender);
	//设置日志输出层
	log.setLogLevel(OFLogger::INFO_LOG_LEVEL);
	//测试输出一个error日志
	OFLOG_ERROR(log, "There are six log levels and each provides a OFLOG_level() macro");



	//继续测试,输出DCMTK C-Echo动作产生的INFO

	//后面是DCMTK的DcmNet模块中 网络通信的测试,大家不需要了解
	DcmTestSCU scu; 
	// set AE titles 
	scu.setAETitle(APPLICATIONTITLE); 
	scu.setPeerHostName(PEERHOSTNAME); 
	scu.setPeerPort(PEERPORT); 
	scu.setPeerAETitle(PEERAPPLICATIONTITLE); 
	// Use presentation context for FIND/MOVE in study root, propose all uncompressed transfer syntaxes 
	OFList<OFString> ts; 
	ts.push_back(UID_LittleEndianExplicitTransferSyntax); 
	ts.push_back(UID_BigEndianExplicitTransferSyntax); 
	ts.push_back(UID_LittleEndianImplicitTransferSyntax); 
	scu.addPresentationContext(UID_FINDStudyRootQueryRetrieveInformationModel, ts); 
	scu.addPresentationContext(UID_MOVEStudyRootQueryRetrieveInformationModel, ts); 
	scu.addPresentationContext(UID_VerificationSOPClass, ts); 

	/* Initialize network */ 
	OFCondition result = scu.initNetwork(); 
	if (result.bad()) 
	{ 
		DCMNET_ERROR("Unable to set up the network: " << result.text()); 
		return 1; 
	} 
 
	/* Negotiate Association */ 
	result = scu.negotiateAssociation(); 
	if (result.bad()) 
	{ 
		DCMNET_ERROR("Unable to negotiate association: " << result.text()); 
		return 1; 
	} 
 
	/* Let's look whether the server is listening: 
	 Assemble and send C-ECHO request 
	*/ 
	result = scu.sendECHORequest(0); 
	if (result.bad()) 
	{ 
		DCMNET_ERROR("Could not process C-ECHO with the server: " << result.text()); 
		return 1; 
	} 
 
	scu.closeAssociation(DCMSCU_RELEASE_ASSOCIATION);

	return a.exec();
}
 

 

实现结果

最终结果,将DCMTK日志输出到VS2008的Debug窗口中。

 

 

------------------------------------

 

柳北风儿

http://qimo601.iteye.com

【原创】自定义Appender类,输出DCMTK日志

------------------------------------

  • 大小: 9.5 KB
  • 大小: 115.6 KB
0
2
分享到:
评论

相关推荐

    log4net自定义Appender

    2. **继承自抽象类AppenderSkeleton**:自定义Appender需要继承自Log4net的`AppenderSkeleton`类,这个基类已经为我们提供了一些基本功能,如初始化、关闭、过滤和日志事件处理。 3. **覆盖必要方法**: - `Append...

    log4j自定义日志文件名及日志输出格式

    当我们面对特定项目需求,比如需要自定义日志文件名和日志输出格式时,Log4j同样提供了相应的解决方案。 首先,让我们深入理解如何自定义日志文件名。默认情况下,Log4j的日志文件名通常是固定的或者基于时间戳生成...

    logjs前端日志工具提供简易的API可以通过配置level和appender来输出日志

    "logjs" 是一个专为前端设计的日志工具库,它的主要功能是提供简单易用的API,让开发者可以方便地根据需要配置日志级别(level)和输出方式(appender),以便于调试和监控应用状态。 首先,让我们深入了解一下**...

    (转)如何自建appender扩展Log4j框架

    然而,这些可能无法满足所有特定场景的需求,因此我们可以通过创建自定义Appender来实现更个性化的日志处理。 要创建自定义Appender,我们需要遵循以下步骤: 1. **定义Appender类**:首先,创建一个继承自`org....

    扩展logback将日志输出到Kafka实例扩展源码

    标题中的“扩展logback将日志输出到Kafka实例扩展源码”指的是在Java应用程序中,使用logback作为日志框架,并通过自定义appender(输出模块)将日志信息发送到Apache Kafka的消息队列中。Logback是SLF4J(Simple ...

    log4j输出多个自定义路径的日志文件小例子

    要实现输出多个自定义路径的日志文件,我们需要在Log4j的配置文件(通常是`log4j.properties`或`log4j.xml`)中定义多个Appender。Appender是Log4j中负责将日志信息输出到指定目的地的组件,例如文件、控制台、网络...

    log4j按照不同appender生成日志例子

    在Log4j中,Appender是负责将日志信息输出到特定目的地的组件,如控制台、文件、网络、数据库等。通过配置多个Appender,我们可以让日志信息分散存储,便于管理和分析。 要实现按接口生成各自日志文件的目标,我们...

    Java自定义日志工具类

    Java自定义日志工具类是Java开发中一个重要的实践,它可以帮助开发者记录应用程序运行过程中的信息,便于调试、排查问题和后期分析。日志工具类通常包含多种级别(如DEBUG, INFO, WARN, ERROR, FATAL)以适应不同...

    logback+slf4j使用

    自定义Appender允许开发者根据特定需求定制日志输出的方式,例如发送邮件、写入特殊格式的文件或者将日志推送到远程服务器。 以下是使用logback+slf4j自定义Appender的详细步骤: 1. **创建Appender类**:首先,你...

    java自定义日志输出文件(log4j日志文件输出多个自定义日志文件)

    要创建多个自定义日志文件,你需要定义多个`Appender`,并为每个`Appender`指定不同的日志级别、输出格式和输出路径。 以下是一个基础的Log4j配置示例,它将日志同时输出到控制台和名为`test.log`的文件: ```...

    Log4Cpp日志输出至文件组件最佳实践

    PatternLayout允许你自定义输出格式,如日期、线程ID、日志级别等。 ```cpp LayoutPtr layout(new PatternLayout("%d{ISO8601} - %p - %c - %m%n")); // 例如,按照ISO8601时间格式、级别、logger名、消息输出 ...

    Log4j扩展的一个按天滚动的appender类,同时支持动态日志

    `Log4j`是一个广泛使用的Java日志框架,它提供了灵活的日志配置和多种Appender(日志输出器),使得开发者可以方便地控制日志的输出。标题提到的是一个针对`Log4j`的扩展,名为`DayRollingFileAppender`,它是一个按...

    log4j(二):动态配置日志输出路径

    Logger负责生成日志事件,Appender决定这些事件如何被输出(例如,写入文件、发送邮件或显示在控制台),而Layout则决定了日志事件的具体格式。 在Log4j的配置文件中,通常使用.properties或.xml格式。在这个例子中...

    扩展logback将日志输出到Kafka实例源码

    2. **配置Logback**:创建一个名为`logback.xml`的配置文件,定义一个Appender(输出器)来指定Kafka作为日志的目标。你需要配置Kafka的topic、服务器地址(bootstrap.servers)以及其它相关参数,例如序列化器...

    log4j输出日志到flume

    在"log4j输出日志到flume"的例子中,我们需要在Log4j配置文件中设置一个自定义的Appender(输出端),这个Appender将会把日志发送到Flume。一个基本的配置示例如下: ```properties # Log4j配置示例 log4j.root...

    重定向log4j日志到jtextarea

    1. **创建自定义Appender**:你需要继承Log4j的AppenderSkeleton类,并实现其必要的方法,如`append()`。在这个方法中,你可以获取到日志事件(LoggingEvent),并从中提取出日志信息。 2. **设置Layout**:根据...

    log4net日志管理(自定义字段,写数据库、文本两种模式)

    在代码中,可以创建一个自定义的类(如`LogInfo`),包含这些字段,然后在日志事件发生时,实例化这个类并填充相关信息。这样,日志信息不仅包含默认的日志级别(如DEBUG、INFO、WARN、ERROR、FATAL),还能包含项目...

    log4cplus开源的C++日志框架

    如果你需要自定义日志的输出方式或格式,可以继承`log4cplus::Appender`和`log4cplus::Layout`类,实现自己的功能。例如,你可以创建一个将日志发送到邮件的Appender,或者创建一个格式化的Layout,使日志更易读。 ...

    Log4j分包输出日志

    Logger负责生成日志事件,Appender决定日志信息将被输出到哪里,而Layout则控制日志事件的格式。 分包日志输出是Log4j的一个高级特性,允许我们根据类所在的包或子包来定制不同的日志级别和输出策略。例如,我们...

    spark通过kafka-appender指定日志输出到kafka引发的死锁问题

    标题中的“spark通过kafka-appender指定日志输出到kafka引发的死锁问题”指出,在使用Apache Spark并配置Kafka-Appender(一个Log4j的插件)将Spark任务的日志输出到Kafka时,可能会遇到死锁的问题。这个问题可能...

Global site tag (gtag.js) - Google Analytics