Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xorg.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/LogController.java323
-rw-r--r--org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicActivator.java287
-rw-r--r--org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProvider.java23
-rwxr-xr-xorg.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationChangeListener.java25
-rw-r--r--org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationProvider.java27
-rw-r--r--org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapperTests.java71
6 files changed, 460 insertions, 296 deletions
diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/LogController.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/LogController.java
new file mode 100755
index 0000000..b7db7a2
--- /dev/null
+++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/LogController.java
@@ -0,0 +1,323 @@
+/*******************************************************************************
+ * Copyright (c) 2011 SAP AG
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Hristo Iliev, SAP AG - initial contribution
+ *******************************************************************************/
+package org.eclipse.virgo.medic.impl;
+
+import org.eclipse.virgo.medic.dump.DumpGenerator;
+import org.eclipse.virgo.medic.dump.impl.DumpContributorPublisher;
+import org.eclipse.virgo.medic.dump.impl.StandardDumpContributorResolver;
+import org.eclipse.virgo.medic.dump.impl.StandardDumpGenerator;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.medic.eventlog.EventLoggerFactory;
+import org.eclipse.virgo.medic.eventlog.impl.BundleSearchingPropertyResourceBundleResolver;
+import org.eclipse.virgo.medic.eventlog.impl.EventLoggerServiceFactory;
+import org.eclipse.virgo.medic.eventlog.impl.StandardLocaleResolver;
+import org.eclipse.virgo.medic.eventlog.impl.logback.LogBackEventLoggerFactory;
+import org.eclipse.virgo.medic.impl.config.ConfigurationChangeListener;
+import org.eclipse.virgo.medic.impl.config.ConfigurationProvider;
+import org.eclipse.virgo.medic.log.ConfigurationPublicationFailedException;
+import org.eclipse.virgo.medic.log.DelegatingPrintStream;
+import org.eclipse.virgo.medic.log.LoggingConfigurationPublisher;
+import org.eclipse.virgo.medic.log.impl.*;
+import org.eclipse.virgo.medic.log.impl.config.*;
+import org.eclipse.virgo.medic.log.impl.logback.DelegatingContextSelector;
+import org.eclipse.virgo.medic.log.impl.logback.JoranLoggerContextConfigurer;
+import org.eclipse.virgo.medic.log.impl.logback.LoggerContextConfigurer;
+import org.eclipse.virgo.medic.log.impl.logback.StandardContextSelectorDelegate;
+import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.bridge.SLF4JBridgeHandler;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Handler;
+import java.util.logging.Logger;
+
+public class LogController implements ConfigurationChangeListener {
+
+ private static final String LOGGER_NAME_SYSERR = "System.err";
+
+ private static final String LOGGER_NAME_SYSOUT = "System.out";
+
+ private static final String LOGGER_NAME_SYSERR_DELEGATE = "delegating.System.err";
+
+ private static final String LOGGER_NAME_SYSOUT_DELEGATE = "delegating.System.out";
+
+ private static final String PROPERTY_MEDIC_CONFIG_PATH = "org.eclipse.virgo.medic.log.config.path";
+
+ private static final String DEFAULT_CONTEXT_SELECTOR = "ch.qos.logback.classic.selector.DefaultContextSelector";
+
+ private static final String PROPERTY_LOGBACK_CONTEXT_SELECTOR = "logback.ContextSelector";
+
+ private volatile StandardDumpGenerator dumpGenerator;
+
+ private volatile LogBackEventLoggerFactory eventLoggerFactory;
+
+ private volatile DumpContributorPublisher dumpContributorPublisher;
+
+ private volatile PrintStream sysOut = System.out;
+
+ private volatile PrintStream sysErr = System.err;
+
+ private PrintStream delegatingSysOut = new StandardDelegatingPrintStream(System.out);
+
+ private PrintStream delegatingSysErr = new StandardDelegatingPrintStream(System.err);
+
+ private ServiceRegistration<?> delegatingSysOutRegistration;
+ private ServiceRegistration<?> delegatingSysErrRegistration;
+
+ private ServiceRegistration<?> sysOutRegistration;
+ private ServiceRegistration<?> sysErrRegistration;
+
+ private volatile ExecutionStackAccessor stackAccessor;
+
+ private volatile ConsoleHandler javaConsoleHandler;
+
+ private static final List<String> DEFAULT_LOGGING_PACKAGES = Arrays.asList(//
+ "org.apache.commons.logging",//
+ "org.apache.log4j",//
+ "org.slf4j",//
+ "org.slf4j.impl",//
+ "org.eclipse.virgo.medic.log",//
+ "org.eclipse.virgo.medic.log.impl",//
+ "org.eclipse.virgo.medic.log.impl.logback");
+
+ private BundleContext bundleContext;
+ private ConfigurationProvider configurationProvider;
+ private ServiceRegistrationTracker registrationTracker;
+
+ public LogController(BundleContext ctx, ConfigurationProvider cfgProvider, ServiceRegistrationTracker regTracker) throws ConfigurationPublicationFailedException {
+ this.bundleContext = ctx;
+ this.configurationProvider = cfgProvider;
+ this.registrationTracker = regTracker;
+
+ StandardContextSelectorDelegate delegate = createContextSelectorDelegate(bundleContext);
+ registrationTracker.track(bundleContext.registerService(BundleListener.class.getName(), delegate, null));
+ DelegatingContextSelector.setDelegate(delegate);
+
+ StandardLoggingConfigurationPublisher loggingConfigurationPublisher = new StandardLoggingConfigurationPublisher(bundleContext);
+ registrationTracker.track(bundleContext.registerService(LoggingConfigurationPublisher.class.getName(), loggingConfigurationPublisher, null));
+
+ publishDefaultConfigurationIfAvailable(bundleContext, loggingConfigurationPublisher);
+
+ System.setProperty(PROPERTY_LOGBACK_CONTEXT_SELECTOR, DelegatingContextSelector.class.getName());
+
+ this.stackAccessor = new SecurityManagerExecutionStackAccessor();
+
+ this.sysOut = System.out;
+ this.sysErr = System.err;
+ }
+
+ public void dumpStart() {
+ this.dumpGenerator = new StandardDumpGenerator(new StandardDumpContributorResolver(bundleContext), configurationProvider, this.eventLoggerFactory.createEventLogger(bundleContext.getBundle()));
+ registrationTracker.track(bundleContext.registerService(DumpGenerator.class.getName(), this.dumpGenerator, null));
+
+ this.dumpContributorPublisher = new DumpContributorPublisher(bundleContext);
+ this.dumpContributorPublisher.publishDumpContributors();
+ }
+
+ public void dumpStop() {
+ if (this.dumpGenerator != null) {
+ this.dumpGenerator.close();
+ }
+
+ if (this.dumpContributorPublisher != null) {
+ this.dumpContributorPublisher.retractDumpContributors();
+ }
+ }
+
+ public void logStart() throws ConfigurationPublicationFailedException {
+ Dictionary<String, String> configuration = configurationProvider.getConfiguration();
+
+ updateLogConfiguration(configuration);
+
+ SLF4JBridgeHandler.install();
+ if (!Boolean.valueOf(configuration.get(ConfigurationProvider.KEY_ENABLE_JUL_CONSOLE_HANDLER))) {
+ disableJulConsoleHandler();
+ }
+ }
+
+ public void logStop() {
+ System.setProperty(PROPERTY_LOGBACK_CONTEXT_SELECTOR, DEFAULT_CONTEXT_SELECTOR);
+
+ DelegatingContextSelector.setDelegate(null);
+
+ if (this.sysOut != null) {
+ System.setOut(this.sysOut);
+ }
+
+ if (this.sysErr != null) {
+ System.setErr(this.sysErr);
+ }
+
+ SLF4JBridgeHandler.uninstall();
+ enableJulConsoleLogger();
+ }
+
+ private void enableJulConsoleLogger() {
+ if (this.javaConsoleHandler != null) {
+ getJavaRootLogger().addHandler(this.javaConsoleHandler);
+ }
+ }
+
+ private void disableJulConsoleHandler() {
+ // remove console handler from root logger
+ Logger rootLogger = getJavaRootLogger();
+ Handler[] handlers = rootLogger.getHandlers();
+ for (Handler handler : handlers) {
+ if (handler instanceof ConsoleHandler) {
+ this.javaConsoleHandler = (ConsoleHandler) handler;
+ rootLogger.removeHandler(handler);
+ }
+ }
+ }
+
+ public void eventLogStart() {
+ this.eventLoggerFactory = createFactory(bundleContext);
+ ServiceFactory<EventLogger> serviceFactory = new EventLoggerServiceFactory(this.eventLoggerFactory);
+ registrationTracker.track(bundleContext.registerService(EventLoggerFactory.class.getName(), this.eventLoggerFactory, null));
+ registrationTracker.track(bundleContext.registerService(EventLogger.class.getName(), serviceFactory, null));
+ }
+
+ private PrintStream wrapPrintStream(PrintStream printStream, String loggerName, LoggingLevel loggingLevel, ExecutionStackAccessor stackAccessor, ConfigurationProvider configurationProvider, String configurationProperty) {
+ LoggingPrintStreamWrapper wrapper = new LoggingPrintStreamWrapper(printStream, loggerName, loggingLevel, stackAccessor, configurationProvider, configurationProperty);
+ return wrapper;
+ }
+
+ private ServiceRegistration<?> publishPrintStream(PrintStream printStream, String name) {
+ Hashtable<String, String> properties = new Hashtable<String, String>();
+ properties.put("org.eclipse.virgo.medic.log.printStream", name);
+
+ ServiceRegistration<?> registration = bundleContext.registerService(PrintStream.class.getName(), printStream, properties);
+ registrationTracker.track(registration);
+
+ return registration;
+ }
+
+ private ServiceRegistration<?> publishDelegatingPrintStream(PrintStream printStream, String name) {
+ Hashtable<String, String> properties = new Hashtable<String, String>();
+ properties.put("org.eclipse.virgo.medic.log.printStream", name);
+
+ String[] classes = new String[]{DelegatingPrintStream.class.getName()};
+ ServiceRegistration<?> delegatingPrintStreamRegistration = bundleContext.registerService(classes, printStream, properties);
+ registrationTracker.track(delegatingPrintStreamRegistration);
+
+ return delegatingPrintStreamRegistration;
+ }
+
+ private void publishDefaultConfigurationIfAvailable(BundleContext context, StandardLoggingConfigurationPublisher publisher) throws ConfigurationPublicationFailedException {
+ String logConfigPath = context.getProperty(PROPERTY_MEDIC_CONFIG_PATH);
+ if (logConfigPath != null) {
+ File logConfigFile = new File(logConfigPath);
+ if (logConfigFile.exists()) {
+ publisher.publishDefaultConfiguration(new File(logConfigPath));
+ }
+ }
+ }
+
+ private static StandardContextSelectorDelegate createContextSelectorDelegate(BundleContext bundleContext) {
+ ConfigurationLocator configurationLocator = createConfigurationLocator(bundleContext);
+ CallingBundleResolver loggingCallerLocator = createLoggingCallerLocator();
+ LoggerContextConfigurer loggerContextConfigurer = new JoranLoggerContextConfigurer();
+ return new StandardContextSelectorDelegate(loggingCallerLocator, configurationLocator, bundleContext.getBundle(), loggerContextConfigurer);
+ }
+
+ /**
+ * Logging configuration is located by searching up to two sources, depending on the bundle doing the logging.
+ * <p/>
+ * Firstly, if and only if the bundle has a specific Medic manifest header, the service registry is searched in
+ * a location specified in the manifest header. Secondly, if the configuration has not already been found, the
+ * the bundle's resources are checked for a Logback configuration file.
+ */
+ private static ConfigurationLocator createConfigurationLocator(BundleContext bundleContext) {
+ return new CompositeConfigurationLocator(new ServiceRegistryConfigurationLocator(bundleContext), new BundleResourceConfigurationLocator());
+ }
+
+ private static CallingBundleResolver createLoggingCallerLocator() {
+ ClassSelector classSelector = createClassSelector();
+ ExecutionStackAccessor executionStackAccessor = createExecutionStackAccessor();
+
+ return new StandardCallingBundleResolver(executionStackAccessor, classSelector);
+ }
+
+ private static ClassSelector createClassSelector() {
+ return new PackageNameFilteringClassSelector(DEFAULT_LOGGING_PACKAGES);
+ }
+
+ private static ExecutionStackAccessor createExecutionStackAccessor() {
+ return new SecurityManagerExecutionStackAccessor();
+ }
+
+ private LogBackEventLoggerFactory createFactory(BundleContext context) {
+ BundleSearchingPropertyResourceBundleResolver resourceBundleResolver = new BundleSearchingPropertyResourceBundleResolver();
+ return new LogBackEventLoggerFactory(resourceBundleResolver, new StandardLocaleResolver(), context.getBundle());
+ }
+
+ private Logger getJavaRootLogger() {
+ return Logger.getLogger("");
+ }
+
+ @Override
+ public void configurationChanged(ConfigurationProvider provider) {
+ Dictionary<String, String> configuration = configurationProvider.getConfiguration();
+
+ updateLogConfiguration(configuration);
+
+ if (Boolean.valueOf(configuration.get(ConfigurationProvider.KEY_ENABLE_JUL_CONSOLE_HANDLER))) {
+ enableJulConsoleLogger();
+ } else {
+ disableJulConsoleHandler();
+ }
+ }
+
+ private synchronized void updateLogConfiguration(Dictionary<String, String> configuration) {
+ if (Boolean.valueOf(configuration.get(ConfigurationProvider.KEY_LOG_WRAP_SYSOUT))) {
+ delegatingSysOutRegistration = publishDelegatingPrintStream(delegatingSysOut, LOGGER_NAME_SYSOUT_DELEGATE);
+ sysOutRegistration = publishPrintStream(this.sysOut, LOGGER_NAME_SYSOUT);
+
+ System.setOut(wrapPrintStream(System.out, LOGGER_NAME_SYSOUT, LoggingLevel.INFO, stackAccessor, configurationProvider, ConfigurationProvider.KEY_LOG_WRAP_SYSOUT));
+ } else {
+ if (delegatingSysOutRegistration != null) {
+ registrationTracker.unregister(delegatingSysOutRegistration);
+ delegatingSysOutRegistration = null;
+ }
+ if (sysOutRegistration != null) {
+ registrationTracker.unregister(sysOutRegistration);
+ sysOutRegistration = null;
+ }
+ System.setOut(delegatingSysOut);
+ }
+
+ if (Boolean.valueOf(configuration.get(ConfigurationProvider.KEY_LOG_WRAP_SYSERR))) {
+ delegatingSysErrRegistration = publishDelegatingPrintStream(delegatingSysErr, LOGGER_NAME_SYSERR_DELEGATE);
+ sysErrRegistration = publishPrintStream(this.sysErr, LOGGER_NAME_SYSERR);
+
+ System.setErr(wrapPrintStream(System.err, LOGGER_NAME_SYSERR, LoggingLevel.ERROR, stackAccessor, configurationProvider, ConfigurationProvider.KEY_LOG_WRAP_SYSERR));
+ } else {
+ if (delegatingSysErrRegistration != null) {
+ registrationTracker.unregister(delegatingSysErrRegistration);
+ delegatingSysErrRegistration = null;
+ }
+ if (sysErrRegistration != null) {
+ registrationTracker.unregister(sysErrRegistration);
+ sysErrRegistration = null;
+ }
+ System.setErr(delegatingSysErr);
+ }
+ }
+}
diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicActivator.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicActivator.java
index 0a05ac8..6337dca 100644
--- a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicActivator.java
+++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/MedicActivator.java
@@ -11,291 +11,60 @@
package org.eclipse.virgo.medic.impl;
-import java.io.File;
-import java.io.PrintStream;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Handler;
-import java.util.logging.LogManager;
-import java.util.logging.Logger;
-
+import org.eclipse.equinox.log.ExtendedLogReaderService;
+import org.eclipse.virgo.medic.impl.config.ConfigurationAdminConfigurationProvider;
+import org.eclipse.virgo.medic.impl.config.ConfigurationProvider;
+import org.eclipse.virgo.medic.log.osgi.OSGiLogServiceListener;
+import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.ConfigurationListener;
import org.osgi.service.log.LogService;
import org.slf4j.LoggerFactory;
-import org.slf4j.bridge.SLF4JBridgeHandler;
-
-import org.eclipse.equinox.log.ExtendedLogReaderService;
-import org.eclipse.virgo.medic.dump.DumpGenerator;
-import org.eclipse.virgo.medic.dump.impl.DumpContributorPublisher;
-import org.eclipse.virgo.medic.dump.impl.StandardDumpContributorResolver;
-import org.eclipse.virgo.medic.dump.impl.StandardDumpGenerator;
-import org.eclipse.virgo.medic.eventlog.EventLogger;
-import org.eclipse.virgo.medic.eventlog.EventLoggerFactory;
-import org.eclipse.virgo.medic.eventlog.impl.BundleSearchingPropertyResourceBundleResolver;
-import org.eclipse.virgo.medic.eventlog.impl.EventLoggerServiceFactory;
-import org.eclipse.virgo.medic.eventlog.impl.StandardLocaleResolver;
-import org.eclipse.virgo.medic.eventlog.impl.logback.LogBackEventLoggerFactory;
-import org.eclipse.virgo.medic.impl.config.ConfigurationAdminConfigurationProvider;
-import org.eclipse.virgo.medic.impl.config.ConfigurationProvider;
-import org.eclipse.virgo.medic.log.ConfigurationPublicationFailedException;
-import org.eclipse.virgo.medic.log.DelegatingPrintStream;
-import org.eclipse.virgo.medic.log.LoggingConfigurationPublisher;
-import org.eclipse.virgo.medic.log.impl.CallingBundleResolver;
-import org.eclipse.virgo.medic.log.impl.ClassSelector;
-import org.eclipse.virgo.medic.log.impl.ExecutionStackAccessor;
-import org.eclipse.virgo.medic.log.impl.LoggingLevel;
-import org.eclipse.virgo.medic.log.impl.LoggingPrintStreamWrapper;
-import org.eclipse.virgo.medic.log.impl.PackageNameFilteringClassSelector;
-import org.eclipse.virgo.medic.log.impl.SecurityManagerExecutionStackAccessor;
-import org.eclipse.virgo.medic.log.impl.StandardCallingBundleResolver;
-import org.eclipse.virgo.medic.log.impl.StandardDelegatingPrintStream;
-import org.eclipse.virgo.medic.log.impl.config.BundleResourceConfigurationLocator;
-import org.eclipse.virgo.medic.log.impl.config.CompositeConfigurationLocator;
-import org.eclipse.virgo.medic.log.impl.config.ConfigurationLocator;
-import org.eclipse.virgo.medic.log.impl.config.ServiceRegistryConfigurationLocator;
-import org.eclipse.virgo.medic.log.impl.config.StandardLoggingConfigurationPublisher;
-import org.eclipse.virgo.medic.log.impl.logback.DelegatingContextSelector;
-import org.eclipse.virgo.medic.log.impl.logback.JoranLoggerContextConfigurer;
-import org.eclipse.virgo.medic.log.impl.logback.LoggerContextConfigurer;
-import org.eclipse.virgo.medic.log.impl.logback.StandardContextSelectorDelegate;
-import org.eclipse.virgo.medic.log.osgi.OSGiLogServiceListener;
-import org.eclipse.virgo.util.osgi.ServiceRegistrationTracker;
public final class MedicActivator implements BundleActivator {
- private static final String LOGGER_NAME_SYSERR = "System.err";
-
- private static final String LOGGER_NAME_SYSOUT = "System.out";
-
- private static final String LOGGER_NAME_SYSERR_DELEGATE = "delegating.System.err";
-
- private static final String LOGGER_NAME_SYSOUT_DELEGATE = "delegating.System.out";
+ private final ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
- private static final String PROPERTY_MEDIC_CONFIG_PATH = "org.eclipse.virgo.medic.log.config.path";
+ private volatile ServiceReference<ExtendedLogReaderService> logReaderReference;
- private static final String DEFAULT_CONTEXT_SELECTOR = "ch.qos.logback.classic.selector.DefaultContextSelector";
+ private LogController logController;
- private static final String PROPERTY_LOGBACK_CONTEXT_SELECTOR = "logback.ContextSelector";
-
- private final ServiceRegistrationTracker registrationTracker = new ServiceRegistrationTracker();
+ private ConfigurationProvider configurationProvider;
- private volatile StandardDumpGenerator dumpGenerator;
-
- private volatile LogBackEventLoggerFactory eventLoggerFactory;
+ public void start(BundleContext context) throws Exception {
+ this.configurationProvider = new ConfigurationAdminConfigurationProvider(context);
+ this.registrationTracker.track(context.registerService(ConfigurationListener.class.getName(), configurationProvider, null));
- private volatile DumpContributorPublisher dumpContributorPublisher;
-
- private volatile ServiceReference<ExtendedLogReaderService> logReaderReference;
+ this.logController = new LogController(context, configurationProvider, registrationTracker);
- private volatile PrintStream sysOut;
-
- private volatile PrintStream sysErr;
+ configurationProvider.addChangeListener(logController);
- private static final List<String> DEFAULT_LOGGING_PACKAGES = Arrays.asList(//
- "org.apache.commons.logging",//
- "org.apache.log4j",//
- "org.slf4j",//
- "org.slf4j.impl",//
- "org.eclipse.virgo.medic.log",//
- "org.eclipse.virgo.medic.log.impl",//
- "org.eclipse.virgo.medic.log.impl.logback");
+ logController.logStart();
+ logController.eventLogStart();
+ logController.dumpStart();
- public void start(BundleContext context) throws Exception {
- ConfigurationProvider configurationProvider = new ConfigurationAdminConfigurationProvider(context);
- this.registrationTracker.track(context.registerService(ConfigurationListener.class.getName(), configurationProvider, null));
- logStart(context, configurationProvider);
- eventLogStart(context);
- dumpStart(context, configurationProvider);
-
- this.logReaderReference = context.getServiceReference(ExtendedLogReaderService.class);
- ExtendedLogReaderService logReader = context.getService(this.logReaderReference);
+ this.logReaderReference = context.getServiceReference(ExtendedLogReaderService.class);
+ ExtendedLogReaderService logReader = context.getService(this.logReaderReference);
logReader.addLogListener(new OSGiLogServiceListener(LoggerFactory.getLogger(LogService.class)));
}
public void stop(BundleContext context) throws Exception {
- this.registrationTracker.unregisterAll();
- ServiceReference<ExtendedLogReaderService> localLogReaderReference = this.logReaderReference;
- if(localLogReaderReference != null){
- context.ungetService(localLogReaderReference);
- }
- dumpStop();
- logStop(context);
- }
-
- private void dumpStart(BundleContext context, ConfigurationProvider configurationProvider) {
-
- this.dumpGenerator = new StandardDumpGenerator(new StandardDumpContributorResolver(context), configurationProvider, this.eventLoggerFactory.createEventLogger(context.getBundle()));
- this.registrationTracker.track(context.registerService(DumpGenerator.class.getName(), this.dumpGenerator, null));
-
- this.dumpContributorPublisher = new DumpContributorPublisher(context);
- this.dumpContributorPublisher.publishDumpContributors();
- }
-
- private void dumpStop() {
- if (this.dumpGenerator != null) {
- this.dumpGenerator.close();
+ this.registrationTracker.unregisterAll();
+ ServiceReference<ExtendedLogReaderService> localLogReaderReference = this.logReaderReference;
+ if (localLogReaderReference != null) {
+ context.ungetService(localLogReaderReference);
}
- if (this.dumpContributorPublisher != null) {
- this.dumpContributorPublisher.retractDumpContributors();
- }
- }
-
- private void logStart(BundleContext context, ConfigurationProvider configurationProvider) throws ConfigurationPublicationFailedException {
-
- StandardContextSelectorDelegate delegate = createContextSelectorDelegate(context);
- this.registrationTracker.track(context.registerService(BundleListener.class.getName(), delegate, null));
- DelegatingContextSelector.setDelegate(delegate);
-
- StandardLoggingConfigurationPublisher loggingConfigurationPublisher = new StandardLoggingConfigurationPublisher(context);
- this.registrationTracker.track(context.registerService(LoggingConfigurationPublisher.class.getName(), loggingConfigurationPublisher, null));
-
- publishDefaultConfigurationIfAvailable(context, loggingConfigurationPublisher);
-
- System.setProperty(PROPERTY_LOGBACK_CONTEXT_SELECTOR, DelegatingContextSelector.class.getName());
-
- ExecutionStackAccessor stackAccessor = new SecurityManagerExecutionStackAccessor();
-
- Dictionary<String, String> configuration = configurationProvider.getConfiguration();
-
- PrintStream delegatingSysOut = new StandardDelegatingPrintStream(System.out);
- PrintStream delegatingSysErr = new StandardDelegatingPrintStream(System.err);
-
- this.sysOut = System.out;
- this.sysErr = System.err;
-
- System.setOut(delegatingSysOut);
- System.setErr(delegatingSysErr);
-
- if (Boolean.valueOf(configuration.get(ConfigurationProvider.KEY_LOG_WRAP_SYSOUT))) {
- publishDelegatingPrintStream(delegatingSysOut, LOGGER_NAME_SYSOUT_DELEGATE, context);
- publishPrintStream(this.sysOut, LOGGER_NAME_SYSOUT, context);
-
- System.setOut(wrapPrintStream(System.out, LOGGER_NAME_SYSOUT, LoggingLevel.INFO, stackAccessor, configurationProvider, ConfigurationProvider.KEY_LOG_WRAP_SYSOUT));
+ if (configurationProvider != null) {
+ configurationProvider.removeChangeListener(logController);
}
-
- if (Boolean.valueOf(configuration.get(ConfigurationProvider.KEY_LOG_WRAP_SYSERR))) {
- publishDelegatingPrintStream(delegatingSysErr, LOGGER_NAME_SYSERR_DELEGATE, context);
- publishPrintStream(this.sysErr, LOGGER_NAME_SYSERR, context);
-
- System.setErr(wrapPrintStream(System.err, LOGGER_NAME_SYSERR, LoggingLevel.ERROR, stackAccessor, configurationProvider, ConfigurationProvider.KEY_LOG_WRAP_SYSERR));
- }
-
- configureJavaLogging(Boolean.valueOf(configuration.get(ConfigurationProvider.KEY_ENABLE_JUL_CONSOLE_HANDLER)));
- }
-
- private PrintStream wrapPrintStream(PrintStream printStream, String loggerName, LoggingLevel loggingLevel, ExecutionStackAccessor stackAccessor, ConfigurationProvider configurationProvider, String configurationProperty) {
- LoggingPrintStreamWrapper wrapper = new LoggingPrintStreamWrapper(printStream, loggerName, loggingLevel, stackAccessor, configurationProvider, configurationProperty);
- return wrapper;
- }
-
- private void publishPrintStream(PrintStream printStream, String name, BundleContext context) {
- Hashtable<String, String> properties = new Hashtable<String, String>();
- properties.put("org.eclipse.virgo.medic.log.printStream", name);
-
- this.registrationTracker.track(context.registerService(PrintStream.class.getName(), printStream, properties));
- }
-
- private void publishDelegatingPrintStream(PrintStream printStream, String name, BundleContext context) {
- Hashtable<String, String> properties = new Hashtable<String, String>();
- properties.put("org.eclipse.virgo.medic.log.printStream", name);
-
- String[] classes = new String[] {DelegatingPrintStream.class.getName()};
- this.registrationTracker.track(context.registerService(classes, printStream, properties));
- }
-
- private void publishDefaultConfigurationIfAvailable(BundleContext context, StandardLoggingConfigurationPublisher publisher) throws ConfigurationPublicationFailedException {
- String logConfigPath = context.getProperty(PROPERTY_MEDIC_CONFIG_PATH);
- if (logConfigPath != null) {
- File logConfigFile = new File(logConfigPath);
- if (logConfigFile.exists()) {
- publisher.publishDefaultConfiguration(new File(logConfigPath));
- }
- }
- }
-
- private static StandardContextSelectorDelegate createContextSelectorDelegate(BundleContext bundleContext) {
- ConfigurationLocator configurationLocator = createConfigurationLocator(bundleContext);
- CallingBundleResolver loggingCallerLocator = createLoggingCallerLocator();
- LoggerContextConfigurer loggerContextConfigurer = new JoranLoggerContextConfigurer();
- return new StandardContextSelectorDelegate(loggingCallerLocator, configurationLocator, bundleContext.getBundle(), loggerContextConfigurer);
- }
-
- /**
- * Logging configuration is located by searching up to two sources, depending on the bundle doing the logging.
- * <p>
- * Firstly, if and only if the bundle has a specific Medic manifest header, the service registry is searched in
- * a location specified in the manifest header. Secondly, if the configuration has not already been found, the
- * the bundle's resources are checked for a Logback configuration file.
- */
- private static ConfigurationLocator createConfigurationLocator(BundleContext bundleContext) {
- return new CompositeConfigurationLocator(new ServiceRegistryConfigurationLocator(bundleContext), new BundleResourceConfigurationLocator());
- }
-
- private static CallingBundleResolver createLoggingCallerLocator() {
- ClassSelector classSelector = createClassSelector();
- ExecutionStackAccessor executionStackAccessor = createExecutionStackAccessor();
-
- return new StandardCallingBundleResolver(executionStackAccessor, classSelector);
- }
- private static ClassSelector createClassSelector() {
- return new PackageNameFilteringClassSelector(DEFAULT_LOGGING_PACKAGES);
- }
-
- private static ExecutionStackAccessor createExecutionStackAccessor() {
- return new SecurityManagerExecutionStackAccessor();
- }
-
- private void logStop(BundleContext context) {
-
- System.setProperty(PROPERTY_LOGBACK_CONTEXT_SELECTOR, DEFAULT_CONTEXT_SELECTOR);
-
- DelegatingContextSelector.setDelegate(null);
-
- if (this.sysOut != null) {
- System.setOut(this.sysOut);
+ if (logController != null) {
+ logController.dumpStop();
+ logController.logStop();
}
-
- if (this.sysErr != null) {
- System.setErr(this.sysErr);
- }
}
- private void eventLogStart(BundleContext context) {
- this.eventLoggerFactory = createFactory(context);
- ServiceFactory<EventLogger> serviceFactory = new EventLoggerServiceFactory(this.eventLoggerFactory);
- this.registrationTracker.track(context.registerService(EventLoggerFactory.class.getName(), this.eventLoggerFactory, null));
- this.registrationTracker.track(context.registerService(EventLogger.class.getName(), serviceFactory, null));
- }
-
- private LogBackEventLoggerFactory createFactory(BundleContext context) {
- BundleSearchingPropertyResourceBundleResolver resourceBundleResolver = new BundleSearchingPropertyResourceBundleResolver();
- return new LogBackEventLoggerFactory(resourceBundleResolver, new StandardLocaleResolver(), context.getBundle());
- }
-
- private void configureJavaLogging(boolean enableConsoleHandler) {
- SLF4JBridgeHandler.install();
-
- // remove console handler from root logger?
- if (enableConsoleHandler) {
- return;
- }
-
- Logger rootLogger = Logger.getLogger("");
- Handler[] handlers = rootLogger.getHandlers();
- for (Handler handler: handlers) {
- if (handler instanceof ConsoleHandler) {
- rootLogger.removeHandler(handler);
- }
- }
- }
}
diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProvider.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProvider.java
index 9e3984b..d9803d6 100644
--- a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProvider.java
+++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationAdminConfigurationProvider.java
@@ -13,8 +13,10 @@ package org.eclipse.virgo.medic.impl.config;
import java.io.IOException;
import java.util.Dictionary;
+import java.util.HashSet;
import java.util.Hashtable;
+import org.eclipse.virgo.util.common.SynchronizedCollection;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.Configuration;
@@ -34,8 +36,11 @@ public final class ConfigurationAdminConfigurationProvider implements Configurat
private volatile Dictionary<String,String> configuration = DEFAULT_CONFIG;
+ private HashSet<ConfigurationChangeListener> listeners;
+
public ConfigurationAdminConfigurationProvider(BundleContext context) {
this.bundleContext = context;
+ this.listeners = new HashSet<ConfigurationChangeListener>();
initialisePropertiesFromConfigurationAdmin();
}
@@ -76,6 +81,8 @@ public final class ConfigurationAdminConfigurationProvider implements Configurat
} else {
this.configuration = DEFAULT_CONFIG;
}
+
+ notifyListeners();
}
private static Dictionary<String, String> createDefaultConfiguration() {
@@ -85,7 +92,21 @@ public final class ConfigurationAdminConfigurationProvider implements Configurat
configuration.put(KEY_LOG_WRAP_SYSERR, Boolean.toString(Boolean.TRUE));
return configuration;
}
-
+
+ public void addChangeListener(ConfigurationChangeListener listener) {
+ listeners.add(listener);
+ }
+
+ public boolean removeChangeListener(ConfigurationChangeListener listener) {
+ return listeners.remove(listener);
+ }
+
+ private void notifyListeners() {
+ for (Object listener: listeners.toArray()) {
+ ((ConfigurationChangeListener) listener).configurationChanged(this);
+ }
+ }
+
private final class MedicConfigurationListener implements ConfigurationListener {
@SuppressWarnings("unchecked")
public void configurationEvent(ConfigurationEvent configEvent) {
diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationChangeListener.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationChangeListener.java
new file mode 100755
index 0000000..f647d94
--- /dev/null
+++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationChangeListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2011 SAP AG
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Hristo Iliev, SAP AG - initial contribution
+ *******************************************************************************/
+package org.eclipse.virgo.medic.impl.config;
+
+public interface ConfigurationChangeListener {
+
+ /**
+ * Called when the configuration changed.
+ * <p/>
+ * The listener can be called although the configuration is virtually the same - no configuration data
+ * comparison is made.
+ *
+ * @param provider ConfigurationProvider that can be used to obtain the properties.
+ */
+ public void configurationChanged(ConfigurationProvider provider);
+
+}
diff --git a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationProvider.java b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationProvider.java
index 08fae62..ce61df0 100644
--- a/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationProvider.java
+++ b/org.eclipse.virgo.medic.core/src/main/java/org/eclipse/virgo/medic/impl/config/ConfigurationProvider.java
@@ -16,18 +16,35 @@ import java.util.Dictionary;
public interface ConfigurationProvider {
public static final String KEY_DUMP_ROOT_DIRECTORY = "dump.root.directory";
-
+
public static final String KEY_LOG_WRAP_SYSOUT = "log.wrapSysOut";
-
+
public static final String KEY_LOG_WRAP_SYSERR = "log.wrapSysErr";
-
+
public static final String KEY_LOG_DUMP_BUFFERSIZE = "log.dump.bufferSize";
-
+
public static final String KEY_LOG_DUMP_LEVEL = "log.dump.level";
-
+
public static final String KEY_LOG_DUMP_PATTERN = "log.dump.pattern";
public static final String KEY_ENABLE_JUL_CONSOLE_HANDLER = "log.jul.consoleHandler";
Dictionary<String, String> getConfiguration();
+
+ /**
+ * Adds listener that will be notified when the configuration changes
+ * <p/>
+ * Multiple listeners are supported.
+ *
+ * @param listener Listener to be added
+ */
+ public void addChangeListener(ConfigurationChangeListener listener);
+
+ /**
+ * Removes previously registered listener
+ *
+ * @param listener Listener to be removed
+ * @return Returns <code>true</code> if the lister was registered and <code>false</code> if not
+ */
+ public boolean removeChangeListener(ConfigurationChangeListener listener);
}
diff --git a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapperTests.java b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapperTests.java
index eb13b49..ec588f7 100644
--- a/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapperTests.java
+++ b/org.eclipse.virgo.medic.core/src/test/java/org/eclipse/virgo/medic/log/impl/LoggingPrintStreamWrapperTests.java
@@ -20,6 +20,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Properties;
+import org.eclipse.virgo.medic.impl.config.ConfigurationChangeListener;
import org.eclipse.virgo.medic.impl.config.ConfigurationProvider;
import org.eclipse.virgo.medic.log.impl.ExecutionStackAccessor;
import org.eclipse.virgo.medic.log.impl.LoggingPrintStreamWrapper;
@@ -30,18 +31,17 @@ import org.junit.Test;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.LoggingEvent;
-
public class LoggingPrintStreamWrapperTests {
-
+
private PrintStream wrapper;
@Test
public void test() {
produceOutput(this.wrapper);
-
+
List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents();
assertEquals(22, loggingEvents.size());
-
+
assertEquals("abcdefghij", loggingEvents.get(0).getMessage());
assertEquals("Three strings", loggingEvents.get(1).getMessage());
assertEquals("last one on a new line.", loggingEvents.get(2).getMessage());
@@ -65,24 +65,24 @@ public class LoggingPrintStreamWrapperTests {
assertEquals("A string with a", loggingEvents.get(20).getMessage());
assertEquals("new line in it.", loggingEvents.get(21).getMessage());
}
-
+
@Test
- public void testOutputWithinLoggingCode() {
+ public void testOutputWithinLoggingCode() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- PrintStream printStream = new PrintStream(baos);
+ PrintStream printStream = new PrintStream(baos);
PrintStream wrapper = new LoggingPrintStreamWrapper(printStream, getClass().getName(), new ExecutionStackAccessor() {
-
+
public Class<?>[] getExecutionStack() {
return new Class[] {Logger.class};
}
}, new StubConfigurationProvider(), "theProperty");
-
+
produceOutput(wrapper);
-
+
List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents();
assertEquals(0, loggingEvents.size());
}
-
+
private void produceOutput(PrintStream printStream) {
printStream.append('a');
printStream.append("bcd");
@@ -113,49 +113,49 @@ public class LoggingPrintStreamWrapperTests {
printStream.println(new Object() {@Override public String toString() { return "toString";}});
printStream.println("A string with a\nnew line in it.");
}
-
+
@Test
- public void testByteArrayHandling() {
+ public void testByteArrayHandling() {
String string = "Some text to be turned into bytes.";
String stringWithNewLine = string + "\n";
byte[] stringBytes = stringWithNewLine.getBytes();
-
- wrapper.write(stringBytes, 0, stringBytes.length);
-
+
+ wrapper.write(stringBytes, 0, stringBytes.length);
+
List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents();
assertEquals(1, loggingEvents.size());
-
+
assertEquals("Some text to be turned into bytes.", loggingEvents.get(0).getMessage());
}
-
+
@Test
- public void testSingleByteHandling() {
+ public void testSingleByteHandling() {
String string = "Some text to be turned into bytes.";
byte[] stringBytes = string.getBytes();
-
+
for (byte b: stringBytes) {
wrapper.write(b);
}
wrapper.println();
-
+
List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents();
assertEquals(1, loggingEvents.size());
-
+
assertEquals("Some text to be turned into bytes.", loggingEvents.get(0).getMessage());
}
-
+
@Test
public void testPrintNullString(){
-
+
String imNull = null;
-
+
wrapper.println(imNull);
wrapper.print(imNull);
wrapper.println();
-
+
List<LoggingEvent> loggingEvents = CapturingAppender.getAndResetLoggingEvents();
assertEquals(2, loggingEvents.size());
-
+
assertEquals("null", loggingEvents.get(0).getMessage());
assertEquals("null", loggingEvents.get(1).getMessage());
}
@@ -166,11 +166,11 @@ public class LoggingPrintStreamWrapperTests {
PrintStream printStream = new PrintStream(baos);
this.wrapper = new LoggingPrintStreamWrapper(printStream, getClass().getName(), new SecurityManagerExecutionStackAccessor(), new StubConfigurationProvider(), "theProperty");
}
-
+
private final class StubConfigurationProvider implements ConfigurationProvider {
-
+
private final Properties configuration;
-
+
private StubConfigurationProvider() {
this.configuration = new Properties();
this.configuration.setProperty("theProperty", "true");
@@ -179,6 +179,15 @@ public class LoggingPrintStreamWrapperTests {
@SuppressWarnings("unchecked")
public Dictionary getConfiguration() {
return this.configuration;
- }
+ }
+
+ public void addChangeListener(ConfigurationChangeListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean removeChangeListener(ConfigurationChangeListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
}
}

Back to the top