365302: made map of loggers concurrent and shared in abstract
This commit is contained in:
parent
08f4b79a66
commit
564cf7329c
|
@ -5,6 +5,6 @@ contexts:MMBean: Deployed Contexts
|
|||
appProviders:MMBean: Application Providers
|
||||
getApps(java.lang.String):MBean:ACTION: List apps that are located at specified App LifeCycle node
|
||||
getApps(java.lang.String)[0]:nodeName: Name of the App LifeCycle node
|
||||
requestAppGoal(java.lang.String,java.lang.String) ACTION: Request the app to be moved to the specified App LifeCycle node
|
||||
requestAppGoal(java.lang.String,java.lang.String):ACTION: Request the app to be moved to the specified App LifeCycle node
|
||||
requestAppGoal(java.lang.String,java.lang.String)[0]:appId:App identifier
|
||||
requestAppGoal(java.lang.String,java.lang.String)[1]:nodeName:Name of the App LifeCycle node
|
|
@ -48,11 +48,10 @@
|
|||
</Call>
|
||||
|
||||
<!-- Add the static log -->
|
||||
<Get id="Logger" class="org.eclipse.jetty.util.log.Log" name="log" />
|
||||
<Ref id="MBeanContainer">
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<Ref id="Logger" />
|
||||
<New class="org.eclipse.jetty.util.log.Log"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Ref>
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009-2009 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
|
||||
package org.eclipse.jetty.util.log.jmx;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.jmx.ObjectMBean;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
*/
|
||||
public class LogMBean extends ObjectMBean
|
||||
{
|
||||
|
||||
public LogMBean(Object managedObject)
|
||||
{
|
||||
super(managedObject);
|
||||
}
|
||||
|
||||
public List<String> getLoggers()
|
||||
{
|
||||
List<String> keySet = new ArrayList<String>(Log.getLoggers().keySet());
|
||||
return keySet;
|
||||
}
|
||||
|
||||
public boolean isDebugEnabled(String logger)
|
||||
{
|
||||
return Log.getLogger(logger).isDebugEnabled();
|
||||
}
|
||||
|
||||
public void setDebugEnabled(String logger, Boolean enabled)
|
||||
{
|
||||
Log.getLogger(logger).setDebugEnabled(enabled);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
Log: Jetty Logging implementaton
|
||||
loggers:MBean: List of all instantiated loggers
|
||||
debugEnabled:RW: True if debug enabled for root logger Log.LOG
|
||||
isDebugEnabled(java.lang.String):MBean:INFO: True if debug is enabled for the given logger
|
||||
isDebugEnabled(java.lang.String)[0]:loggerName: Name of the logger to return isDebugEnabled for
|
||||
setDebugEnabled(java.lang.String,java.lang.Boolean):MBean:ACTION: Set debug enabled for the given logger
|
||||
setDebugEnabled(java.lang.String,java.lang.Boolean)[0]:loggerName: Name of the logger to set debug enabled
|
||||
setDebugEnabled(java.lang.String,java.lang.Boolean)[1]:enabled: true to enable debug, false otherwise
|
|
@ -1,3 +0,0 @@
|
|||
Logger: Jetty Logging implementaton
|
||||
debugEnabled: True if debug enabled
|
||||
name: Logger name
|
|
@ -1,2 +1 @@
|
|||
ThreadMonitor: Detect and report spinning and deadlocked threads
|
||||
|
||||
|
|
|
@ -3,4 +3,3 @@ name: RO:Name
|
|||
displayName: RO:Display Name
|
||||
className: RO:Class Name
|
||||
initParameters: RO:Initial parameters
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package org.eclipse.jetty.util.log;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Abstract Logger.
|
||||
* Manages the atomic registration of the logger by name.
|
||||
*/
|
||||
public abstract class AbstractLogger implements Logger
|
||||
{
|
||||
public final Logger getLogger(String name)
|
||||
{
|
||||
if (isBlank(name))
|
||||
return this;
|
||||
|
||||
final String basename = getName();
|
||||
final String fullname = (isBlank(basename) || Log.getRootLogger()==this)?name:(basename + "." + name);
|
||||
|
||||
Logger logger = Log.getLoggers().get(fullname);
|
||||
if (logger == null)
|
||||
{
|
||||
Logger newlog = newLogger(fullname);
|
||||
|
||||
logger = Log.getMutableLoggers().putIfAbsent(fullname,newlog);
|
||||
if (logger == null)
|
||||
logger=newlog;
|
||||
}
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
|
||||
protected abstract Logger newLogger(String fullname);
|
||||
|
||||
/**
|
||||
* A more robust form of name blank test. Will return true for null names, and names that have only whitespace
|
||||
*
|
||||
* @param name
|
||||
* the name to test
|
||||
* @return true for null or blank name, false if any non-whitespace character is found.
|
||||
*/
|
||||
private static boolean isBlank(String name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int size = name.length();
|
||||
char c;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
c = name.charAt(i);
|
||||
if (!Character.isWhitespace(c))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ import java.util.logging.Level;
|
|||
* standard java.util.logging configuration</a>.
|
||||
* </p>
|
||||
*/
|
||||
public class JavaUtilLog implements Logger
|
||||
public class JavaUtilLog extends AbstractLogger
|
||||
{
|
||||
private Level configuredLevel;
|
||||
private java.util.logging.Logger _logger;
|
||||
|
@ -116,9 +116,12 @@ public class JavaUtilLog implements Logger
|
|||
_logger.log(Level.FINE, msg, thrown);
|
||||
}
|
||||
|
||||
public Logger getLogger(String name)
|
||||
/**
|
||||
* Create a Child Logger of this Logger.
|
||||
*/
|
||||
protected Logger newLogger(String fullname)
|
||||
{
|
||||
return new JavaUtilLog(name);
|
||||
return new JavaUtilLog(fullname);
|
||||
}
|
||||
|
||||
public void ignore(Throwable ignored)
|
||||
|
|
|
@ -19,10 +19,14 @@ import java.lang.reflect.Method;
|
|||
import java.net.URL;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
|
@ -61,7 +65,11 @@ public class Log
|
|||
*/
|
||||
public static boolean __ignored;
|
||||
|
||||
public static Map<String, Logger> __loggers = new HashMap<String, Logger>();
|
||||
/**
|
||||
* Hold loggers only.
|
||||
*/
|
||||
private final static ConcurrentMap<String, Logger> __loggers = new ConcurrentHashMap<String, Logger>();
|
||||
|
||||
|
||||
static
|
||||
{
|
||||
|
@ -427,14 +435,16 @@ public class Log
|
|||
|
||||
Logger logger = __loggers.get(name);
|
||||
if(logger==null)
|
||||
{
|
||||
logger = LOG.getLogger(name);
|
||||
__loggers.put(name,logger);
|
||||
}
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
static ConcurrentMap<String, Logger> getMutableLoggers()
|
||||
{
|
||||
return __loggers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map of all configured {@link Logger} instances.
|
||||
*
|
||||
|
@ -442,6 +452,6 @@ public class Log
|
|||
*/
|
||||
public static Map<String, Logger> getLoggers()
|
||||
{
|
||||
return __loggers;
|
||||
return Collections.unmodifiableMap(__loggers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import java.lang.reflect.Method;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
public class LoggerLog implements Logger
|
||||
public class LoggerLog extends AbstractLogger
|
||||
{
|
||||
private final Object _logger;
|
||||
private final Method _debugMT;
|
||||
|
@ -189,11 +189,14 @@ public class LoggerLog implements Logger
|
|||
}
|
||||
}
|
||||
|
||||
public Logger getLogger(String name)
|
||||
/**
|
||||
* Create a Child Logger of this Logger.
|
||||
*/
|
||||
protected Logger newLogger(String fullname)
|
||||
{
|
||||
try
|
||||
{
|
||||
Object logger=_getLoggerN.invoke(_logger, name);
|
||||
Object logger=_getLoggerN.invoke(_logger, fullname);
|
||||
return new LoggerLog(logger);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -18,7 +18,7 @@ package org.eclipse.jetty.util.log;
|
|||
/**
|
||||
* Slf4jLog Logger
|
||||
*/
|
||||
public class Slf4jLog implements Logger
|
||||
public class Slf4jLog extends AbstractLogger
|
||||
{
|
||||
private final org.slf4j.Logger _logger;
|
||||
|
||||
|
@ -114,9 +114,12 @@ public class Slf4jLog implements Logger
|
|||
warn("setDebugEnabled not implemented",null,null);
|
||||
}
|
||||
|
||||
public Logger getLogger(String name)
|
||||
/**
|
||||
* Create a Child Logger of this Logger.
|
||||
*/
|
||||
protected Logger newLogger(String fullname)
|
||||
{
|
||||
return new Slf4jLog(name);
|
||||
return new Slf4jLog(fullname);
|
||||
}
|
||||
|
||||
public void ignore(Throwable ignored)
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.eclipse.jetty.util.DateCache;
|
|||
* used for logging. For named debuggers, the system property name+".LONG" is checked. If it is not not set, then
|
||||
* "org.eclipse.jetty.util.log.LONG" is used as the default.
|
||||
*/
|
||||
public class StdErrLog implements Logger
|
||||
public class StdErrLog extends AbstractLogger
|
||||
{
|
||||
private static final String EOL = System.getProperty("line.separator");
|
||||
private static DateCache _dateCache;
|
||||
|
@ -45,11 +45,6 @@ public class StdErrLog implements Logger
|
|||
Log.__props.getProperty("org.eclipse.jetty.util.log.stderr.SOURCE","false")));
|
||||
private final static boolean __long = Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.stderr.LONG","false"));
|
||||
|
||||
/**
|
||||
* Tracking for child loggers only.
|
||||
*/
|
||||
private final static ConcurrentMap<String, StdErrLog> __loggers = new ConcurrentHashMap<String, StdErrLog>();
|
||||
|
||||
static
|
||||
{
|
||||
String deprecatedProperties[] =
|
||||
|
@ -331,29 +326,23 @@ public class StdErrLog implements Logger
|
|||
public void setDebugEnabled(boolean enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
synchronized (__loggers)
|
||||
{
|
||||
this._level = LEVEL_DEBUG;
|
||||
|
||||
// Boot stomp all cached log levels to DEBUG
|
||||
for(StdErrLog log: __loggers.values())
|
||||
for (Logger log : Log.getLoggers().values())
|
||||
{
|
||||
log._level = LEVEL_DEBUG;
|
||||
}
|
||||
if (log instanceof StdErrLog)
|
||||
((StdErrLog)log).setLevel(LEVEL_DEBUG);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
synchronized (__loggers)
|
||||
{
|
||||
this._level = this._configuredLevel;
|
||||
|
||||
// restore all cached log configured levels
|
||||
for(StdErrLog log: __loggers.values())
|
||||
for (Logger log : Log.getLoggers().values())
|
||||
{
|
||||
log._level = log._configuredLevel;
|
||||
}
|
||||
if (log instanceof StdErrLog)
|
||||
((StdErrLog)log).setLevel(((StdErrLog)log)._configuredLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -570,67 +559,18 @@ public class StdErrLog implements Logger
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A more robust form of name blank test. Will return true for null names, and names that have only whitespace
|
||||
*
|
||||
* @param name
|
||||
* the name to test
|
||||
* @return true for null or blank name, false if any non-whitespace character is found.
|
||||
*/
|
||||
private static boolean isBlank(String name)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
int size = name.length();
|
||||
char c;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
c = name.charAt(i);
|
||||
if (!Character.isWhitespace(c))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Child Logger relative to this Logger.
|
||||
*
|
||||
* @param name
|
||||
* the child name
|
||||
* @return the appropriate child logger (if name specified results in a new unique child)
|
||||
* Create a Child Logger of this Logger.
|
||||
*/
|
||||
public Logger getLogger(String name)
|
||||
protected Logger newLogger(String fullname)
|
||||
{
|
||||
if (isBlank(name))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
String fullname = name;
|
||||
if (!isBlank(_name))
|
||||
{
|
||||
fullname = _name + "." + name;
|
||||
}
|
||||
|
||||
StdErrLog logger = __loggers.get(fullname);
|
||||
if (logger == null)
|
||||
{
|
||||
StdErrLog sel = new StdErrLog(fullname);
|
||||
StdErrLog logger = new StdErrLog(fullname);
|
||||
// Preserve configuration for new loggers configuration
|
||||
sel.setPrintLongNames(_printLongNames);
|
||||
logger.setPrintLongNames(_printLongNames);
|
||||
// Let Level come from configured Properties instead - sel.setLevel(_level);
|
||||
sel.setSource(_source);
|
||||
sel._stderr = this._stderr;
|
||||
logger = __loggers.putIfAbsent(fullname,sel);
|
||||
if (logger == null)
|
||||
{
|
||||
logger = sel;
|
||||
}
|
||||
}
|
||||
logger.setSource(_source);
|
||||
logger._stderr = this._stderr;
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@ package org.eclipse.jetty.util.log;
|
|||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -23,18 +26,23 @@ import org.junit.Test;
|
|||
public class LogTest
|
||||
{
|
||||
private static Logger originalLogger;
|
||||
private static Map<String,Logger> originalLoggers;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@BeforeClass
|
||||
public static void rememberOriginalLogger()
|
||||
{
|
||||
originalLogger = Log.getLog();
|
||||
originalLoggers = new HashMap<String, Logger>(Log.getLoggers());
|
||||
Log.getMutableLoggers().clear();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void restoreOriginalLogger()
|
||||
{
|
||||
Log.setLog(originalLogger);
|
||||
Log.getMutableLoggers().clear();
|
||||
Log.getMutableLoggers().putAll(originalLoggers);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -1,26 +1,9 @@
|
|||
package org.eclipse.jetty.util.log;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class NamedLogTest
|
||||
{
|
||||
private static Logger originalLogger;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@BeforeClass
|
||||
public static void rememberOriginalLogger()
|
||||
{
|
||||
originalLogger = Log.getLog();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void restoreOriginalLogger()
|
||||
{
|
||||
Log.setLog(originalLogger);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedLogging()
|
||||
{
|
||||
|
|
|
@ -43,4 +43,10 @@ public class StdErrCapture
|
|||
String output = new String(test.toByteArray());
|
||||
Assert.assertThat(output,not(containsString(unexpectedString)));
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
err.flush();
|
||||
return new String(test.toByteArray());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue