Added logging highlight.

This commit is contained in:
huanghongxun 2015-11-16 18:41:28 +08:00
parent 990f830300
commit b7aa99550d
9 changed files with 144 additions and 92 deletions

View File

@ -99,7 +99,7 @@ public final class Launcher {
Method minecraftMain;
try {
minecraftMain = new URLClassLoader(urls, URLClassLoader.getSystemClassLoader().getParent()).loadClass(mainClass).getMethod("main", String[].class);
minecraftMain = new URLClassLoader(urls, URLClassLoader.getSystemClassLoader()).loadClass(mainClass).getMethod("main", String[].class);
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException t) {
MessageBox.Show(C.i18n("crash.main_class_not_found"));
println("Minecraft main class not found.");
@ -118,9 +118,9 @@ public final class Launcher {
final String advice = MinecraftCrashAdvicer.getAdvice(trace);
MessageBox.Show(C.i18n("crash.minecraft") + ": " + advice);
LogWindow.instance.log(C.i18n("crash.minecraft"));
LogWindow.instance.log(advice);
LogWindow.instance.log(trace);
LogWindow.instance.warning(C.i18n("crash.minecraft"));
LogWindow.instance.warning(advice);
LogWindow.instance.warning(trace);
LogWindow.instance.setExit(TrueFunction.instance);
LogWindow.instance.setVisible(true);

View File

@ -70,7 +70,7 @@ import org.jackhuang.hellominecraft.utils.system.OS;
*/
public final class Main implements Runnable {
private static final X509TrustManager xtm = new X509TrustManager() {
private static final X509TrustManager XTM = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@ -84,21 +84,21 @@ public final class Main implements Runnable {
return null;
}
};
private static final HostnameVerifier hnv = (hostname, session) -> true;
private static final HostnameVerifier HNV = (hostname, session) -> true;
static {
SSLContext sslContext = null;
try {
sslContext = SSLContext.getInstance("TLS");
X509TrustManager[] xtmArray = new X509TrustManager[]{xtm};
X509TrustManager[] xtmArray = new X509TrustManager[]{XTM};
sslContext.init(null, xtmArray, new java.security.SecureRandom());
} catch (GeneralSecurityException gse) {
}
if (sslContext != null)
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(hnv);
HttpsURLConnection.setDefaultHostnameVerifier(HNV);
}
public static String launcherName = "Hello Minecraft! Launcher";
@ -123,7 +123,7 @@ public final class Main implements Runnable {
return launcherName + ' ' + makeVersion();
}
public static final Main instance = new Main();
public static final Main INSTANCE = new Main();
public static void main(String[] args) {
{

View File

@ -144,7 +144,7 @@ public class GameLauncher {
.environment().put("APPDATA", get.getCanonicalGameDir());
JavaProcess jp = new JavaProcess(str, builder.start(), PROCESS_MANAGER);
launchEvent.execute(jp);
} catch (IOException e) {
} catch (Exception e) {
failEvent.execute(C.i18n("launch.failed_creating_process") + "\n" + e.getMessage());
HMCLog.err("Failed to launch when creating a new process.", e);
}

View File

@ -16,33 +16,82 @@
*/
package org.jackhuang.hellominecraft.logging;
import java.awt.Color;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
* @author huangyuhui
*/
public enum Level {
OFF(0),
FATAL(1),
ERROR(2),
WARN(3),
INFO(4),
DEBUG(5),
TRACE(6),
ALL(2147483647);
OFF(0, Color.gray),
FATAL(1, Color.red),
ERROR(2, Color.red),
WARN(3, Color.orange),
INFO(4, Color.black),
DEBUG(5, Color.blue),
TRACE(6, Color.blue),
ALL(2147483647, Color.black);
public final int level;
public final Color COLOR;
private Level(int i) {
level = i;
private Level(int i, Color c) {
level = i;
COLOR = c;
}
public boolean lessOrEqual(Level level) {
return this.level <= level.level;
return this.level <= level.level;
}
public boolean lessOrEqual(int level) {
return this.level <= level;
return this.level <= level;
}
public static final Pattern MINECRAFT_LOGGER = Pattern.compile("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
public static final String JAVA_SYMBOL = "([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$][a-zA-Z\\d_$]*";
public static Level guessLevel(String line, Level level) {
Matcher m = MINECRAFT_LOGGER.matcher(line);
if (m.find()) {
// New style logs from log4j
String levelStr = m.group("level");
if ("INFO".equals(levelStr))
level = INFO;
else if ("WARN".equals(levelStr))
level = WARN;
else if ("ERROR".equals(levelStr))
level = ERROR;
else if ("FATAL".equals(levelStr))
level = FATAL;
else if ("TRACE".equals(levelStr))
level = TRACE;
else if ("DEBUG".equals(levelStr))
level = DEBUG;
} else {
if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]")
|| line.contains("[FINER]") || line.contains("[FINEST]"))
level = INFO;
if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
level = ERROR;
if (line.contains("[WARNING]"))
level = WARN;
if (line.contains("[DEBUG]"))
level = DEBUG;
}
if (line.contains("overwriting existing"))
return FATAL;
if (line.contains("Exception in thread")
|| line.matches("\\s+at " + JAVA_SYMBOL)
|| line.matches("Caused by: " + JAVA_SYMBOL)
|| line.matches("([a-zA-Z_$][a-zA-Z\\d_$]*\\.)+[a-zA-Z_$]?[a-zA-Z\\d_$]*(Exception|Error|Throwable)")
|| line.matches("... \\d+ more$"))
return ERROR;
return level;
}
}

View File

@ -29,7 +29,7 @@ public class DefaultLayout extends AbstractStringLayout {
@Override
public String toSerializable(LogEvent event) {
return "[" + sdf.format(new Date()) + "][" + event.threadName + "/" + event.level.name() + "] " + event.message.getFormattedMessage() + "\n";
return "[" + sdf.format(new Date()) + "] [" + event.threadName + "/" + event.level.name() + "] " + event.message.getFormattedMessage() + "\n";
}
}

View File

@ -18,19 +18,21 @@ package org.jackhuang.hellominecraft.utils;
import java.io.OutputStream;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;
import org.jackhuang.hellominecraft.logging.Level;
import org.jackhuang.hellominecraft.views.LogWindow;
/**
*
* @author huangyuhui
*/
public class TextComponentOutputStream extends OutputStream {
public class LogWindowOutputStream extends OutputStream {
private static final Timer TIMER = new Timer();
private final JTextComponent txt;
private final LogWindow txt;
private final Level sas;
/*
private final CacheTask t = new CacheTask();
private class CacheTask extends TimerTask {
private final Object lock = new Object();
@ -53,12 +55,11 @@ public class TextComponentOutputStream extends OutputStream {
cachedString.append(s);
}
}
}
}*/
public TextComponentOutputStream(JTextComponent paramJTextComponent) {
txt = paramJTextComponent;
//TIMER.schedule(t, 20);
public LogWindowOutputStream(LogWindow logWindow, Level l) {
txt = logWindow;
this.sas = l;
}
@Override
@ -72,12 +73,9 @@ public class TextComponentOutputStream extends OutputStream {
}
private void append(final String newString) {
//t.cache(newString);
try {
SwingUtilities.invokeLater(() -> {
String t = txt.getText() + newString.replace("\t", " ");
txt.setText(t);
txt.setCaretPosition(t.length());
txt.log(newString, Level.guessLevel(newString, sas));
});
} catch (Throwable e) {
e.printStackTrace();

View File

@ -29,10 +29,10 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane1" max="32767" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="jScrollPane2" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="btnTieBa" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
@ -50,7 +50,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="btnClose" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="lblCrash" alignment="0" pref="674" max="32767" attributes="0"/>
<Component id="lblCrash" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
@ -62,7 +62,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="lblCrash" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" pref="375" max="32767" attributes="0"/>
<Component id="jScrollPane2" pref="356" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="btnClear" alignment="3" min="-2" max="-2" attributes="0"/>
@ -80,22 +80,6 @@
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="txtLog">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="columns" type="int" value="20"/>
<Property name="rows" type="int" value="5"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="btnClear">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
@ -177,5 +161,16 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="btnGitHubActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextPane" name="txtLog">
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -16,13 +16,18 @@
*/
package org.jackhuang.hellominecraft.views;
import java.util.Timer;
import java.awt.Color;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import org.jackhuang.hellominecraft.C;
import org.jackhuang.hellominecraft.HMCLog;
import org.jackhuang.hellominecraft.logging.Level;
import org.jackhuang.hellominecraft.utils.functions.NonFunction;
import org.jackhuang.hellominecraft.utils.DoubleOutputStream;
import org.jackhuang.hellominecraft.utils.LauncherPrintStream;
import org.jackhuang.hellominecraft.utils.StrUtils;
import org.jackhuang.hellominecraft.utils.TextComponentOutputStream;
import org.jackhuang.hellominecraft.utils.LogWindowOutputStream;
import org.jackhuang.hellominecraft.utils.Utils;
/**
@ -44,11 +49,10 @@ public class LogWindow extends javax.swing.JFrame {
movingEnd = true;
setLocationRelativeTo(null);
TextComponentOutputStream tc = new TextComponentOutputStream(txtLog);
DoubleOutputStream out = new DoubleOutputStream(tc, System.out);
txtLog.setEditable(false);
DoubleOutputStream out = new DoubleOutputStream(new LogWindowOutputStream(this, Level.INFO), System.out);
System.setOut(new LauncherPrintStream(out));
DoubleOutputStream err = new DoubleOutputStream(tc, System.err);
DoubleOutputStream err = new DoubleOutputStream(new LogWindowOutputStream(this, Level.ERROR), System.err);
System.setErr(new LauncherPrintStream(err));
}
@ -63,8 +67,6 @@ public class LogWindow extends javax.swing.JFrame {
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
txtLog = new javax.swing.JTextArea();
btnClear = new javax.swing.JButton();
btnClose = new javax.swing.JButton();
btnCopy = new javax.swing.JButton();
@ -74,6 +76,8 @@ public class LogWindow extends javax.swing.JFrame {
btnMCF = new javax.swing.JButton();
btnTerminateGame = new javax.swing.JButton();
btnGitHub = new javax.swing.JButton();
jScrollPane2 = new javax.swing.JScrollPane();
txtLog = new javax.swing.JTextPane();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle(C.I18N.getString("logwindow.title")); // NOI18N
@ -83,11 +87,6 @@ public class LogWindow extends javax.swing.JFrame {
}
});
txtLog.setEditable(false);
txtLog.setColumns(20);
txtLog.setRows(5);
jScrollPane1.setViewportView(txtLog);
btnClear.setText(C.I18N.getString("ui.button.clear")); // NOI18N
btnClear.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@ -146,15 +145,17 @@ public class LogWindow extends javax.swing.JFrame {
}
});
jScrollPane2.setViewportView(txtLog);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(jScrollPane2)
.addGroup(layout.createSequentialGroup()
.addComponent(btnTieBa)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnMCBBS)
@ -170,7 +171,7 @@ public class LogWindow extends javax.swing.JFrame {
.addComponent(btnClear)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnClose))
.addComponent(lblCrash, javax.swing.GroupLayout.DEFAULT_SIZE, 674, Short.MAX_VALUE))
.addComponent(lblCrash, javax.swing.GroupLayout.Alignment.LEADING))
.addContainerGap())
);
layout.setVerticalGroup(
@ -179,7 +180,7 @@ public class LogWindow extends javax.swing.JFrame {
.addContainerGap()
.addComponent(lblCrash, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 375, Short.MAX_VALUE)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 356, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnClear)
@ -235,19 +236,28 @@ public class LogWindow extends javax.swing.JFrame {
}//GEN-LAST:event_btnGitHubActionPerformed
public void log(String status) {
String text = txtLog.getText();
text += status + System.getProperty("line.separator");
txtLog.setText(text);
if (movingEnd) {
int position = text.length();
txtLog.setCaretPosition(position);
}
log(status, Level.INFO);
}
public void log(String status, Throwable t) {
log(status);
log(StrUtils.getStackTrace(t));
public void warning(String status) {
log(status, Level.WARN);
}
public void log(String status, Level c) {
status = status.replace("\t", " ");
Document d = txtLog.getStyledDocument();
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setForeground(sas, c.COLOR);
try {
d.insertString(d.getLength(), status, sas);
} catch (BadLocationException ex) {
HMCLog.err("Failed to insert \"" + status + "\" to " + d.getLength(), ex);
}
if (movingEnd) {
int position = d.getLength();
txtLog.setCaretPosition(position);
}
}
public void setExit(NonFunction<Boolean> exit) {
@ -306,8 +316,8 @@ public class LogWindow extends javax.swing.JFrame {
private javax.swing.JButton btnMCF;
private javax.swing.JButton btnTerminateGame;
private javax.swing.JButton btnTieBa;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JLabel lblCrash;
private javax.swing.JTextArea txtLog;
private javax.swing.JTextPane txtLog;
// End of variables declaration//GEN-END:variables
}

View File

@ -63,10 +63,10 @@ public class Main {
HMCLog.err("There's something wrong when running server holder.", t);
LogWindow.instance.clean();
LogWindow.instance.log("开服器崩溃了QAQ");
LogWindow.instance.warning("开服器崩溃了QAQ");
StringWriter trace = new StringWriter();
t.printStackTrace(new PrintWriter(trace));
LogWindow.instance.log(trace.toString());
LogWindow.instance.warning(trace.toString());
LogWindow.instance.setVisible(true);
System.exit(-1);