/* * RED5 Open Source Flash Server - http://code.google.com/p/red5/ * * Copyright 2006-2012 by respective authors (see below). All rights reserved. * * 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.red5.logging; import java.lang.reflect.Method; import org.red5.server.adapter.StatefulScopeWrappingAdapter; import org.red5.server.api.scope.IScope; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.impl.StaticLoggerBinder; import ch.qos.logback.classic.LoggerContext; import ch.qos.logback.classic.selector.ContextSelector; /** * LoggerFactory to simplify requests for Logger instances within * Red5 applications. This class is expected to be run only once per * logger request and is optimized as such. * * @author Paul Gregoire (mondain@gmail.com) */ public class Red5LoggerFactory { @SuppressWarnings({ "unchecked", "rawtypes" }) public static Logger getLogger(Class<?> clazz) { //determine the red5 app name or servlet context name String contextName = null; //if the incoming class extends StatefulScopeWrappingAdapter we lookup the context //by scope name boolean scopeAware = StatefulScopeWrappingAdapter.class.isAssignableFrom(clazz); //System.out.printf("Wrapper - %s\n", StatefulScopeWrappingAdapter.class.isAssignableFrom(clazz)); if (scopeAware) { try { Class wrapper = null; if ((wrapper = clazz.asSubclass(StatefulScopeWrappingAdapter.class)) != null) { Method getScope = wrapper.getMethod("getScope", new Class[0]); //NPE will occur here if the scope is not yet set on the application adapter IScope scope = (IScope) getScope.invoke(null, new Object[0]); contextName = scope.getName(); } } catch (Exception cce) { //cclog.warn("Exception {}", e); } } else { //route the Launcher entries to the correct context String[] parts = Thread.currentThread().getName().split("Launcher:/"); if (parts.length > 1) { contextName = parts[1]; } } /* TODO: For a future day, the context or application will be determined //get a reference to our caller Class caller = Reflection.getCallerClass(2); //System.err.printf("Caller class: %s classloader: %s\n", caller, caller.getClassLoader()); try { //check to see if we've been called by a servlet Class sub = caller.asSubclass(Servlet.class); //System.err.println("Caller is a Servlet"); //Method[] methods = caller.getMethods(); //for (Method meth : methods) { // System.err.printf("Method: %s\n", meth.getName()); //} Method getContext = caller.getMethod("getServletContext", new Class[0]); //System.err.printf("got context method - %s\n", getContext); ServletContext context = (ServletContext) getContext.invoke(caller, null); System.err.printf("invoked context\n"); contextName = context.getServletContextName(); //System.err.printf("Servlet context name: %s\n", contextName); Method getContextName = context.getClass().getMethod("getServletContextName", new Class[0]); System.err.printf("got context name\n"); Object ctxName = getContextName.invoke(null, new Object[0]); System.err.printf("Servlet context result: %s\n", ctxName); if (ctxName != null && ctxName instanceof String) { contextName = ctxName.toString(); } } catch (Exception ex) { //ex.printStackTrace(); } */ return getLogger(clazz, contextName); } @SuppressWarnings({ "rawtypes" }) public static Logger getLogger(Class clazz, String contextName) { Logger logger = null; try { //check for logback Class cs = Class.forName("ch.qos.logback.classic.selector.ContextSelector"); //trigger an exception if the class doesn't actually exist cs.getDeclaredMethods(); // get the class for static binding cs = Class.forName("org.slf4j.impl.StaticLoggerBinder"); // get its declared methods Method[] methods = cs.getDeclaredMethods(); for (Method method : methods) { //ensure method exists if (method.getName().equals("getContextSelector")) { //System.out.println("Logger context selector method found"); //get the context selector StaticLoggerBinder binder = StaticLoggerBinder.getSingleton(); Method m1 = binder.getClass().getMethod("getContextSelector", (Class[]) null); ContextSelector selector = (ContextSelector) m1.invoke(binder, (Object[]) null); //get the context for the given context name or default if null LoggerContext ctx = null; if (contextName != null && contextName.length() > 0) { ctx = selector.getLoggerContext(contextName); } // and if we get here, fall back to the default context if (ctx == null) { ctx = selector.getLoggerContext(); } //debug //StatusPrinter.print(ctx); //get the logger from the context or default context logger = ((ctx != null) ? ctx.getLogger(clazz) : selector.getDefaultLoggerContext().getLogger(clazz)); break; } } } catch (Exception e) { //no logback, use whatever logger is in-place System.err.printf("Exception %s", e.getMessage()); } if (logger == null) { //no logback, use whatever logger is in-place logger = LoggerFactory.getLogger(clazz); } return logger; } public static ContextSelector getContextSelector() { ContextSelector selector = null; StaticLoggerBinder binder = StaticLoggerBinder.getSingleton(); try { Method m1 = binder.getClass().getMethod("getContextSelector", (Class[]) null); selector = (ContextSelector) m1.invoke(binder, (Object[]) null); } catch (Exception e) { System.err.printf("Exception %s", e.getMessage()); } return selector; } }