diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9a24f23f4..285fa65be 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ jmh = "1.35" jmhPlugin = "0.6.8" junit = "5.9.1" mockito = "4.5.1" -slf4j = "1.7.36" +slf4j = "2.0.1" truth = "1.1.3" [libraries] @@ -32,6 +32,7 @@ configurate-v4 = "org.spongepowered:configurate-core:4.1.2" # text-logger-slf4j slf4j = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } +slf4jRuntime = { module = "org.slf4j:slf4j-api", version = "1.7.36"} slf4jtest = "com.github.valfirst:slf4j-test:2.6.1" # Specific versions are needed for different SLF4J versions # text-serializer-gson diff --git a/renovate.json b/renovate.json index ee452c8b2..203ca0038 100644 --- a/renovate.json +++ b/renovate.json @@ -3,7 +3,8 @@ "local>KyoriPowered/.github:renovate-config" ], "ignoreDeps": [ - "com.google.code.gson:gson" + "com.google.code.gson:gson", + "org.slf4j:slf4j-api" ], "packageRules": [ { diff --git a/text-logger-slf4j/build.gradle.kts b/text-logger-slf4j/build.gradle.kts index f5c0c54e1..5c62a79df 100644 --- a/text-logger-slf4j/build.gradle.kts +++ b/text-logger-slf4j/build.gradle.kts @@ -2,10 +2,27 @@ plugins { id("adventure.common-conventions") } +val exposedVersion by configurations.creating { +} + +configurations { + apiElements { + extendsFrom(exposedVersion) + } + runtimeClasspath { + extendsFrom(exposedVersion) + } + runtimeElements { + extendsFrom(exposedVersion) + } +} + dependencies { api(projects.adventureApi) - api(libs.slf4j) + compileOnly(libs.slf4j) + exposedVersion(libs.slf4jRuntime) testImplementation(libs.slf4jtest) + testImplementation(libs.slf4j) } sourceSets.main { 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 index 63a027938..36d392970 100644 --- 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 @@ -28,6 +28,7 @@ import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.Marker; +import org.slf4j.event.Level; import static java.util.Objects.requireNonNull; @@ -198,6 +199,19 @@ public interface ComponentLogger extends Logger { */ void trace(final @NotNull Marker marker, final @NotNull Component msg, final @Nullable Throwable t); + /** + * Entry point for fluent-logging for {@link Level#TRACE} level. + * + *

Warning: This method is only available when running with SLF4J 2.0+

+ * + * @return LoggingEventBuilder instance as appropriate for level TRACE + * @since 4.12.0 + */ + @Override + default ComponentLoggingEventBuilder atTrace() { + return this.atLevel(Level.TRACE); + } + /** * Log a message at the DEBUG level. * @@ -316,6 +330,19 @@ public interface ComponentLogger extends Logger { */ void debug(final @NotNull Marker marker, final @NotNull Component msg, final @Nullable Throwable t); + /** + * Entry point for fluent-logging for {@link Level#DEBUG} level. + * + *

Warning: This method is only available when running with SLF4J 2.0+

+ * + * @return LoggingEventBuilder instance as appropriate for level DEBUG + * @since 4.12.0 + */ + @Override + default ComponentLoggingEventBuilder atDebug() { + return this.atLevel(Level.DEBUG); + } + /** * Log a message at the INFO level. * @@ -434,6 +461,19 @@ public interface ComponentLogger extends Logger { */ void info(final @NotNull Marker marker, final @NotNull Component msg, final @NotNull Throwable t); + /** + * Entry point for fluent-logging for {@link Level#INFO} level. + * + *

Warning: This method is only available when running with SLF4J 2.0+

+ * + * @return LoggingEventBuilder instance as appropriate for level INFO + * @since 4.12.0 + */ + @Override + default ComponentLoggingEventBuilder atInfo() { + return this.atLevel(Level.INFO); + } + /** * Log a message at the WARN level. * @@ -552,6 +592,19 @@ public interface ComponentLogger extends Logger { */ void warn(final @NotNull Marker marker, final @NotNull Component msg, final @NotNull Throwable t); + /** + * Entry point for fluent-logging for {@link Level#WARN} level. + * + *

Warning: This method is only available when running with SLF4J 2.0+

+ * + * @return LoggingEventBuilder instance as appropriate for level WARN + * @since 4.12.0 + */ + @Override + default ComponentLoggingEventBuilder atWarn() { + return this.atLevel(Level.WARN); + } + /** * Log a message at the ERROR level. * @@ -670,4 +723,43 @@ public interface ComponentLogger extends Logger { * @since 4.11.0 */ void error(final @NotNull Marker marker, final @NotNull Component msg, final @NotNull Throwable t); + + /** + * Entry point for fluent-logging for {@link Level#ERROR} level. + * + *

Warning: This method is only available when running with SLF4J 2.0+

+ * + * @return LoggingEventBuilder instance as appropriate for level ERROR + * @since 4.12.0 + */ + @Override + default @NotNull ComponentLoggingEventBuilder atError() { + return this.atLevel(Level.ERROR); + } + + /** + * Unconditionally create a new logging event builder. + * + *

Warning: This method is only available when running with SLF4J 2.0+

+ * + * @param level desired level for the event builder + * @return a new event builder + * @since 4.12.0 + */ + @Override + @NotNull ComponentLoggingEventBuilder makeLoggingEventBuilder(final @NotNull Level level); + + /** + * Create the appropriate builder for the supplied level. + * + *

This may be a no-op if the passed level is disabled.

+ * + *

Warning: This method is only available when running with SLF4J 2.0+

+ * + * @param level desired level for the event builder + * @return a new event builder + * @since 4.12.0 + */ + @Override + @NotNull ComponentLoggingEventBuilder atLevel(final @NotNull Level level); } diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilder.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilder.java new file mode 100644 index 000000000..018f439f1 --- /dev/null +++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilder.java @@ -0,0 +1,146 @@ +/* + * 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.Supplier; +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.Marker; +import org.slf4j.helpers.CheckReturnValue; +import org.slf4j.spi.LoggingEventBuilder; + +/** + * A builder for logging events that accepts {@link Component} messages and arguments. + * + *

Note: This class is only available when used in conjunction with SLF4J 2.0.0 or newer.

+ * + * @since 4.12.0 + */ +public interface ComponentLoggingEventBuilder extends LoggingEventBuilder { + + @Override + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder setCause(final @Nullable Throwable cause); + + @Override + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder addMarker(final @NotNull Marker marker); + + @Override + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder addArgument(final @Nullable Object p); + + @Override + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder addArgument(final @Nullable Supplier objectSupplier); + + @Override + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final @Nullable Object value); + + @Override + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final Supplier valueSupplier); + + @Override + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder setMessage(final @Nullable String message); + + /** + * Set the message to be logged for this event. + * + * @param message the message + * @return this builder + * @since 4.12.0 + */ + @SuppressWarnings("checkstyle:MethodName") // match overloads + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder setMessage(final @Nullable ComponentLike message); + + @Override + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder setMessage(final @NotNull Supplier messageSupplier); + + /** + * Set the message supplier to be logged for this event. + * + * @param messageSupplier the message supplier + * @return this builder + * @since 4.12.0 + */ + @SuppressWarnings("checkstyle:MethodName") // match overloads + @CheckReturnValue + @NotNull ComponentLoggingEventBuilder setComponentMessage(final @NotNull Supplier messageSupplier); + + /** + * Set the message and publish this logging event. + * + * @param message the message + * @see #log() + * @since 4.12.0 + */ + void log(final @Nullable ComponentLike message); + + /** + * Set the message with one argument and publish this logging event. + * + * @param message the message + * @param arg the argument + * @see #log() + * @since 4.12.0 + */ + void log(final @Nullable ComponentLike message, final @Nullable Object arg); + + /** + * Set the message with two arguments and publish this logging event. + * + * @param message the message + * @param arg0 the first argument + * @param arg1 the second argument + * @see #log() + * @since 4.12.0 + */ + void log(final @Nullable ComponentLike message, final @Nullable Object arg0, final @Nullable Object arg1); + + /** + * Set the message with an array of arguments and publish this logging event. + * + * @param message the message + * @param args the arguments + * @see #log() + * @since 4.12.0 + */ + void log(final @Nullable ComponentLike message, @Nullable Object@NotNull... args); + + /** + * Set the message supplier and publish this logging event. + * + * @param messageSupplier the message supplier + * @see #log() + * @since 4.12.0 + */ + void logComponent(final @NotNull Supplier messageSupplier); +} diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilderImpl.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilderImpl.java new file mode 100644 index 000000000..55711485f --- /dev/null +++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/ComponentLoggingEventBuilderImpl.java @@ -0,0 +1,252 @@ +/* + * 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 java.util.function.Supplier; +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.event.Level; +import org.slf4j.event.LoggingEvent; +import org.slf4j.helpers.CheckReturnValue; +import org.slf4j.spi.DefaultLoggingEventBuilder; +import org.slf4j.spi.LoggingEventAware; + +final class ComponentLoggingEventBuilderImpl extends DefaultLoggingEventBuilder implements ComponentLoggingEventBuilder { + + private static final String FQCN = ComponentLoggingEventBuilderImpl.class.getName(); + + private final Function serializer; + + ComponentLoggingEventBuilderImpl(final Logger logger, final Level level, final Function serializer) { + super(logger, level); + this.serializer = serializer; + } + + private String serialize(final ComponentLike component) { + return component == null ? null : this.serializer.apply(component.asComponent()); + } + + 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; + } + + @Override + public @NotNull ComponentLoggingEventBuilder setMessage(final ComponentLike message) { + super.setMessage(this.serialize(message)); + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder setComponentMessage(final @NotNull Supplier messageSupplier) { + super.setMessage(this.serialize(messageSupplier.get())); + return this; + } + + @Override + public void log(final ComponentLike message) { + this.loggingEvent.setMessage(this.serialize(message)); + this.logOwnBoundary(this.loggingEvent); + } + + /** + * Set the message with one argument and publish this logging event. + * + * @param message the message + * @param arg the argument + * @see #log() + * @since 4.12.0 + */ + @Override + public void log(final ComponentLike message, final Object arg) { + this.loggingEvent.setMessage(this.serialize(message)); + this.loggingEvent.addArgument(this.maybeSerialize(arg)); + this.logOwnBoundary(this.loggingEvent); + } + + /** + * Set the message with two arguments and publish this logging event. + * + * @param message the message + * @param arg0 the first argument + * @param arg1 the second argument + * @see #log() + * @since 4.12.0 + */ + @Override + public void log(final ComponentLike message, final Object arg0, final Object arg1) { + this.loggingEvent.setMessage(this.serialize(message)); + this.loggingEvent.addArgument(this.maybeSerialize(arg0)); + this.loggingEvent.addArgument(this.maybeSerialize(arg1)); + this.logOwnBoundary(this.loggingEvent); + } + + /** + * Set the message with an array of arguments and publish this logging event. + * + * @param message the message + * @param args the arguments + * @see #log() + * @since 4.12.0 + */ + @Override + public void log(final ComponentLike message, final Object @NotNull ... args) { + this.loggingEvent.setMessage(this.serialize(message)); + this.loggingEvent.addArguments(this.maybeSerialize(args)); + this.logOwnBoundary(this.loggingEvent); + } + + /** + * Set the message supplier and publish this logging event. + * + * @param messageSupplier the message supplier + * @see #log() + * @since 4.12.0 + */ + @Override + public void logComponent(final @NotNull Supplier messageSupplier) { + this.log(messageSupplier.get()); + } + + // Impl junk + + private void logOwnBoundary(final LoggingEvent event) { + this.setCallerBoundary(FQCN); + if (this.logger instanceof LoggingEventAware) { + ((LoggingEventAware) this.logger).log(event); + } else { + super.log(event); + } + } + + // Overloads for direct-log methods + @Override + public void log(final String message, final Object arg) { + this.loggingEvent.setMessage(message); + this.loggingEvent.addArgument(this.maybeSerialize(arg)); + this.logOwnBoundary(this.loggingEvent); + } + + @Override + public void log(final String message, final Object arg0, final Object arg1) { + this.loggingEvent.setMessage(message); + this.loggingEvent.addArgument(this.maybeSerialize(arg0)); + this.loggingEvent.addArgument(this.maybeSerialize(arg1)); + this.logOwnBoundary(this.loggingEvent); + } + + @Override + public void log(final String message, final Object... args) { + this.loggingEvent.setMessage(message); + this.loggingEvent.addArguments(this.maybeSerialize(args)); + this.logOwnBoundary(this.loggingEvent); + } + + // Overloads for return types + @Override + @CheckReturnValue + public @NotNull ComponentLoggingEventBuilder setCause(final @Nullable Throwable cause) { + super.setCause(UnpackedComponentThrowable.unpack(cause, this.serializer)); + return this; + } + + @Override + @CheckReturnValue + public @NotNull ComponentLoggingEventBuilder addMarker(final @NotNull Marker marker) { + super.addMarker(marker); + return this; + } + + @Override + @CheckReturnValue + public @NotNull ComponentLoggingEventBuilder addArgument(final @Nullable Object p) { + super.addArgument(this.maybeSerialize(p)); + return this; + } + + @Override + @CheckReturnValue + public @NotNull ComponentLoggingEventBuilder addArgument(final @Nullable Supplier objectSupplier) { + super.addArgument(objectSupplier == null ? null : this.maybeSerialize(objectSupplier.get())); + return this; + } + + @Override + @CheckReturnValue + public @NotNull ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final @Nullable Object value) { + super.addKeyValue(key, this.maybeSerialize(value)); + return this; + } + + @Override + @CheckReturnValue + public @NotNull ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final Supplier valueSupplier) { + super.addKeyValue(key, this.maybeSerialize(valueSupplier.get())); + return this; + } + + @Override + @CheckReturnValue + public @NotNull ComponentLoggingEventBuilder setMessage(final @Nullable String message) { + super.setMessage(message); + return this; + } + + @Override + @CheckReturnValue + public @NotNull ComponentLoggingEventBuilder setMessage(final @Nullable Supplier messageSupplier) { + super.setMessage(messageSupplier); + return this; + } +} 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 index 33d8c85cd..0cd4417c7 100644 --- 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 @@ -71,7 +71,7 @@ static final class LoggerHelperImpl implements ComponentLoggerProvider.LoggerHel } @Override - public Function plainSerializer() { + public @NotNull Function plainSerializer() { return comp -> { final Component translated = GlobalTranslator.render(comp, Locale.getDefault()); final StringBuilder contents = new StringBuilder(); diff --git a/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/NoOpComponentLoggingEventBuilderImpl.java b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/NoOpComponentLoggingEventBuilderImpl.java new file mode 100644 index 000000000..0372d69c3 --- /dev/null +++ b/text-logger-slf4j/src/main/java/net/kyori/adventure/text/logger/slf4j/NoOpComponentLoggingEventBuilderImpl.java @@ -0,0 +1,131 @@ +/* + * 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.Supplier; +import net.kyori.adventure.text.ComponentLike; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Marker; + +final class NoOpComponentLoggingEventBuilderImpl implements ComponentLoggingEventBuilder { + static final NoOpComponentLoggingEventBuilderImpl INSTANCE = new NoOpComponentLoggingEventBuilderImpl(); + + private NoOpComponentLoggingEventBuilderImpl() { + } + + @Override + public @NotNull ComponentLoggingEventBuilder setCause(final @Nullable Throwable cause) { + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder addMarker(final @NotNull Marker marker) { + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder addArgument(final @Nullable Object p) { + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder addArgument(final @Nullable Supplier objectSupplier) { + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final @Nullable Object value) { + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder addKeyValue(final @Nullable String key, final Supplier valueSupplier) { + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder setMessage(final @Nullable String message) { + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder setMessage(final @Nullable ComponentLike message) { + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder setMessage(final @NotNull Supplier messageSupplier) { + return this; + } + + @Override + public @NotNull ComponentLoggingEventBuilder setComponentMessage(final @NotNull Supplier messageSupplier) { + return this; + } + + @Override + public void log() { + } + + @Override + public void log(final String message) { + } + + @Override + public void log(final String message, final Object arg) { + } + + @Override + public void log(final String message, final Object arg0, final Object arg1) { + } + + @Override + public void log(final String message, final Object... args) { + } + + @Override + public void log(final Supplier messageSupplier) { + } + + @Override + public void log(final @Nullable ComponentLike message) { + } + + @Override + public void log(final @Nullable ComponentLike message, final @Nullable Object arg) { + } + + @Override + public void log(final @Nullable ComponentLike message, final @Nullable Object arg0, final @Nullable Object arg1) { + } + + @Override + public void log(final @Nullable ComponentLike message, final @Nullable Object @NotNull ... args) { + } + + @Override + public void logComponent(final @NotNull Supplier messageSupplier) { + } +} 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 index 4d13594fd..51ad87922 100644 --- 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 @@ -31,6 +31,7 @@ import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.Marker; +import org.slf4j.event.Level; import org.slf4j.spi.LocationAwareLogger; final class WrappingComponentLoggerImpl implements ComponentLogger { @@ -138,6 +139,25 @@ public boolean isErrorEnabled(final Marker marker) { return this.logger.isErrorEnabled(marker); } + @Override + public boolean isEnabledForLevel(final Level level) { + return this.logger.isEnabledForLevel(level); + } + + @Override + public @NotNull ComponentLoggingEventBuilder makeLoggingEventBuilder(final @NotNull Level level) { + return new ComponentLoggingEventBuilderImpl(this.logger, level, this.serializer); + } + + @Override + public @NotNull ComponentLoggingEventBuilder atLevel(final @NotNull Level level) { + if (this.logger.isEnabledForLevel(level)) { + return this.makeLoggingEventBuilder(level); + } else { + return NoOpComponentLoggingEventBuilderImpl.INSTANCE; + } + } + // Standard string methods, to process potential Component arguments @Override 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 index ba7b759e2..0724dce5d 100644 --- 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 @@ -156,4 +156,17 @@ void testComponentAsArgToPlainLog() { ImmutableList.of(LoggingEvent.info("Hello {}", "friend")) ); } + + @Test + void testFluentApi() { + final Component message = Component.text("Hello ").append(Component.text("{}", NamedTextColor.BLUE)); + final String arg = "world"; + + this.makeLogger().atDebug() + .setMessage(message) + .addArgument(arg) + .log(); + + assertEquals(LOGGER.getLoggingEvents(), ImmutableList.of(LoggingEvent.debug("Hello {}", arg))); + } }