mirror of
https://github.com/GravitLauncher/Launcher
synced 2024-12-22 16:41:46 +03:00
[FEATURE][EXPERIMENTAL] LogHelper slf4j bridge
This commit is contained in:
parent
3b6997a723
commit
5547909c16
9 changed files with 464 additions and 245 deletions
|
@ -31,17 +31,8 @@ public SecurityCheckCommand(LaunchServer server) {
|
|||
}
|
||||
|
||||
public static void printCheckResult(LogHelper.Level level, String module, String comment, Boolean status) {
|
||||
LogHelper.rawLog(() -> FormatHelper.rawFormat(level, LogHelper.getDataTime(), false).concat(String.format("[%s] %s - %s", module, comment, status == null ? "WARN" : (status ? "OK" : "FAIL"))),
|
||||
() -> FormatHelper.rawAnsiFormat(level, LogHelper.getDataTime(), false)
|
||||
.fgBright(Ansi.Color.WHITE)
|
||||
.a("[")
|
||||
.fgBright(Ansi.Color.BLUE)
|
||||
.a(module)
|
||||
.fgBright(Ansi.Color.WHITE)
|
||||
.a("] ".concat(comment).concat(" - "))
|
||||
.fgBright(status == null ? Ansi.Color.YELLOW : (status ? Ansi.Color.GREEN : Ansi.Color.RED))
|
||||
.a(status == null ? "WARN" : (status ? "OK" : "FAIL"))
|
||||
.reset().toString());
|
||||
LogHelper.log(level, String.format("[%s] %s - %s", module, comment, status == null ? "WARN" : (status ? "OK" : "FAIL")), false);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="%d{HH:mm:ss.SSS} %highlight{[%-5level]}{FATAL=red, ERROR=red, WARN=yellow, INFO=default, DEBUG=green, TRACE=blue} %highlight{%msg}{FATAL=red, ERROR=red, WARN=yellow, INFO=default, DEBUG=green, TRACE=blue}%n" />
|
||||
<Filters>
|
||||
<MarkerFilter marker="JANSI" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
|
||||
<MarkerFilter marker="NOJANSI" onMatch="DENY" onMismatch="NEUTRAL"/>
|
||||
</Filters>
|
||||
</Console>
|
||||
<RollingFile name="MainFile" fileName="logs/latest.log"
|
||||
filePattern="logs/%d{yyyy-MM-dd}.log.gz">
|
||||
|
@ -10,9 +14,15 @@
|
|||
<Policies>
|
||||
<TimeBasedTriggeringPolicy />
|
||||
</Policies>
|
||||
<Filters>
|
||||
<MarkerFilter marker="JANSI" onMatch="DENY" onMismatch="NEUTRAL"/>
|
||||
</Filters>
|
||||
</RollingFile>
|
||||
<File name="DebugFile" fileName="logs/debug.log" immediateFlush="false" append="false">
|
||||
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
|
||||
<Filters>
|
||||
<MarkerFilter marker="JANSI" onMatch="DENY" onMismatch="NEUTRAL"/>
|
||||
</Filters>
|
||||
</File>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
compileOnly group: 'org.jline', name: 'jline-reader', version: rootProject['verJline']
|
||||
compileOnly group: 'org.jline', name: 'jline-terminal', version: rootProject['verJline']
|
||||
compileOnly group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: rootProject['verBcprov']
|
||||
compileOnly group: 'org.slf4j', name: 'slf4j-api', version: rootProject['verSlf4j']
|
||||
api group: 'com.google.code.gson', name: 'gson', version: rootProject['verGson']
|
||||
testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: rootProject['verJunit']
|
||||
testImplementation group: 'org.jline', name: 'jline', version: rootProject['verJline']
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class HelpCommand extends Command {
|
||||
private final CommandHandler handler;
|
||||
|
@ -19,9 +20,9 @@ public HelpCommand(CommandHandler handler) {
|
|||
|
||||
public static void printCommand(String name, Command command) {
|
||||
String args = command.getArgsDescription();
|
||||
//LogHelper.subInfo("%s %s - %s", name, args == null ? "[nothing]" : args, command.getUsageDescription());
|
||||
LogHelper.rawLog(() -> FormatHelper.rawFormat(LogHelper.Level.INFO, LogHelper.getDataTime(), true) + String.format("%s %s - %s", name, args == null ? "[nothing]" : args, command.getUsageDescription()), () -> {
|
||||
Ansi ansi = FormatHelper.rawAnsiFormat(LogHelper.Level.INFO, LogHelper.getDataTime(), true);
|
||||
Supplier<String> plaintext = () -> String.format("%s %s - %s", name, args == null ? "[nothing]" : args, command.getUsageDescription());
|
||||
Supplier<String> jansitext = () -> {
|
||||
Ansi ansi = new Ansi();
|
||||
ansi.fgBright(Ansi.Color.GREEN);
|
||||
ansi.a(name + " ");
|
||||
ansi.fgBright(Ansi.Color.CYAN);
|
||||
|
@ -32,7 +33,8 @@ public static void printCommand(String name, Command command) {
|
|||
ansi.a(command.getUsageDescription());
|
||||
ansi.reset();
|
||||
return ansi.toString();
|
||||
}, () -> LogHelper.htmlFormatLog(LogHelper.Level.INFO, LogHelper.getDataTime(), String.format("<font color=\"green\">%s</font> <font color=\"cyan\">%s</font> - <font color=\"yellow\">%s</font>", name, args == null ? "[nothing]" : args, command.getUsageDescription()), true));
|
||||
};
|
||||
LogHelper.logJAnsi(LogHelper.Level.INFO, plaintext, jansitext, true);
|
||||
}
|
||||
|
||||
public static void printSubCommandsHelp(String base, Command command) {
|
||||
|
|
|
@ -53,7 +53,7 @@ public static Ansi rawAnsiFormat(LogHelper.Level level, String dateTime, boolean
|
|||
return ansi;
|
||||
}
|
||||
|
||||
static String ansiFormatVersion(String product) {
|
||||
public static String ansiFormatVersion(String product) {
|
||||
return new Ansi().bold(). // Setup
|
||||
fgBright(Ansi.Color.MAGENTA).a("GravitLauncher "). // sashok724's
|
||||
fgBright(Ansi.Color.BLUE).a("(fork sashok724's Launcher) ").
|
||||
|
@ -63,7 +63,7 @@ static String ansiFormatVersion(String product) {
|
|||
reset().toString(); // To file
|
||||
}
|
||||
|
||||
static String ansiFormatLicense(String product) {
|
||||
public static String ansiFormatLicense(String product) {
|
||||
return new Ansi().bold(). // Setup
|
||||
fgBright(Ansi.Color.MAGENTA).a("License for "). // sashok724's
|
||||
fgBright(Ansi.Color.CYAN).a(product). // Product
|
||||
|
@ -76,11 +76,11 @@ public static String rawFormat(LogHelper.Level level, String dateTime, boolean s
|
|||
return dateTime + " [" + level.name + (sub ? "] " : "] ");
|
||||
}
|
||||
|
||||
static String formatVersion(String product) {
|
||||
public static String formatVersion(String product) {
|
||||
return String.format("GravitLauncher (fork sashok724's Launcher) %s v%s", product, Version.getVersion().toString());
|
||||
}
|
||||
|
||||
static String formatLicense(String product) {
|
||||
public static String formatLicense(String product) {
|
||||
return String.format("License for %s GPLv3. SourceCode: https://github.com/GravitLauncher/Launcher", product);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package pro.gravit.utils.helper;
|
||||
|
||||
import org.fusesource.jansi.Ansi;
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
import pro.gravit.launcher.LauncherNetworkAPI;
|
||||
import pro.gravit.utils.logging.LogHelperAppender;
|
||||
import pro.gravit.utils.logging.SimpleLogHelperImpl;
|
||||
import pro.gravit.utils.logging.Slf4jLogHelperImpl;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Path;
|
||||
|
@ -13,12 +14,12 @@
|
|||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class LogHelper {
|
||||
|
||||
private static LogHelperAppender impl;
|
||||
public static final String DEBUG_PROPERTY = "launcher.debug";
|
||||
|
||||
public static final String DEV_PROPERTY = "launcher.dev";
|
||||
|
@ -27,45 +28,21 @@ public final class LogHelper {
|
|||
|
||||
public static final String NO_JANSI_PROPERTY = "launcher.noJAnsi";
|
||||
|
||||
public static final boolean JANSI;
|
||||
public static final String NO_SLF4J_PROPERTY = "launcher.noSlf4j";
|
||||
|
||||
// Output settings
|
||||
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss", Locale.US);
|
||||
private static final AtomicBoolean DEBUG_ENABLED = new AtomicBoolean(Boolean.getBoolean(DEBUG_PROPERTY));
|
||||
private static final AtomicBoolean STACKTRACE_ENABLED = new AtomicBoolean(Boolean.getBoolean(STACKTRACE_PROPERTY));
|
||||
private static final AtomicBoolean DEV_ENABLED = new AtomicBoolean(Boolean.getBoolean(DEV_PROPERTY));
|
||||
private static final Set<OutputEnity> OUTPUTS = Collections.newSetFromMap(new ConcurrentHashMap<>(2));
|
||||
private static final Set<Consumer<Throwable>> EXCEPTIONS_CALLBACKS = Collections.newSetFromMap(new ConcurrentHashMap<>(2));
|
||||
private static final OutputEnity STD_OUTPUT;
|
||||
|
||||
static {
|
||||
// Use JAnsi if available
|
||||
boolean jansi;
|
||||
boolean useSlf4j = false;
|
||||
try {
|
||||
if (Boolean.getBoolean(NO_JANSI_PROPERTY)) {
|
||||
jansi = false;
|
||||
} else {
|
||||
Class.forName("org.fusesource.jansi.Ansi");
|
||||
AnsiConsole.systemInstall();
|
||||
jansi = true;
|
||||
}
|
||||
Class.forName("org.slf4j.Logger");
|
||||
useSlf4j = !Boolean.getBoolean(NO_SLF4J_PROPERTY);
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
jansi = false;
|
||||
}
|
||||
JANSI = jansi;
|
||||
|
||||
// Add std writer
|
||||
STD_OUTPUT = new OutputEnity(System.out::println, JANSI ? OutputTypes.JANSI : OutputTypes.PLAIN);
|
||||
addOutput(STD_OUTPUT);
|
||||
|
||||
// Add file log writer
|
||||
String logFile = System.getProperty("launcher.logFile");
|
||||
if (logFile != null) {
|
||||
try {
|
||||
addOutput(IOHelper.toPath(logFile));
|
||||
} catch (IOException e) {
|
||||
error(e);
|
||||
}
|
||||
if(useSlf4j) {
|
||||
impl = new Slf4jLogHelperImpl();
|
||||
} else {
|
||||
impl = new SimpleLogHelperImpl();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +50,7 @@ private LogHelper() {
|
|||
}
|
||||
|
||||
public static void addOutput(OutputEnity output) {
|
||||
OUTPUTS.add(Objects.requireNonNull(output, "output"));
|
||||
impl.addOutput(output);
|
||||
}
|
||||
|
||||
public static void addExcCallback(Consumer<Throwable> output) {
|
||||
|
@ -81,19 +58,15 @@ public static void addExcCallback(Consumer<Throwable> output) {
|
|||
}
|
||||
|
||||
public static void addOutput(Output output, OutputTypes type) {
|
||||
OUTPUTS.add(new OutputEnity(Objects.requireNonNull(output, "output"), type));
|
||||
addOutput(new OutputEnity(Objects.requireNonNull(output, "output"), type));
|
||||
}
|
||||
|
||||
public static void addOutput(Path file) throws IOException {
|
||||
if (JANSI) {
|
||||
addOutput(new JAnsiOutput(IOHelper.newOutput(file, true)), OutputTypes.JANSI);
|
||||
} else {
|
||||
addOutput(IOHelper.newWriter(file, true));
|
||||
}
|
||||
addOutput(IOHelper.newWriter(file, true));
|
||||
}
|
||||
|
||||
public static void addOutput(Writer writer) {
|
||||
addOutput(new WriterOutput(writer), OutputTypes.PLAIN);
|
||||
addOutput(new SimpleLogHelperImpl.WriterOutput(writer), OutputTypes.PLAIN);
|
||||
}
|
||||
|
||||
public static void debug(String message) {
|
||||
|
@ -140,152 +113,51 @@ public static void info(String format, Object... args) {
|
|||
}
|
||||
|
||||
public static boolean isDebugEnabled() {
|
||||
return DEBUG_ENABLED.get();
|
||||
return impl.isDebugEnabled();
|
||||
}
|
||||
|
||||
public static void setDebugEnabled(boolean debugEnabled) {
|
||||
DEBUG_ENABLED.set(debugEnabled);
|
||||
impl.setDebugEnabled(debugEnabled);
|
||||
}
|
||||
|
||||
public static boolean isStacktraceEnabled() {
|
||||
return STACKTRACE_ENABLED.get();
|
||||
return impl.isStacktraceEnabled();
|
||||
}
|
||||
|
||||
public static void setStacktraceEnabled(boolean stacktraceEnabled) {
|
||||
STACKTRACE_ENABLED.set(stacktraceEnabled);
|
||||
impl.setStacktraceEnabled(stacktraceEnabled);
|
||||
}
|
||||
|
||||
public static boolean isDevEnabled() {
|
||||
return DEV_ENABLED.get();
|
||||
return impl.isDevEnabled();
|
||||
}
|
||||
|
||||
public static void setDevEnabled(boolean stacktraceEnabled) {
|
||||
DEV_ENABLED.set(stacktraceEnabled);
|
||||
impl.setDevEnabled(stacktraceEnabled);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String getDataTime() {
|
||||
return DATE_TIME_FORMATTER.format(LocalDateTime.now());
|
||||
return DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss", Locale.US).format(LocalDateTime.now());
|
||||
}
|
||||
|
||||
public static void log(Level level, String message, boolean sub) {
|
||||
String dateTime = DATE_TIME_FORMATTER.format(LocalDateTime.now());
|
||||
String jansiString = null, plainString = null, htmlString = null;
|
||||
for (OutputEnity output : OUTPUTS) {
|
||||
if (output.type == OutputTypes.JANSI && JANSI) {
|
||||
if (jansiString != null) {
|
||||
output.output.println(jansiString);
|
||||
continue;
|
||||
}
|
||||
|
||||
jansiString = ansiFormatLog(level, dateTime, message, sub);
|
||||
output.output.println(jansiString);
|
||||
} else if (output.type == OutputTypes.HTML) {
|
||||
if (htmlString != null) {
|
||||
output.output.println(htmlString);
|
||||
continue;
|
||||
}
|
||||
|
||||
htmlString = htmlFormatLog(level, dateTime, message, sub);
|
||||
output.output.println(htmlString);
|
||||
} else {
|
||||
if (plainString != null) {
|
||||
output.output.println(plainString);
|
||||
continue;
|
||||
}
|
||||
|
||||
plainString = formatLog(level, message, dateTime, sub);
|
||||
output.output.println(plainString);
|
||||
}
|
||||
}
|
||||
impl.log(level, message, sub);
|
||||
}
|
||||
|
||||
public static void rawLog(Supplier<String> plainStr, Supplier<String> jansiStr) {
|
||||
rawLog(plainStr, jansiStr, null);
|
||||
}
|
||||
|
||||
public static void rawLog(Supplier<String> plainStr, Supplier<String> jansiStr, Supplier<String> htmlStr) {
|
||||
String jansiString = null, plainString = null, htmlString = null;
|
||||
for (OutputEnity output : OUTPUTS) {
|
||||
if (output.type == OutputTypes.JANSI && JANSI) {
|
||||
if (jansiString != null) {
|
||||
output.output.println(jansiString);
|
||||
continue;
|
||||
}
|
||||
|
||||
jansiString = jansiStr.get();
|
||||
output.output.println(jansiString);
|
||||
} else if (output.type == OutputTypes.HTML) {
|
||||
if (htmlString != null) {
|
||||
output.output.println(htmlString);
|
||||
continue;
|
||||
}
|
||||
|
||||
htmlString = htmlStr.get();
|
||||
output.output.println(htmlString);
|
||||
} else {
|
||||
if (plainString != null) {
|
||||
output.output.println(plainString);
|
||||
continue;
|
||||
}
|
||||
|
||||
plainString = plainStr.get();
|
||||
output.output.println(plainString);
|
||||
}
|
||||
}
|
||||
public static void logJAnsi(LogHelper.Level level, Supplier<String> plaintext, Supplier<String> jansitext, boolean sub) {
|
||||
impl.logJAnsi(level, plaintext, jansitext, sub);
|
||||
}
|
||||
|
||||
public static void printVersion(String product) {
|
||||
String jansiString = null, plainString = null;
|
||||
for (OutputEnity output : OUTPUTS) {
|
||||
if (output.type == OutputTypes.JANSI && JANSI) {
|
||||
if (jansiString != null) {
|
||||
output.output.println(jansiString);
|
||||
continue;
|
||||
}
|
||||
|
||||
jansiString = FormatHelper.ansiFormatVersion(product);
|
||||
output.output.println(jansiString);
|
||||
} else {
|
||||
if (plainString != null) {
|
||||
output.output.println(plainString);
|
||||
continue;
|
||||
}
|
||||
|
||||
plainString = FormatHelper.formatVersion(product);
|
||||
output.output.println(plainString);
|
||||
}
|
||||
}
|
||||
impl.printVersion(product);
|
||||
}
|
||||
|
||||
public static void printLicense(String product) {
|
||||
String jansiString = null, plainString = null;
|
||||
for (OutputEnity output : OUTPUTS) {
|
||||
if (output.type == OutputTypes.JANSI && JANSI) {
|
||||
if (jansiString != null) {
|
||||
output.output.println(jansiString);
|
||||
continue;
|
||||
}
|
||||
|
||||
jansiString = FormatHelper.ansiFormatLicense(product);
|
||||
output.output.println(jansiString);
|
||||
} else {
|
||||
if (plainString != null) {
|
||||
output.output.println(plainString);
|
||||
continue;
|
||||
}
|
||||
|
||||
plainString = FormatHelper.formatLicense(product);
|
||||
output.output.println(plainString);
|
||||
}
|
||||
}
|
||||
impl.printLicense(product);
|
||||
}
|
||||
|
||||
public static boolean removeOutput(OutputEnity output) {
|
||||
return OUTPUTS.remove(output);
|
||||
}
|
||||
|
||||
public static boolean removeStdOutput() {
|
||||
return removeOutput(STD_OUTPUT);
|
||||
return impl.removeOutput(output);
|
||||
}
|
||||
|
||||
public static void subDebug(String message) {
|
||||
|
@ -328,51 +200,13 @@ public static void warning(String format, Object... args) {
|
|||
warning(String.format(format, args));
|
||||
}
|
||||
|
||||
private static String ansiFormatLog(Level level, String dateTime, String message, boolean sub) {
|
||||
|
||||
Ansi ansi = FormatHelper.rawAnsiFormat(level, dateTime, sub);
|
||||
ansi.a(message);
|
||||
|
||||
// Finish with reset code
|
||||
return ansi.reset().toString();
|
||||
}
|
||||
|
||||
public static String htmlFormatLog(Level level, String dateTime, String message, boolean sub) {
|
||||
String levelColor;
|
||||
switch (level) {
|
||||
case WARNING:
|
||||
levelColor = "gravitlauncher-log-warning";
|
||||
break;
|
||||
case ERROR:
|
||||
levelColor = "gravitlauncher-log-error";
|
||||
break;
|
||||
case INFO:
|
||||
levelColor = "gravitlauncher-log-info";
|
||||
break;
|
||||
case DEBUG:
|
||||
levelColor = "gravitlauncher-log-debug";
|
||||
break;
|
||||
case DEV:
|
||||
levelColor = "gravitlauncher-log-dev";
|
||||
break;
|
||||
default:
|
||||
levelColor = "gravitlauncher-log-unknown";
|
||||
break;
|
||||
}
|
||||
if (sub) levelColor += " gravitlauncher-log-sub";
|
||||
return String.format("%s <span class=\"gravitlauncher-log %s\">[%s] %s</span>", dateTime, levelColor, level.toString(), sub ? ' ' + message : message);
|
||||
}
|
||||
|
||||
private static String formatLog(Level level, String message, String dateTime, boolean sub) {
|
||||
return FormatHelper.rawFormat(level, dateTime, sub) + message;
|
||||
}
|
||||
|
||||
public enum OutputTypes {
|
||||
@LauncherNetworkAPI
|
||||
PLAIN,
|
||||
@LauncherNetworkAPI
|
||||
JANSI,
|
||||
@LauncherNetworkAPI
|
||||
@Deprecated
|
||||
HTML
|
||||
}
|
||||
|
||||
|
@ -405,33 +239,4 @@ public OutputEnity(Output output, OutputTypes type) {
|
|||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class JAnsiOutput extends WriterOutput {
|
||||
private JAnsiOutput(OutputStream output) {
|
||||
super(IOHelper.newWriter(output));
|
||||
}
|
||||
}
|
||||
|
||||
private static class WriterOutput implements Output, AutoCloseable {
|
||||
private final Writer writer;
|
||||
|
||||
private WriterOutput(Writer writer) {
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println(String message) {
|
||||
try {
|
||||
writer.write(message + System.lineSeparator());
|
||||
writer.flush();
|
||||
} catch (IOException ignored) {
|
||||
// Do nothing?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package pro.gravit.utils.logging;
|
||||
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public interface LogHelperAppender {
|
||||
void log(LogHelper.Level level, String message, boolean sub);
|
||||
void logJAnsi(LogHelper.Level level, Supplier<String> plaintext, Supplier<String> jansitext, boolean sub);
|
||||
boolean isDebugEnabled();
|
||||
void setDebugEnabled(boolean debugEnabled);
|
||||
boolean isStacktraceEnabled();
|
||||
void setStacktraceEnabled(boolean stacktraceEnabled);
|
||||
boolean isDevEnabled();
|
||||
void setDevEnabled(boolean stacktraceEnabled);
|
||||
void addOutput(LogHelper.OutputEnity output);
|
||||
boolean removeOutput(LogHelper.OutputEnity output);
|
||||
void printVersion(String product);
|
||||
void printLicense(String product);
|
||||
}
|
|
@ -0,0 +1,271 @@
|
|||
package pro.gravit.utils.logging;
|
||||
|
||||
import org.fusesource.jansi.Ansi;
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
import pro.gravit.utils.helper.FormatHelper;
|
||||
import pro.gravit.utils.helper.IOHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static pro.gravit.utils.helper.LogHelper.*;
|
||||
|
||||
public class SimpleLogHelperImpl implements LogHelperAppender {
|
||||
|
||||
// Output settings
|
||||
private final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss", Locale.US);
|
||||
private static final AtomicBoolean DEBUG_ENABLED = new AtomicBoolean(Boolean.getBoolean(DEBUG_PROPERTY));
|
||||
private static final AtomicBoolean STACKTRACE_ENABLED = new AtomicBoolean(Boolean.getBoolean(STACKTRACE_PROPERTY));
|
||||
private static final AtomicBoolean DEV_ENABLED = new AtomicBoolean(Boolean.getBoolean(DEV_PROPERTY));
|
||||
private final Set<LogHelper.OutputEnity> OUTPUTS = Collections.newSetFromMap(new ConcurrentHashMap<>(2));
|
||||
private final LogHelper.OutputEnity STD_OUTPUT;
|
||||
|
||||
public final boolean JANSI;
|
||||
|
||||
public SimpleLogHelperImpl() {
|
||||
// Use JAnsi if available
|
||||
boolean jansi;
|
||||
try {
|
||||
if (Boolean.getBoolean(NO_JANSI_PROPERTY)) {
|
||||
jansi = false;
|
||||
} else {
|
||||
Class.forName("org.fusesource.jansi.Ansi");
|
||||
AnsiConsole.systemInstall();
|
||||
jansi = true;
|
||||
}
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
jansi = false;
|
||||
}
|
||||
JANSI = jansi;
|
||||
|
||||
// Add std writer
|
||||
STD_OUTPUT = new LogHelper.OutputEnity(System.out::println, JANSI ? LogHelper.OutputTypes.JANSI : LogHelper.OutputTypes.PLAIN);
|
||||
addOutput(STD_OUTPUT);
|
||||
|
||||
// Add file log writer
|
||||
String logFile = System.getProperty("launcher.logFile");
|
||||
if (logFile != null) {
|
||||
try {
|
||||
addOutput(IOHelper.toPath(logFile));
|
||||
} catch (IOException e) {
|
||||
error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addOutput(Writer writer) {
|
||||
addOutput(new WriterOutput(writer), OutputTypes.PLAIN);
|
||||
}
|
||||
|
||||
|
||||
public void log(Level level, String message, boolean sub) {
|
||||
String dateTime = DATE_TIME_FORMATTER.format(LocalDateTime.now());
|
||||
String jansiString = null, plainString = null;
|
||||
for (OutputEnity output : OUTPUTS) {
|
||||
if (output.type == OutputTypes.JANSI && JANSI) {
|
||||
if (jansiString != null) {
|
||||
output.output.println(jansiString);
|
||||
continue;
|
||||
}
|
||||
|
||||
jansiString = ansiFormatLog(level, dateTime, message, sub);
|
||||
output.output.println(jansiString);
|
||||
} else {
|
||||
if (plainString != null) {
|
||||
output.output.println(plainString);
|
||||
continue;
|
||||
}
|
||||
|
||||
plainString = formatLog(level, message, dateTime, sub);
|
||||
output.output.println(plainString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logJAnsi(Level level, Supplier<String> plaintext, Supplier<String> jansitext, boolean sub) {
|
||||
if(JANSI) {
|
||||
log(level, jansitext.get(), sub);
|
||||
} else {
|
||||
log(level, plaintext.get(), sub);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugEnabled() {
|
||||
return DEBUG_ENABLED.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDebugEnabled(boolean debugEnabled) {
|
||||
DEBUG_ENABLED.set(debugEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStacktraceEnabled() {
|
||||
return STACKTRACE_ENABLED.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStacktraceEnabled(boolean stacktraceEnabled) {
|
||||
STACKTRACE_ENABLED.set(stacktraceEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDevEnabled() {
|
||||
return DEV_ENABLED.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDevEnabled(boolean stacktraceEnabled) {
|
||||
DEV_ENABLED.set(stacktraceEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOutput(OutputEnity output) {
|
||||
OUTPUTS.add(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeOutput(OutputEnity output) {
|
||||
return OUTPUTS.remove(output);
|
||||
}
|
||||
|
||||
public void rawLog(Supplier<String> plainStr, Supplier<String> jansiStr) {
|
||||
String jansiString = null, plainString = null;
|
||||
for (OutputEnity output : OUTPUTS) {
|
||||
if (output.type == OutputTypes.JANSI && JANSI) {
|
||||
if (jansiString != null) {
|
||||
output.output.println(jansiString);
|
||||
continue;
|
||||
}
|
||||
|
||||
jansiString = jansiStr.get();
|
||||
output.output.println(jansiString);
|
||||
} else {
|
||||
if (plainString != null) {
|
||||
output.output.println(plainString);
|
||||
continue;
|
||||
}
|
||||
|
||||
plainString = plainStr.get();
|
||||
output.output.println(plainString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addOutput(Output output, OutputTypes type) {
|
||||
addOutput(new OutputEnity(Objects.requireNonNull(output, "output"), type));
|
||||
}
|
||||
|
||||
public void addOutput(Path file) throws IOException {
|
||||
if (JANSI) {
|
||||
addOutput(new JAnsiOutput(IOHelper.newOutput(file, true)), OutputTypes.JANSI);
|
||||
} else {
|
||||
addOutput(IOHelper.newWriter(file, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String ansiFormatLog(Level level, String dateTime, String message, boolean sub) {
|
||||
|
||||
Ansi ansi = FormatHelper.rawAnsiFormat(level, dateTime, sub);
|
||||
ansi.a(message);
|
||||
|
||||
// Finish with reset code
|
||||
return ansi.reset().toString();
|
||||
}
|
||||
|
||||
private String formatLog(Level level, String message, String dateTime, boolean sub) {
|
||||
return FormatHelper.rawFormat(level, dateTime, sub) + message;
|
||||
}
|
||||
|
||||
public void printVersion(String product) {
|
||||
String jansiString = null, plainString = null;
|
||||
for (OutputEnity output : OUTPUTS) {
|
||||
if (output.type == OutputTypes.JANSI && JANSI) {
|
||||
if (jansiString != null) {
|
||||
output.output.println(jansiString);
|
||||
continue;
|
||||
}
|
||||
|
||||
jansiString = FormatHelper.ansiFormatVersion(product);
|
||||
output.output.println(jansiString);
|
||||
} else {
|
||||
if (plainString != null) {
|
||||
output.output.println(plainString);
|
||||
continue;
|
||||
}
|
||||
|
||||
plainString = FormatHelper.formatVersion(product);
|
||||
output.output.println(plainString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void printLicense(String product) {
|
||||
String jansiString = null, plainString = null;
|
||||
for (OutputEnity output : OUTPUTS) {
|
||||
if (output.type == OutputTypes.JANSI && JANSI) {
|
||||
if (jansiString != null) {
|
||||
output.output.println(jansiString);
|
||||
continue;
|
||||
}
|
||||
|
||||
jansiString = FormatHelper.ansiFormatLicense(product);
|
||||
output.output.println(jansiString);
|
||||
} else {
|
||||
if (plainString != null) {
|
||||
output.output.println(plainString);
|
||||
continue;
|
||||
}
|
||||
|
||||
plainString = FormatHelper.formatLicense(product);
|
||||
output.output.println(plainString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class JAnsiOutput extends WriterOutput {
|
||||
private JAnsiOutput(OutputStream output) {
|
||||
super(IOHelper.newWriter(output));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class WriterOutput implements Output, AutoCloseable {
|
||||
private final Writer writer;
|
||||
|
||||
public WriterOutput(Writer writer) {
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
writer.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println(String message) {
|
||||
try {
|
||||
writer.write(message + System.lineSeparator());
|
||||
writer.flush();
|
||||
} catch (IOException ignored) {
|
||||
// Do nothing?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package pro.gravit.utils.logging;
|
||||
|
||||
import org.fusesource.jansi.AnsiConsole;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import pro.gravit.utils.helper.FormatHelper;
|
||||
import pro.gravit.utils.helper.LogHelper;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static pro.gravit.utils.helper.LogHelper.NO_JANSI_PROPERTY;
|
||||
|
||||
public class Slf4jLogHelperImpl implements LogHelperAppender {
|
||||
private final Logger logger = LoggerFactory.getLogger("LogHelper");
|
||||
private final boolean JANSI;
|
||||
public Slf4jLogHelperImpl() {
|
||||
boolean jansi;
|
||||
try {
|
||||
if (Boolean.getBoolean(NO_JANSI_PROPERTY)) {
|
||||
jansi = false;
|
||||
} else {
|
||||
Class.forName("org.fusesource.jansi.Ansi");
|
||||
AnsiConsole.systemInstall();
|
||||
jansi = true;
|
||||
}
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
jansi = false;
|
||||
}
|
||||
JANSI = jansi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(LogHelper.Level level, String message, boolean sub) {
|
||||
switch (level) {
|
||||
case DEV:
|
||||
logger.trace(message);
|
||||
break;
|
||||
case DEBUG:
|
||||
logger.debug(message);
|
||||
break;
|
||||
case INFO:
|
||||
logger.info(message);
|
||||
break;
|
||||
case WARNING:
|
||||
logger.warn(message);
|
||||
break;
|
||||
case ERROR:
|
||||
logger.error(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logJAnsi(LogHelper.Level level, Supplier<String> plaintext, Supplier<String> jansitext, boolean sub) {
|
||||
if(JANSI) {
|
||||
log(level, jansitext.get(), sub);
|
||||
} else {
|
||||
log(level, plaintext.get(), sub);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebugEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDebugEnabled(boolean debugEnabled) {
|
||||
//NOP
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStacktraceEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStacktraceEnabled(boolean stacktraceEnabled) {
|
||||
//NOP
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDevEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDevEnabled(boolean stacktraceEnabled) {
|
||||
//NOP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOutput(LogHelper.OutputEnity output) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeOutput(LogHelper.OutputEnity output) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printVersion(String product) {
|
||||
if(JANSI) {
|
||||
logger.info(FormatHelper.ansiFormatVersion(product));
|
||||
} else {
|
||||
logger.info(FormatHelper.formatVersion(product));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printLicense(String product) {
|
||||
if(JANSI) {
|
||||
logger.info(FormatHelper.ansiFormatLicense(product));
|
||||
} else {
|
||||
logger.info(FormatHelper.formatLicense(product));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue