网络上很多例子,都不完整,这里整理一下.
由于OSGi每个Bundle都有自己的独立的类加载器,所以如果将Log4j的配置放到一个Bundle中,是不能被其他Bundle共享的,而且也分散了对log的管理,显然不是太好。 比较理想的作法就是单独建立一个Log Bundle,负责处理日志问题,包括加载、关闭、配置等。由于我的项目中涉及到Jetty、Wicket、Hibernate、Spring等这些开源的项目分别使用了Jetty和Wicket使用的是slf4j,而Spring和Hibernate使用了Apache的commons-logging,所以只好使用slf4j作为通用的日志工具,使用Log4j的实现。 因为日志管理属于全局的,所以我将一些全局的东西都打包到一个Bundle中,方便管理。这个Bundle的主要目的就是加载Log4j的配置文件,并管理其生命周期。 首先要添加slf4j-api-1.4.2.jar和slf4j-log4j12-1.4.2.jar,用来让slf4j使用log4j的jar包,当然也不能忘了log4j自身的jar包。新建一个CoreActivator实现BundleActivator接口:
- package test;
- import java.util.Properties;
- import org.apache.log4j.LogManager;
- import org.apache.log4j.PropertyConfigurator;
- import org.osgi.framework.BundleActivator;
- import org.osgi.framework.BundleContext;
- public class CoreActivator implements BundleActivator {
- public void start(BundleContext context) throws Exception {
- Properties props = new Properties();
- props.load(CoreActivator.class.getResourceAsStream("log4j.properties")); //log4j.properties 放到该类的同一目录,避免log4j自动识别,无法手动管理
- PropertyConfigurator.configure(props);
- }
- public void stop(BundleContext context) throws Exception {
- LogManager.shutdown();
- }
- }
log4j配置文件
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Set root category priority to INFO and its only appender to CONSOLE.
log4j.rootCategory=INFO, CONSOLE
#log4j.rootCategory=INFO, CONSOLE, LOGFILE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%p] %l %x %m%n
# LOGFILE is set to be a File appender using a PatternLayout.
#log4j.appender.LOGFILE=org.apache.log4j.FileAppender
#log4j.appender.LOGFILE.File=asf.log
#log4j.appender.LOGFILE.Append=true
#og4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
#log4j.appender.LOGFILE.layout.ConversionPattern=%d [%t] %-5p %c %x - %m%n
#log4j.logger.com.alisoft.aep.sip.analyzer=INFO,CONSOLE,LOGFILE
接下来是重点:
MANIFEST.MF:输出包org.slf4j
其他插件需要用日志服务的,需要依赖日志Bundle即可。
然后:
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- public class TestClass{
- private static Logger log = LoggerFactory.getLogger("TestClass");
- public void doThings(){
- log.info("doThings()");
- }
- }