/* * Copyright to the original author or authors. * * Licensed 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. */ package org.rioproject.start; import org.slf4j.LoggerFactory; import java.io.File; import java.io.PrintStream; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URL; /** * Helper for management of logging system * * @author Dennis Reedy */ public final class LogManagementHelper { private static final org.slf4j.Logger stdOutLogger = LoggerFactory.getLogger("std.out"); private static final org.slf4j.Logger stdErrLogger = LoggerFactory.getLogger("std.err"); private LogManagementHelper() {} /** * Installs a {@code ServiceLogEventHandler} based on the logging system being used. */ public static void setup() { //redirectIfNecessary(); try { Class<?> cl = Class.forName("org.rioproject.logging.ServiceLogEventHandlerHelper"); Method addServiceLogEventHandler = cl.getMethod("addServiceLogEventHandler"); addServiceLogEventHandler.invoke(null); } catch(Exception e) { stdErrLogger.warn("Unable to add ServiceLogEventHandler {}: {}", e.getClass().getName(), e.getMessage()); } } /** * Checks if the underlying logging system configuration has been changed from default * startup settings. */ public static void checkConfigurationReset() { String config = System.getProperty("logback.configurationFile"); if(config==null) return; try { Class<?> loggerFactory = Class.forName("org.slf4j.LoggerFactory"); Method getILoggerFactory = loggerFactory.getMethod("getILoggerFactory"); Object loggerContext = getILoggerFactory.invoke(null); Class<?> configurationWatchListUtil = Class.forName("ch.qos.logback.core.joran.util.ConfigurationWatchListUtil"); URL main = (URL) getMethod("getMainWatchURL", configurationWatchListUtil).invoke(null, loggerContext); File currentConfigFile = null; if(main!=null) { currentConfigFile = new File(main.toURI()); } File configFile = new File(config); if (currentConfigFile == null || !currentConfigFile.getAbsolutePath().equals(configFile.getAbsolutePath())) { Method reset = loggerContext.getClass().getMethod("reset"); reset.invoke(loggerContext); if(configFile.getName().endsWith(".xml")) { Class<?> joranConfigurator = Class.forName("ch.qos.logback.classic.joran.JoranConfigurator"); Object configurator = joranConfigurator.newInstance(); getMethod("setContext", joranConfigurator).invoke(configurator, loggerContext); joranConfigurator.getMethod("doConfigure", File.class).invoke(configurator, configFile); } else { Class<?> gafferConfigurator = Class.forName("ch.qos.logback.classic.gaffer.GafferConfigurator"); Constructor<?> constructor = gafferConfigurator.getConstructor(loggerContext.getClass()); Object configurator = constructor.newInstance(loggerContext); gafferConfigurator.getMethod("run", File.class).invoke(configurator, configFile); } } } catch (Exception e) { e.printStackTrace(); } } private static Method getMethod(String name, Class<?> cl) { for(Method m : cl.getMethods()) { if(m.getName().equals(name)) { return m; } } throw new NoSuchMethodError("Could not find "+name+" in "+cl.getName()); } static void redirectIfNecessary() { /* If we have been exec'd by Rio (such as a service that has been declared to be forked, * stdout and stderr have already been redirected */ if(System.getenv("RIO_EXEC")==null && System.console()==null) { redirectToLogger(); } } static void redirectToLogger(){ System.setOut(new PrintStream(System.out){ public void print(String s){ stdOutLogger.info(s); } }); System.setErr(new PrintStream(System.err){ public void print(String s){ stdErrLogger.error(s); } }); } }