docs(logger): document new stuff

This commit is contained in:
Johannes Frohnmeyer 2024-03-09 13:37:54 +01:00
parent f38ebc3a62
commit fea0d4cc66
Signed by: Johannes
GPG Key ID: E76429612C2929F4
10 changed files with 111 additions and 0 deletions

View File

@ -6,7 +6,15 @@ import org.slf4j.Marker;
import org.slf4j.event.Level;
import org.slf4j.helpers.MessageFormatter;
/**
* Abstract logger that implements formatting and redirects calls to methods taking strings.
* Simplifies the implementation of custom loggers.
*/
public interface CompactLogger extends Logger {
/**
* Set the logging level
* @return the current logging level
*/
Level getLevel();
@Override

View File

@ -3,6 +3,9 @@ package io.gitlab.jfronny.commons.logger;
import org.slf4j.Logger;
import org.slf4j.Marker;
/**
* Logger implementation that logs to multiple loggers at once.
*/
public class CompoundLogger implements Logger {
private final String name;
private final Logger[] loggers;

View File

@ -3,6 +3,9 @@ package io.gitlab.jfronny.commons.logger;
import org.slf4j.Logger;
import org.slf4j.Marker;
/**
* A logger that delegates all calls to another logger.
*/
public abstract class DelegateLogger implements Logger {
public static DelegateLogger create(Logger delegate) {
return new DelegateLogger() {

View File

@ -9,27 +9,45 @@ import org.slf4j.event.Level;
import java.util.Objects;
import java.util.Set;
/**
* A logger factory that allows apps to swap the backing factory at runtime, automatically updating all created loggers.
*/
public class HotswapLoggerFactory implements LeveledLoggerFactory {
private static final Set<HotswapLoggerFactory> KNOWN_INSTANCES = new WeakSet<>();
/**
* Resets all known instances to use the default logger factory.
*/
public static void resetAllStrategies() {
for (HotswapLoggerFactory factory : KNOWN_INSTANCES) {
factory.resetStrategy();
}
}
/**
* Updates all known instances to use the new logger factory.
* @param factory the new logger factory to use for all known instances
*/
public static void updateAllStrategies(ILoggerFactory factory) {
for (HotswapLoggerFactory f : KNOWN_INSTANCES) {
f.updateStrategy(factory);
}
}
/**
* Updates all known instances to use the new logger factory.
* @param factory the new logger factory to use for all known instances
*/
public static void updateAllStrategies(LeveledLoggerFactory factory) {
for (HotswapLoggerFactory f : KNOWN_INSTANCES) {
f.updateStrategy(factory);
}
}
/**
* Updates all known instances to use the new minimum log level if supported.
* @param minimumLevel the new minimum level to use for all known instances
*/
public static void updateAllDefaultLevels(Level minimumLevel) {
for (HotswapLoggerFactory f : KNOWN_INSTANCES) {
f.updateDefaultLevel(minimumLevel);
@ -44,10 +62,17 @@ public class HotswapLoggerFactory implements LeveledLoggerFactory {
private Level minimumLevel = Level.INFO;
private int version = 0;
/**
* Resets the strategy to use the default logger factory.
*/
public void resetStrategy() {
updateStrategy(StdoutLogger::fancy);
}
/**
* Updates the strategy to use the new logger factory.
* @param factory the new logger factory to use
*/
public void updateStrategy(ILoggerFactory factory) {
if (factory instanceof LeveledLoggerFactory f) {
updateStrategy(f);
@ -56,6 +81,10 @@ public class HotswapLoggerFactory implements LeveledLoggerFactory {
}
}
/**
* Updates the strategy to use the new logger factory.
* @param factory the new logger factory to use
*/
public void updateStrategy(LeveledLoggerFactory factory) {
synchronized (this) {
defaultFactory = Objects.requireNonNull(factory);
@ -63,6 +92,10 @@ public class HotswapLoggerFactory implements LeveledLoggerFactory {
}
}
/**
* Updates the minimum log level to use if supported.
* @param minimumLevel the new minimum level to use if supported
*/
public void updateDefaultLevel(Level minimumLevel) {
synchronized (this) {
this.minimumLevel = Objects.requireNonNull(minimumLevel);

View File

@ -7,6 +7,9 @@ import org.slf4j.helpers.NOPMDCAdapter;
import org.slf4j.spi.MDCAdapter;
import org.slf4j.spi.SLF4JServiceProvider;
/**
* A ServiceProvider creating HotswapLoggerFactories.
*/
public class HotswapServiceProvider implements SLF4JServiceProvider {
private ILoggerFactory loggerFactory;
private IMarkerFactory markerFactory;

View File

@ -5,6 +5,9 @@ import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.event.Level;
/**
* Abstract logger factory that optionally takes a log level.
*/
@FunctionalInterface
public interface LeveledLoggerFactory extends ILoggerFactory {
@Override

View File

@ -6,6 +6,9 @@ import org.slf4j.event.Level;
import java.util.*;
import java.util.function.Consumer;
/**
* A logger that stores all log messages in memory.
*/
public class MemoryLogger implements CompactLogger, Iterable<String> {
private final String name;
private final List<String> lines;

View File

@ -2,6 +2,9 @@ package io.gitlab.jfronny.commons.logger;
import org.slf4j.event.Level;
/**
* A class that provides ANSI escape codes for colored console output.
*/
public class OutputColors {
// Reset
public static final String RESET = "\033[0m"; // Text Reset
@ -76,6 +79,12 @@ public class OutputColors {
public static final String CYAN_BACKGROUND_BRIGHT = "\033[0;106m"; // CYAN
public static final String WHITE_BACKGROUND_BRIGHT = "\033[0;107m"; // WHITE
/**
* Gets the ANSI escape code to use for the given log level.
*
* @param level the level to get the color for
* @return the ANSI escape code for the given level
*/
public static String byLevel(Level level) {
return switch (level) {
case INFO -> BLUE;

View File

@ -9,6 +9,9 @@ import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
/**
* A simple logger that writes to a PrintStream.
*/
public class PrintStreamLogger implements CompactLogger {
private final @Nullable String name;
private final boolean color;
@ -17,6 +20,15 @@ public class PrintStreamLogger implements CompactLogger {
private final Level level;
private final PrintStream target;
/**
* Creates a new PrintStreamLogger.
* @param target the PrintStream to write to
* @param name the name of the logger
* @param level the minimum log level
* @param color whether to color the output using ANSI escape codes
* @param thread whether to include the thread name in the output
* @param timestamp whether to include a timestamp in the output
*/
public PrintStreamLogger(@NotNull PrintStream target, @Nullable String name, Level level, boolean color, boolean thread, boolean timestamp) {
this.target = Objects.requireNonNull(target);
this.name = name;
@ -61,6 +73,12 @@ public class PrintStreamLogger implements CompactLogger {
target.println(generateMessage(msg, Level.ERROR));
}
/**
* Formats the message to write to the PrintStream.
* @param msg the message to format
* @param level the level of the message
* @return the formatted message
*/
protected String generateMessage(String msg, Level level) {
StringBuilder sb = new StringBuilder();
// Timestamp

View File

@ -3,19 +3,47 @@ package io.gitlab.jfronny.commons.logger;
import org.jetbrains.annotations.Nullable;
import org.slf4j.event.Level;
/**
* A simple logger that writes to stdout.
*/
public class StdoutLogger extends PrintStreamLogger {
/**
* Creates a new StdoutLogger.
* @param name the name of the logger
* @param level the minimum log level
*/
public StdoutLogger(@Nullable String name, Level level) {
this(name, level, false);
}
/**
* Creates a new StdoutLogger.
* @param name the name of the logger
* @param level the minimum log level
* @param color whether to color the output using ANSI escape codes
*/
public StdoutLogger(@Nullable String name, Level level, boolean color) {
this(name, level, color, false, false);
}
/**
* Creates a new StdoutLogger.
* @param name the name of the logger
* @param level the minimum log level
* @param color whether to color the output using ANSI escape codes
* @param thread whether to include the thread name in the output
* @param timestamp whether to include a timestamp in the output
*/
public StdoutLogger(@Nullable String name, Level level, boolean color, boolean thread, boolean timestamp) {
super(System.out, name, level, color, thread, timestamp);
}
/**
* Creates a new StdoutLogger configured to be fancy.
* @param name the name of the logger
* @param level the minimum log level
* @return a new StdoutLogger with the given name and level
*/
public static StdoutLogger fancy(String name, Level level) {
return new StdoutLogger(name, level, true, true, true);
}