Skip to content

Commit

Permalink
Make logger adapters more better, do the thing with the vararg throwable
Browse files Browse the repository at this point in the history
  • Loading branch information
Mumfrey committed Aug 19, 2021
1 parent 212d5d1 commit b79b42a
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 49 deletions.
101 changes: 67 additions & 34 deletions src/main/java/org/spongepowered/asm/logging/LoggerAdapterAbstract.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,77 @@
package org.spongepowered.asm.logging;

/**
* Abstract base adapter which contains convenience methods for formatting
* Abstract base adapter which contains a convenience class for formatting
* log4j2-style messages and also routes all level-specific overloads to calls
* to <tt>log</tt>, which can simplify some implementations.
*/
public abstract class LoggerAdapterAbstract implements ILogger {

/**
* This is a very naive implementation of log4j2's <tt>ParameterizedMessage
* </tt> which is less efficient and less defensive because it doesn't need
* to handle all the cases that the log4j2 formatter does. All we're really
* doing here is substituting in the values for <tt>{}</tt> placeholders
* because I know that in mixin there aren't any cases where we need to
* handle anything else, such as escaped <tt>{</tt> characters or whatever.
* It also handles the case where the last param of the varargs is a
* <tt>Throwable</tt>, and makes it available to consumers.
*/
public static class FormattedMessage {

private String message;

private Throwable t;

/**
* Create a new formatted message
*
* @param message Message patterm
* @param params Message parameters
*/
public FormattedMessage(String message, Object... params) {
if (params.length == 0) {
this.message = message;
return;
}
StringBuilder sb = new StringBuilder();
int pos = 0, param = 0;
for (; pos < message.length() && param < params.length; param++) {
int delimPos = message.indexOf("{}", pos);
if (delimPos < 0) {
break;
}
sb.append(message.substring(pos, delimPos)).append(params[param]);
pos = delimPos + 2;
}
if (pos < message.length()) {
sb.append(message.substring(pos));
}
// If last arg is throwable and not consumed by the message, store it
if (param < params.length && params[params.length - 1] instanceof Throwable) {
this.t = (Throwable)params[params.length - 1];
}
this.message = sb.toString();
}

@Override
public String toString() {
return this.message;
}

public String getMessage() {
return this.message;
}

public boolean hasThrowable() {
return this.t != null;
}

public Throwable getThrowable() {
return this.t;
}

}

/**
* Logger id
Expand All @@ -51,39 +117,6 @@ public String getId() {
return this.id;
}

/**
* This is a very naive implementation of log4j2's
* ParameterizedMessage::format method which is less efficient and less
* defensive because it doesn't need to handle all the cases that the log4j2
* formatter does. All we're really doing here is substituting in the values
* for <tt>{}</tt> placeholders because I know that in mixin there aren't
* any cases where we need to handle anything else, such as escaped <tt>{
* </tt> characters or whatever.
*
* @param message Message patterm
* @param params Message parameters
* @return Message with {} placeholders filled in
*/
protected static String getFormattedMessage(String message, Object... params) {
if (params.length == 0) {
return message;
}
StringBuilder sb = new StringBuilder();
int pos = 0;
for (int param = 0; pos < message.length() && param < params.length; param++) {
int delimPos = message.indexOf("{}", pos);
if (delimPos < 0) {
return sb.append(message.substring(pos)).toString();
}
sb.append(message.substring(pos, delimPos)).append(params[param]);
pos = delimPos + 2;
}
if (pos < message.length()) {
sb.append(message.substring(pos));
}
return sb.toString();
}

@Override
public void catching(Throwable t) {
this.catching(Level.WARN, t);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,18 @@ public LoggerAdapterConsole setDebugStream(PrintStream debug) {

@Override
public void catching(Level level, Throwable t) {
this.log(Level.WARN, "Catching", t);
this.log(Level.WARN, "Catching {}: {}", t.getClass().getName(), t.getMessage(), t);
}

@Override
public void log(Level level, String message, Object... params) {
PrintStream out = this.getOutputStream(level);
if (out != null) {
String formatted = LoggerAdapterAbstract.getFormattedMessage(message, params);
FormattedMessage formatted = new FormattedMessage(message, params);
out.println(String.format("[%s] [%s/%s] %s", LoggerAdapterConsole.DATE_FORMAT.format(new Date()), this.getId(), level, formatted));
if (formatted.hasThrowable()) {
formatted.getThrowable().printStackTrace(out);
}
}
}

Expand All @@ -88,13 +91,13 @@ public void log(Level level, String message, Throwable t) {
PrintStream out = this.getOutputStream(level);
if (out != null) {
out.println(String.format("[%s] [%s/%s] %s", LoggerAdapterConsole.DATE_FORMAT.format(new Date()), this.getId(), level, message));
t.printStackTrace();
t.printStackTrace(out);
}
}

@Override
public <T extends Throwable> T throwing(T t) {
this.log(Level.WARN, "Throwing", t);
this.log(Level.WARN, "Throwing {}: {}", t.getClass().getName(), t.getMessage(), t);
return t;
}

Expand Down
52 changes: 41 additions & 11 deletions src/main/java/org/spongepowered/asm/logging/LoggerAdapterJava.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
import java.util.logging.Logger;

/**
* Logger adapter which uses the
* Logger adapter which uses the built-in Java logging functionality to emit
* logging messages.
*/
public class LoggerAdapterJava extends LoggerAdapterAbstract {

Expand All @@ -50,17 +51,21 @@ public LoggerAdapterJava(String name) {

@Override
public String getType() {
return "Default Console Logger";
return "java.util.logging Log Adapter";
}

@Override
public void catching(Level level, Throwable t) {
this.warn("Catching", t);
this.warn("Catching {}: {}", t.getClass().getName(), t.getMessage(), t);
}

@Override
public void debug(String message, Object... params) {
this.logger.fine(LoggerAdapterAbstract.getFormattedMessage(message, params));
FormattedMessage formatted = new FormattedMessage(message, params);
this.logger.fine(formatted.getMessage());
if (formatted.hasThrowable()) {
this.logger.fine(formatted.getThrowable().toString());
}
}

@Override
Expand All @@ -71,7 +76,11 @@ public void debug(String message, Throwable t) {

@Override
public void error(String message, Object... params) {
this.logger.severe(LoggerAdapterAbstract.getFormattedMessage(message, params));
FormattedMessage formatted = new FormattedMessage(message, params);
this.logger.severe(formatted.getMessage());
if (formatted.hasThrowable()) {
this.logger.severe(formatted.getThrowable().toString());
}
}

@Override
Expand All @@ -82,7 +91,11 @@ public void error(String message, Throwable t) {

@Override
public void fatal(String message, Object... params) {
this.logger.severe(LoggerAdapterAbstract.getFormattedMessage(message, params));
FormattedMessage formatted = new FormattedMessage(message, params);
this.logger.severe(formatted.getMessage());
if (formatted.hasThrowable()) {
this.logger.severe(formatted.getThrowable().toString());
}
}

@Override
Expand All @@ -93,7 +106,11 @@ public void fatal(String message, Throwable t) {

@Override
public void info(String message, Object... params) {
this.logger.info(LoggerAdapterAbstract.getFormattedMessage(message, params));
FormattedMessage formatted = new FormattedMessage(message, params);
this.logger.info(formatted.getMessage());
if (formatted.hasThrowable()) {
this.logger.info(formatted.getThrowable().toString());
}
}

@Override
Expand All @@ -104,7 +121,12 @@ public void info(String message, Throwable t) {

@Override
public void log(Level level, String message, Object... params) {
this.logger.log(LoggerAdapterJava.LEVELS[level.ordinal()], LoggerAdapterAbstract.getFormattedMessage(message, params));
java.util.logging.Level logLevel = LoggerAdapterJava.LEVELS[level.ordinal()];
FormattedMessage formatted = new FormattedMessage(message, params);
this.logger.log(logLevel, formatted.getMessage());
if (formatted.hasThrowable()) {
this.logger.log(LoggerAdapterJava.LEVELS[level.ordinal()], formatted.getThrowable().toString());
}
}

@Override
Expand All @@ -116,13 +138,17 @@ public void log(Level level, String message, Throwable t) {

@Override
public <T extends Throwable> T throwing(T t) {
this.warn("Throwing", t);
this.warn("Throwing {}: {}", t.getClass().getName(), t.getMessage(), t);
return t;
}

@Override
public void trace(String message, Object... params) {
this.logger.finer(LoggerAdapterAbstract.getFormattedMessage(message, params));
FormattedMessage formatted = new FormattedMessage(message, params);
this.logger.finer(formatted.getMessage());
if (formatted.hasThrowable()) {
this.logger.finer(formatted.getThrowable().toString());
}
}

@Override
Expand All @@ -133,7 +159,11 @@ public void trace(String message, Throwable t) {

@Override
public void warn(String message, Object... params) {
this.logger.warning(LoggerAdapterAbstract.getFormattedMessage(message, params));
FormattedMessage formatted = new FormattedMessage(message, params);
this.logger.warning(formatted.getMessage());
if (formatted.hasThrowable()) {
this.logger.warning(formatted.getThrowable().toString());
}
}

@Override
Expand Down

0 comments on commit b79b42a

Please sign in to comment.