diff --git a/.checkstyle/suppressions.xml b/.checkstyle/suppressions.xml
index 04ed5fffe..ea0de2320 100644
--- a/.checkstyle/suppressions.xml
+++ b/.checkstyle/suppressions.xml
@@ -8,6 +8,9 @@
+
+
+
diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts
index 90e7633c4..51c6a7f99 100644
--- a/bom/build.gradle.kts
+++ b/bom/build.gradle.kts
@@ -18,6 +18,7 @@ dependencies {
"nbt",
"serializer-configurate3",
"serializer-configurate4",
+ "text-logger-slf4j",
"text-minimessage",
"text-serializer-gson",
"text-serializer-gson-legacy-impl",
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4032f3d23..1f67e61a7 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -10,6 +10,8 @@ indra = "2.1.1"
jmh = "1.35"
jmhPlugin = "0.6.6"
junit = "5.8.2"
+mockito = "4.5.1"
+slf4j = "1.7.36"
truth = "1.1.3"
[libraries]
@@ -28,6 +30,10 @@ kotlin-testJunit5 = { module = "org.jetbrains.kotlin:kotlin-test-junit5" }
configurate-v3 = "org.spongepowered:configurate-core:3.7.3"
configurate-v4 = "org.spongepowered:configurate-core:4.1.2"
+# text-logger-slf4j
+slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
+slf4jtest = "com.github.valfirst:slf4j-test:2.6.1" # Specific versions are needed for different SLF4J versions
+
# text-serializer-gson
gson = "com.google.code.gson:gson:2.8.0"
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 86282d8f6..24b270f19 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -34,6 +34,7 @@ sequenceOf(
"nbt",
"serializer-configurate3",
"serializer-configurate4",
+ "text-logger-slf4j",
"text-minimessage",
"text-serializer-gson",
"text-serializer-gson-legacy-impl",
diff --git a/text-logger-slf4j/build.gradle.kts b/text-logger-slf4j/build.gradle.kts
new file mode 100644
index 000000000..f5c0c54e1
--- /dev/null
+++ b/text-logger-slf4j/build.gradle.kts
@@ -0,0 +1,28 @@
+plugins {
+ id("adventure.common-conventions")
+}
+
+dependencies {
+ api(projects.adventureApi)
+ api(libs.slf4j)
+ testImplementation(libs.slf4jtest)
+}
+
+sourceSets.main {
+ multirelease {
+ alternateVersions(9)
+ }
+}
+
+applyJarMetadata("net.kyori.adventure.text.logger.slf4j")
+
+eclipse {
+ // Make sure slf4j doesn't end up on the module path until we are actually a module
+ classpath.file.whenMerged {
+ (this as org.gradle.plugins.ide.eclipse.model.Classpath).entries.forEach { entry ->
+ if (entry is org.gradle.plugins.ide.eclipse.model.Library) {
+ entry.entryAttributes["module"] = false
+ }
+ }
+ }
+}
diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/CallerClassFinder.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/CallerClassFinder.java
new file mode 100644
index 000000000..886c89417
--- /dev/null
+++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/CallerClassFinder.java
@@ -0,0 +1,43 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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 net.kyori.adventure.text.logger.slf4j;
+
+// Java 8 version, see Java 9 version as well
+final class CallerClassFinder {
+ private CallerClassFinder() {
+ }
+
+ static String callingClassName() {
+ return callingClassName(2); // this, plus the calling method
+ }
+
+ static String callingClassName(final int elementsToSkip) { // elementsToSkip not counting this method
+ final StackTraceElement[] elements = Thread.currentThread().getStackTrace(); // includes call to getStackTrace()
+ if (elements.length <= elementsToSkip) {
+ throw new IllegalArgumentException("Not enough stack elements to skip " + elementsToSkip + " elements");
+ } else {
+ return elements[elementsToSkip + 2].getClassName();
+ }
+ }
+}
diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLogger.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLogger.java
new file mode 100644
index 000000000..63a027938
--- /dev/null
+++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLogger.java
@@ -0,0 +1,673 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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 net.kyori.adventure.text.logger.slf4j;
+
+import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * An extended type of Logger capable of logging formatted components to the console.
+ *
+ *
The methods in this logger interface are intended to exactly mirror those methods in {@link Logger} that take a format string, but instead accepting {@link Component}s.
+ *
+ * Any {@code arg}s may be passed as Components as well.
+ *
+ * @since 4.11.0
+ */
+public interface ComponentLogger extends Logger {
+ /**
+ * Get a logger instance with the name of the calling class.
+ *
+ * This method is caller-sensitive and should not be wrapped.
+ *
+ * This logger is produced by implementations of the {@link ComponentLoggerProvider}.
+ *
+ * @return a logger with the name of the calling class
+ * @since 4.11.0
+ */
+ static @NotNull ComponentLogger logger() {
+ return logger(CallerClassFinder.callingClassName());
+ }
+
+ /**
+ * Get a logger instance with the provided name.
+ *
+ * This logger is produced by implementations of the {@link ComponentLoggerProvider}.
+ *
+ * @param name the name of the logger
+ * @return a logger with the provided name
+ * @since 4.11.0
+ */
+ static @NotNull ComponentLogger logger(final @NotNull String name) {
+ return Handler.logger(requireNonNull(name, "name"));
+ }
+
+ /**
+ * Get a logger instance with the binary name of the provided class.
+ *
+ * This logger is produced by implementations of the {@link ComponentLoggerProvider}.
+ *
+ * @param clazz the class to use when naming the logger
+ * @return a logger with the name of the calling class
+ * @since 4.11.0
+ */
+ static @NotNull ComponentLogger logger(final @NotNull Class> clazz) {
+ return logger(clazz.getName());
+ }
+
+ /**
+ * Log a message at the TRACE level.
+ *
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Component msg);
+
+ /**
+ * 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
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * 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 arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * 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 Object[]
before invoking the method,
+ * even if this logger is disabled for TRACE. The variants taking {@link #trace(Component, Object) one} and
+ * {@link #trace(Component, 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
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Component format, final @Nullable Object @NotNull... 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
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Component msg, final @Nullable Throwable t);
+
+ /**
+ * Log a message with the specific Marker at the TRACE level.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Marker marker, final @NotNull Component msg);
+
+ /**
+ * This method is similar to {@link #trace(Component, Object)} method except that the
+ * marker data is also taken into consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg the argument
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * This method is similar to {@link #trace(Component, Object, Object)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * This method is similar to {@link #trace(Component, Object...)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param argArray an array of arguments
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object @NotNull... argArray);
+
+ /**
+ * This method is similar to {@link #trace(Component, Throwable)} method except that the
+ * marker data is also taken into consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @since 4.11.0
+ */
+ void trace(final @NotNull Marker marker, final @NotNull Component msg, final @Nullable Throwable t);
+
+ /**
+ * Log a message at the DEBUG level.
+ *
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Component msg);
+
+ /**
+ * 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
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * 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 arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * 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 Object[]
before invoking the method,
+ * even if this logger is disabled for DEBUG. The variants taking
+ * {@link #debug(Component, Object) one} and {@link #debug(Component, 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
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Component format, final @Nullable Object @NotNull... 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
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Component msg, final @Nullable Throwable t);
+
+ /**
+ * Log a message with the specific Marker at the DEBUG level.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Marker marker, final @NotNull Component msg);
+
+ /**
+ * This method is similar to {@link #debug(Component, Object)} method except that the
+ * marker data is also taken into consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg the argument
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * This method is similar to {@link #debug(Component, Object, Object)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * This method is similar to {@link #debug(Component, Object...)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object @NotNull... arguments);
+
+ /**
+ * This method is similar to {@link #debug(Component, Throwable)} method except that the
+ * marker data is also taken into consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @since 4.11.0
+ */
+ void debug(final @NotNull Marker marker, final @NotNull Component msg, final @Nullable Throwable t);
+
+ /**
+ * Log a message at the INFO level.
+ *
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void info(final @NotNull Component msg);
+
+ /**
+ * 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
+ * @since 4.11.0
+ */
+ void info(final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * 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 arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void info(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * 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 Object[]
before invoking the method,
+ * even if this logger is disabled for INFO. The variants taking
+ * {@link #info(Component, Object) one} and {@link #info(Component, 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
+ * @since 4.11.0
+ */
+ void info(final @NotNull Component format, final @Nullable Object@NotNull... 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
+ * @since 4.11.0
+ */
+ void info(final @NotNull Component msg, final @Nullable Throwable t);
+
+ /**
+ * Log a message with the specific Marker at the INFO level.
+ *
+ * @param marker The marker specific to this log statement
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void info(final @NotNull Marker marker, final @NotNull Component msg);
+
+ /**
+ * This method is similar to {@link #info(Component, Object)} method except that the
+ * marker data is also taken into consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg the argument
+ * @since 4.11.0
+ */
+ void info(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * This method is similar to {@link #info(Component, Object, Object)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void info(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * This method is similar to {@link #info(Component, Object...)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ * @since 4.11.0
+ */
+ void info(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object@NotNull... arguments);
+
+ /**
+ * This method is similar to {@link #info(Component, Throwable)} method
+ * except that the marker data is also taken into consideration.
+ *
+ * @param marker the marker data for this log statement
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @since 4.11.0
+ */
+ void info(final @NotNull Marker marker, final @NotNull Component msg, final @NotNull Throwable t);
+
+ /**
+ * Log a message at the WARN level.
+ *
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Component msg);
+
+ /**
+ * 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
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * 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 Object[]
before invoking the method,
+ * even if this logger is disabled for WARN. The variants taking
+ * {@link #warn(Component, Object) one} and {@link #warn(Component, 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
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Component format, final @Nullable Object@NotNull... 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 arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * 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
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Component msg, final @NotNull Throwable t);
+
+ /**
+ * Log a message with the specific final @NotNull Marker at the WARN level.
+ *
+ * @param marker The marker specific to this log statement
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Marker marker, final @NotNull Component msg);
+
+ /**
+ * This method is similar to {@link #warn(Component, Object)} method except that the
+ * marker data is also taken into consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg the argument
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * This method is similar to {@link #warn(Component, Object, Object)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * This method is similar to {@link #warn(Component, Object...)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object@NotNull... arguments);
+
+ /**
+ * This method is similar to {@link #warn(Component, Throwable)} method
+ * except that the marker data is also taken into consideration.
+ *
+ * @param marker the marker data for this log statement
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @since 4.11.0
+ */
+ void warn(final @NotNull Marker marker, final @NotNull Component msg, final @NotNull Throwable t);
+
+ /**
+ * Log a message at the ERROR level.
+ *
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void error(final @NotNull Component msg);
+
+ /**
+ * 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
+ * @since 4.11.0
+ */
+ void error(final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * 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 arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void error(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * 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 Object[]
before invoking the method,
+ * even if this logger is disabled for ERROR. The variants taking
+ * {@link #error(Component, Object) one} and {@link #error(Component, 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
+ * @since 4.11.0
+ */
+ void error(final @NotNull Component format, final @Nullable Object@NotNull... 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
+ * @since 4.11.0
+ */
+ void error(final @NotNull Component msg, final @NotNull Throwable t);
+
+ /**
+ * Log a message with the specific final @NotNull Marker at the ERROR level.
+ *
+ * @param marker The marker specific to this log statement
+ * @param msg the message string to be logged
+ * @since 4.11.0
+ */
+ void error(final @NotNull Marker marker, final @NotNull Component msg);
+
+ /**
+ * This method is similar to {@link #error(Component, Object)} method except that the
+ * marker data is also taken into consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg the argument
+ * @since 4.11.0
+ */
+ void error(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg);
+
+ /**
+ * This method is similar to {@link #error(Component, Object, Object)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arg1 the first argument
+ * @param arg2 the second argument
+ * @since 4.11.0
+ */
+ void error(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2);
+
+ /**
+ * This method is similar to {@link #error(Component, Object...)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param format the format string
+ * @param arguments a list of 3 or more arguments
+ * @since 4.11.0
+ */
+ void error(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object@NotNull... arguments);
+
+ /**
+ * This method is similar to {@link #error(Component, Throwable)}
+ * method except that the marker data is also taken into
+ * consideration.
+ *
+ * @param marker the marker data specific to this log statement
+ * @param msg the message accompanying the exception
+ * @param t the exception (throwable) to log
+ * @since 4.11.0
+ */
+ void error(final @NotNull Marker marker, final @NotNull Component msg, final @NotNull Throwable t);
+}
diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggerProvider.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggerProvider.java
new file mode 100644
index 000000000..4e9f50520
--- /dev/null
+++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggerProvider.java
@@ -0,0 +1,77 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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 net.kyori.adventure.text.logger.slf4j;
+
+import java.util.function.Function;
+import net.kyori.adventure.text.Component;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+
+/**
+ * A service interface for platforms to provide their own component logger implementations.
+ *
+ * @since 4.11.0
+ */
+@ApiStatus.Internal // SPI for platform use only
+public interface ComponentLoggerProvider {
+ /**
+ * Create a component logger for the provided logger name.
+ *
+ * @param helper a source for common helper implementations when building a logger
+ * @param name the logger name
+ * @return a component logger with the provided name
+ * @since 4.11.0
+ */
+ @NotNull ComponentLogger logger(final @NotNull LoggerHelper helper, final @NotNull String name);
+
+ /**
+ * A factory for default implementations of component loggers.
+ *
+ * @since 4.11.0
+ */
+ @ApiStatus.NonExtendable
+ interface LoggerHelper {
+
+ /**
+ * Create a serializer function that will translate logged output into the system default locale, and then serialize it to plain text.
+ *
+ * @return a plain serializer
+ * @since 4.11.0
+ */
+ @NotNull Function plainSerializer();
+
+ /**
+ * Create a component logger based on one which delegates to an underlying plain {@link Logger} implementation.
+ *
+ * This sort of logger requires Components to be serialized to some sort of formatted {@link String} to match the SLF4J contract.
+ *
+ * @param base the base logger
+ * @param serializer the serializer to translate and format a component in a log message.
+ * @return a new logger
+ * @since 4.11.0
+ */
+ @NotNull ComponentLogger delegating(final @NotNull Logger base, final @NotNull Function serializer);
+ }
+}
diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/Handler.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/Handler.java
new file mode 100644
index 000000000..33d8c85cd
--- /dev/null
+++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/Handler.java
@@ -0,0 +1,88 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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 net.kyori.adventure.text.logger.slf4j;
+
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.flattener.ComponentFlattener;
+import net.kyori.adventure.translation.GlobalTranslator;
+import net.kyori.adventure.util.Services;
+import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility methods relating to creating component loggers.
+ */
+final class Handler {
+ private static final ComponentLoggerProvider PROVIDER = Services.service(ComponentLoggerProvider.class)
+ .orElse(LoggerFactory.getILoggerFactory() instanceof ComponentLoggerProvider ? (ComponentLoggerProvider) LoggerFactory.getILoggerFactory() : new DefaultProvider());
+
+ private Handler() {
+ }
+
+ static ComponentLogger logger(final String name) {
+ return PROVIDER.logger(LoggerHelperImpl.INSTANCE, name);
+ }
+
+ static final class DefaultProvider implements ComponentLoggerProvider {
+ private final Map loggers = new ConcurrentHashMap<>();
+
+ @Override
+ public @NotNull ComponentLogger logger(final @NotNull LoggerHelper helper, final @NotNull String name) {
+ final ComponentLogger initial = this.loggers.get(name);
+ if (initial != null) return initial;
+
+ final Logger backing = LoggerFactory.getLogger(name);
+ final ComponentLogger created = helper.delegating(backing, helper.plainSerializer());
+ final ComponentLogger existing = this.loggers.putIfAbsent(name, created);
+ return existing == null ? created : existing;
+ }
+ }
+
+ static final class LoggerHelperImpl implements ComponentLoggerProvider.LoggerHelper {
+ static final LoggerHelperImpl INSTANCE = new LoggerHelperImpl();
+
+ LoggerHelperImpl() {
+ }
+
+ @Override
+ public Function plainSerializer() {
+ return comp -> {
+ final Component translated = GlobalTranslator.render(comp, Locale.getDefault());
+ final StringBuilder contents = new StringBuilder();
+ ComponentFlattener.basic().flatten(translated, contents::append);
+ return contents.toString();
+ };
+ }
+
+ @Override
+ public @NotNull ComponentLogger delegating(final @NotNull Logger base, final @NotNull Function serializer) {
+ return new WrappingComponentLoggerImpl(base, serializer);
+ }
+ }
+}
diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/UnpackedComponentThrowable.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/UnpackedComponentThrowable.java
new file mode 100644
index 000000000..25388b1f4
--- /dev/null
+++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/UnpackedComponentThrowable.java
@@ -0,0 +1,73 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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 net.kyori.adventure.text.logger.slf4j;
+
+import java.util.function.Function;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.util.ComponentMessageThrowable;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * A wrapper for exceptions that implement ComponentMessageThrowable.
+ */
+final class UnpackedComponentThrowable extends Throwable {
+ private static final long serialVersionUID = -1L;
+
+ private final Class extends Throwable> backingType;
+
+ static Throwable unpack(final Throwable maybeRich, final Function serializer) {
+ if (!(maybeRich instanceof ComponentMessageThrowable)) return maybeRich; // TODO: do we need to unwrap any nested exceptions?
+
+ final @Nullable Component message = ((ComponentMessageThrowable) maybeRich).componentMessage();
+ final Throwable cause = maybeRich.getCause() != null ? unpack(maybeRich.getCause(), serializer) : null;
+ final Throwable[] suppressed = maybeRich.getSuppressed();
+
+ final UnpackedComponentThrowable ret = new UnpackedComponentThrowable(maybeRich.getClass(), serializer.apply(message), cause);
+ ret.setStackTrace(maybeRich.getStackTrace());
+ if (suppressed.length > 0) {
+ for (int i = 0; i < suppressed.length; i++) {
+ ret.addSuppressed(unpack(suppressed[i], serializer));
+ }
+ }
+
+ return ret;
+ }
+
+ private UnpackedComponentThrowable(final Class extends Throwable> backingType, final String serializedMessage, final Throwable cause) {
+ super(serializedMessage, cause);
+ this.backingType = backingType;
+ }
+
+ @Override
+ public String toString() {
+ final String className = this.backingType.getName();
+ final String message = this.getMessage();
+ return message == null ? className : className + ":" + message;
+ }
+
+ @Override
+ public synchronized Throwable fillInStackTrace() {
+ return this;
+ }
+}
diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/WrappingComponentLoggerImpl.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/WrappingComponentLoggerImpl.java
new file mode 100644
index 000000000..4d13594fd
--- /dev/null
+++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/WrappingComponentLoggerImpl.java
@@ -0,0 +1,1944 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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 net.kyori.adventure.text.logger.slf4j;
+
+import java.util.Arrays;
+import java.util.function.Function;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.ComponentLike;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+import org.slf4j.spi.LocationAwareLogger;
+
+final class WrappingComponentLoggerImpl implements ComponentLogger {
+ private static final String FQCN = WrappingComponentLoggerImpl.class.getName();
+
+ private final Logger logger;
+ private final boolean isLocationAware;
+ private final Function serializer;
+
+ WrappingComponentLoggerImpl(final Logger backing, final Function serializer) {
+ this.serializer = serializer;
+ this.logger = backing;
+ this.isLocationAware = backing instanceof LocationAwareLogger;
+ }
+
+ private String serialize(final Component input) {
+ if (input == null) return null;
+
+ return this.serializer.apply(input);
+ }
+
+ private Object maybeSerialize(final @Nullable Object input) {
+ if (input instanceof ComponentLike) {
+ return this.serialize(((ComponentLike) input).asComponent());
+ } else {
+ return input;
+ }
+ }
+
+ private Object[] maybeSerialize(final @Nullable Object@NotNull... args) {
+ Object[] writable = args;
+ for (int i = 0; i < writable.length; i++) {
+ if (writable[i] instanceof ComponentLike) {
+ if (writable == args) {
+ writable = Arrays.copyOf(args, args.length);
+ }
+ writable[i] = this.serialize(((ComponentLike) writable[i]).asComponent());
+ }
+ }
+
+ if (writable.length > 0 && writable[writable.length - 1] instanceof Throwable) {
+ if (writable == args) {
+ writable = Arrays.copyOf(args, args.length);
+ }
+ writable[writable.length - 1] = UnpackedComponentThrowable.unpack((Throwable) writable[writable.length - 1], this.serializer);
+ }
+
+ return writable;
+ }
+
+ // Basic methods, plain delegation
+
+ @Override
+ public String getName() {
+ return this.logger.getName();
+ }
+
+ @Override
+ public boolean isTraceEnabled() {
+ return this.logger.isTraceEnabled();
+ }
+
+ @Override
+ public boolean isTraceEnabled(final Marker marker) {
+ return this.logger.isTraceEnabled(marker);
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return this.logger.isDebugEnabled();
+ }
+
+ @Override
+ public boolean isDebugEnabled(final Marker marker) {
+ return this.logger.isDebugEnabled(marker);
+ }
+
+ @Override
+ public boolean isInfoEnabled() {
+ return this.logger.isInfoEnabled();
+ }
+
+ @Override
+ public boolean isInfoEnabled(final Marker marker) {
+ return this.logger.isInfoEnabled(marker);
+ }
+
+ @Override
+ public boolean isWarnEnabled() {
+ return this.logger.isWarnEnabled();
+ }
+
+ @Override
+ public boolean isWarnEnabled(final Marker marker) {
+ return this.logger.isWarnEnabled(marker);
+ }
+
+ @Override
+ public boolean isErrorEnabled() {
+ return this.logger.isErrorEnabled();
+ }
+
+ @Override
+ public boolean isErrorEnabled(final Marker marker) {
+ return this.logger.isErrorEnabled(marker);
+ }
+
+ // Standard string methods, to process potential Component arguments
+
+ @Override
+ public void trace(final @NotNull String format) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ format,
+ null,
+ null
+ );
+ } else {
+ this.logger.trace(format);
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.trace(format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.trace(format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull String format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ format,
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.trace(format, this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.trace(msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull String msg) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ msg,
+ null,
+ null
+ );
+ } else {
+ this.logger.trace(marker, msg);
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.trace(marker, format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.trace(marker, format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ format,
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.trace(marker, format, this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.trace(marker, msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull String format) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ format,
+ null,
+ null
+ );
+ } else {
+ this.logger.debug(format);
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.debug(format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.debug(format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull String format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ format,
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.debug(format, this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.debug(msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull String msg) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ msg,
+ null,
+ null
+ );
+ } else {
+ this.logger.debug(marker, msg);
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.debug(marker, format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.debug(marker, format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ format,
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.debug(marker, format, this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.debug(marker, msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull String format) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ format,
+ null,
+ null
+ );
+ } else {
+ this.logger.info(format);
+ }
+ }
+
+ @Override
+ public void info(final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.info(format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.info(format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull String format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ format,
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.info(format, this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.info(msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull String msg) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ msg,
+ null,
+ null
+ );
+ } else {
+ this.logger.info(marker, msg);
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.info(marker, format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.info(marker, format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ format,
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.info(marker, format, this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.info(marker, msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull String format) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ format,
+ null,
+ null
+ );
+ } else {
+ this.logger.warn(format);
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.warn(format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.warn(format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull String format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ format,
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.warn(format, this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.warn(msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull String msg) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ msg,
+ null,
+ null
+ );
+ } else {
+ this.logger.warn(marker, msg);
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.warn(marker, format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.warn(marker, format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ format,
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.warn(marker, format, this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.warn(marker, msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull String format) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ format,
+ null,
+ null
+ );
+ } else {
+ this.logger.error(format);
+ }
+ }
+
+ @Override
+ public void error(final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.error(format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.error(format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull String format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ format,
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.error(format, this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.error(msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull String msg) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ msg,
+ null,
+ null
+ );
+ } else {
+ this.logger.error(marker, msg);
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.error(marker, format, this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ format,
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.error(marker, format, this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull String format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ format,
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.error(marker, format, this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull String msg, final @Nullable Throwable t) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ msg,
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.error(marker, msg, UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ // Component-primary methods
+
+ @Override
+ public void trace(final @NotNull Component format) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(format),
+ null,
+ null
+ );
+ } else {
+ this.logger.trace(this.serialize(format));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.trace(this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.trace(this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Component format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(format),
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.trace(this.serialize(format), this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isTraceEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.trace(this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull Component msg) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(msg),
+ null,
+ null
+ );
+ } else {
+ this.logger.trace(marker, this.serialize(msg));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.trace(marker, this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.trace(marker, this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(format),
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.trace(marker, this.serialize(format), this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void trace(final @NotNull Marker marker, final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isTraceEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.TRACE_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.trace(marker, this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Component format) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(format),
+ null,
+ null
+ );
+ } else {
+ this.logger.debug(this.serialize(format));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.debug(this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.debug(this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Component format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(format),
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.debug(this.serialize(format), this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isDebugEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.debug(this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull Component msg) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(msg),
+ null,
+ null
+ );
+ } else {
+ this.logger.debug(marker, this.serialize(msg));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.debug(marker, this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.debug(marker, this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(format),
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.debug(marker, this.serialize(format), this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void debug(final @NotNull Marker marker, final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isDebugEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.DEBUG_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.debug(marker, this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Component format) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(format),
+ null,
+ null
+ );
+ } else {
+ this.logger.info(this.serialize(format));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.info(this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.info(this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Component format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(format),
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.info(this.serialize(format), this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isInfoEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.info(this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull Component msg) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(msg),
+ null,
+ null
+ );
+ } else {
+ this.logger.info(marker, this.serialize(msg));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.info(marker, this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.info(marker, this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(format),
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.info(marker, this.serialize(format), this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void info(final @NotNull Marker marker, final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isInfoEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.INFO_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.info(marker, this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Component format) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(format),
+ null,
+ null
+ );
+ } else {
+ this.logger.warn(this.serialize(format));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.warn(this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.warn(this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Component format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(format),
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.warn(this.serialize(format), this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isWarnEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.warn(this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull Component msg) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(msg),
+ null,
+ null
+ );
+ } else {
+ this.logger.warn(marker, this.serialize(msg));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.warn(marker, this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.warn(marker, this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(format),
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.warn(marker, this.serialize(format), this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void warn(final @NotNull Marker marker, final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isWarnEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.WARN_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.warn(marker, this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Component format) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(format),
+ null,
+ null
+ );
+ } else {
+ this.logger.error(this.serialize(format));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.error(this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.error(this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Component format, final @Nullable Object @NotNull... arguments) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(format),
+ this.maybeSerialize(arguments),
+ null
+ );
+ } else {
+ this.logger.error(this.serialize(format), this.maybeSerialize(arguments));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isErrorEnabled()) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ null,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.error(this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull Component msg) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(msg),
+ null,
+ null
+ );
+ } else {
+ this.logger.error(marker, this.serialize(msg));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg)},
+ null
+ );
+ } else {
+ this.logger.error(marker, this.serialize(format), this.maybeSerialize(arg));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object arg1, final @Nullable Object arg2) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(format),
+ new Object[] {this.maybeSerialize(arg1), this.maybeSerialize(arg2)},
+ null
+ );
+ } else {
+ this.logger.error(marker, this.serialize(format), this.maybeSerialize(arg1), this.maybeSerialize(arg2));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull Component format, final @Nullable Object @NotNull... argArray) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(format),
+ this.maybeSerialize(argArray),
+ null
+ );
+ } else {
+ this.logger.error(marker, this.serialize(format), this.maybeSerialize(argArray));
+ }
+ }
+
+ @Override
+ public void error(final @NotNull Marker marker, final @NotNull Component msg, final @Nullable Throwable t) {
+ if (!this.isErrorEnabled(marker)) return;
+
+ if (this.isLocationAware) {
+ ((LocationAwareLogger) this.logger).log(
+ marker,
+ FQCN,
+ LocationAwareLogger.ERROR_INT,
+ this.serialize(msg),
+ null,
+ UnpackedComponentThrowable.unpack(t, this.serializer)
+ );
+ } else {
+ this.logger.error(marker, this.serialize(msg), UnpackedComponentThrowable.unpack(t, this.serializer));
+ }
+ }
+}
diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/package-info.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/package-info.java
new file mode 100644
index 000000000..04aa92e82
--- /dev/null
+++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/package-info.java
@@ -0,0 +1,29 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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.
+ */
+/**
+ * A wrapper around SLF4J providing methods for formatted logging of Components.
+ *
+ * This wrapper supports the API provided in 1.7/1.8, but does not yet implement the fluent API present in the 2.0 betas.
+ */
+package net.kyori.adventure.text.logger.slf4j;
diff --git a/text-logger-slf4j/src/main/java9/net/kyori/adventure/text/logger/slf4j/CallerClassFinder.java b/text-logger-slf4j/src/main/java9/net/kyori/adventure/text/logger/slf4j/CallerClassFinder.java
new file mode 100644
index 000000000..0054a096a
--- /dev/null
+++ b/text-logger-slf4j/src/main/java9/net/kyori/adventure/text/logger/slf4j/CallerClassFinder.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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 net.kyori.adventure.text.logger.slf4j;
+
+// Java 9+ version, see Java 8 version as well
+final class CallerClassFinder {
+ private CallerClassFinder() {
+ }
+
+ static String callingClassName() {
+ return callingClassName(2); // this, plus the calling method
+ }
+
+ static String callingClassName(final int elementsToSkip) { // elementsToSkip not counting this method
+ return StackWalker.getInstance().walk(stream -> stream.map(StackWalker.StackFrame::getClassName)
+ .skip(elementsToSkip + 1)
+ .findFirst())
+ .orElseThrow(() -> new IllegalArgumentException("Not enough stack elements to skip " + elementsToSkip + " elements"));
+ }
+}
diff --git a/text-logger-slf4j/src/test/java/net/kyori/adventure/text/logger/slf4j/CallerClassFinderTest.java b/text-logger-slf4j/src/test/java/net/kyori/adventure/text/logger/slf4j/CallerClassFinderTest.java
new file mode 100644
index 000000000..afe3240ea
--- /dev/null
+++ b/text-logger-slf4j/src/test/java/net/kyori/adventure/text/logger/slf4j/CallerClassFinderTest.java
@@ -0,0 +1,42 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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 net.kyori.adventure.text.logger.slf4j;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class CallerClassFinderTest {
+
+ @Test
+ void testCallerClass() {
+ assertEquals(CallerClassFinderTest.class.getName(), Holder.test());
+ }
+
+ static final class Holder {
+ static String test() {
+ return CallerClassFinder.callingClassName();
+ }
+ }
+}
diff --git a/text-logger-slf4j/src/test/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggerTest.java b/text-logger-slf4j/src/test/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggerTest.java
new file mode 100644
index 000000000..ba7b759e2
--- /dev/null
+++ b/text-logger-slf4j/src/test/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggerTest.java
@@ -0,0 +1,159 @@
+/*
+ * This file is part of adventure, licensed under the MIT License.
+ *
+ * Copyright (c) 2017-2022 KyoriPowered
+ *
+ * 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 net.kyori.adventure.text.logger.slf4j;
+
+import com.github.valfirst.slf4jtest.LoggingEvent;
+import com.github.valfirst.slf4jtest.TestLogger;
+import com.github.valfirst.slf4jtest.TestLoggerFactory;
+import com.github.valfirst.slf4jtest.TestLoggerFactoryExtension;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.util.ComponentMessageThrowable;
+import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@ExtendWith(TestLoggerFactoryExtension.class)
+public class ComponentLoggerTest {
+ private static final TestLogger LOGGER = TestLoggerFactory.getTestLogger(ComponentLoggerTest.class);
+
+ private static final Marker MARKED = MarkerFactory.getMarker("MARKED");
+
+ ComponentLogger makeLogger() {
+ return ComponentLogger.logger();
+ }
+
+ @Test
+ void testCallerLogger() {
+ final ComponentLogger logger = ComponentLogger.logger();
+ assertEquals(this.getClass().getName(), logger.getName());
+ }
+
+ @Test
+ void testLogSimple() {
+ final Component toLog = Component.text()
+ .content("Hello ")
+ .color(NamedTextColor.RED)
+ .append(Component.translatable("location.world"))
+ .build();
+
+ this.makeLogger().info(toLog);
+
+ assertEquals(LOGGER.getLoggingEvents(), ImmutableList.of(LoggingEvent.info("Hello location.world")));
+ }
+
+ @Test
+ void testComponentArg() {
+ final Component message = Component.text("Hello ").append(Component.text("{}", NamedTextColor.BLUE));
+ final Component arg = Component.selector("@s");
+
+ this.makeLogger().warn(message, arg);
+
+ assertEquals(LOGGER.getLoggingEvents(), ImmutableList.of(LoggingEvent.warn("Hello {}", "@s")));
+ }
+
+ @Test
+ void testStringArg() {
+ final Component message = Component.text("Hello ").append(Component.text("{}", NamedTextColor.BLUE));
+ final String arg = "world";
+
+ this.makeLogger().debug(message, arg);
+
+ assertEquals(LOGGER.getLoggingEvents(), ImmutableList.of(LoggingEvent.debug("Hello {}", arg)));
+ }
+
+ @Test
+ void testMultiArgs() {
+ final Component message = Component.text("Good morning! The time is {} and you have {} cats!");
+ final Component arg0 = Component.text("14:28", NamedTextColor.BLUE);
+ final String arg1 = "11";
+
+ this.makeLogger().error(message, arg0, arg1);
+ assertEquals(
+ LOGGER.getLoggingEvents(),
+ ImmutableList.of(LoggingEvent.error("Good morning! The time is {} and you have {} cats!", "14:28", "11"))
+ );
+ }
+
+ @Test
+ void testUnwrapThrowable() {
+ final Component message = Component.text("Hello world");
+ final Exception error = new RichTestException(Component.translatable("test.failed", NamedTextColor.DARK_PURPLE));
+
+ this.makeLogger().warn(message, error);
+
+ final List events = LOGGER.getLoggingEvents();
+ assertEquals(1, events.size());
+ final Throwable thrownException = events.get(0).getThrowable().orElse(null);
+ assertNotNull(thrownException);
+
+ assertEquals("test.failed", thrownException.getMessage());
+ assertArrayEquals(error.getStackTrace(), thrownException.getStackTrace());
+ assertTrue(thrownException.toString().startsWith("net.kyori.adventure.text.logger.slf4j.ComponentLoggerTest$RichTestException"));
+ }
+
+ static class RichTestException extends Exception implements ComponentMessageThrowable {
+ private static final long serialVersionUID = -1l;
+
+ private final Component richMessage;
+
+ RichTestException(final Component richMessage) {
+ super("no");
+ this.richMessage = richMessage;
+ }
+
+ @Override
+ public @Nullable Component componentMessage() {
+ return this.richMessage;
+ }
+ }
+
+ @Test
+ void testWithMarker() {
+ final Component message = Component.text("meow :3");
+ this.makeLogger().info(MARKED, message);
+ assertEquals(
+ LOGGER.getLoggingEvents(),
+ ImmutableList.of(LoggingEvent.info(MARKED, "meow :3"))
+ );
+ }
+
+ @Test
+ void testComponentAsArgToPlainLog() {
+ this.makeLogger().info("Hello {}", Component.text("friend"));
+ assertEquals(
+ LOGGER.getLoggingEvents(),
+ ImmutableList.of(LoggingEvent.info("Hello {}", "friend"))
+ );
+ }
+}