📄 logger.java
字号:
package com.icbcsdc.ddlexp.pub.staticLog;
import java.io.File;
import java.io.RandomAccessFile;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.Date;
//import com.icbc.ct.cts.mng.MngReporter;
/**
* 日志接口,提供日志记录功能
* Logger和Debugger使用相同的Level等级划分,由高到低分别是:
* (1) OFF(关闭Log或Debug功能), val <= 0
* (2) FATAL(会导致程序中止的严重错误), 0 < val <= 1000
* (3) ERROR(错误), 1000 < val <= 2000
* (4) WARN(警告), 2000 < val <= 3000
* (5) INFO(提示信息), 3000 < val <= 4000
* (6) DEBUG(调试信息), 4000 < val <= 5000
* OFF > FATAL > ERROR > WARN > INFO > DEBUG
* 用户可根据需要对每一条Log或Debug指定合适的Level等级。
* 使用步骤:
* Logger.setLogLeverl(Logger.INFO);
* Logger.log(int,String);
*
* 默认值:
* logLevel=DEBUG_INT
* outputType=CONSOLE
* layout=SIMPLELAYOUT
*/
/*
//使用例子: by zhangping
****Log的初始化****
//设置输出log的等级
Logger.setLogLevel(Logger.DEBUG);
//设置输出信息的完整性 Logger.SIMPLELAYOUT 为简单 Logger.FULLLAYOUT 为完整
Logger.setLayout(Logger.SIMPLELAYOUT);
//设置log的输出类型: Logger.CONSOLE 为控制台, Logger.FILE 为文件
Logger.setOutputType(Logger.CONSOLE);
//设置log的文件目录
Logger.setLogPath("c:/log");
****常用的写log的方法****
Logger.log(Logger.ERROR_INT,"error message");
Logger.log(Logger.INFO_INT,"一般信息");
//
//*/
public class Logger {
/**
* 关闭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;
/**
* 简单输出
*/
public final static String SIMPLELAYOUT = "S";
/**
* 完整输出
*/
public final static String FULLLAYOUT = "F";
/**
* 完整输出
*/
public final static String MILLISLAYOUT = "M";
/**
* 定义输出类型为到console的值
*/
public final static Integer CONSOLE = new Integer(1);
/**
* 定义输出类型为到文件的值
*/
public final static Integer FILE = new Integer(2);
/**
* 定义输出类型为到日志服务器的值
*/
public final static Integer SERVER = new Integer(4);
/**
* 默认输出类型为输出到文件
*
*/
//private static byte outputType = FILE.byteValue();
private static byte outputType = CONSOLE.byteValue();
/**
* 默认输出格式为完整输出
*/
//private static String layout = FULLLAYOUT;
private static String layout = SIMPLELAYOUT;
/**
* 输出文件大小。默认为64兆。
*/
private static long fileLength = 67108864;//64M
/**
* 日志输出文件路径
*/
private static String path = "";
/**
* 线程名
*/
private static String threadName;
/**
* 公共变量logLevel设定默认的log等级,
* 若Logger语句的等级高于或等于该等级,
* 则输出log信息;
* 否则不处理
*/
//private static int logLevel = OFF_INT;
private static int logLevel = DEBUG_INT;
/**
* RandomAccessFile对象
*/
private static RandomAccessFile raf = null;
/**
* 文件序号
*/
private static int fileNum = 1;
private static int warn = 0;
private static int error = 0;
private static int fatal = 0;
/**
* 时间
*/
static Date now; // = new Date();
// 用byte[] 作为synchronized锁性能较佳
/**
* 同步锁1
*/
private static byte[] lock1 = new byte[0];
/**
* 同步锁2
*/
private static byte[] lock2 = new byte[0];
/**
* 开始时间
*/
private static long start=System.currentTimeMillis();
//private Logger() {}
/**
* 提供外部设定logLevel的方法。
* 程序调用该方法,则将输入的int类型值作为新的logLevel等级
*
* @param logLevel 设定的等级
*/
public static void setLogLevel(Integer logLevel) {
synchronized (lock1) {
Logger.logLevel = logLevel.intValue();
}
}
/**
* 提供外部设定logLevel的另一种方法,
* 程序调用该方法,将输入的String类型值转为相应的Level数值,
* 作为新的logLevel等级
*
* @param logLevel 设定的等级
*/
public static void setLogLevel(String logLevel) {
synchronized (lock1) {
if (logLevel.equals(OFF)) {
Logger.logLevel = OFF_INT;
} else if (logLevel.equals(DEBUG)) {
Logger.logLevel = DEBUG_INT;
} else if (logLevel.equals(INFO)) {
Logger.logLevel = INFO_INT;
} else if (logLevel.equals(WARN)) {
Logger.logLevel = WARN_INT;
} else if (logLevel.equals(ERROR)) {
Logger.logLevel = ERROR_INT;
} else if (logLevel.equals(FATAL)) {
Logger.logLevel = FATAL_INT;
}
}
}
/**
* 读取记录等级参数
*
* @return logLevel 记录等级
*/
public static int getLogLevel() {
return Logger.logLevel;
}
/**
* 设置输出类型
*
* @param outputType 输出类型,详见《日志接口说明》
*/
public static void setOutputType(Integer outputType) {
Logger.outputType = outputType.byteValue();
}
/**
* 读取输出类型
* @return outputType 输出类型
*/
public static byte getOutputType() {
return Logger.outputType;
}
/**
* 检查RandomAccessFile对象是否已经存在,
* 若未存在,则创建新的RandomAccessFile对象。
* 检查文件长度,若超过64M,则文件序号加1。
* 文件序号在1-10间循环
*
* @return 正确的RandomAccessFile对象
*/
private static RandomAccessFile openFile() {
String fileName = Logger.path + "log_" + fileNum + ".txt";
if (raf == null) {
try {
raf = new RandomAccessFile(fileName, "rws");
} catch (FileNotFoundException e) {
//System.out.println(e);
}
}
synchronized (lock2) {
// 检查文件长度,若大于64M,则文件序号加1
// 加入文件控制保护机制,文件序号在1-10间循环,自动将旧文件备份覆盖
try {
while (raf.length() >= fileLength) {
if (fileNum < 10) {
++fileNum;
//System.out.println("fileNum = " + fileNum);
} else {
fileNum = 1;
backupFiles(1);
}
fileName = Logger.path + "log_" + fileNum + ".txt";
raf.close();
raf = new RandomAccessFile(fileName, "rws");
}
if (fileNum < 10) {
int nextFile = fileNum + 1;
backupFiles(nextFile);
}
/* 若使用该else,则log_10.txt只使用一次就跳回log_1.txt
else {
backupFiles(1);
System.out.println("backupFiles = 1 !!!!!!!");
}*/
} catch (IOException e) {
//System.out.println(e);
}
return raf;
}
}
/**
* 实例化一个log语句的方法,
* 该方法中Level使用int类型
*
* @param levelVal 该条日志等级对应的数值
* @param msg 日志信息
*/
public static void log(int levelVal, String msg) {
now = new Date();
if ((Logger.outputType & CONSOLE.byteValue()) == 0x01) {
logToConsole(levelVal, msg);
}
if ((Logger.outputType & FILE.byteValue()) == 0x02) {
logToFile(levelVal, msg);
}
if ((Logger.outputType & SERVER.byteValue()) == 0x04) {
logToServer(levelVal, msg);
}
}
/**
* log方法的另一个实例,
* 其中等级Level使用string类型
*
* @param inputLevel 该条日志的等级
* @param msg 日志信息
*/
public static void log(String inputLevel, String msg) {
// 判断给出的inputLevel等级
// 转为相应的Level数值后交由上一方法实现
//
if (inputLevel.equals(OFF)) {
} else if (inputLevel.equals(DEBUG)) {
log(DEBUG_INT, msg);
} else if (inputLevel.equals(INFO)) {
log(INFO_INT, msg);
} else if (inputLevel.equals(WARN)) {
log(WARN_INT, msg);
} else if (inputLevel.equals(ERROR)) {
log(ERROR_INT, msg);
} else if (inputLevel.equals(FATAL)) {
log(FATAL_INT, msg);
}
}
/**
* 将旧的log文件备份为.bak文件
*
* @param backupFileNum 指定需要备份的文件序号
*/
protected static void backupFiles(int backupFileNum) {
File file = new File(Logger.path + "log_" + backupFileNum + ".txt");
if (file.exists()) {
File backupFile = new File(Logger.path + "log_" + backupFileNum + ".bak");
if (backupFile.exists()) {
backupFile.delete();
//System.out.println(backupFile + " deleted");
}
file.renameTo(backupFile);
//System.out.println("backupFiles success");
}
}
/**
* 获取具体的log描述信息(根据 Logger.layout来判断是输出简单信息还是完整信息)
* @param levelVal log的等级
* @param msg 需要记录的信息
*/
private static String getLogMsg(int levelVal,String msg){
String logMsg="";
String level="OFF";
//判断给出的levelVal属于什么等级
if (levelVal <= FATAL_INT) {
level = "FATAL";
Logger.isFatal();
} else if ((levelVal > FATAL_INT) && (levelVal <= ERROR_INT)) {
level = "ERROR";
Logger.isError();
} else if ((levelVal > ERROR_INT) && (levelVal <= WARN_INT)) {
level = "WARN";
Logger.isWarn();
} else if ((levelVal > WARN_INT) && (levelVal <= INFO_INT)) {
level = "INFO";
} else if (levelVal > INFO_INT) {
level = "DEBUG";
}
if (Logger.layout.equals(Logger.SIMPLELAYOUT)) {
//level=level.substring(0,0);//取第一个字符
//logMsg="[" + level + "], " + Logger.getThreadName() + ", " + msg + "\n";
logMsg="[" + level + "]" + msg + "\n";
}
else if(Logger.layout.equals(Logger.MILLISLAYOUT))
{
long end=System.currentTimeMillis();
long gap=end-start;
logMsg=gap +"[" + level + "]" + msg + "\n";
}
else {
logMsg=Logger.now + ",[" + level + "]," + levelVal + ", [Thread]" + Logger.getThreadName() + ", " + msg + "\n";
}
return logMsg;
}
/**
* 将log信息写入文件
*
* @param levelVal log的等级
* @param msg 需要记录的信息
*/
protected static void logToFile(int levelVal, String msg) {
if ((levelVal <= Logger.logLevel) && (levelVal > OFF_INT)) {
try {
RandomAccessFile lograf = Logger.openFile();
// 写文件,需要加锁
synchronized (lograf) {
long offset = lograf.length();
lograf.seek(offset);
lograf.write(getLogMsg(levelVal,msg).getBytes());
}
} catch (IOException e) {
//System.out.println(e);
}
}
}
/**
* 将log输出到console
*
* @param levelVal log的等级
* @param msg 需要记录的信息
*/
protected static void logToConsole(int levelVal, String msg) {
System.out.println(getLogMsg(levelVal,msg));
}
/**
* 将log输出到日志服务器
*
* @param levelVal log的等级
* @param msg 需要记录的信息
*/
protected static void logToServer(int levelVal, String msg) {
}
/**
* 获得线程名称
*
* @return 该日志所在线程名称
*/
protected static String getThreadName() {
threadName = (Thread.currentThread()).getName();
return threadName;
}
/**
* 设置输出格式
*
* @param layout 输出格式。"S"为简单输出,"F"为完整输出
*/
public static void setLayout(String layout) {
Logger.layout = layout;
}
/**
* 设置输出文件大小的最大值
*
* @param fileLength 文件大小
*/
public static void setFileLength(Long fileLength) {
Logger.fileLength = fileLength.longValue();
}
/**
* 设置输出文件路径
*
* @param path 输出文件的路径
*/
public static void setLogPath(String path) {
Logger.path = path;
}
/**
* 读取输出文件路径参数的方法
*
* @return path 输出文件路径
*/
public static String getLogPath() {
return Logger.path;
}
/**
* 读取WARN事件发生次数
*
* @return warn WARN事件发生次数
*/
public static Integer getSumWarn() {
return new Integer(Logger.warn);
}
/**
* 读取WARN事件发生次数
*
* @return warn WARN事件发生次数
*/
public static Integer getSumError() {
return new Integer(Logger.error);
}
/**
* 读取WARN事件发生次数
*
* @return warn WARN事件发生次数
*/
public static Integer getSumFatal() {
return new Integer(Logger.fatal);
}
/**
* 当前日志语句为FATAL等级,fatal事件次数累加。
*
*/
public static void isFatal() {
fatal++;
}
/**
* 当前日志语句为ERROR等级,error事件次数累加。
*
*/
public static void isError() {
error++;
}
/**
* 当前日志语句为WARN等级,warn事件次数累加。
*
*/
public static void isWarn() {
warn++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -