在osgi中应用log4j(一)

      Osgi中对于Log的提供,在规范中规定了几种方式,felix也提供了一个LogService实现osgi中的日志输出。在利用这个日志是遇到了两个方面的问题,一是LogService的可管理功能比较弱,二是对于大多数的java开发人员而言,log4j是一个既好用又熟悉的工具了,为什么不继续利用log4j作为自己的日志输出工具呢?

     在Osgi的bundle中,是可以直接利用传统的jar包的!只要把这个jar包放在bundle的classpath中。利用这个方式下面对log4j做了一个proxy的bundle,并发布出来一个日志服务,这样,在其他的bundle中只要引用这个服务,就可以利用熟悉的log4j日志的功能了。

     首先是建立一个bundle:org.osgi.log.proxy,利用eclipse的向导建立就可以了。具体实现的步骤如下:

1、建立一个lib目录,在其中加入log4j和它的支持jar包,然后,把它们加入到MANIFEST.MF文件的bundle-classpath中:

Bundle-ClassPath: lib/log4j-2.1.8.jar,
 .,
 lib/xmlParserAPIs-2.6.2.jar,
 lib/xercesImpl-2.6.2.jar,
 lib/

 

2、建立一个log4j.xml配置文件,放在lib目录下,这样在bundle中log4j才能够找到这个文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
	<appender name="logfile" class="org.apache.log4j.RollingFileAppender">
		<param name="File" value="d:/temp/felix_log4j.log"/>
		<param name="MaxFileSize" value="4096KB"/>
		<param name="MaxBackupIndex" value="20"/>
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d %p [%c] - %m%n"/>
		</layout>
	</appender>
	<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d %p [%c] - %m%n" />
		</layout>
	</appender>

	<logger name = "com.example.time.web.action" additivity = "false">
		<level value = "DEBUG"/>
		<appender-ref ref = "logfile"/>
	</logger>


	<root>
		<level value="DEBUG"/>
		<appender-ref ref="logfile" />
		<appender-ref ref="stdout" />
	</root>

</log4j:configuration>

 3、建立一个log4j日志的代理接口,这个接口是应用这个日志的服务的入口,由于是利用log4j 输出日志,接口中定义的函数和log4j中名字完成一致,只是在输入参数中加了一个日志输出位置,这样可以保证输出的结果和log4j完成相同:

package org.osgi.log.proxy.log;

public interface Log4jProxy {

	public void trace(Object message,String position);
	public void trace(Object message, Throwable t,String position);


	public void debug(Object message,String position);
	public void debug(Object message, Throwable t,String position);

	public void info(Object message,String position);
	public void info(Object message, Throwable t,String position);

	public void warn(Object message,String position);
	public void warn(Object message, Throwable t,String position);

	public void error(Object message,String position);
	public void error(Object message, Throwable t,String position);

	public void fatal(Object message,String position);
	public void fatal(Object message, Throwable t,String position);


}

  4、实现Log4J的代理服务,在一个代理的实现类中,对上面的接口中定义的方法进行实现,完成对于log4j函数的调用。在其中做了一个Classloader的转换,在普通的OSGI环境中,这一步是不需要的,但是在把Felix嵌入到其它的应用中时,并且调用的应用中已经应用了Log4j,这样的转换就非常必要了:

package org.osgi.log.proxy.log.impl;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.osgi.log.proxy.Activator;
import org.osgi.log.proxy.log.Log4jProxy;

public class Log4jProxyImpl implements Log4jProxy {

	private final String TRACE = "trace";
	private final String DEBUG = "debug";
	private final String INFO = "info";
	private final String WARN = "warn";
	private final String ERROR = "error";
	private final String FATAL = "fatal";



	private void executeLog(String level,Object message,String position)
	{
		ClassLoader cl = Thread.currentThread().getContextClassLoader();

		Thread.currentThread().setContextClassLoader(Activator.class.getClassLoader());
		Logger log = LogManager.getLogger(position);

		if(level.equals(this.DEBUG))
		{
			log.debug(message);
		}
		else if(level.equals(this.INFO))
		{
			log.info(message);
		}
		else if(level.equals(this.WARN))
		{
			log.info(message);
		}
		else if(level.equals(this.ERROR))
		{
			log.error(message);
		}
		else if(level.equals(this.FATAL))
		{
			log.error(message);
		}
		else
		{
			log.debug(message);
		}

		Thread.currentThread().setContextClassLoader(cl);

	}

	private void executeLog(String level,Object message,Throwable t,String position)
	{
		ClassLoader cl = Thread.currentThread().getContextClassLoader();

		Thread.currentThread().setContextClassLoader(Activator.class.getClassLoader());
		Logger log = LogManager.getLogger(position);

		if(level.equals(this.DEBUG))
		{
			log.debug(message,t);
		}
		else if(level.equals(this.INFO))
		{
			log.info(message,t);
		}
		else if(level.equals(this.WARN))
		{
			log.info(message,t);
		}
		else if(level.equals(this.ERROR))
		{
			log.error(message,t);
		}
		else if(level.equals(this.FATAL))
		{
			log.error(message,t);
		}
		else
		{
			log.debug(message,t);
		}

		Thread.currentThread().setContextClassLoader(cl);

	}

	@Override
	public void debug(Object message, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.DEBUG, message, position);
	}

	@Override
	public void debug(Object message, Throwable t, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.DEBUG, message, t, position);
	}

	@Override
	public void error(Object message, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.ERROR, message, position);
	}

	@Override
	public void error(Object message, Throwable t, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.ERROR, message, t, position);
	}

	@Override
	public void fatal(Object message, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.FATAL, message, position);
	}

	@Override
	public void fatal(Object message, Throwable t, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.FATAL, message, t, position);
	}

	@Override
	public void info(Object message, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.INFO, message, position);
	}

	@Override
	public void info(Object message, Throwable t, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.INFO, message, t, position);
	}

	@Override
	public void trace(Object message, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.TRACE, message, position);
	}

	@Override
	public void trace(Object message, Throwable t, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.TRACE, message, t, position);
	}

	@Override
	public void warn(Object message, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.WARN, message, position);
	}

	@Override
	public void warn(Object message, Throwable t, String position) {
		// TODO Auto-generated method stub
		this.executeLog(this.WARN, message, t, position);
	}


}

 5、在Activator的Start方法中,注册日志服务:

		context.registerService(Log4jProxy.class.getName(), new Log4jProxyImpl() , null);

 

6、这个日志服务在其他的bundle中的应用方式为:

		ServiceTracker st = new ServiceTracker(context,Log4jProxy.class.getName(),null);
		st.open();
		Log4jProxy log = (Log4jProxy) st.getService();
		log.debug("felix log use call log4jProxy", this.getClass().getName());

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值