mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-01 08:39:31 +01:00
Begin work on console appending
This commit is contained in:
parent
80017829e5
commit
7148944537
@ -0,0 +1,60 @@
|
||||
package com.discordsrv.common.config.main;
|
||||
|
||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class ConsoleConfig {
|
||||
|
||||
@Comment("The format for log lines")
|
||||
public String lineFormat = "[%log_time:'ccc HH:mm:ss zzz'%] [%log_level%] [%logger_name%] %message%";
|
||||
|
||||
@Comment("The mode for the console output, available options are:\n"
|
||||
+ "- ansi: A colored ansi code block\n"
|
||||
+ "- log: A \"accesslog\" code block\n"
|
||||
+ "- diff: A \"diff\" code block highlighting warnings and errors with different colors\n"
|
||||
+ "- plain: Plain text code block\n"
|
||||
+ "- plain_content: Plain text")
|
||||
public String outputMode = "ansi";
|
||||
|
||||
public OutputMode getOutputMode() {
|
||||
switch (outputMode.toLowerCase(Locale.ROOT)) {
|
||||
default:
|
||||
case "ansi": return OutputMode.ANSI;
|
||||
case "log": return OutputMode.LOG;
|
||||
case "diff": return OutputMode.DIFF;
|
||||
case "plain": return OutputMode.PLAIN;
|
||||
case "plain_content": return OutputMode.PLAIN_CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
@Comment("Avoids sending new messages by editing the most recent message until it reaches it's maximum length")
|
||||
public boolean useEditing = true;
|
||||
|
||||
@Comment("If console messages should be silent, not causing a notification")
|
||||
public boolean silentMessages = true;
|
||||
|
||||
public enum OutputMode {
|
||||
ANSI("```ansi\n", "```"),
|
||||
LOG("```accesslog\n", "```"),
|
||||
DIFF("```diff\n", "```"),
|
||||
PLAIN("```\n", "```"),
|
||||
PLAIN_CONTENT("", "");
|
||||
|
||||
private final String prefix;
|
||||
private final String suffix;
|
||||
|
||||
OutputMode(String prefix, String suffix) {
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public String prefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public String suffix() {
|
||||
return suffix;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.discordsrv.common.console;
|
||||
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.config.main.ConsoleConfig;
|
||||
import com.discordsrv.common.console.entry.LogEntry;
|
||||
import com.discordsrv.common.logging.LogAppender;
|
||||
import com.discordsrv.common.logging.LogLevel;
|
||||
import com.discordsrv.common.logging.NamedLogger;
|
||||
import com.discordsrv.common.logging.backend.LoggingBackend;
|
||||
import com.discordsrv.common.module.type.AbstractModule;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConsoleModule extends AbstractModule<DiscordSRV> implements LogAppender {
|
||||
|
||||
private LoggingBackend backend;
|
||||
private final List<SingleConsoleHandler> handlers = new ArrayList<>();
|
||||
|
||||
public ConsoleModule(DiscordSRV discordSRV) {
|
||||
super(discordSRV, new NamedLogger(discordSRV, "CONSOLE"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
backend = discordSRV.console().loggingBackend();
|
||||
backend.addAppender(this);
|
||||
|
||||
reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadNoResult() {
|
||||
handlers.add(new SingleConsoleHandler(discordSRV, new ConsoleConfig())); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
if (backend != null) {
|
||||
backend.removeAppender(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(
|
||||
@Nullable String loggerName,
|
||||
@NotNull LogLevel logLevel,
|
||||
@Nullable String message,
|
||||
@Nullable Throwable throwable
|
||||
) {
|
||||
LogEntry entry = new LogEntry(loggerName, logLevel, message, throwable);
|
||||
for (SingleConsoleHandler handler : handlers) {
|
||||
handler.queue(entry);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
package com.discordsrv.common.console;
|
||||
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.config.main.ConsoleConfig;
|
||||
import com.discordsrv.common.console.entry.LogEntry;
|
||||
import com.discordsrv.common.console.entry.LogMessage;
|
||||
import com.discordsrv.common.logging.LogLevel;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
public class SingleConsoleHandler {
|
||||
|
||||
private static final int MESSAGE_MAX_LENGTH = Message.MAX_CONTENT_LENGTH;
|
||||
|
||||
private final DiscordSRV discordSRV;
|
||||
private final ConsoleConfig config;
|
||||
private final Queue<LogEntry> queue = new LinkedBlockingQueue<>();
|
||||
private final List<LogMessage> messageCache;
|
||||
|
||||
public SingleConsoleHandler(DiscordSRV discordSRV, ConsoleConfig config) {
|
||||
this.discordSRV = discordSRV;
|
||||
this.config = config;
|
||||
this.messageCache = config.useEditing ? new ArrayList<>() : null;
|
||||
}
|
||||
|
||||
public void queue(LogEntry entry) {
|
||||
queue.offer(entry);
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
|
||||
}
|
||||
|
||||
private void processQueue() {
|
||||
ConsoleConfig.OutputMode outputMode = config.getOutputMode();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private List<String> formatEntry(LogEntry entry) {
|
||||
String message = entry.message();
|
||||
String throwable = ExceptionUtils.getMessage(entry.throwable());
|
||||
|
||||
message = discordSRV.placeholderService().replacePlaceholders(config.lineFormat, entry);
|
||||
|
||||
ConsoleConfig.OutputMode outputMode = config.getOutputMode();
|
||||
|
||||
String prefix = outputMode.prefix();
|
||||
String suffix = outputMode.suffix();
|
||||
int blockLength = prefix.length() + suffix.length();
|
||||
int maximumPart = MESSAGE_MAX_LENGTH - blockLength - "\n".length();
|
||||
|
||||
if (outputMode == ConsoleConfig.OutputMode.DIFF) {
|
||||
message = getLogLevelDiffCharacter(entry.level()) + message;
|
||||
// TODO: also format throwable?
|
||||
}
|
||||
|
||||
message += "\n";
|
||||
if (!throwable.isEmpty()) {
|
||||
throwable += "\n";
|
||||
}
|
||||
|
||||
List<String> formatted = new ArrayList<>();
|
||||
|
||||
// Handle message being longer than a message
|
||||
message = cutToSizeIfNeeded(message, blockLength, maximumPart, formatted);
|
||||
|
||||
// Handle log entry being longer than a message
|
||||
int totalLength = blockLength + throwable.length() + message.length();
|
||||
if (totalLength > MESSAGE_MAX_LENGTH) {
|
||||
StringBuilder builder = new StringBuilder(message);
|
||||
for (String line : throwable.split("\n")) {
|
||||
line += "\n";
|
||||
|
||||
// Handle a single line of a throwable being longer than a message
|
||||
line = cutToSizeIfNeeded(line, blockLength, maximumPart, formatted);
|
||||
|
||||
if (blockLength + line.length() > MESSAGE_MAX_LENGTH) {
|
||||
// Need to split here
|
||||
formatted.add(builder.toString());
|
||||
builder.setLength(0);
|
||||
}
|
||||
builder.append(line);
|
||||
}
|
||||
formatted.add(builder.toString());
|
||||
} else {
|
||||
formatted.add(message + throwable);
|
||||
}
|
||||
|
||||
return formatted;
|
||||
}
|
||||
|
||||
private String cutToSizeIfNeeded(
|
||||
String content,
|
||||
int blockLength,
|
||||
int maximumPart,
|
||||
List<String> formatted
|
||||
) {
|
||||
while (content.length() + blockLength > MESSAGE_MAX_LENGTH) {
|
||||
String cutToSize = content.substring(0, maximumPart) + "\n";
|
||||
if (cutToSize.endsWith("\n\n")) {
|
||||
// maximumPart excludes the newline at the end of message/line
|
||||
cutToSize = cutToSize.substring(0, cutToSize.length() - 1);
|
||||
}
|
||||
|
||||
formatted.add(cutToSize);
|
||||
content = content.substring(maximumPart);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
private String getLogLevelDiffCharacter(LogLevel level) {
|
||||
if (level == LogLevel.StandardLogLevel.WARNING) {
|
||||
return "+";
|
||||
} else if (level == LogLevel.StandardLogLevel.ERROR) {
|
||||
return "-";
|
||||
}
|
||||
return " ";
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package com.discordsrv.common.console.entry;
|
||||
|
||||
import com.discordsrv.api.placeholder.PlaceholderLookupResult;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
||||
import com.discordsrv.common.logging.LogLevel;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class LogEntry {
|
||||
|
||||
@Placeholder("logger_name")
|
||||
private final String loggerName;
|
||||
@Placeholder("log_level")
|
||||
private final LogLevel level;
|
||||
private final String message;
|
||||
private final Throwable throwable;
|
||||
private final Instant logTime;
|
||||
|
||||
public LogEntry(String loggerName, LogLevel level, String message, Throwable throwable) {
|
||||
this.loggerName = loggerName;
|
||||
this.level = level;
|
||||
this.message = message;
|
||||
this.throwable = throwable;
|
||||
this.logTime = Instant.now();
|
||||
}
|
||||
|
||||
public String loggerName() {
|
||||
return loggerName;
|
||||
}
|
||||
|
||||
public LogLevel level() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public String message() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Throwable throwable() {
|
||||
return throwable;
|
||||
}
|
||||
|
||||
public Instant logTime() {
|
||||
return logTime;
|
||||
}
|
||||
|
||||
@Placeholder("log_time")
|
||||
public PlaceholderLookupResult _logTimePlaceholder(@PlaceholderRemainder String format) {
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); // TODO: cache
|
||||
|
||||
Set<Object> extras = new LinkedHashSet<>();
|
||||
extras.add(formatter);
|
||||
extras.add(logTime);
|
||||
|
||||
return PlaceholderLookupResult.newLookup("date", extras);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.discordsrv.common.console.entry;
|
||||
|
||||
public class LogMessage {
|
||||
|
||||
private final LogEntry entry;
|
||||
private String formatted;
|
||||
|
||||
public LogMessage(LogEntry entry) {
|
||||
this.entry = entry;
|
||||
}
|
||||
|
||||
public String getFormatted() {
|
||||
return formatted;
|
||||
}
|
||||
|
||||
public void setFormatted(String formatted) {
|
||||
this.formatted = formatted;
|
||||
}
|
||||
}
|
@ -149,8 +149,8 @@ public class Log4JLoggerImpl implements Logger, LoggingBackend {
|
||||
public boolean removeAppender(LogAppender appender) {
|
||||
if (logger instanceof org.apache.logging.log4j.core.Logger) {
|
||||
org.apache.logging.log4j.core.Logger loggerImpl = (org.apache.logging.log4j.core.Logger) logger;
|
||||
Appender log4jAppender = appenders.get(appender);
|
||||
loggerImpl.addAppender(log4jAppender);
|
||||
Appender log4jAppender = appenders.remove(appender);
|
||||
loggerImpl.removeAppender(log4jAppender);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user