在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());

 

 

OSGi中使用log4j NULL 博文链接:https://ouyanggod.iteye.com/blog/1335233 立即下载

相关推荐

神联动:LSTM+卡尔曼滤波!一区大门轻松开!

近来热度飙升,成为时间序列预测和状态估计等领域的香饽饽,非常好发高区!主要在于:这两者结合,不仅能提高模型预测准确性;还能拓展应用场景,为我们的论文创新提供发挥空间,且当下还在蓝海阶段,还不算卷。具体点说:卡尔曼滤波擅长处理线性状态估计和噪声,能使LSTM更好地适应动态环境的变化,减少噪声干扰,降低预测误差。而LSTM通过捕捉长期依赖关系,擅长处理非线性时间序列,能够弥补卡尔曼滤波在这方面的不足,从而把应用场景从传统的状态估计,延伸到金融预测、工业检测、自动驾驶等任务。

2401_82426425的博客 2208

OSGI环境下的log4j日志配置

废话不多说了,log4j相信大家都用过的,现在公司有很多项目的研究都是基于OSGI的,所以我们的日志处理必须换到OSGI环境下去做了。于是相应的 问题也随之而来。其中最主要的问题就是一个classloader的问题。知道OSGI架构原理的都知道OSGI里面的各个Bundle是有独立的 ClassLoader来进行加载的。所以当我们把log4j的配置文件直接放在某个Bundle的classpath下...

zhoufu24 396

Ubuntu22.04安装ROS2 —— ROS2 humble 详细图文教程

本文详细介绍了如何在Ubuntu22.04(Jammy)系统下配置ROS2环境,安装RO2软件包,并验证安装成功。ROS2的版本是Humble Hawksbill。:ROS是一个开源的,提供硬件抽象、设备驱动、库、工具和通信机制,支持模块化开发与集成,广泛用于机器人控制和自动化应用。ROS2 相较于 ROS1 在架构设计、通信机制和平台支持等方面做出了改进。ROS1 采用集中式主节点(Master)进行节点间通信,存在单点故障风险,且实时性和跨平台支持较弱。

weixin_49649078的博客 8807

osgi bundle服务中log4j配置文件

osgi中log4j的配置文件就放在src的根目录就可以了。 log4j.rootLogger=INFO, stdout,file #记住这里千万别忘记写上你的file log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternL...

tiger-hu 358

AquaCrop-OSPy学习笔记02:模型输入设置

AquaCrop-OSPy的输入设置

EWBA_GIS_RS_ER的博客 3692

目标检测之Mask R-CNN(Pytorch):小白动手实现项目

目标检测之Mask R-CNN:小白动手实现项目Pytorch引言Mask R-CNN原理简述代码、注释及详细解释 引言 首先声明本项目的运行环境。操作系统为Windows,编写环境为Anaconda3 + Jupyter Notebook。Pytorch版本为 torch 1.7.1+cu110 、torchvision版本为 0.8.2+cu110,cuda版本为cu100,显卡为Nvidia 2060。 我是目标检测领域的小白,刚刚完成了Pytorch的相关入门学习任务,所以我认为学习本篇博客的基础

dzc_go的博客 1万+

在osgi中应用log4j(二)

 在上一篇中,利用了Proxy和在Bundle中加载jar包的方法,对其他的bundle输出log4j的服务,应用log4j输出日志。但是在其中,是回避了在osgi整个环境中加载log4j的问题。从而带来的问题是,在系统应用的其他的框架,利用log4j输入的日志,无法正确的显示出来,这带来了很多的问题,特别是在系统调试时,因为看不到所用框架的日志,就无法正确的判断系统的运行状况。所以,在osgi的...

沧海一粟 227

视觉SLAM十四讲slambook2示例代码所有依赖库的编译安装教程(VTK、OpenCV3、ceres、Sophus、g2o、Eigen、Pangolin、googletest等)

这是2021年的最后一篇博客~ 新年快乐! 0 准备工作   首先需要先安装cmake编译器: sudo apt-get install cmake   以及,将十四讲的示例代码克隆下来(十四讲的源码地址点击这里): git clone --recursive https://github.com/gaoxiang12/slambook2.git   由于里面的3rdparty文件夹内所有内容都来自于其他github仓库,所以需要加上--recursive参数,不然克隆下来的内容不完整。   如果你.

zeeq的博客 7839

OSGI - Log4j配置

关键字: log4j slf4j 由于OSGi每个Bundle都有自己的独立的类加载器,所以如果将Log4j的配置放到一个Bundle中,是不能被其他Bundle共享的,而且也分散了对log的管理,显然不是太好。 比较理想的作法就是单独建立一个Log Bundle,负责处理日志问题,包括加载、关闭、配置等。由于我的项目中涉及到Jetty、Wicket、Hibern...

