📄 debugger.java
字号:
package com.icbcsdc.ddlexp.pub.staticLog;
import java.util.Date;
import java.io.File;
import java.io.RandomAccessFile;
import java.io.IOException;
import java.io.FileNotFoundException;
/**
* Debug接口,提供显示Debug信息,以便程序员进行调试的功能
* Debugger和Logger使用相同的Level等级划分,由高到低分别是:
* (1) OFF(关闭Log或Debug功能), val <= 0
* (2) FATAL(会导致程序中止的严重错误), 0 < val <= 1000
* (3) ERROR(错误), 1000 < val <= 2000
* (4) WARN(警告), 2000 < val <= 3000
* (5) DEBUG(调试信息), 3000 < val <= 4000
* (6) INFO(提示信息), 4000 < val <= 5000
* OFF > FATAL > ERROR > WARN > DEBUG > INFO
* 用户可根据需要对每一条Log或Debug指定合适的Level等级。
*
*/
public class Debugger {
/**
* 关闭Log或Debug功能的等级, val <= 0
*/
public final static String OFF = new String("OFF");
public final static int OFF_INT = 0;
/**
* 会导致程序中止的严重错误的等级, 0 < val <= 1000
*/
public final static String FATAL = new String("FATAL");
public final static int FATAL_INT = 1000;
/**
* 错误的等级, 1000 < val <= 2000
*/
public final static String ERROR = new String("ERROR");
public final static int ERROR_INT = 2000;
/**
* 警告的等级, 2000 < val <= 3000
*/
public final static String WARN = new String("WARN");
public final static int WARN_INT = 3000;
/**
* 提示信息, 3000 < val <= 4000
*/
public final static String INFO = new String("INFO");
public final static int INFO_INT = 4000;
/**
* 调试信息, 4000 < val <= 5000
*/
public final static String DEBUG = new String("DEBUG");
public final static int DEBUG_INT = 5000;
/**
* 公共变量debugLevel设定默认的debug等级,
* 若Debug语句的等级高于或等于该等级,
* 则输出debug信息;
* 否则不处理。默认为关闭debug输出(OFF)。
*/
private static int debugLevel = OFF_INT;
//private static boolean isToFile = false;
/**
* 输出到console的类型定义
*/
public final static Integer CONSOLE = new Integer(1);
/**
* 输出到文件的类型定义
*/
public final static Integer FILE = new Integer(2);
/**
* 默认输出类型为输出到console
*/
private static byte outputType = CONSOLE.byteValue();
/**
* 文件大小。默认为64兆。
*/
private static long fileLength = 67108864;
/**
* 线程名
*/
private static String threadName;
/**
* RandomAccessFile对象
*/
private static RandomAccessFile raf = null;
/**
* 文件序号
*/
private static int fileNum = 1;
/**
* 输出文件路径
*/
private static String path = "";
/**
* 时间
*/
// 读取当前时间
static Date now;
// 用byte[] 作为synchronized锁性能较佳
/**
* 同步锁1
*/
private static byte[] lock1 = new byte[0];
/**
* 同步锁2
*/
private static byte[] lock2 = new byte[0];
/**
* 提供外部设定debugLevel的方法,
* 程序调用该方法,则将输入的int类型值作为新的debugLevel等级
*
* @param debugLevel 设置的等级数值
*/
public static void setDebugLevel(Integer debugLevel) {
synchronized (lock1) {
Debugger.debugLevel = debugLevel.intValue();
}
}
/**
* 提供外部设定debugLevel的另一种方法,
* 程序调用该方法,将输入的String类型值转为相应的Level数值,
* 作为新的debugLevel等级
*
* @param debugLevel 设置的等级
*/
public static void setDebugLevel(String debugLevel) {
synchronized (lock1) {
if (debugLevel.equals(OFF)) {
Debugger.debugLevel = OFF_INT;
} else if (debugLevel.equals(DEBUG)) {
Debugger.debugLevel = DEBUG_INT;
} else if (debugLevel.equals(INFO)) {
Debugger.debugLevel = INFO_INT;
} else if (debugLevel.equals(WARN)) {
Debugger.debugLevel = WARN_INT;
} else if (debugLevel.equals(ERROR)) {
Debugger.debugLevel = ERROR_INT;
} else if (debugLevel.equals(FATAL)) {
Debugger.debugLevel = FATAL_INT;
}
}
}
/**
* 读取记录等级
*
* @return debugLevel 记录等级
*/
public static int getDebugLevel() {
return Debugger.debugLevel;
}
/**
* debug信息输出类型设置。
* 默认输出到console,
* debug信息不写入文件
*
* @param outputType 输出类型,详见《日志接口说明.doc》
*/
public static void setOutputType(Integer outputType) {
Debugger.outputType = outputType.byteValue();
}
/**
* 读取输出类型
*
* @return outputType 输出类型
*/
public static byte getOutputType() {
return Debugger.outputType;
}
/**
* 检查RandomAccessFile对象是否已经存在,
* 若未存在,则创建新的RandomAccessFile对象。
* 检查文件长度,若超过1M,则文件序号加1。
* 文件序号在1-10间循环
*
* @return 正确的RandomAccessFile对象
*/
private synchronized static RandomAccessFile openFile() {
//定义文件名
String fileName = Debugger.path + "debug_" + fileNum + ".txt";
if (raf == null)
try {
raf = new RandomAccessFile(fileName, "rws");
} catch (FileNotFoundException e) {
//System.out.println(e);
}
// 检查文件长度,若大于64M,则文件序号加1
// 提供文件数量保护机制,文件序号在1-10间循环使用
// 并且将旧文件备份成.bak文件
synchronized (lock2) {
try {
while (raf.length() >= fileLength) {
if (fileNum < 10) {
++fileNum;
//System.out.println("fileNum = " + fileNum);
} else {
fileNum = 1;
backupFiles(1);
}
fileName = Debugger.path + "debug_" + fileNum + ".txt";
raf.close();
raf = new RandomAccessFile(fileName, "rws");
}
if (fileNum < 10) {
int nextFile = fileNum + 1;
backupFiles(nextFile);
}
} catch (IOException e) {
//System.out.println(e);
}
return raf;
}
}
/**
* 实例化一个debug语句的方法,
* 该方法中Level使用int类型
*
* @param levelVal 该条debug信息的等级
* @param teller 需过滤的柜员号
* @param tradeCode 需过滤的交易号
* @param msg debug信息
*/
public static void debug(int levelVal, int teller, int tradeCode, String msg) {
now = new Date();
if ((Debugger.outputType & CONSOLE.byteValue()) == 0x01)
debugToConsole(levelVal, teller, tradeCode, msg);
if ((Debugger.outputType & FILE.byteValue()) == 0x02)
debugToFile(levelVal, teller, tradeCode, msg);
}
/**
* debug方法的另一个实例,
* 其中等级Level使用string类型
*
* @param inputLevel 该条debug信息的等级
* @param teller 需过滤的柜员号
* @param tradeCode 需过滤的交易号
* @param msg debug信息
*/
public static void debug(String inputLevel, int teller, int tradeCode, String msg) {
/*
* 判断给出的levelStr等级
* 转为相应的Level数值后交由上一方法实现
*/
if (inputLevel.equals(OFF)) {
} else if (inputLevel.equals(DEBUG)) {
debug(DEBUG_INT, teller, tradeCode, msg);
} else if (inputLevel.equals(INFO)) {
debug(INFO_INT, teller, tradeCode, msg);
} else if (inputLevel.equals(WARN)) {
debug(WARN_INT, teller, tradeCode, msg);
} else if (inputLevel.equals(ERROR)) {
debug(ERROR_INT, teller, tradeCode, msg);
} else if (inputLevel.equals(FATAL)) {
debug(FATAL_INT, teller, tradeCode, msg);
}
}
/**
* debug信息输出到文件
*
* @param levelVal debug信息的等级
* @param teller 需要过滤的柜员号
* @param tradeCode 需要过滤的交易号
* @param msg 需要记录的信息
*/
protected static void debugToFile(int levelVal, int teller, int tradeCode, String msg) {
// 若给出的levelVal非法
// 则系统默认将level定为OFF
// 即关闭该条语句的Debug功能
String level = "OFF";
// 比较给出的levelVal和默认的debugLevel等级
// 若levelVal等级高于或等于debugLevel
// 则输出debug信息
// 否则不处理
if ((levelVal <= Debugger.debugLevel) && (levelVal > OFF_INT)) {
// 判断给出的levelVal属于什么等级
if (levelVal <= FATAL_INT) {
level = "FATAL";
} else if ((levelVal > FATAL_INT) && (levelVal <= ERROR_INT)) {
level = "ERROR";
} else if ((levelVal > ERROR_INT) && (levelVal <= WARN_INT)) {
level = "WARN";
} else if ((levelVal > WARN_INT) && (levelVal <= INFO_INT)) {
level = "INFO";
} else if (levelVal > INFO_INT) {
level = "DEBUG";
}
try {
RandomAccessFile debugraf = Debugger.openFile();
synchronized (debugraf) {
long offset = debugraf.length();
debugraf.seek(offset);
//debugraf.writeBytes(Debugger.now + ",[" + level + "]," + levelVal + ", #" + teller + "," + tradeCode + ", [Thread]" + Debugger.getThreadName() + ", " + msg + "\n");
byte bb[] = (Debugger.now + ",[" + level + "]," + levelVal + ", #" + teller + "," + tradeCode + ", [Thread]" + Debugger.getThreadName() + ", " + msg + "\n").getBytes();
debugraf.write(bb);
}
} catch (IOException e) {
//System.out.println(e);
}
}
}
/**
* debug信息输出到console
*
* @param levelVal debug信息的等级
* @param teller 需要过滤的柜员号
* @param tradeCode 需要过滤的交易号
* @param msg 需要记录的信息
*/
protected static void debugToConsole(int levelVal, int teller, int tradeCode, String msg) {
String level = "OFF";
if (levelVal <= FATAL_INT) {
level = "FATAL";
} else if ((levelVal > FATAL_INT) && (levelVal <= ERROR_INT)) {
level = "ERROR";
} else if ((levelVal > ERROR_INT) && (levelVal <= WARN_INT)) {
level = "WARN";
} else if ((levelVal > WARN_INT) && (levelVal <= INFO_INT)) {
level = "INFO";
} else if (levelVal > INFO_INT) {
level = "DEBUG";
}
System.out.println(Debugger.now + ",[" + level + "]," + levelVal + ", #" + teller + "," + tradeCode + ", [Thread]" + Debugger.getThreadName() + "," + msg);
}
/**
* 将旧的debug文件备份为.bak文件
*
* @param backupFileNum 指定需要备份的文件序号
*/
protected static void backupFiles(int backupFileNum) {
File file = new File(Debugger.path + "debug_" + backupFileNum + ".txt");
if (file.exists()) {
File backupFile = new File(Debugger.path + "debug_" + backupFileNum + ".bak");
if (backupFile.exists()) {
backupFile.delete();
}
file.renameTo(backupFile);
}
}
/**
* 获得该条debug信息所在的线程名
*
* @return 线程名
*/
public static String getThreadName() {
//if (threadName == null)
threadName = (Thread.currentThread()).getName();
return threadName;
}
/**
* 设置输出文件路径
*
* @param path 输出路径
*/
public static void setDebugPath(String path) {
Debugger.path = path;
}
/**
* 设置输出文件大小的最大值。
*
* @param fileLength 文件大小
*/
public static void setFileLength(Long fileLength) {
Debugger.fileLength = fileLength.longValue();
}
/**
* 读取输出文件路径
*
* @return path 输出文件路径
*/
public static String getDebugPath() {
return Debugger.path;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -