Skip to content

Commit

Permalink
Added custom print stream logging (#645)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
ipkpjersi authored Sep 21, 2024
1 parent db69643 commit af522db
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
5 changes: 5 additions & 0 deletions 2006Scape Server/src/main/java/com/rs2/GameEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
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;
Expand Down Expand Up @@ -127,6 +128,10 @@ public static long getMinutesCounter() {

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;
Expand Down
104 changes: 104 additions & 0 deletions 2006Scape Server/src/main/java/com/rs2/util/CustomPrintStream.java
Original file line number Diff line number Diff line change
@@ -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();
}
}

0 comments on commit af522db

Please sign in to comment.