0

Added support for static logger initialization

If the plugin is not ready or otherwise cannot be found, the Bukkit server
logger is used instead
This commit is contained in:
rjenkinsjr
2016-03-28 18:24:17 -04:00
parent aaee2297aa
commit 30b9978d6d
2 changed files with 206 additions and 136 deletions

View File

@@ -49,6 +49,7 @@ import java.io.InputStream;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.LogRecord; import java.util.logging.LogRecord;
import java.util.logging.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@@ -62,7 +63,7 @@ import org.yaml.snakeyaml.Yaml;
/** /**
* <p> * <p>
* A merger of SLF4J's {@code SimpleLogger} and {@code JDK14LoggerAdapter}, * A merger of SLF4J's {@code SimpleLogger} and {@code JDK14LoggerAdapter},
* wired to log all messages to the Bukkit plugin found in this plugin's * wired to log all messages to the Bukkit plugin found in this class's
* classloader (by way of reading plugin.yml). * classloader (by way of reading plugin.yml).
* </p> * </p>
* *
@@ -91,16 +92,19 @@ import org.yaml.snakeyaml.Yaml;
* level of nearest parent logger will be used, and if none is set, then the * level of nearest parent logger will be used, and if none is set, then the
* value specified by <code>slf4j.defaultLogLevel</code> will be used.</li> * value specified by <code>slf4j.defaultLogLevel</code> will be used.</li>
* *
* <li><code>slf4j.showHeader</code> -Set to <code>true</code> if you want to
* output the [SLF4J]. Defaults to <code>false</code>.</li>
*
* <li><code>slf4j.showThreadName</code> -Set to <code>true</code> if you want * <li><code>slf4j.showThreadName</code> -Set to <code>true</code> if you want
* to output the current thread name. Defaults to <code>true</code>.</li> * to output the current thread name. Defaults to <code>false</code>.</li>
* *
* <li><code>slf4j.showLogName</code> - Set to <code>true</code> if you want the * <li><code>slf4j.showLogName</code> - Set to <code>true</code> if you want the
* Logger instance name to be included in output messages. Defaults to * Logger instance name to be included in output messages. Defaults to
* <code>true</code>.</li> * <code>false</code>.</li>
* *
* <li><code>slf4j.showShortLogName</code> - Set to <code>true</code> if you * <li><code>slf4j.showShortLogName</code> - Set to <code>true</code> if you
* want the last component of the name to be included in output messages. * want the last component of the name to be included in output messages.
* Defaults to <code>false</code>.</li> * Defaults to <code>true</code>.</li>
* *
* </ul> * </ul>
* *
@@ -131,37 +135,42 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
// Plugin reference. // Plugin reference.
private static transient Plugin BUKKIT_PLUGIN; private static transient Plugin BUKKIT_PLUGIN;
// Constants for JUL record creation.
private static final String CLASS_SELF = BukkitPluginLoggerAdapter.class.getName();
private static final String CLASS_SUPER = MarkerIgnoringBase.class.getName();
// Configuration parameters. // Configuration parameters.
private static int CONFIG_DEFAULT_LOG_LEVEL; private static int CONFIG_DEFAULT_LOG_LEVEL;
private static final String CONFIG_FALLBACK_DEFAULT_LOG_LEVEL = "info"; private static final String CONFIG_FALLBACK_DEFAULT_LOG_LEVEL = "info";
private static final boolean CONFIG_FALLBACK_SHOW_LOG_NAME = true; private static final boolean CONFIG_FALLBACK_SHOW_HEADER = false;
private static final boolean CONFIG_FALLBACK_SHOW_SHORT_LOG_NAME = false; private static final boolean CONFIG_FALLBACK_SHOW_LOG_NAME = false;
private static final boolean CONFIG_FALLBACK_SHOW_THREAD_NAME = true; private static final boolean CONFIG_FALLBACK_SHOW_SHORT_LOG_NAME = true;
private static final boolean CONFIG_FALLBACK_SHOW_THREAD_NAME = false;
private static final String CONFIG_KEY_DEFAULT_LOG_LEVEL = "slf4j.defaultLogLevel"; private static final String CONFIG_KEY_DEFAULT_LOG_LEVEL = "slf4j.defaultLogLevel";
private static final String CONFIG_KEY_PREFIX_LOG = "slf4j.log."; private static final String CONFIG_KEY_PREFIX_LOG = "slf4j.log.";
private static final String CONFIG_KEY_SHOW_HEADER = "slf4j.showHeader";
private static final String CONFIG_KEY_SHOW_LOG_NAME = "slf4j.showLogName"; private static final String CONFIG_KEY_SHOW_LOG_NAME = "slf4j.showLogName";
private static final String CONFIG_KEY_SHOW_SHORT_LOG_NAME = "slf4j.showShortLogName"; private static final String CONFIG_KEY_SHOW_SHORT_LOG_NAME = "slf4j.showShortLogName";
private static final String CONFIG_KEY_SHOW_THREAD_NAME = "slf4j.showThreadName"; private static final String CONFIG_KEY_SHOW_THREAD_NAME = "slf4j.showThreadName";
private static boolean CONFIG_SHOW_HEADER;
private static boolean CONFIG_SHOW_LOG_NAME; private static boolean CONFIG_SHOW_LOG_NAME;
private static boolean CONFIG_SHOW_SHORT_LOG_NAME; private static boolean CONFIG_SHOW_SHORT_LOG_NAME;
private static boolean CONFIG_SHOW_THREAD_NAME; private static boolean CONFIG_SHOW_THREAD_NAME;
// Initialization status.
private static boolean INIT_FAILURE_WARNED = false;
// Logging level constants. // Logging level constants.
private static final int LOG_LEVEL_DEBUG = LocationAwareLogger.DEBUG_INT; private static final int LOG_LEVEL_DEBUG = LocationAwareLogger.DEBUG_INT;
private static final int LOG_LEVEL_ERROR = LocationAwareLogger.ERROR_INT; private static final int LOG_LEVEL_ERROR = LocationAwareLogger.ERROR_INT;
private static final int LOG_LEVEL_INFO = LocationAwareLogger.INFO_INT; private static final int LOG_LEVEL_INFO = LocationAwareLogger.INFO_INT;
private static final int LOG_LEVEL_TRACE = LocationAwareLogger.TRACE_INT; private static final int LOG_LEVEL_TRACE = LocationAwareLogger.TRACE_INT;
private static final int LOG_LEVEL_WARN = LocationAwareLogger.WARN_INT; private static final int LOG_LEVEL_WARN = LocationAwareLogger.WARN_INT;
// Constants for JUL record creation. // serialVersionUID
private static final String SELF = BukkitPluginLoggerAdapter.class.getName();
private static final long serialVersionUID = -2270127287235697381L; private static final long serialVersionUID = -2270127287235697381L;
private static final String SUPER = MarkerIgnoringBase.class.getName();
/** The current log level */ /** The current log level */
protected int currentLogLevel = BukkitPluginLoggerAdapter.LOG_LEVEL_INFO; protected int currentLogLevel = BukkitPluginLoggerAdapter.LOG_LEVEL_INFO;
/** The short name of this simple log instance */ /** The short name of this simple log instance */
private transient String shortLogName = null; private transient String shortLogName = null;
// WARN: BukkitPluginLoggerAdapter constructor should have only package access // NOTE: BukkitPluginLoggerAdapter constructor should have only package access
// so that only BukkitPluginLoggerFactory be able to create one. // so that only BukkitPluginLoggerFactory be able to create one.
BukkitPluginLoggerAdapter(final String name) { BukkitPluginLoggerAdapter(final String name) {
this.name = name; this.name = name;
@@ -173,59 +182,111 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
} }
} }
// Initialize class attributes, relying on plugin configuration. /**
public static void init() { * (Re)initializes all SLF4Bukkit loggers, relying on the YAML configuration
// Get a reference to the plugin in this classloader. * of the containing plugin.
InputStream pluginYmlFile = null; *
try { * @param reinitialize
pluginYmlFile = BukkitPluginLoggerAdapter.class.getClassLoader() * set to {@code true} to reinitialize all loggers, e.g. after
.getResource("plugin.yml") * reloading the plugin config.
.openStream(); */
final Yaml yaml = new Yaml(); public static void init(final boolean reinitialize) {
@SuppressWarnings("rawtypes") synchronized (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN) {
final Map pluginYml = (Map) yaml.load(pluginYmlFile); // Do not re-initialize unless requested.
BukkitPluginLoggerAdapter.BUKKIT_PLUGIN = Bukkit.getPluginManager() if (reinitialize) {
.getPlugin((String) pluginYml.get("name")); BukkitPluginLoggerAdapter.BUKKIT_PLUGIN = null;
} catch (final IOException e) { } else if (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN != null) { return; }
throw new IllegalStateException(e); // Get a reference to the plugin in this classloader.
} finally { InputStream pluginYmlFile = null;
if (pluginYmlFile != null) { String pluginName;
try { try {
pluginYmlFile.close(); pluginYmlFile = BukkitPluginLoggerAdapter.class.getClassLoader()
} catch (final IOException e) { .getResource("plugin.yml")
e.printStackTrace(); .openStream();
final Yaml yaml = new Yaml();
@SuppressWarnings("rawtypes")
final Map pluginYml = (Map) yaml.load(pluginYmlFile);
pluginName = (String) pluginYml.get("name");
} catch (final IOException e) {
throw new IllegalStateException(e);
} finally {
if (pluginYmlFile != null) {
try {
pluginYmlFile.close();
} catch (final IOException e) {
e.printStackTrace();
}
} }
} }
// Get the plugin.
BukkitPluginLoggerAdapter.BUKKIT_PLUGIN = Bukkit.getPluginManager()
.getPlugin(pluginName);
if (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN == null) {
// Initialization failed.
if (!BukkitPluginLoggerAdapter.INIT_FAILURE_WARNED) {
System.err.println("WARN: SLF4Bukkit could not be initialized for plugin "
+ pluginName + "; default configuration assumed!");
}
BukkitPluginLoggerAdapter.INIT_FAILURE_WARNED = true;
} else {
// Initialization successful.
BukkitPluginLoggerAdapter.INIT_FAILURE_WARNED = false;
}
// Get the configuration values.
// 1. Look in the plugin's on-disk config.
// 2. If the value is absent, use the plugin's built-in config.
// 3. If the value is absent, use the default values hardcoded above.
// (1 and 2 are handled by using the Bukkit API.)
BukkitPluginLoggerAdapter.CONFIG_DEFAULT_LOG_LEVEL = BukkitPluginLoggerAdapter.stringToLevel(BukkitPluginLoggerAdapter.getStringProperty(BukkitPluginLoggerAdapter.CONFIG_KEY_DEFAULT_LOG_LEVEL,
BukkitPluginLoggerAdapter.CONFIG_FALLBACK_DEFAULT_LOG_LEVEL));
BukkitPluginLoggerAdapter.CONFIG_SHOW_HEADER = BukkitPluginLoggerAdapter.getBooleanProperty(BukkitPluginLoggerAdapter.CONFIG_KEY_SHOW_HEADER,
BukkitPluginLoggerAdapter.CONFIG_FALLBACK_SHOW_HEADER);
BukkitPluginLoggerAdapter.CONFIG_SHOW_LOG_NAME = BukkitPluginLoggerAdapter.getBooleanProperty(BukkitPluginLoggerAdapter.CONFIG_KEY_SHOW_LOG_NAME,
BukkitPluginLoggerAdapter.CONFIG_FALLBACK_SHOW_LOG_NAME);
BukkitPluginLoggerAdapter.CONFIG_SHOW_SHORT_LOG_NAME = BukkitPluginLoggerAdapter.getBooleanProperty(BukkitPluginLoggerAdapter.CONFIG_KEY_SHOW_SHORT_LOG_NAME,
BukkitPluginLoggerAdapter.CONFIG_FALLBACK_SHOW_SHORT_LOG_NAME);
BukkitPluginLoggerAdapter.CONFIG_SHOW_THREAD_NAME = BukkitPluginLoggerAdapter.getBooleanProperty(BukkitPluginLoggerAdapter.CONFIG_KEY_SHOW_THREAD_NAME,
BukkitPluginLoggerAdapter.CONFIG_FALLBACK_SHOW_THREAD_NAME);
} }
// Get the configuration values.
// 1. Look in the plugin's on-disk config.
// 2. If the value is absent, use the plugin's built-in config.
// 3. If the value is absent, use the default values hardcoded above.
// (1 and 2 are handled by using the Bukkit API.)
BukkitPluginLoggerAdapter.CONFIG_DEFAULT_LOG_LEVEL = BukkitPluginLoggerAdapter.stringToLevel(BukkitPluginLoggerAdapter.getStringProperty(BukkitPluginLoggerAdapter.CONFIG_KEY_DEFAULT_LOG_LEVEL,
BukkitPluginLoggerAdapter.CONFIG_FALLBACK_DEFAULT_LOG_LEVEL));
BukkitPluginLoggerAdapter.CONFIG_SHOW_LOG_NAME = BukkitPluginLoggerAdapter.getBooleanProperty(BukkitPluginLoggerAdapter.CONFIG_KEY_SHOW_LOG_NAME,
BukkitPluginLoggerAdapter.CONFIG_FALLBACK_SHOW_LOG_NAME);
BukkitPluginLoggerAdapter.CONFIG_SHOW_SHORT_LOG_NAME = BukkitPluginLoggerAdapter.getBooleanProperty(BukkitPluginLoggerAdapter.CONFIG_KEY_SHOW_SHORT_LOG_NAME,
BukkitPluginLoggerAdapter.CONFIG_FALLBACK_SHOW_SHORT_LOG_NAME);
BukkitPluginLoggerAdapter.CONFIG_SHOW_THREAD_NAME = BukkitPluginLoggerAdapter.getBooleanProperty(BukkitPluginLoggerAdapter.CONFIG_KEY_SHOW_THREAD_NAME,
BukkitPluginLoggerAdapter.CONFIG_FALLBACK_SHOW_THREAD_NAME);
} }
private static boolean getBooleanProperty(final String name, private static boolean getBooleanProperty(final String name,
final boolean defaultValue) { final boolean defaultValue) {
final String prop = BukkitPluginLoggerAdapter.BUKKIT_PLUGIN.getConfig() synchronized (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN) {
.getString(name); if (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN == null) { return defaultValue; }
return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop); final String prop = BukkitPluginLoggerAdapter.BUKKIT_PLUGIN.getConfig()
.getString(name);
return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop);
}
}
/**
* Returns the most appropriate logger.
*
* @return the logger for the plugin if available; otherwise the server
* logger. Never null.
*/
private static Logger getBukkitLogger() {
synchronized (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN) {
return BukkitPluginLoggerAdapter.BUKKIT_PLUGIN == null ? Bukkit.getLogger()
: BukkitPluginLoggerAdapter.BUKKIT_PLUGIN.getLogger();
}
} }
private static String getStringProperty(final String name, private static String getStringProperty(final String name,
final String defaultValue) { final String defaultValue) {
final String prop = BukkitPluginLoggerAdapter.BUKKIT_PLUGIN.getConfig() synchronized (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN) {
.getString(name); if (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN == null) { return defaultValue; }
return (prop == null) ? defaultValue : prop; final String prop = BukkitPluginLoggerAdapter.BUKKIT_PLUGIN.getConfig()
.getString(name);
return (prop == null) ? defaultValue : prop;
}
} }
/*
* Logger API implementations
*/
private static int stringToLevel(final String levelStr) { private static int stringToLevel(final String levelStr) {
if ("trace".equalsIgnoreCase(levelStr)) { if ("trace".equalsIgnoreCase(levelStr)) {
return BukkitPluginLoggerAdapter.LOG_LEVEL_TRACE; return BukkitPluginLoggerAdapter.LOG_LEVEL_TRACE;
@@ -242,17 +303,13 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
} }
} }
/*
* Logger API implementations
*/
/** /**
* A simple implementation which logs messages of level DEBUG according * A simple implementation which logs messages of level DEBUG according
* to the format outlined above. * to the format outlined above.
*/ */
@Override @Override
public void debug(final String msg) { public void debug(final String msg) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_DEBUG, msg, null); BukkitPluginLoggerAdapter.LOG_LEVEL_DEBUG, msg, null);
} }
@@ -290,7 +347,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
/** Log a message of level DEBUG, including an exception. */ /** Log a message of level DEBUG, including an exception. */
@Override @Override
public void debug(final String msg, final Throwable t) { public void debug(final String msg, final Throwable t) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_DEBUG, msg, t); BukkitPluginLoggerAdapter.LOG_LEVEL_DEBUG, msg, t);
} }
@@ -300,7 +357,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
*/ */
@Override @Override
public void error(final String msg) { public void error(final String msg) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_ERROR, msg, null); BukkitPluginLoggerAdapter.LOG_LEVEL_ERROR, msg, null);
} }
@@ -337,7 +394,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
/** Log a message of level ERROR, including an exception. */ /** Log a message of level ERROR, including an exception. */
@Override @Override
public void error(final String msg, final Throwable t) { public void error(final String msg, final Throwable t) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_ERROR, msg, t); BukkitPluginLoggerAdapter.LOG_LEVEL_ERROR, msg, t);
} }
@@ -347,7 +404,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
*/ */
@Override @Override
public void info(final String msg) { public void info(final String msg) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_INFO, msg, null); BukkitPluginLoggerAdapter.LOG_LEVEL_INFO, msg, null);
} }
@@ -384,7 +441,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
/** Log a message of level INFO, including an exception. */ /** Log a message of level INFO, including an exception. */
@Override @Override
public void info(final String msg, final Throwable t) { public void info(final String msg, final Throwable t) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_INFO, msg, t); BukkitPluginLoggerAdapter.LOG_LEVEL_INFO, msg, t);
} }
@@ -435,7 +492,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
*/ */
@Override @Override
public void trace(final String msg) { public void trace(final String msg) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_TRACE, msg, null); BukkitPluginLoggerAdapter.LOG_LEVEL_TRACE, msg, null);
} }
@@ -473,7 +530,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
/** Log a message of level TRACE, including an exception. */ /** Log a message of level TRACE, including an exception. */
@Override @Override
public void trace(final String msg, final Throwable t) { public void trace(final String msg, final Throwable t) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_TRACE, msg, t); BukkitPluginLoggerAdapter.LOG_LEVEL_TRACE, msg, t);
} }
@@ -483,7 +540,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
*/ */
@Override @Override
public void warn(final String msg) { public void warn(final String msg) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_WARN, msg, null); BukkitPluginLoggerAdapter.LOG_LEVEL_WARN, msg, null);
} }
@@ -517,16 +574,67 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
arg2); arg2);
} }
/*
* Logic from SimpleLogger/JDK14LoggerAdapter
*/
/** Log a message of level WARN, including an exception. */ /** Log a message of level WARN, including an exception. */
@Override @Override
public void warn(final String msg, final Throwable t) { public void warn(final String msg, final Throwable t) {
this.log(BukkitPluginLoggerAdapter.SELF, this.log(BukkitPluginLoggerAdapter.CLASS_SELF,
BukkitPluginLoggerAdapter.LOG_LEVEL_WARN, msg, t); BukkitPluginLoggerAdapter.LOG_LEVEL_WARN, msg, t);
} }
/* /**
* SimpleLogger functionality * For formatted messages, first substitute arguments and then log.
*
* @param level
* @param format
* @param arguments
* a list of 3 ore more arguments
*/ */
private void formatAndLog(final int level, final String format,
final Object... arguments) {
BukkitPluginLoggerAdapter.init(false);
if (!this.isLevelEnabled(level)) { return; }
final FormattingTuple tp = MessageFormatter.arrayFormat(format, arguments);
this.log(BukkitPluginLoggerAdapter.CLASS_SELF, level, tp.getMessage(),
tp.getThrowable());
}
/**
* For formatted messages, first substitute arguments and then log.
*
* @param level
* @param format
* @param arg1
* @param arg2
*/
private void formatAndLog(final int level, final String format,
final Object arg1, final Object arg2) {
BukkitPluginLoggerAdapter.init(false);
if (!this.isLevelEnabled(level)) { return; }
final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
this.log(BukkitPluginLoggerAdapter.CLASS_SELF, level, tp.getMessage(),
tp.getThrowable());
}
/**
* Is the given log level currently enabled?
*
* @param logLevel
* is this level enabled?
*/
private boolean isLevelEnabled(final int logLevel) {
// log level are numerically ordered so can use simple numeric comparison
//
// the PLUGIN.getLogger().isLoggable() check avoids the unconditional
// construction of location data for disabled log statements. As of
// 2008-07-31, callers of this method do not perform this check. See also
// http://jira.qos.ch/browse/SLF4J-81
return (logLevel >= this.currentLogLevel)
&& (BukkitPluginLoggerAdapter.getBukkitLogger().isLoggable(this.slf4jLevelIntToBukkitJULLevel(logLevel)));
}
/** /**
* Fill in caller data if possible. * Fill in caller data if possible.
@@ -534,15 +642,15 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
* @param record * @param record
* The record to update * The record to update
*/ */
final private void bukkitFillCallerData(final String callerFQCN, private void
final LogRecord record) { julFillCallerData(final String callerFQCN, final LogRecord record) {
final StackTraceElement[] steArray = new Throwable().getStackTrace(); final StackTraceElement[] steArray = new Throwable().getStackTrace();
int selfIndex = -1; int selfIndex = -1;
for (int i = 0; i < steArray.length; i++) { for (int i = 0; i < steArray.length; i++) {
final String className = steArray[i].getClassName(); final String className = steArray[i].getClassName();
if (className.equals(callerFQCN) if (className.equals(callerFQCN)
|| className.equals(BukkitPluginLoggerAdapter.SUPER)) { || className.equals(BukkitPluginLoggerAdapter.CLASS_SUPER)) {
selfIndex = i; selfIndex = i;
break; break;
} }
@@ -551,7 +659,7 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
int found = -1; int found = -1;
for (int i = selfIndex + 1; i < steArray.length; i++) { for (int i = selfIndex + 1; i < steArray.length; i++) {
final String className = steArray[i].getClassName(); final String className = steArray[i].getClassName();
if (!(className.equals(callerFQCN) || className.equals(BukkitPluginLoggerAdapter.SUPER))) { if (!(className.equals(callerFQCN) || className.equals(BukkitPluginLoggerAdapter.CLASS_SUPER))) {
found = i; found = i;
break; break;
} }
@@ -573,69 +681,22 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
* *
* See bug report #13 for more details. * See bug report #13 for more details.
* *
* @param logger
* @param level * @param level
* @param msg * @param msg
* @param t * @param t
*/ */
private void bukkitLog(final String callerFQCN, final Level level, private void julLog(final Logger logger, final String callerFQCN,
final String msg, final Throwable t) { final Level level, final String msg, final Throwable t) {
// millis and thread are filled by the constructor // millis and thread are filled by the constructor
final LogRecord record = new LogRecord(level, msg); final LogRecord record = new LogRecord(level, msg);
record.setLoggerName(this.getName()); record.setLoggerName(this.getName());
record.setThrown(t); record.setThrown(t);
// Note: parameters in record are not set because SLF4J only // Note: parameters in record are not set because SLF4J only
// supports a single formatting style // supports a single formatting style
this.bukkitFillCallerData(callerFQCN, record); this.julFillCallerData(callerFQCN, record);
BukkitPluginLoggerAdapter.BUKKIT_PLUGIN.getLogger().log(record); System.out.println(logger);
} logger.log(record);
/**
* For formatted messages, first substitute arguments and then log.
*
* @param level
* @param format
* @param arguments
* a list of 3 ore more arguments
*/
private void formatAndLog(final int level, final String format,
final Object... arguments) {
if (!this.isLevelEnabled(level)) { return; }
final FormattingTuple tp = MessageFormatter.arrayFormat(format, arguments);
this.log(BukkitPluginLoggerAdapter.SELF, level, tp.getMessage(),
tp.getThrowable());
}
/**
* For formatted messages, first substitute arguments and then log.
*
* @param level
* @param format
* @param arg1
* @param arg2
*/
private void formatAndLog(final int level, final String format,
final Object arg1, final Object arg2) {
if (!this.isLevelEnabled(level)) { return; }
final FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
this.log(BukkitPluginLoggerAdapter.SELF, level, tp.getMessage(),
tp.getThrowable());
}
/**
* Is the given log level currently enabled?
*
* @param logLevel
* is this level enabled?
*/
private boolean isLevelEnabled(final int logLevel) {
// log level are numerically ordered so can use simple numeric comparison
//
// the PLUGIN.getLogger().isLoggable() check avoids the unconditional
// construction of location data for disabled log statements. As of
// 2008-07-31, callers of this method do not perform this check. See also
// http://jira.qos.ch/browse/SLF4J-81
return (logLevel >= this.currentLogLevel)
&& (BukkitPluginLoggerAdapter.BUKKIT_PLUGIN.getLogger().isLoggable(this.slf4jLevelIntToBukkitJULLevel(logLevel)));
} }
/** /**
@@ -653,21 +714,36 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
*/ */
private void log(final String callerFQCN, final int level, private void log(final String callerFQCN, final int level,
final String message, final Throwable t) { final String message, final Throwable t) {
// Determine which logger will be used.
final Logger logger = BukkitPluginLoggerAdapter.getBukkitLogger();
// Ensure that the logger will accept this request.
BukkitPluginLoggerAdapter.init(false);
if (!this.isLevelEnabled(level)) { return; } if (!this.isLevelEnabled(level)) { return; }
// Prepare message
final StringBuilder buf = new StringBuilder(32); final StringBuilder buf = new StringBuilder(32);
// Indicate that this message comes from SLF4J // Indicate that this message comes from SLF4J
buf.append("[SLF4J"); buf.append('[');
if (BukkitPluginLoggerAdapter.CONFIG_SHOW_HEADER) {
buf.append("SLF4J");
}
// Append a readable representation of the log level, but only for log // Append a readable representation of the log level, but only for log
// levels that Bukkit would otherwise eat // levels that Bukkit would otherwise eat
switch (level) { switch (level) {
case LOG_LEVEL_TRACE: case LOG_LEVEL_TRACE:
buf.append(":TRACE"); if (BukkitPluginLoggerAdapter.CONFIG_SHOW_HEADER) {
buf.append('|');
}
buf.append("TRACE");
break; break;
case LOG_LEVEL_DEBUG: case LOG_LEVEL_DEBUG:
buf.append(":DEBUG"); if (BukkitPluginLoggerAdapter.CONFIG_SHOW_HEADER) {
buf.append('|');
}
buf.append("DEBUG");
break; break;
} }
buf.append("] "); buf.append("] ");
@@ -693,15 +769,10 @@ public final class BukkitPluginLoggerAdapter extends MarkerIgnoringBase
buf.append(message); buf.append(message);
// Log to Bukkit // Log to Bukkit
this.bukkitLog(BukkitPluginLoggerAdapter.SELF, this.julLog(logger, BukkitPluginLoggerAdapter.CLASS_SELF,
this.slf4jLevelIntToBukkitJULLevel(level), buf.toString(), t); this.slf4jLevelIntToBukkitJULLevel(level), buf.toString(), t);
} }
/*
* JDK14LoggerAdapter functionality
*/
private String recursivelyComputeLevelString() { private String recursivelyComputeLevelString() {
String tempName = this.name; String tempName = this.name;
String levelString = null; String levelString = null;

View File

@@ -65,7 +65,6 @@ public class BukkitPluginLoggerFactory implements ILoggerFactory {
public BukkitPluginLoggerFactory() { public BukkitPluginLoggerFactory() {
this.loggerMap = new ConcurrentHashMap<String, Logger>(); this.loggerMap = new ConcurrentHashMap<String, Logger>();
BukkitPluginLoggerAdapter.init();
// ensure jul initialization. see also SLF4J-359 // ensure jul initialization. see also SLF4J-359
java.util.logging.LogManager.getLogManager(); java.util.logging.LogManager.getLogManager();
} }