xiao_feng68的专栏 294

Python 爬虫实战:手机应用商店评论数据爬取与分析

移动应用市场蓬勃发展,用户的评论数据包含了大量有价值的信息,如用户满意度、功能反馈、改进建议等。通过分析这些评论,我们可以挖掘应用的优缺点,甚至预测用户趋势。由于 Apple App Store 评论是动态加载的,我们使用。本篇博客将详细介绍如何使用 Python 爬取。爬取大量数据时,可能会遇到反爬机制。库获取 Google Play 评论。评论数据是动态加载的,需要使用。

2201_76125261的博客 2322

ClaudeCode入门01-环境安装(小白入门:手把手教你配置,超简单的一种接入方式)

文手把手教你从零搭建 Claude Code 开发环境。针对国内网络现状,我们采用 OpenRouter + Claude Code Router 的方案,支持支付宝/微信充值,无需科学上网即可完成配置。内容涵盖 Node.js 安装(macOS/Windows/Linux)、OpenRouter 注册与充值、Claude Code 和 Router 安装配置,以及一键启动脚本的编写。跟着截图一步步操作,10分钟搞定全部环境!

yueyeguzhuo的专栏 278

Log4j被OSGI撞了一下腰

         自从n多年前使用log4j起,印象中就没有觉得Log4j有什么太折磨人的问题,稍微复杂些的可能就是扩展自己的Appender。       不过这一次是碰到了一个比较棘手的“麻烦”。这个麻烦并不是因为难,而是遇到之前不曾注意到问题,被Log4j不小心撞了一下腰,还挺酸疼的。        之前使用Log4j非常简单,因为大多都是在同一个ClassLoader或Co

游弋在移动互联网的银狐999 4924

三菱FX5U气缸控制功能块(完整ST源代码+示例程序)

如果机器包含100个气缸,我们只需要修改数组的元素数量就可以了,效率非常的高。待续....博途PLC 面向对象系列之“双通气缸功能块“(SCL代码)_plc面向对象-优快云博客文章浏览阅读667次。本文介绍了博途PLC中面向对象编程的应用,重点讲解了双通气缸的功能块设计,包括双通电磁阀功能块、双通气缸的UDT数据类型以及SCL代码实现。同时,对比了双通与单通电磁阀的差异,并讨论了将单通气缸改造为双通气缸的方法,强调了双通气缸在安全性上的优势。

RXXW_Dor的博客 1027

osgi系列之二 集成log4j

osgi

smithdoudou88的专栏 851

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Karaf + OSGI + log4j 实现日志监控

通常我们在项目中手动配置log4j,一般是根据log4j的PropertyConfigurator方法,把log4j的配置文件放在项目根目录下,因为配置文件可以容易找到。 但是本人配置外部log4j的原因是: 1. 在osgi项目中配置log4j文件时,因为是聚合项目,项目打包bundle后不一定可以找到项目根目录下的配置文件 2. 要在karaf容器中发布,并且需要集成日志监控和elk功能,外部...

莫忘、初心 1万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

OSGI整合日志slf4j、log4j、log4j2、logback

OSGI整合日志slf4j、log4j、log4j2、logback方案一:slf4j+ logback1. 说明2. 部署与配置3. 业务模块方案二:log4j1. 说明2. 部署与配置3.业务模块方案三:slf4j+log4j1. 说明2. 部署与配置3. 业务模块方案:slf4j+log4j21. 说明2. 部署与配置3. 业务模块方案六:log4j21. 说明2. 部署与配置3. 业务模块 方案一:slf4j+ logback 1. 说明 slf4j-api、logback-classic、logb

qq_35035468的博客 928

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

log4j2.2 java,java – Log4j2 api在OSGi环境中找不到Log4j2核心

当启动Activator并开始搜索日志插件时,log4j-core包会注册一个bundle监听器,如果找到了什么,它会执行一系列与通常的Logger初始化类似的操作(不是真正的惯用OSGi东西,我不确定它工作,但它似乎至少设置Log4jContextSelector和LoggerContextFactory),只是为了确保它,你安装并启动log4j核心包并验证没有改变?更新:我做了一些测试,发现l...

weixin_29341747的博客 359

OSGI环境下配置log4j日志

转帖:http://www.javaeye.com/topic/100816 废话不多说了,log4j相信大家都用过的,现在公司有很多项目的研究都是基于OSGI的,所以我们的日志处理必须换到OSGI环境下去做了。于是相应的 问题也随之而来。其中最主要的问题就是一个classloader的问题。知道OSGI架构原理的都知道OSGI里面的各个Bundle是有独立的 ClassLoader来进行

波波的专栏 2209
上一篇: 利用struts2 springdm felix实现一个web应用
下一篇: 在osgi容器外应用osgi bundle提供的服务
tkxing
博客等级 码龄19年 1粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值