Added custom print stream logging (#645)

* Added custom print stream

* Fixed custom print stream stack trace detection

* Implement custom print stream

* Fixed formatting

* Fixed custom info print stream

* Improved custom PrintStream
This commit is contained in:
ipkpjersi
2024-09-21 13:45:17 -04:00
committed by GitHub
parent db696431e6
commit af522dbe1b
2 changed files with 109 additions and 0 deletions
@@ -18,6 +18,7 @@ import com.rs2.game.npcs.Npc;
import com.rs2.game.npcs.NpcList;
import com.rs2.gui.ControlPanel;
import com.rs2.util.CustomPrintStream;
import org.apollo.cache.IndexedFileSystem;
import org.apollo.cache.decoder.ItemDefinitionDecoder;
import org.apollo.cache.decoder.ObjectDefinitionDecoder;
@@ -127,6 +128,10 @@ public class GameEngine {
public static void main(java.lang.String[] args)
throws NullPointerException, IOException {
CustomPrintStream errorStream = new CustomPrintStream(System.err, "ERROR", true);
System.setErr(errorStream);
CustomPrintStream infoStream = new CustomPrintStream(System.out, "INFO", true);
System.setOut(infoStream);
serverStartTime = System.currentTimeMillis();
if (NetworkConstants.RSA_EXPONENT != Constants.RSA_EXPONENT) {
NetworkConstants.RSA_EXPONENT = Constants.RSA_EXPONENT;
@@ -0,0 +1,104 @@
package com.rs2.util;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class CustomPrintStream extends PrintStream {
private final SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss a");
private final String logType;
private final FileWriter fileWriter;
private final boolean fileOutput;
private final ExecutorService executor = Executors.newSingleThreadExecutor();
public CustomPrintStream(OutputStream out, String logType, boolean fileOutput) throws IOException {
super(out);
this.fileOutput = fileOutput;
StackTraceElement[] stackTrace = new Throwable().getStackTrace();
boolean throwable = false;
if (stackTrace.length > 2) {
throwable = stackTrace[2].getFileName() != null && stackTrace[2].getFileName().replace(".java", "").equals("Throwable");
}
this.logType = throwable ? "ERROR" : logType;
String date = new SimpleDateFormat("MM_dd_yyyy").format(new Date());
String logFileName = "data/logs/server_" + logType.toLowerCase() + "_" + date + ".log";
File logFile = this.fileOutput ? new File(logFileName) : null;
if (logFile != null) {
logFile.getParentFile().mkdirs(); // Ensure the directory exists
}
this.fileWriter = logFile != null ? new FileWriter(logFile, true) : null;
}
private void log(String message) {
// Get calling class and method
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
// Set the default caller if we can't find the class for some reason
String caller = "Unknown";
if (stack.length > 3) {
StackTraceElement elem = stack[3];
String className = elem.getClassName();
// Remove instance from class name since we care about files, not objects
className = className.replaceAll("\\$.*", "");
String simpleClassName = className.substring(className.lastIndexOf('.') + 1); // Get simple class name
String methodName = elem.getMethodName();
caller = simpleClassName + "." + methodName + "()";
}
// Construct log message
String logMessage = String.format("[%s] [%s] [%s] %s", dateFormat.format(new Date()), logType.toUpperCase(), caller, message);
// Print to console and file
super.println(logMessage);
if (this.fileOutput) {
executor.submit(() -> {
try {
fileWriter.write(logMessage + "\n");
fileWriter.flush();
} catch (IOException e) {
super.println("Failed to write to log file: " + e.getMessage());
}
});
}
}
@Override
public void println(String x) {
log(x);
}
public void close() {
this.executor.shutdown();
if (fileWriter != null) {
try {
fileWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private static void test() throws IOException {
CustomPrintStream infoPrintStream = new CustomPrintStream(System.out, "INFO", true);
System.setOut(infoPrintStream);
CustomPrintStream errorPrintStream = new CustomPrintStream(System.err, "ERROR", true);
System.setErr(errorPrintStream);
System.out.println("This is a test message.");
System.out.println("This is another test message.");
System.err.println("This is an error message.");
System.err.println("This is another error message.");
infoPrintStream.close();
errorPrintStream.close();
}
public static void main(String[] args) throws IOException {
CustomPrintStream.test();
}
}