2021-12-06 10:49:40 +08:00
|
|
|
package com.janetfilter.core.commons;
|
2021-11-29 14:24:13 +08:00
|
|
|
|
2021-12-06 10:49:40 +08:00
|
|
|
import com.janetfilter.core.utils.DateUtils;
|
2022-01-20 14:55:03 +08:00
|
|
|
import com.janetfilter.core.utils.ProcessUtils;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.PrintStream;
|
2021-11-29 14:24:13 +08:00
|
|
|
|
|
|
|
public class DebugInfo {
|
2022-01-13 19:31:41 +08:00
|
|
|
private static final String CLASS_NAME = DebugInfo.class.getName();
|
2022-01-20 14:55:03 +08:00
|
|
|
private static final String LOG_TEMPLATE = "[%s] %s %s : %s%n";
|
|
|
|
private static final Level LOG_LEVEL;
|
|
|
|
private static File logFile;
|
|
|
|
|
|
|
|
static {
|
|
|
|
Level level = Level.of(System.getProperty("janf.debug"));
|
|
|
|
LOG_LEVEL = Level.NONE == level ? Level.of(System.getenv("JANF_DEBUG")) : level;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void useFile(File dir) {
|
|
|
|
if (LOG_LEVEL == Level.NONE || null == dir) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dir.exists() && !dir.mkdirs()) {
|
|
|
|
error("Can't make directory: " + dir);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dir.isDirectory()) {
|
|
|
|
error("It's not a directory: " + dir);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!dir.canWrite()) {
|
|
|
|
error("Read-only directory: " + dir);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
File file = new File(dir, String.format("%s-%s.log", DateUtils.formatDate(), ProcessUtils.currentId()));
|
|
|
|
if (file.exists()) {
|
|
|
|
error("Log file exists: " + file);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
logFile = file;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void debug(String content, Throwable e) {
|
|
|
|
output(Level.DEBUG, content, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void debug(String content) {
|
|
|
|
debug(content, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void info(String content, Throwable e) {
|
|
|
|
output(Level.INFO, content, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void info(String content) {
|
|
|
|
info(content, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void warn(String content, Throwable e) {
|
|
|
|
output(Level.WARN, content, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void warn(String content) {
|
|
|
|
warn(content, null);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void error(String content, Throwable e) {
|
|
|
|
output(Level.ERROR, content, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void error(String content) {
|
|
|
|
error(content, null);
|
|
|
|
}
|
2021-11-29 14:24:13 +08:00
|
|
|
|
2021-12-28 15:02:34 +08:00
|
|
|
public static void output(String content) {
|
2022-01-20 14:55:03 +08:00
|
|
|
debug(content);
|
2021-12-28 15:02:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void output(String content, Throwable e) { // No logger lib required
|
2022-01-20 14:55:03 +08:00
|
|
|
debug(content, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void output(Level level, String content, Throwable e) { // No logger lib required
|
|
|
|
if (Level.NONE == LOG_LEVEL || level.ordinal() < LOG_LEVEL.ordinal()) {
|
2021-11-29 14:24:13 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-13 19:31:41 +08:00
|
|
|
String caller = "UNKNOWN";
|
2021-11-29 14:24:13 +08:00
|
|
|
StackTraceElement[] traces = new Throwable().getStackTrace();
|
2022-01-13 19:31:41 +08:00
|
|
|
for (int i = 1, l = traces.length; i < l; i++) { // thank RayGicEFL
|
|
|
|
StackTraceElement element = traces[i];
|
|
|
|
if (!CLASS_NAME.equals(element.getClassName())) {
|
|
|
|
caller = element.toString();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-11-29 14:24:13 +08:00
|
|
|
|
2022-01-20 14:55:03 +08:00
|
|
|
String outContent = String.format(LOG_TEMPLATE, DateUtils.formatDateTime(), caller, level, content);
|
2021-12-28 15:02:34 +08:00
|
|
|
if (null == e) {
|
2022-01-20 14:55:03 +08:00
|
|
|
writeContent(outContent);
|
2021-12-28 15:02:34 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (DebugInfo.class) {
|
2022-01-20 14:55:03 +08:00
|
|
|
writeContent(outContent, System.err);
|
|
|
|
writeException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void writeContent(String content) {
|
|
|
|
writeContent(content, System.out);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void writeContent(String content, PrintStream fallback) {
|
|
|
|
if (null == logFile) {
|
|
|
|
fallback.print(content);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try (PrintStream ps = new PrintStream(new FileOutputStream(logFile, true))) {
|
|
|
|
ps.print(content);
|
|
|
|
} catch (IOException e) {
|
|
|
|
fallback.println(content);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void writeException(Throwable e) {
|
|
|
|
writeException(e, System.err);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void writeException(Throwable e, PrintStream fallback) {
|
|
|
|
if (null == logFile) {
|
|
|
|
e.printStackTrace(fallback);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try (PrintStream ps = new PrintStream(new FileOutputStream(logFile, true))) {
|
|
|
|
e.printStackTrace(ps);
|
|
|
|
} catch (IOException ex) {
|
|
|
|
e.printStackTrace(fallback);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private enum Level {
|
|
|
|
NONE, DEBUG, INFO, WARN, ERROR;
|
|
|
|
|
|
|
|
public static Level of(String valueStr) {
|
|
|
|
if (null == valueStr) {
|
|
|
|
return NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int value;
|
|
|
|
try {
|
|
|
|
value = Integer.parseInt(valueStr);
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
return NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Level level : values()) {
|
|
|
|
if (level.ordinal() == value) {
|
|
|
|
return level;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NONE;
|
2021-12-28 15:02:34 +08:00
|
|
|
}
|
2021-11-29 14:24:13 +08:00
|
|
|
}
|
|
|
|
}
|