//
// ========================================================================
// Copyright (c) 1995-2019 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;
import java.util.Properties;
Abstract Logger.
Manages the atomic registration of the logger by name.
/**
* Abstract Logger.
* Manages the atomic registration of the logger by name.
*/
public abstract class AbstractLogger implements Logger
{
public static final int LEVEL_DEFAULT = -1;
public static final int LEVEL_ALL = 0;
public static final int LEVEL_DEBUG = 1;
public static final int LEVEL_INFO = 2;
public static final int LEVEL_WARN = 3;
public static final int LEVEL_OFF = 10;
@Override
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
Params: - name – the name to test
Returns: true for null or blank name, false if any non-whitespace character is found.
/**
* 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 the Logging Level for the provided log name. Using the FQCN first, then each package segment from longest to
shortest.
Params: - props – the properties to check
- name – the name to get log for
Returns: the logging level
/**
* Get the Logging Level for the provided log name. Using the FQCN first, then each package segment from longest to
* shortest.
*
* @param props the properties to check
* @param name the name to get log for
* @return the logging level
*/
public static int lookupLoggingLevel(Properties props, final String name)
{
if ((props == null) || (props.isEmpty()) || name == null)
return LEVEL_DEFAULT;
// Calculate the level this named logger should operate under.
// Checking with FQCN first, then each package segment from longest to shortest.
String nameSegment = name;
while ((nameSegment != null) && (nameSegment.length() > 0))
{
String levelStr = props.getProperty(nameSegment + ".LEVEL");
// System.err.printf("[StdErrLog.CONFIG] Checking for property [%s.LEVEL] = %s%n",nameSegment,levelStr);
int level = getLevelId(nameSegment + ".LEVEL", levelStr);
if (level != (-1))
{
return level;
}
// Trim and try again.
int idx = nameSegment.lastIndexOf('.');
if (idx >= 0)
{
nameSegment = nameSegment.substring(0, idx);
}
else
{
nameSegment = null;
}
}
// Default Logging Level
return LEVEL_DEFAULT;
}
public static String getLoggingProperty(Properties props, String name, String property)
{
// Calculate the level this named logger should operate under.
// Checking with FQCN first, then each package segment from longest to shortest.
String nameSegment = name;
while ((nameSegment != null) && (nameSegment.length() > 0))
{
String s = props.getProperty(nameSegment + "." + property);
if (s != null)
return s;
// Trim and try again.
int idx = nameSegment.lastIndexOf('.');
nameSegment = (idx >= 0) ? nameSegment.substring(0, idx) : null;
}
return null;
}
protected static int getLevelId(String levelSegment, String levelName)
{
if (levelName == null)
{
return -1;
}
String levelStr = levelName.trim();
if ("ALL".equalsIgnoreCase(levelStr))
{
return LEVEL_ALL;
}
else if ("DEBUG".equalsIgnoreCase(levelStr))
{
return LEVEL_DEBUG;
}
else if ("INFO".equalsIgnoreCase(levelStr))
{
return LEVEL_INFO;
}
else if ("WARN".equalsIgnoreCase(levelStr))
{
return LEVEL_WARN;
}
else if ("OFF".equalsIgnoreCase(levelStr))
{
return LEVEL_OFF;
}
System.err.println("Unknown StdErrLog level [" + levelSegment + "]=[" + levelStr + "], expecting only [ALL, DEBUG, INFO, WARN, OFF] as values.");
return -1;
}
Condenses a classname by stripping down the package name to just the first character of each package name
segment.Configured
Examples:
"org.eclipse.jetty.test.FooTest" = "oejt.FooTest"
"org.eclipse.jetty.server.logging.LogTest" = "orjsl.LogTest"
Params: - classname – the fully qualified class name
Returns: the condensed name
/**
* Condenses a classname by stripping down the package name to just the first character of each package name
* segment.Configured
*
* <pre>
* Examples:
* "org.eclipse.jetty.test.FooTest" = "oejt.FooTest"
* "org.eclipse.jetty.server.logging.LogTest" = "orjsl.LogTest"
* </pre>
*
* @param classname the fully qualified class name
* @return the condensed name
*/
@SuppressWarnings("Duplicates")
protected static String condensePackageString(String classname)
{
if (classname == null || classname.isEmpty())
{
return "";
}
int rawLen = classname.length();
StringBuilder dense = new StringBuilder(rawLen);
boolean foundStart = false;
boolean hasPackage = false;
int startIdx = -1;
int endIdx = -1;
for (int i = 0; i < rawLen; i++)
{
char c = classname.charAt(i);
if (!foundStart)
{
foundStart = Character.isJavaIdentifierStart(c);
if (foundStart)
{
if (startIdx >= 0)
{
dense.append(classname.charAt(startIdx));
hasPackage = true;
}
startIdx = i;
}
}
if (foundStart)
{
if (!Character.isJavaIdentifierPart(c))
{
foundStart = false;
}
else
{
endIdx = i;
}
}
}
// append remaining from startIdx
if ((startIdx >= 0) && (endIdx >= startIdx))
{
if (hasPackage)
{
dense.append('.');
}
dense.append(classname, startIdx, endIdx + 1);
}
return dense.toString();
}
@Override
public void debug(String msg, long arg)
{
if (isDebugEnabled())
{
debug(msg, new Object[]{arg});
}
}
}