diff --git a/NOTICE.txt b/NOTICE.txt
index 15f070e5bd..cda0d4ce33 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -59,13 +59,21 @@ WebSocket and HTTP server, which can be obtained at:
* https://github.com/joewalnes/webbit
This product contains a modified portion of 'Caliper', Google's micro-
-benchmarking framework, which can be obtained at::
+benchmarking framework, which can be obtained at:
* LICENSE:
* license/LICENSE.caliper.txt (Apache License 2.0)
* HOMEPAGE:
* http://code.google.com/p/caliper/
+This product contains a modified portion of 'SLF4J', a simple logging
+facade for Java, which can be obtained at:
+
+ * LICENSE:
+ * license/LICENSE.slf4j.txt (MIT License)
+ * HOMEPAGE:
+ * http://www.slf4j.org/
+
This product optionally depends on 'Metrics', Yammer's JVM- and application-
level metrics library, which can be obtained at:
@@ -90,16 +98,6 @@ serialization API, which can be obtained at:
* HOMEPAGE:
* http://www.jboss.org/jbossmarshalling
-This product optionally depends on 'SLF4J', a simple logging facade for Java.
-The monitor registries implementation is based on the approach used by SLF4J.
-
-Slf4j can be obtained at:
-
- * LICENSE:
- * license/LICENSE.slf4j.txt (MIT License)
- * HOMEPAGE:
- * http://www.slf4j.org/
-
This product optionally depends on 'Apache Commons Logging', a logging
framework, which can be obtained at:
@@ -116,22 +114,6 @@ can be obtained at:
* HOMEPAGE:
* http://logging.apache.org/log4j/
-This product optionally depends on 'JBoss Logging', a logging framework, which
-can be obtained at:
-
- * LICENSE:
- * license/LICENSE.jboss-logging.txt (GNU LGPL 2.1)
- * HOMEPAGE:
- * http://anonsvn.jboss.org/repos/common/common-logging-spi/
-
-This product optionally depends on 'OSGi Service Platform API', which can be
-obtained at:
-
- * LICENSE:
- * license/LICENSE.osgi.txt (Apache License 2.0)
- * HOMEPAGE:
- * http://www.osgi.org/
-
This product optionally depends on 'Snappy', a compression library produced
by Google Inc, which can be obtained at:
diff --git a/all/pom.xml b/all/pom.xml
index 9d0b3ac7ca..0070b99ac6 100644
--- a/all/pom.xml
+++ b/all/pom.xml
@@ -86,37 +86,16 @@
org.slf4jslf4j-api
- compiletruecommons-loggingcommons-logging
- compile
- true
-
-
- org.jboss.logging
- jboss-logging-spi
- compiletruelog4jlog4j
- compile
- true
-
-
- org.osgi
- org.osgi.core
- compile
- true
-
-
- org.osgi
- org.osgi.compendium
- compiletrue
@@ -288,7 +267,6 @@
-link http://docs.oracle.com/javase/7/docs/api/
-link http://code.google.com/apis/protocolbuffers/docs/reference/java/
-link http://docs.oracle.com/javaee/6/api/
- -link http://www.osgi.org/javadoc/r4v43/core/
-link http://www.slf4j.org/apidocs/
-link http://commons.apache.org/logging/commons-logging-1.1.1/apidocs/
-link http://logging.apache.org/log4j/1.2/apidocs/
diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java
index 61ab25119c..b7922a3a7a 100644
--- a/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/websocketx/WebSocket08FrameDecoder.java
@@ -139,7 +139,7 @@ public class WebSocket08FrameDecoder extends ReplayingDecoderorg.slf4jslf4j-api
- compiletruecommons-loggingcommons-logging
- compile
- true
-
-
- org.jboss.logging
- jboss-logging-spi
- compiletruelog4jlog4j
- compile
- true
-
-
- org.osgi
- org.osgi.core
- compile
- true
-
-
- org.osgi
- org.osgi.compendium
- compiletrue
diff --git a/common/src/main/java/io/netty/logging/AbstractInternalLogger.java b/common/src/main/java/io/netty/logging/AbstractInternalLogger.java
index e88a2e3879..99516a45ab 100644
--- a/common/src/main/java/io/netty/logging/AbstractInternalLogger.java
+++ b/common/src/main/java/io/netty/logging/AbstractInternalLogger.java
@@ -15,17 +15,33 @@
*/
package io.netty.logging;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
/**
* A skeletal implementation of {@link InternalLogger}. This class implements
* all methods that have a {@link InternalLogLevel} parameter by default to call
* specific logger methods such as {@link #info(String)} or {@link #isInfoEnabled()}.
*/
-public abstract class AbstractInternalLogger implements InternalLogger {
+public abstract class AbstractInternalLogger implements InternalLogger, Serializable {
+
+ private static final long serialVersionUID = -6382972526573193470L;
+
+ private final String name;
/**
* Creates a new instance.
*/
- protected AbstractInternalLogger() {
+ protected AbstractInternalLogger(String name) {
+ if (name == null) {
+ throw new NullPointerException("name");
+ }
+ this.name = name;
+ }
+
+ @Override
+ public String name() {
+ return name;
}
@Override
@@ -91,4 +107,82 @@ public abstract class AbstractInternalLogger implements InternalLogger {
throw new Error();
}
}
+
+ @Override
+ public void log(InternalLogLevel level, String format, Object arg) {
+ switch (level) {
+ case TRACE:
+ trace(format, arg);
+ break;
+ case DEBUG:
+ debug(format, arg);
+ break;
+ case INFO:
+ info(format, arg);
+ break;
+ case WARN:
+ warn(format, arg);
+ break;
+ case ERROR:
+ error(format, arg);
+ break;
+ default:
+ throw new Error();
+ }
+ }
+
+ @Override
+ public void log(InternalLogLevel level, String format, Object argA, Object argB) {
+ switch (level) {
+ case TRACE:
+ trace(format, argA, argB);
+ break;
+ case DEBUG:
+ debug(format, argA, argB);
+ break;
+ case INFO:
+ info(format, argA, argB);
+ break;
+ case WARN:
+ warn(format, argA, argB);
+ break;
+ case ERROR:
+ error(format, argA, argB);
+ break;
+ default:
+ throw new Error();
+ }
+ }
+
+ @Override
+ public void log(InternalLogLevel level, String format, Object... arguments) {
+ switch (level) {
+ case TRACE:
+ trace(format, arguments);
+ break;
+ case DEBUG:
+ debug(format, arguments);
+ break;
+ case INFO:
+ info(format, arguments);
+ break;
+ case WARN:
+ warn(format, arguments);
+ break;
+ case ERROR:
+ error(format, arguments);
+ break;
+ default:
+ throw new Error();
+ }
+ }
+
+ protected Object readResolve() throws ObjectStreamException {
+ return InternalLoggerFactory.getInstance(name());
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + '(' + name() + ')';
+ }
}
diff --git a/common/src/main/java/io/netty/logging/CommonsLogger.java b/common/src/main/java/io/netty/logging/CommonsLogger.java
index 9a3378d31c..521585c94c 100644
--- a/common/src/main/java/io/netty/logging/CommonsLogger.java
+++ b/common/src/main/java/io/netty/logging/CommonsLogger.java
@@ -13,6 +13,30 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
package io.netty.logging;
import org.apache.commons.logging.Log;
@@ -23,91 +47,518 @@ import org.apache.commons.logging.Log;
*/
class CommonsLogger extends AbstractInternalLogger {
- private final Log logger;
- private final String loggerName;
+ private static final long serialVersionUID = 8647838678388394885L;
- CommonsLogger(Log logger, String loggerName) {
+ private final transient Log logger;
+
+ CommonsLogger(Log logger, String name) {
+ super(name);
+ if (logger == null) {
+ throw new NullPointerException("logger");
+ }
this.logger = logger;
- this.loggerName = loggerName;
- }
-
- @Override
- public void trace(String msg) {
- logger.trace(msg);
- }
-
- @Override
- public void trace(String msg, Throwable cause) {
- logger.trace(msg, cause);
- }
-
- @Override
- public void debug(String msg) {
- logger.debug(msg);
- }
-
- @Override
- public void debug(String msg, Throwable cause) {
- logger.debug(msg, cause);
- }
-
- @Override
- public void error(String msg) {
- logger.error(msg);
- }
-
- @Override
- public void error(String msg, Throwable cause) {
- logger.error(msg, cause);
- }
-
- @Override
- public void info(String msg) {
- logger.info(msg);
- }
-
- @Override
- public void info(String msg, Throwable cause) {
- logger.info(msg, cause);
}
+ /**
+ * Delegates to the {@link Log#isTraceEnabled} method of the underlying
+ * {@link Log} instance.
+ */
@Override
public boolean isTraceEnabled() {
return logger.isTraceEnabled();
}
+ /**
+ * Delegates to the {@link Log#trace(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ * @param msg - the message object to be logged
+ */
+ @Override
+ public void trace(String msg) {
+ logger.trace(msg);
+ }
+
+ /**
+ * Delegates to the {@link Log#trace(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level TRACE.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void trace(String format, Object arg) {
+ if (logger.isTraceEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.trace(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#trace(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level TRACE.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void trace(String format, Object argA, Object argB) {
+ if (logger.isTraceEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.trace(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#trace(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level TRACE.
+ *
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ @Override
+ public void trace(String format, Object... arguments) {
+ if (logger.isTraceEnabled()) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
+ logger.trace(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#trace(Object, Throwable)} method of
+ * the underlying {@link Log} instance.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void trace(String msg, Throwable t) {
+ logger.trace(msg, t);
+ }
+
+ /**
+ * Delegates to the {@link Log#isDebugEnabled} method of the underlying
+ * {@link Log} instance.
+ */
@Override
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
+ //
+
+ /**
+ * Delegates to the {@link Log#debug(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ * @param msg - the message object to be logged
+ */
@Override
- public boolean isErrorEnabled() {
- return logger.isErrorEnabled();
+ public void debug(String msg) {
+ logger.debug(msg);
}
+ /**
+ * Delegates to the {@link Log#debug(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level DEBUG.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void debug(String format, Object arg) {
+ if (logger.isDebugEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.debug(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#debug(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level DEBUG.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void debug(String format, Object argA, Object argB) {
+ if (logger.isDebugEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.debug(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#debug(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level DEBUG.
+ *
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ @Override
+ public void debug(String format, Object... arguments) {
+ if (logger.isDebugEnabled()) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
+ logger.debug(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#debug(Object, Throwable)} method of
+ * the underlying {@link Log} instance.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void debug(String msg, Throwable t) {
+ logger.debug(msg, t);
+ }
+
+ /**
+ * Delegates to the {@link Log#isInfoEnabled} method of the underlying
+ * {@link Log} instance.
+ */
@Override
public boolean isInfoEnabled() {
return logger.isInfoEnabled();
}
+ /**
+ * Delegates to the {@link Log#debug(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ * @param msg - the message object to be logged
+ */
+ @Override
+ public void info(String msg) {
+ logger.info(msg);
+ }
+
+ /**
+ * Delegates to the {@link Log#info(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level INFO.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+
+ @Override
+ public void info(String format, Object arg) {
+ if (logger.isInfoEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.info(ft.getMessage(), ft.getThrowable());
+ }
+ }
+ /**
+ * Delegates to the {@link Log#info(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level INFO.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void info(String format, Object argA, Object argB) {
+ if (logger.isInfoEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.info(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#info(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level INFO.
+ *
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ @Override
+ public void info(String format, Object... arguments) {
+ if (logger.isInfoEnabled()) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
+ logger.info(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#info(Object, Throwable)} method of
+ * the underlying {@link Log} instance.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void info(String msg, Throwable t) {
+ logger.info(msg, t);
+ }
+
+ /**
+ * Delegates to the {@link Log#isWarnEnabled} method of the underlying
+ * {@link Log} instance.
+ */
@Override
public boolean isWarnEnabled() {
return logger.isWarnEnabled();
}
+ /**
+ * Delegates to the {@link Log#warn(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ * @param msg - the message object to be logged
+ */
@Override
public void warn(String msg) {
logger.warn(msg);
}
+ /**
+ * Delegates to the {@link Log#warn(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level WARN.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
@Override
- public void warn(String msg, Throwable cause) {
- logger.warn(msg, cause);
+ public void warn(String format, Object arg) {
+ if (logger.isWarnEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.warn(ft.getMessage(), ft.getThrowable());
+ }
}
+ /**
+ * Delegates to the {@link Log#warn(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level WARN.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
@Override
- public String toString() {
- return loggerName;
+ public void warn(String format, Object argA, Object argB) {
+ if (logger.isWarnEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.warn(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#warn(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level WARN.
+ *
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ @Override
+ public void warn(String format, Object... arguments) {
+ if (logger.isWarnEnabled()) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
+ logger.warn(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#warn(Object, Throwable)} method of
+ * the underlying {@link Log} instance.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+
+ @Override
+ public void warn(String msg, Throwable t) {
+ logger.warn(msg, t);
+ }
+
+ /**
+ * Delegates to the {@link Log#isErrorEnabled} method of the underlying
+ * {@link Log} instance.
+ */
+ @Override
+ public boolean isErrorEnabled() {
+ return logger.isErrorEnabled();
+ }
+
+ /**
+ * Delegates to the {@link Log#error(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ * @param msg - the message object to be logged
+ */
+ @Override
+ public void error(String msg) {
+ logger.error(msg);
+ }
+
+ /**
+ * Delegates to the {@link Log#error(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level ERROR.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void error(String format, Object arg) {
+ if (logger.isErrorEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.error(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#error(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level ERROR.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void error(String format, Object argA, Object argB) {
+ if (logger.isErrorEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.error(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#error(Object)} method of the underlying
+ * {@link Log} instance.
+ *
+ *
+ * However, this form avoids superfluous object creation when the logger is disabled
+ * for level ERROR.
+ *
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ @Override
+ public void error(String format, Object... arguments) {
+ if (logger.isErrorEnabled()) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
+ logger.error(ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Delegates to the {@link Log#error(Object, Throwable)} method of
+ * the underlying {@link Log} instance.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void error(String msg, Throwable t) {
+ logger.error(msg, t);
}
}
diff --git a/common/src/main/java/io/netty/logging/CommonsLoggerFactory.java b/common/src/main/java/io/netty/logging/CommonsLoggerFactory.java
index 480ff20d78..77790a7af6 100644
--- a/common/src/main/java/io/netty/logging/CommonsLoggerFactory.java
+++ b/common/src/main/java/io/netty/logging/CommonsLoggerFactory.java
@@ -18,6 +18,9 @@ package io.netty.logging;
import org.apache.commons.logging.LogFactory;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* Logger factory which creates an
* Apache Commons Logging
@@ -25,6 +28,8 @@ import org.apache.commons.logging.LogFactory;
*/
public class CommonsLoggerFactory extends InternalLoggerFactory {
+ Map loggerMap = new HashMap();
+
@Override
public InternalLogger newInstance(String name) {
return new CommonsLogger(LogFactory.getLog(name), name);
diff --git a/common/src/main/java/io/netty/logging/FormattingTuple.java b/common/src/main/java/io/netty/logging/FormattingTuple.java
new file mode 100644
index 0000000000..2fbe0ad2b6
--- /dev/null
+++ b/common/src/main/java/io/netty/logging/FormattingTuple.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2013 The Netty Project
+ *
+ * The Netty Project licenses this file to you 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.
+ */
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+package io.netty.logging;
+
+/**
+ * Holds the results of formatting done by {@link MessageFormatter}.
+ */
+class FormattingTuple {
+
+ static final FormattingTuple NULL = new FormattingTuple(null);
+
+ private final String message;
+ private final Throwable throwable;
+ private final Object[] argArray;
+
+ FormattingTuple(String message) {
+ this(message, null, null);
+ }
+
+ FormattingTuple(String message, Object[] argArray, Throwable throwable) {
+ this.message = message;
+ this.throwable = throwable;
+ if (throwable == null) {
+ this.argArray = argArray;
+ } else {
+ this.argArray = trimmedCopy(argArray);
+ }
+ }
+
+ static Object[] trimmedCopy(Object[] argArray) {
+ if (argArray == null || argArray.length == 0) {
+ throw new IllegalStateException("non-sensical empty or null argument array");
+ }
+ final int trimemdLen = argArray.length - 1;
+ Object[] trimmed = new Object[trimemdLen];
+ System.arraycopy(argArray, 0, trimmed, 0, trimemdLen);
+ return trimmed;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public Object[] getArgArray() {
+ return argArray;
+ }
+
+ public Throwable getThrowable() {
+ return throwable;
+ }
+}
diff --git a/common/src/main/java/io/netty/logging/InternalLogger.java b/common/src/main/java/io/netty/logging/InternalLogger.java
index 1b1496ff8e..1824195db2 100644
--- a/common/src/main/java/io/netty/logging/InternalLogger.java
+++ b/common/src/main/java/io/netty/logging/InternalLogger.java
@@ -13,6 +13,30 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
package io.netty.logging;
/**
@@ -20,93 +44,401 @@ package io.netty.logging;
* access this class outside of Netty.
*/
public interface InternalLogger {
+
/**
- * Returns {@code true} if a TRACE level message is logged.
+ * Return the name of this {@link InternalLogger} instance.
+ *
+ * @return name of this logger instance
+ */
+ String name();
+
+ /**
+ * Is the logger instance enabled for the TRACE level?
+ *
+ * @return True if this Logger is enabled for the TRACE level,
+ * false otherwise.
*/
boolean isTraceEnabled();
/**
- * Returns {@code true} if a DEBUG level message is logged.
- */
- boolean isDebugEnabled();
-
- /**
- * Returns {@code true} if an INFO level message is logged.
- */
- boolean isInfoEnabled();
-
- /**
- * Returns {@code true} if a WARN level message is logged.
- */
- boolean isWarnEnabled();
-
- /**
- * Returns {@code true} if an ERROR level message is logged.
- */
- boolean isErrorEnabled();
-
- /**
- * Returns {@code true} if the specified log level message is logged.
- */
- boolean isEnabled(InternalLogLevel level);
-
- /**
- * Logs a TRACE level message.
+ * Log a message at the TRACE level.
+ *
+ * @param msg the message string to be logged
*/
void trace(String msg);
/**
- * Logs a TRACE level message.
+ * Log a message at the TRACE level according to the specified format
+ * and argument.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the TRACE level.
+ *
+ * @param format the format string
+ * @param arg the argument
*/
- void trace(String msg, Throwable cause);
+ void trace(String format, Object arg);
/**
- * Logs a DEBUG level message.
+ * Log a message at the TRACE level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the TRACE level.
+ *
+ * @param format the format string
+ * @param argA the first argument
+ * @param argB the second argument
+ */
+ void trace(String format, Object argA, Object argB);
+
+ /**
+ * Log a message at the TRACE level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous string concatenation when the logger
+ * is disabled for the TRACE level. However, this variant incurs the hidden
+ * (and relatively small) cost of creating an {@code Object[]} before invoking the method,
+ * even if this logger is disabled for TRACE. The variants taking {@link #trace(String, Object) one} and
+ * {@link #trace(String, Object, Object) two} arguments exist solely in order to avoid this hidden cost.
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ void trace(String format, Object... arguments);
+
+ /**
+ * Log an exception (throwable) at the TRACE level with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ */
+ void trace(String msg, Throwable t);
+
+ /**
+ * Is the logger instance enabled for the DEBUG level?
+ *
+ * @return True if this Logger is enabled for the DEBUG level,
+ * false otherwise.
+ */
+ boolean isDebugEnabled();
+
+ /**
+ * Log a message at the DEBUG level.
+ *
+ * @param msg the message string to be logged
*/
void debug(String msg);
/**
- * Logs a DEBUG level message.
+ * Log a message at the DEBUG level according to the specified format
+ * and argument.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the DEBUG level.
+ *
+ * @param format the format string
+ * @param arg the argument
*/
- void debug(String msg, Throwable cause);
+ void debug(String format, Object arg);
/**
- * Logs an INFO level message.
+ * Log a message at the DEBUG level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the DEBUG level.
+ *
+ * @param format the format string
+ * @param argA the first argument
+ * @param argB the second argument
+ */
+ void debug(String format, Object argA, Object argB);
+
+ /**
+ * Log a message at the DEBUG level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous string concatenation when the logger
+ * is disabled for the DEBUG level. However, this variant incurs the hidden
+ * (and relatively small) cost of creating an {@code Object[]} before invoking the method,
+ * even if this logger is disabled for DEBUG. The variants taking
+ * {@link #debug(String, Object) one} and {@link #debug(String, Object, Object) two}
+ * arguments exist solely in order to avoid this hidden cost.
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ void debug(String format, Object... arguments);
+
+ /**
+ * Log an exception (throwable) at the DEBUG level with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ */
+ void debug(String msg, Throwable t);
+
+ /**
+ * Is the logger instance enabled for the INFO level?
+ *
+ * @return True if this Logger is enabled for the INFO level,
+ * false otherwise.
+ */
+ boolean isInfoEnabled();
+
+ /**
+ * Log a message at the INFO level.
+ *
+ * @param msg the message string to be logged
*/
void info(String msg);
/**
- * Logs an INFO level message.
+ * Log a message at the INFO level according to the specified format
+ * and argument.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the INFO level.
+ *
+ * @param format the format string
+ * @param arg the argument
*/
- void info(String msg, Throwable cause);
+ void info(String format, Object arg);
/**
- * Logs a WARN level message.
+ * Log a message at the INFO level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the INFO level.
+ *
+ * @param format the format string
+ * @param argA the first argument
+ * @param argB the second argument
+ */
+ void info(String format, Object argA, Object argB);
+
+ /**
+ * Log a message at the INFO level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous string concatenation when the logger
+ * is disabled for the INFO level. However, this variant incurs the hidden
+ * (and relatively small) cost of creating an {@code Object[]} before invoking the method,
+ * even if this logger is disabled for INFO. The variants taking
+ * {@link #info(String, Object) one} and {@link #info(String, Object, Object) two}
+ * arguments exist solely in order to avoid this hidden cost.
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ void info(String format, Object... arguments);
+
+ /**
+ * Log an exception (throwable) at the INFO level with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ */
+ void info(String msg, Throwable t);
+
+ /**
+ * Is the logger instance enabled for the WARN level?
+ *
+ * @return True if this Logger is enabled for the WARN level,
+ * false otherwise.
+ */
+ boolean isWarnEnabled();
+
+ /**
+ * Log a message at the WARN level.
+ *
+ * @param msg the message string to be logged
*/
void warn(String msg);
/**
- * Logs a WARN level message.
+ * Log a message at the WARN level according to the specified format
+ * and argument.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the WARN level.
+ *
+ * @param format the format string
+ * @param arg the argument
*/
- void warn(String msg, Throwable cause);
+ void warn(String format, Object arg);
/**
- * Logs an ERROR level message.
+ * Log a message at the WARN level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous string concatenation when the logger
+ * is disabled for the WARN level. However, this variant incurs the hidden
+ * (and relatively small) cost of creating an {@code Object[]} before invoking the method,
+ * even if this logger is disabled for WARN. The variants taking
+ * {@link #warn(String, Object) one} and {@link #warn(String, Object, Object) two}
+ * arguments exist solely in order to avoid this hidden cost.
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ void warn(String format, Object... arguments);
+
+ /**
+ * Log a message at the WARN level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the WARN level.
+ *
+ * @param format the format string
+ * @param argA the first argument
+ * @param argB the second argument
+ */
+ void warn(String format, Object argA, Object argB);
+
+ /**
+ * Log an exception (throwable) at the WARN level with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ */
+ void warn(String msg, Throwable t);
+
+ /**
+ * Is the logger instance enabled for the ERROR level?
+ *
+ * @return True if this Logger is enabled for the ERROR level,
+ * false otherwise.
+ */
+ boolean isErrorEnabled();
+
+ /**
+ * Log a message at the ERROR level.
+ *
+ * @param msg the message string to be logged
*/
void error(String msg);
/**
- * Logs an ERROR level message.
+ * Log a message at the ERROR level according to the specified format
+ * and argument.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the ERROR level.
+ *
+ * @param format the format string
+ * @param arg the argument
*/
- void error(String msg, Throwable cause);
+ void error(String format, Object arg);
/**
- * Logs a message.
+ * Log a message at the ERROR level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the ERROR level.
+ *
+ * @param format the format string
+ * @param argA the first argument
+ * @param argB the second argument
+ */
+ void error(String format, Object argA, Object argB);
+
+ /**
+ * Log a message at the ERROR level according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous string concatenation when the logger
+ * is disabled for the ERROR level. However, this variant incurs the hidden
+ * (and relatively small) cost of creating an {@code Object[]} before invoking the method,
+ * even if this logger is disabled for ERROR. The variants taking
+ * {@link #error(String, Object) one} and {@link #error(String, Object, Object) two}
+ * arguments exist solely in order to avoid this hidden cost.
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ void error(String format, Object... arguments);
+
+ /**
+ * Log an exception (throwable) at the ERROR level with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ */
+ void error(String msg, Throwable t);
+
+ /**
+ * Is the logger instance enabled for the specified {@code level}?
+ *
+ * @return True if this Logger is enabled for the specified {@code level},
+ * false otherwise.
+ */
+ boolean isEnabled(InternalLogLevel level);
+
+ /**
+ * Log a message at the specified {@code level}.
+ *
+ * @param msg the message string to be logged
*/
void log(InternalLogLevel level, String msg);
/**
- * Logs a message.
+ * Log a message at the specified {@code level} according to the specified format
+ * and argument.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the specified {@code level}.
+ *
+ * @param format the format string
+ * @param arg the argument
*/
- void log(InternalLogLevel level, String msg, Throwable cause);
+ void log(InternalLogLevel level, String format, Object arg);
+
+ /**
+ * Log a message at the specified {@code level} according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous object creation when the logger
+ * is disabled for the specified {@code level}.
+ *
+ * @param format the format string
+ * @param argA the first argument
+ * @param argB the second argument
+ */
+ void log(InternalLogLevel level, String format, Object argA, Object argB);
+
+ /**
+ * Log a message at the specified {@code level} according to the specified format
+ * and arguments.
+ *
+ *
This form avoids superfluous string concatenation when the logger
+ * is disabled for the specified {@code level}. However, this variant incurs the hidden
+ * (and relatively small) cost of creating an {@code Object[]} before invoking the method,
+ * even if this logger is disabled for the specified {@code level}. The variants taking
+ * {@link #log(InternalLogLevel, String, Object) one} and
+ * {@link #log(InternalLogLevel, String, Object, Object) two} arguments exist solely
+ * in order to avoid this hidden cost.
+ *
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ */
+ void log(InternalLogLevel level, String format, Object... arguments);
+
+ /**
+ * Log an exception (throwable) at the specified {@code level} with an
+ * accompanying message.
+ *
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ */
+ void log(InternalLogLevel level, String msg, Throwable t);
}
diff --git a/common/src/main/java/io/netty/logging/InternalLoggerFactory.java b/common/src/main/java/io/netty/logging/InternalLoggerFactory.java
index 90cd8b4f02..9898bf5050 100644
--- a/common/src/main/java/io/netty/logging/InternalLoggerFactory.java
+++ b/common/src/main/java/io/netty/logging/InternalLoggerFactory.java
@@ -32,7 +32,27 @@ package io.netty.logging;
* @apiviz.has io.netty.logging.InternalLogger oneway - - creates
*/
public abstract class InternalLoggerFactory {
- private static volatile InternalLoggerFactory defaultFactory = new JdkLoggerFactory();
+ private static volatile InternalLoggerFactory defaultFactory;
+
+ static {
+ final String name = InternalLoggerFactory.class.getName();
+ InternalLoggerFactory f;
+ try {
+ f = new Slf4JLoggerFactory(true);
+ f.newInstance(name).debug("Using SLF4J as the default logging framework");
+ defaultFactory = f;
+ } catch (Throwable t1) {
+ try {
+ f = new Log4JLoggerFactory();
+ f.newInstance(name).debug("Using Log4J as the default logging framework");
+ } catch (Throwable t2) {
+ f = new JdkLoggerFactory();
+ f.newInstance(name).debug("Using java.util.logging as the default logging framework");
+ }
+ }
+
+ defaultFactory = f;
+ }
/**
* Returns the default factory. The initial default factory is
@@ -63,103 +83,11 @@ public abstract class InternalLoggerFactory {
* Creates a new logger instance with the specified name.
*/
public static InternalLogger getInstance(String name) {
- final InternalLogger logger = getDefaultFactory().newInstance(name);
- return new InternalLogger() {
-
- @Override
- public void trace(String msg) {
- logger.trace(msg);
- }
-
- @Override
- public void trace(String msg, Throwable cause) {
- logger.trace(msg, cause);
- }
-
- @Override
- public void debug(String msg) {
- logger.debug(msg);
- }
-
- @Override
- public void debug(String msg, Throwable cause) {
- logger.debug(msg, cause);
- }
-
- @Override
- public void error(String msg) {
- logger.error(msg);
- }
-
- @Override
- public void error(String msg, Throwable cause) {
- logger.error(msg, cause);
- }
-
- @Override
- public void info(String msg) {
- logger.info(msg);
- }
-
- @Override
- public void info(String msg, Throwable cause) {
- logger.info(msg, cause);
- }
-
- @Override
- public boolean isTraceEnabled() {
- return logger.isTraceEnabled();
- }
-
- @Override
- public boolean isDebugEnabled() {
- return logger.isDebugEnabled();
- }
-
- @Override
- public boolean isErrorEnabled() {
- return logger.isErrorEnabled();
- }
-
- @Override
- public boolean isInfoEnabled() {
- return logger.isInfoEnabled();
- }
-
- @Override
- public boolean isWarnEnabled() {
- return logger.isWarnEnabled();
- }
-
- @Override
- public void warn(String msg) {
- logger.warn(msg);
- }
-
- @Override
- public void warn(String msg, Throwable cause) {
- logger.warn(msg, cause);
- }
-
- @Override
- public boolean isEnabled(InternalLogLevel level) {
- return logger.isEnabled(level);
- }
-
- @Override
- public void log(InternalLogLevel level, String msg) {
- logger.log(level, msg);
- }
-
- @Override
- public void log(InternalLogLevel level, String msg, Throwable cause) {
- logger.log(level, msg, cause);
- }
- };
+ return getDefaultFactory().newInstance(name);
}
/**
* Creates a new logger instance with the specified name.
*/
- public abstract InternalLogger newInstance(String name);
+ protected abstract InternalLogger newInstance(String name);
}
diff --git a/common/src/main/java/io/netty/logging/JBossLogger.java b/common/src/main/java/io/netty/logging/JBossLogger.java
deleted file mode 100644
index f134ff19aa..0000000000
--- a/common/src/main/java/io/netty/logging/JBossLogger.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2012 The Netty Project
- *
- * The Netty Project licenses this file to you 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 io.netty.logging;
-
-import org.jboss.logging.Logger;
-
-/**
- * JBoss Logging
- * logger.
- */
-class JBossLogger extends AbstractInternalLogger {
-
- private final Logger logger;
-
- JBossLogger(Logger logger) {
- this.logger = logger;
- }
-
- @Override
- public void trace(String msg) {
- logger.trace(msg);
- }
-
- @Override
- public void trace(String msg, Throwable cause) {
- logger.trace(msg, cause);
- }
-
- @Override
- public void debug(String msg) {
- logger.debug(msg);
- }
-
- @Override
- public void debug(String msg, Throwable cause) {
- logger.debug(msg, cause);
- }
-
- @Override
- public void error(String msg) {
- logger.error(msg);
- }
-
- @Override
- public void error(String msg, Throwable cause) {
- logger.error(msg, cause);
- }
-
- @Override
- public void info(String msg) {
- logger.info(msg);
- }
-
- @Override
- public void info(String msg, Throwable cause) {
- logger.info(msg, cause);
- }
-
- @Override
- public boolean isTraceEnabled() {
- return logger.isTraceEnabled();
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public boolean isDebugEnabled() {
- return logger.isDebugEnabled();
- }
-
- @Override
- public boolean isErrorEnabled() {
- return true;
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public boolean isInfoEnabled() {
- return logger.isInfoEnabled();
- }
-
- @Override
- public boolean isWarnEnabled() {
- return true;
- }
-
- @Override
- public void warn(String msg) {
- logger.warn(msg);
- }
-
- @Override
- public void warn(String msg, Throwable cause) {
- logger.warn(msg, cause);
- }
-
- @Override
- public String toString() {
- return String.valueOf(logger.getName());
- }
-}
diff --git a/common/src/main/java/io/netty/logging/JBossLoggerFactory.java b/common/src/main/java/io/netty/logging/JBossLoggerFactory.java
deleted file mode 100644
index d758aa9225..0000000000
--- a/common/src/main/java/io/netty/logging/JBossLoggerFactory.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2012 The Netty Project
- *
- * The Netty Project licenses this file to you 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 io.netty.logging;
-
-
-import org.jboss.logging.Logger;
-
-/**
- * Logger factory which creates a
- * JBoss Logging
- * logger.
- */
-public class JBossLoggerFactory extends InternalLoggerFactory {
-
- @Override
- public InternalLogger newInstance(String name) {
- final Logger logger =
- Logger.getLogger(name);
- return new JBossLogger(logger);
- }
-}
diff --git a/common/src/main/java/io/netty/logging/JdkLogger.java b/common/src/main/java/io/netty/logging/JdkLogger.java
index 274a0accaa..e978ae7d68 100644
--- a/common/src/main/java/io/netty/logging/JdkLogger.java
+++ b/common/src/main/java/io/netty/logging/JdkLogger.java
@@ -13,9 +13,34 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
package io.netty.logging;
import java.util.logging.Level;
+import java.util.logging.LogRecord;
import java.util.logging.Logger;
/**
@@ -24,91 +49,599 @@ import java.util.logging.Logger;
*/
class JdkLogger extends AbstractInternalLogger {
- private final Logger logger;
- private final String loggerName;
+ private static final long serialVersionUID = -1767272577989225979L;
- JdkLogger(Logger logger, String loggerName) {
+ final transient Logger logger;
+
+ JdkLogger(Logger logger) {
+ super(logger.getName());
this.logger = logger;
- this.loggerName = loggerName;
- }
-
- @Override
- public void trace(String msg) {
- logger.logp(Level.FINEST, loggerName, null, msg);
- }
-
- @Override
- public void trace(String msg, Throwable cause) {
- logger.logp(Level.FINEST, loggerName, null, msg, cause);
- }
-
- @Override
- public void debug(String msg) {
- logger.logp(Level.FINE, loggerName, null, msg);
- }
-
- @Override
- public void debug(String msg, Throwable cause) {
- logger.logp(Level.FINE, loggerName, null, msg, cause);
- }
-
- @Override
- public void error(String msg) {
- logger.logp(Level.SEVERE, loggerName, null, msg);
- }
-
- @Override
- public void error(String msg, Throwable cause) {
- logger.logp(Level.SEVERE, loggerName, null, msg, cause);
- }
-
- @Override
- public void info(String msg) {
- logger.logp(Level.INFO, loggerName, null, msg);
- }
-
- @Override
- public void info(String msg, Throwable cause) {
- logger.logp(Level.INFO, loggerName, null, msg, cause);
}
+ /**
+ * Is this logger instance enabled for the FINEST level?
+ *
+ * @return True if this Logger is enabled for level FINEST, false otherwise.
+ */
@Override
public boolean isTraceEnabled() {
return logger.isLoggable(Level.FINEST);
}
+ /**
+ * Log a message object at level FINEST.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
+ @Override
+ public void trace(String msg) {
+ if (logger.isLoggable(Level.FINEST)) {
+ log(SELF, Level.FINEST, msg, null);
+ }
+ }
+
+ /**
+ * Log a message at level FINEST according to the specified format and
+ * argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for level FINEST.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void trace(String format, Object arg) {
+ if (logger.isLoggable(Level.FINEST)) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level FINEST according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the FINEST level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void trace(String format, Object argA, Object argB) {
+ if (logger.isLoggable(Level.FINEST)) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level FINEST according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the FINEST level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argArray
+ * an array of arguments
+ */
+ @Override
+ public void trace(String format, Object... argArray) {
+ if (logger.isLoggable(Level.FINEST)) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+ log(SELF, Level.FINEST, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at level FINEST with an accompanying message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void trace(String msg, Throwable t) {
+ if (logger.isLoggable(Level.FINEST)) {
+ log(SELF, Level.FINEST, msg, t);
+ }
+ }
+
+ /**
+ * Is this logger instance enabled for the FINE level?
+ *
+ * @return True if this Logger is enabled for level FINE, false otherwise.
+ */
@Override
public boolean isDebugEnabled() {
return logger.isLoggable(Level.FINE);
}
+ /**
+ * Log a message object at level FINE.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
@Override
- public boolean isErrorEnabled() {
- return logger.isLoggable(Level.SEVERE);
+ public void debug(String msg) {
+ if (logger.isLoggable(Level.FINE)) {
+ log(SELF, Level.FINE, msg, null);
+ }
}
+ /**
+ * Log a message at level FINE according to the specified format and argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for level FINE.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void debug(String format, Object arg) {
+ if (logger.isLoggable(Level.FINE)) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level FINE according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the FINE level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void debug(String format, Object argA, Object argB) {
+ if (logger.isLoggable(Level.FINE)) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level FINE according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the FINE level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argArray
+ * an array of arguments
+ */
+ @Override
+ public void debug(String format, Object... argArray) {
+ if (logger.isLoggable(Level.FINE)) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+ log(SELF, Level.FINE, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at level FINE with an accompanying message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void debug(String msg, Throwable t) {
+ if (logger.isLoggable(Level.FINE)) {
+ log(SELF, Level.FINE, msg, t);
+ }
+ }
+
+ /**
+ * Is this logger instance enabled for the INFO level?
+ *
+ * @return True if this Logger is enabled for the INFO level, false otherwise.
+ */
@Override
public boolean isInfoEnabled() {
return logger.isLoggable(Level.INFO);
}
+ /**
+ * Log a message object at the INFO level.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
+ @Override
+ public void info(String msg) {
+ if (logger.isLoggable(Level.INFO)) {
+ log(SELF, Level.INFO, msg, null);
+ }
+ }
+
+ /**
+ * Log a message at level INFO according to the specified format and argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the INFO level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void info(String format, Object arg) {
+ if (logger.isLoggable(Level.INFO)) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at the INFO level according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the INFO level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void info(String format, Object argA, Object argB) {
+ if (logger.isLoggable(Level.INFO)) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level INFO according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the INFO level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argArray
+ * an array of arguments
+ */
+ @Override
+ public void info(String format, Object... argArray) {
+ if (logger.isLoggable(Level.INFO)) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+ log(SELF, Level.INFO, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at the INFO level with an accompanying
+ * message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void info(String msg, Throwable t) {
+ if (logger.isLoggable(Level.INFO)) {
+ log(SELF, Level.INFO, msg, t);
+ }
+ }
+
+ /**
+ * Is this logger instance enabled for the WARNING level?
+ *
+ * @return True if this Logger is enabled for the WARNING level, false
+ * otherwise.
+ */
@Override
public boolean isWarnEnabled() {
return logger.isLoggable(Level.WARNING);
}
+ /**
+ * Log a message object at the WARNING level.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
@Override
public void warn(String msg) {
- logger.logp(Level.WARNING, loggerName, null, msg);
+ if (logger.isLoggable(Level.WARNING)) {
+ log(SELF, Level.WARNING, msg, null);
+ }
}
+ /**
+ * Log a message at the WARNING level according to the specified format and
+ * argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the WARNING level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
@Override
- public void warn(String msg, Throwable cause) {
- logger.logp(Level.WARNING, loggerName, null, msg, cause);
+ public void warn(String format, Object arg) {
+ if (logger.isLoggable(Level.WARNING)) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
+ }
}
+ /**
+ * Log a message at the WARNING level according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the WARNING level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
@Override
- public String toString() {
- return loggerName;
+ public void warn(String format, Object argA, Object argB) {
+ if (logger.isLoggable(Level.WARNING)) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level WARNING according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the WARNING level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argArray
+ * an array of arguments
+ */
+ @Override
+ public void warn(String format, Object... argArray) {
+ if (logger.isLoggable(Level.WARNING)) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+ log(SELF, Level.WARNING, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at the WARNING level with an accompanying
+ * message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void warn(String msg, Throwable t) {
+ if (logger.isLoggable(Level.WARNING)) {
+ log(SELF, Level.WARNING, msg, t);
+ }
+ }
+
+ /**
+ * Is this logger instance enabled for level SEVERE?
+ *
+ * @return True if this Logger is enabled for level SEVERE, false otherwise.
+ */
+ @Override
+ public boolean isErrorEnabled() {
+ return logger.isLoggable(Level.SEVERE);
+ }
+
+ /**
+ * Log a message object at the SEVERE level.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
+ @Override
+ public void error(String msg) {
+ if (logger.isLoggable(Level.SEVERE)) {
+ log(SELF, Level.SEVERE, msg, null);
+ }
+ }
+
+ /**
+ * Log a message at the SEVERE level according to the specified format and
+ * argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the SEVERE level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void error(String format, Object arg) {
+ if (logger.isLoggable(Level.SEVERE)) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at the SEVERE level according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the SEVERE level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void error(String format, Object argA, Object argB) {
+ if (logger.isLoggable(Level.SEVERE)) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level SEVERE according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the SEVERE level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arguments
+ * an array of arguments
+ */
+ @Override
+ public void error(String format, Object... arguments) {
+ if (logger.isLoggable(Level.SEVERE)) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
+ log(SELF, Level.SEVERE, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at the SEVERE level with an accompanying
+ * message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void error(String msg, Throwable t) {
+ if (logger.isLoggable(Level.SEVERE)) {
+ log(SELF, Level.SEVERE, msg, t);
+ }
+ }
+
+ /**
+ * Log the message at the specified level with the specified throwable if any.
+ * This method creates a LogRecord and fills in caller date before calling
+ * this instance's JDK14 logger.
+ *
+ * See bug report #13 for more details.
+ */
+ private void log(String callerFQCN, Level level, String msg, Throwable t) {
+ // millis and thread are filled by the constructor
+ LogRecord record = new LogRecord(level, msg);
+ record.setLoggerName(name());
+ record.setThrown(t);
+ fillCallerData(callerFQCN, record);
+ logger.log(record);
+ }
+
+ static final String SELF = JdkLogger.class.getName();
+ static final String SUPER = AbstractInternalLogger.class.getName();
+
+ /**
+ * Fill in caller data if possible.
+ *
+ * @param record
+ * The record to update
+ */
+ private static void fillCallerData(String callerFQCN, LogRecord record) {
+ StackTraceElement[] steArray = new Throwable().getStackTrace();
+
+ int selfIndex = -1;
+ for (int i = 0; i < steArray.length; i++) {
+ final String className = steArray[i].getClassName();
+ if (className.equals(callerFQCN) || className.equals(SUPER)) {
+ selfIndex = i;
+ break;
+ }
+ }
+
+ int found = -1;
+ for (int i = selfIndex + 1; i < steArray.length; i++) {
+ final String className = steArray[i].getClassName();
+ if (!(className.equals(callerFQCN) || className.equals(SUPER))) {
+ found = i;
+ break;
+ }
+ }
+
+ if (found != -1) {
+ StackTraceElement ste = steArray[found];
+ // setting the class name has the side effect of setting
+ // the needToInferCaller variable to false.
+ record.setSourceClassName(ste.getClassName());
+ record.setSourceMethodName(ste.getMethodName());
+ }
}
}
diff --git a/common/src/main/java/io/netty/logging/JdkLoggerFactory.java b/common/src/main/java/io/netty/logging/JdkLoggerFactory.java
index e98f6232bf..5dd0f032c2 100644
--- a/common/src/main/java/io/netty/logging/JdkLoggerFactory.java
+++ b/common/src/main/java/io/netty/logging/JdkLoggerFactory.java
@@ -27,8 +27,6 @@ public class JdkLoggerFactory extends InternalLoggerFactory {
@Override
public InternalLogger newInstance(String name) {
- final Logger logger =
- Logger.getLogger(name);
- return new JdkLogger(logger, name);
+ return new JdkLogger(Logger.getLogger(name));
}
}
diff --git a/common/src/main/java/io/netty/logging/Log4JLogger.java b/common/src/main/java/io/netty/logging/Log4JLogger.java
index 5e379d2932..17bceb933e 100644
--- a/common/src/main/java/io/netty/logging/Log4JLogger.java
+++ b/common/src/main/java/io/netty/logging/Log4JLogger.java
@@ -13,8 +13,33 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
package io.netty.logging;
+import org.apache.log4j.Level;
import org.apache.log4j.Logger;
/**
@@ -23,89 +48,550 @@ import org.apache.log4j.Logger;
*/
class Log4JLogger extends AbstractInternalLogger {
- private final Logger logger;
+ private static final long serialVersionUID = 2851357342488183058L;
+
+ final transient Logger logger;
+
+ /**
+ * Following the pattern discussed in pages 162 through 168 of "The complete
+ * log4j manual".
+ */
+ static final String FQCN = Log4JLogger.class.getName();
+
+ // Does the log4j version in use recognize the TRACE level?
+ // The trace level was introduced in log4j 1.2.12.
+ final boolean traceCapable;
Log4JLogger(Logger logger) {
+ super(logger.getName());
this.logger = logger;
+ traceCapable = isTraceCapable();
}
- @Override
- public void trace(String msg) {
- logger.trace(msg);
- }
-
- @Override
- public void trace(String msg, Throwable cause) {
- logger.trace(msg, cause);
- }
-
- @Override
- public void debug(String msg) {
- logger.debug(msg);
- }
-
- @Override
- public void debug(String msg, Throwable cause) {
- logger.debug(msg, cause);
- }
-
- @Override
- public void error(String msg) {
- logger.error(msg);
- }
-
- @Override
- public void error(String msg, Throwable cause) {
- logger.error(msg, cause);
- }
-
- @Override
- public void info(String msg) {
- logger.info(msg);
- }
-
- @Override
- public void info(String msg, Throwable cause) {
- logger.info(msg, cause);
+ private boolean isTraceCapable() {
+ try {
+ logger.isTraceEnabled();
+ return true;
+ } catch (NoSuchMethodError e) {
+ return false;
+ }
}
+ /**
+ * Is this logger instance enabled for the TRACE level?
+ *
+ * @return True if this Logger is enabled for level TRACE, false otherwise.
+ */
@Override
public boolean isTraceEnabled() {
- return logger.isTraceEnabled();
+ if (traceCapable) {
+ return logger.isTraceEnabled();
+ } else {
+ return logger.isDebugEnabled();
+ }
}
+ /**
+ * Log a message object at level TRACE.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
+ @Override
+ public void trace(String msg) {
+ logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, null);
+ }
+
+ /**
+ * Log a message at level TRACE according to the specified format and
+ * argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for level TRACE.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void trace(String format, Object arg) {
+ if (isTraceEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft
+ .getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level TRACE according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the TRACE level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void trace(String format, Object argA, Object argB) {
+ if (isTraceEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft
+ .getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level TRACE according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the TRACE level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arguments
+ * an array of arguments
+ */
+ @Override
+ public void trace(String format, Object... arguments) {
+ if (isTraceEnabled()) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
+ logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, ft
+ .getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at level TRACE with an accompanying message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void trace(String msg, Throwable t) {
+ logger.log(FQCN, traceCapable ? Level.TRACE : Level.DEBUG, msg, t);
+ }
+
+ /**
+ * Is this logger instance enabled for the DEBUG level?
+ *
+ * @return True if this Logger is enabled for level DEBUG, false otherwise.
+ */
@Override
public boolean isDebugEnabled() {
return logger.isDebugEnabled();
}
+ /**
+ * Log a message object at level DEBUG.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
@Override
- public boolean isErrorEnabled() {
- return true;
+ public void debug(String msg) {
+ logger.log(FQCN, Level.DEBUG, msg, null);
}
+ /**
+ * Log a message at level DEBUG according to the specified format and
+ * argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for level DEBUG.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void debug(String format, Object arg) {
+ if (logger.isDebugEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level DEBUG according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the DEBUG level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void debug(String format, Object argA, Object argB) {
+ if (logger.isDebugEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level DEBUG according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the DEBUG level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arguments an array of arguments
+ */
+ @Override
+ public void debug(String format, Object... arguments) {
+ if (logger.isDebugEnabled()) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
+ logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at level DEBUG with an accompanying message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void debug(String msg, Throwable t) {
+ logger.log(FQCN, Level.DEBUG, msg, t);
+ }
+
+ /**
+ * Is this logger instance enabled for the INFO level?
+ *
+ * @return True if this Logger is enabled for the INFO level, false otherwise.
+ */
@Override
public boolean isInfoEnabled() {
return logger.isInfoEnabled();
}
+ /**
+ * Log a message object at the INFO level.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
+ @Override
+ public void info(String msg) {
+ logger.log(FQCN, Level.INFO, msg, null);
+ }
+
+ /**
+ * Log a message at level INFO according to the specified format and argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the INFO level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void info(String format, Object arg) {
+ if (logger.isInfoEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at the INFO level according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the INFO level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void info(String format, Object argA, Object argB) {
+ if (logger.isInfoEnabled()) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level INFO according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the INFO level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argArray
+ * an array of arguments
+ */
+ @Override
+ public void info(String format, Object... argArray) {
+ if (logger.isInfoEnabled()) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+ logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at the INFO level with an accompanying
+ * message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void info(String msg, Throwable t) {
+ logger.log(FQCN, Level.INFO, msg, t);
+ }
+
+ /**
+ * Is this logger instance enabled for the WARN level?
+ *
+ * @return True if this Logger is enabled for the WARN level, false otherwise.
+ */
@Override
public boolean isWarnEnabled() {
- return true;
+ return logger.isEnabledFor(Level.WARN);
}
+ /**
+ * Log a message object at the WARN level.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
@Override
public void warn(String msg) {
- logger.warn(msg);
+ logger.log(FQCN, Level.WARN, msg, null);
}
+ /**
+ * Log a message at the WARN level according to the specified format and
+ * argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the WARN level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
@Override
- public void warn(String msg, Throwable cause) {
- logger.warn(msg, cause);
+ public void warn(String format, Object arg) {
+ if (logger.isEnabledFor(Level.WARN)) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable());
+ }
}
+ /**
+ * Log a message at the WARN level according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the WARN level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
@Override
- public String toString() {
- return String.valueOf(logger.getName());
+ public void warn(String format, Object argA, Object argB) {
+ if (logger.isEnabledFor(Level.WARN)) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level WARN according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the WARN level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argArray
+ * an array of arguments
+ */
+ @Override
+ public void warn(String format, Object... argArray) {
+ if (logger.isEnabledFor(Level.WARN)) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+ logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at the WARN level with an accompanying
+ * message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void warn(String msg, Throwable t) {
+ logger.log(FQCN, Level.WARN, msg, t);
+ }
+
+ /**
+ * Is this logger instance enabled for level ERROR?
+ *
+ * @return True if this Logger is enabled for level ERROR, false otherwise.
+ */
+ @Override
+ public boolean isErrorEnabled() {
+ return logger.isEnabledFor(Level.ERROR);
+ }
+
+ /**
+ * Log a message object at the ERROR level.
+ *
+ * @param msg
+ * - the message object to be logged
+ */
+ @Override
+ public void error(String msg) {
+ logger.log(FQCN, Level.ERROR, msg, null);
+ }
+
+ /**
+ * Log a message at the ERROR level according to the specified format and
+ * argument.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the ERROR level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param arg
+ * the argument
+ */
+ @Override
+ public void error(String format, Object arg) {
+ if (logger.isEnabledFor(Level.ERROR)) {
+ FormattingTuple ft = MessageFormatter.format(format, arg);
+ logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at the ERROR level according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the ERROR level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argA
+ * the first argument
+ * @param argB
+ * the second argument
+ */
+ @Override
+ public void error(String format, Object argA, Object argB) {
+ if (logger.isEnabledFor(Level.ERROR)) {
+ FormattingTuple ft = MessageFormatter.format(format, argA, argB);
+ logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log a message at level ERROR according to the specified format and
+ * arguments.
+ *
+ *
+ * This form avoids superfluous object creation when the logger is disabled
+ * for the ERROR level.
+ *
+ *
+ * @param format
+ * the format string
+ * @param argArray
+ * an array of arguments
+ */
+ @Override
+ public void error(String format, Object... argArray) {
+ if (logger.isEnabledFor(Level.ERROR)) {
+ FormattingTuple ft = MessageFormatter.arrayFormat(format, argArray);
+ logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable());
+ }
+ }
+
+ /**
+ * Log an exception (throwable) at the ERROR level with an accompanying
+ * message.
+ *
+ * @param msg
+ * the message accompanying the exception
+ * @param t
+ * the exception (throwable) to log
+ */
+ @Override
+ public void error(String msg, Throwable t) {
+ logger.log(FQCN, Level.ERROR, msg, t);
}
}
diff --git a/common/src/main/java/io/netty/logging/Log4JLoggerFactory.java b/common/src/main/java/io/netty/logging/Log4JLoggerFactory.java
index 4b0667ee45..47f84fc1a2 100644
--- a/common/src/main/java/io/netty/logging/Log4JLoggerFactory.java
+++ b/common/src/main/java/io/netty/logging/Log4JLoggerFactory.java
@@ -26,8 +26,6 @@ public class Log4JLoggerFactory extends InternalLoggerFactory {
@Override
public InternalLogger newInstance(String name) {
- final Logger logger =
- Logger.getLogger(name);
- return new Log4JLogger(logger);
+ return new Log4JLogger(Logger.getLogger(name));
}
}
diff --git a/common/src/main/java/io/netty/logging/MessageFormatter.java b/common/src/main/java/io/netty/logging/MessageFormatter.java
new file mode 100644
index 0000000000..7a9eb234e8
--- /dev/null
+++ b/common/src/main/java/io/netty/logging/MessageFormatter.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2013 The Netty Project
+ *
+ * The Netty Project licenses this file to you 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.
+ */
+/**
+ * Copyright (c) 2004-2011 QOS.ch
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+package io.netty.logging;
+
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+// contributors: lizongbo: proposed special treatment of array parameter values
+// Joern Huxhorn: pointed out double[] omission, suggested deep array copy
+
+/**
+ * Formats messages according to very simple substitution rules. Substitutions
+ * can be made 1, 2 or more arguments.
+ *
+ *
+ * For example,
+ *
+ *
+ *
+ * will return the string "Hi there.".
+ *
+ * The {} pair is called the formatting anchor. It serves to designate
+ * the location where arguments need to be substituted within the message
+ * pattern.
+ *
+ * In case your message contains the '{' or the '}' character, you do not have
+ * to do anything special unless the '}' character immediately follows '{'. For
+ * example,
+ *
+ *
+ * MessageFormatter.format("Set {1,2,3} is not equal to {}.", "1,2");
+ *
+ *
+ * will return the string "Set {1,2,3} is not equal to 1,2.".
+ *
+ *
+ * If for whatever reason you need to place the string "{}" in the message
+ * without its formatting anchor meaning, then you need to escape the
+ * '{' character with '\', that is the backslash character. Only the '{'
+ * character should be escaped. There is no need to escape the '}' character.
+ * For example,
+ *
+ *
+ * MessageFormatter.format("Set \\{} is not equal to {}.", "1,2");
+ *
+ *
+ * will return the string "Set {} is not equal to 1,2.".
+ *
+ *
+ * The escaping behavior just described can be overridden by escaping the escape
+ * character '\'. Calling
+ *
+ *
+ * MessageFormatter.format("File name is C:\\\\{}.", "file.zip");
+ *
+ *
+ * will return the string "File name is C:\file.zip".
+ *
+ *
+ * The formatting conventions are different than those of {@link MessageFormat}
+ * which ships with the Java platform. This is justified by the fact that
+ * SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.
+ * This local performance difference is both measurable and significant in the
+ * larger context of the complete logging processing chain.
+ *
+ *
+ * See also {@link #format(String, Object)},
+ * {@link #format(String, Object, Object)} and
+ * {@link #arrayFormat(String, Object[])} methods for more details.
+ */
+final class MessageFormatter {
+ static final char DELIM_START = '{';
+ static final char DELIM_STOP = '}';
+ static final String DELIM_STR = "{}";
+ private static final char ESCAPE_CHAR = '\\';
+
+ /**
+ * Performs single argument substitution for the 'messagePattern' passed as
+ * parameter.
+ *
+ * For example,
+ *
+ *
+ *
+ * will return the string "Hi there.".
+ *
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param arg The argument to be substituted in place of the formatting anchor
+ * @return The formatted message
+ */
+ static FormattingTuple format(String messagePattern, Object arg) {
+ return arrayFormat(messagePattern, new Object[]{arg});
+ }
+
+ /**
+ * Performs a two argument substitution for the 'messagePattern' passed as
+ * parameter.
+ *
+ * For example,
+ *
+ *
+ * MessageFormatter.format("Hi {}. My name is {}.", "Alice", "Bob");
+ *
+ *
+ * will return the string "Hi Alice. My name is Bob.".
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param argA The argument to be substituted in place of the first formatting
+ * anchor
+ * @param argB The argument to be substituted in place of the second formatting
+ * anchor
+ * @return The formatted message
+ */
+ static FormattingTuple format(final String messagePattern,
+ Object argA, Object argB) {
+ return arrayFormat(messagePattern, new Object[]{argA, argB});
+ }
+
+ static Throwable getThrowableCandidate(Object[] argArray) {
+ if (argArray == null || argArray.length == 0) {
+ return null;
+ }
+
+ final Object lastEntry = argArray[argArray.length - 1];
+ if (lastEntry instanceof Throwable) {
+ return (Throwable) lastEntry;
+ }
+ return null;
+ }
+
+ /**
+ * Same principle as the {@link #format(String, Object)} and
+ * {@link #format(String, Object, Object)} methods except that any number of
+ * arguments can be passed in an array.
+ *
+ * @param messagePattern The message pattern which will be parsed and formatted
+ * @param argArray An array of arguments to be substituted in place of formatting
+ * anchors
+ * @return The formatted message
+ */
+ static FormattingTuple arrayFormat(final String messagePattern,
+ final Object[] argArray) {
+
+ Throwable throwableCandidate = getThrowableCandidate(argArray);
+
+ if (messagePattern == null) {
+ return new FormattingTuple(null, argArray, throwableCandidate);
+ }
+
+ if (argArray == null) {
+ return new FormattingTuple(messagePattern);
+ }
+
+ int i = 0;
+ int j;
+ StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);
+
+ int L;
+ for (L = 0; L < argArray.length; L++) {
+
+ j = messagePattern.indexOf(DELIM_STR, i);
+
+ if (j == -1) {
+ // no more variables
+ if (i == 0) { // this is a simple string
+ return new FormattingTuple(messagePattern, argArray,
+ throwableCandidate);
+ } else { // add the tail string which contains no variables and return
+ // the result.
+ sbuf.append(messagePattern.substring(i, messagePattern.length()));
+ return new FormattingTuple(sbuf.toString(), argArray,
+ throwableCandidate);
+ }
+ } else {
+ if (isEscapedDelimeter(messagePattern, j)) {
+ if (!isDoubleEscaped(messagePattern, j)) {
+ L--; // DELIM_START was escaped, thus should not be incremented
+ sbuf.append(messagePattern.substring(i, j - 1));
+ sbuf.append(DELIM_START);
+ i = j + 1;
+ } else {
+ // The escape character preceding the delimiter start is
+ // itself escaped: "abc x:\\{}"
+ // we have to consume one backward slash
+ sbuf.append(messagePattern.substring(i, j - 1));
+ deeplyAppendParameter(sbuf, argArray[L], new HashMap