io.github.kits.log.LoggerFomtter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of whimthen-kits Show documentation
Show all versions of whimthen-kits Show documentation
Easy to use java tool library.
The newest version!
package io.github.kits.log;
import io.github.kits.*;
import io.github.kits.enums.PropEnum;
import io.github.kits.json.JsonKit;
import java.util.Arrays;
import static io.github.kits.enums.PropEnum.*;
/**
* 日志格式化
*
* @project: kits
* @created: with IDEA
* @author: kits
* @date: 2018 04 27 下午3:49 | 四月. 星期五
*/
public class LoggerFomtter {
// @Value(prop = "logger", name = "LogTemplate")
private static String logTemplate;
// @Value(name = "FullClassName", defaultValue = "false")
private static boolean isFullClassName;
private static String level = LOGGER_INFO.getProp();
public static int loggerLevelNumber = 1;
static {
PropertiesKit.getString(DEFAULT_LOGGER_PROPERTIES.getProp(), "LogTemplate").ifPresent(template -> logTemplate = template);
isFullClassName = PropertiesKit.getBoolean(DEFAULT_LOGGER_PROPERTIES.getProp(), "FullClassName").orElse(false);
}
static void setLevel(String lev) {
level = lev;
}
/**
* 将日志信息写入到队列中等待输出
*
* @param message 日志信息
*/
private synchronized static void writeLog(String message) {
if (LoggerThread.mainLogThrad == null) {
LoggerThread.start();
}
LoggerThread.addLogMessage(message);
}
/**
* 获取日志输出的类名
*
* @return 堆栈信息
*/
private static String getStackClassName() {
return EnvKit.getStaceTraceE(6).getClassName();
}
/**
* 获取日志输出的行数
*
* @return 行数
*/
private static int getStackLineNumber() {
return EnvKit.getStaceTraceE(6).getLineNumber();
}
/**
* 获取当前线程的名称
*
* @return 线程名称
*/
private static String currentThreadName() {
Thread currentThread = Thread.currentThread();
String threadName = currentThread.getName();
// int threadNameLength = threadName.length();
// if (StringKit.isNotNullOrEmpty(threadName) && threadNameLength < 21) {
// threadName = StringKit.repeat(" ", 21 - threadNameLength) + threadName;
// }
// if (threadNameLength > 21) {
// threadName = threadName.substring(threadName.length() - 21);
// }
long id = currentThread.getId();
String threadId = String.valueOf(id);
// if (StringKit.isNotNullOrEmpty(threadId)) {
// if (threadId.length() >= 1 && threadId.length() < 2) {
// threadId = " " + threadId;
// }
// if (threadId.length() < 3 && threadId.length() >= 2) {
// threadId = " " + threadId;
// }
// }
return threadName + ": " + threadId;
}
/**
* 日志信息中的线程信息
* eg: [ main: 1]
* 输出线程名称和线程id, 以冒号分割, 暂时为设定线程信息的长度可控, 默认21
*
* @return 线程信息
*/
private static String logThreadName() {
String threadName = "[" + currentThreadName() + "] ";
threadName = colorful() ? ColorKit.toCanary(threadName) : threadName;
return threadName;
}
/**
* 日志信息中的时间信息
* eg: [2018-11-21 11:21:44:179]
* 时间信息带有下划线格式, 在error时红色输出
* @return 时间
*/
private static String logTime() {
String time = DateTimeKit.now(DateTimeKit.YYYY_MM_DD_MM_HH_MM_SS_SSS);
time = colorful() ? ColorKit.toUnderLine(time) : time;
return "[" + time + "] ";
}
/**
* 获取日志中的class信息
* eg: [ i.g.w.k.PropertiesKit.java: 698]
* 类信息的输出长度可控,在config.properties中配置 ClassNameLength 即可, 默认40
*
* @return class信息
*/
private static String logClassInfo() {
String classInfo = getStackClassName();
StringBuilder className = new StringBuilder();
if (StringKit.isNotNullOrEmpty(classInfo)) {
if (isFullClassName) {
String[] split = classInfo.split("\\.");
for (int i = 0; i < split.length - 1; i++) {
className.append(split[i].charAt(0))
.append(".");
}
className.append(split[split.length - 1]);
} else {
className.append(classInfo);
}
}
int lineNumber = getStackLineNumber();
String lineStr = String.valueOf(lineNumber);
// if (lineStr.length() < 4) {
// lineStr = StringKit.repeat(" ", 4 - lineStr.length()) + lineStr;
// }
className.append(".java: ").append(lineStr);
// int nameLength = PropertiesKit.getIntOrDefault(DEFAULT_LOGGER_PROPERTIES.getProp(), "ClassNameLength", 40);
// if (StringKit.isNotNullOrEmpty(className.toString()) && className.length() < nameLength) {
// int spaceNumber = nameLength - className.length();
// for (int i = 0; i < spaceNumber; i++) {
// className.insert(0, " ");
// }
// }
className.insert(0, "[");
className.append("]");
return colorful() ? ColorKit.toGreen(className.toString()) : className.toString();
}
/**
* 日志结束标志
*
* @return end
*/
private static String getEnd() {
return colorful() ? ColorKit.toCanaryBold(": ") : ": ";
}
/**
* 是否全部内容彩色输出
* 当日志级别为error时全部日志信息彩色输出
*
* @return true-是 | false-否
*/
private static boolean colorful() {
return level != null && !level.equals(LOGGER_ERROR.getProp());
}
/**
* 将构造的日志信息写到队列等待输出
*
* @param logLevel 日志级别
* @param message 日志信息
* @param exception 异常
* @param objects 参数
*/
public static void writeLog(String logLevel, boolean isNewLine, Object message, Throwable exception, Object... objects) {
try {
level = logLevel;
String logMessage, msg = buildMessage(message, exception, objects);
logMessage = appendMessage(logLevel, msg, isNewLine);
/*if (checkLoggerLevel(level)) {
writeLog(logMessage);
}*/
boolean isLog = (PropEnum.LOGGER_DEBUG.getProp().equals(logLevel) && Logger.isDebugEnabled()) || PropEnum.LOGGER_INFO.getProp().equals(logLevel)
|| PropEnum.LOGGER_WARN.getProp().equals(logLevel) || PropEnum.LOGGER_ERROR.getProp().equals(logLevel);
if (isLog) {
writeLog(logMessage);
}
} catch (Exception ex) {
ex.printStackTrace();
Logger.errorf("Log output failed", ex);
}
}
/**
* 构造日志信息
*
* @param message 日志信息
* @param exception 异常
* @param objects 参数
* @return 日志字符串
*/
private static String buildMessage(Object message, Throwable exception, Object[] objects) {
StringBuilder buildMessge = new StringBuilder();
if (ListKit.isNullOrEmpty(Arrays.asList(objects)) && exception == null) {
return JsonKit.toJson(message);
} else if (ListKit.isNotNullOrEmpty(Arrays.asList(objects))) {
String msg = message.toString();
int index = 0;
for (int i = 0; i < msg.length(); i++) {
char left = msg.charAt(i);
if (left == '{' && index < objects.length) {
Character reight = (++i) >= msg.length() ? null : msg.charAt(i);
if (reight != null && reight == '}') {
buildMessge.append(JsonKit.toJson(objects[index++]));
}
} else {
buildMessge.append(left);
}
}
} else if (message != null){
buildMessge.append(JsonKit.toJson(message));
}
if (exception != null) {
if (StringKit.isNotNullOrEmpty(buildMessge.toString().trim())) {
buildMessge.append(" ").append(getEnd());
}
do {
buildMessge.append(exception.getClass().getCanonicalName())
.append(": ")
.append(exception.getMessage())
.append(FileKit.getLineSeparator())
.append(StringKit.indent(EnvKit.getStackElementsMessage(exception.getStackTrace()), 6));
exception = exception.getCause();
} while (exception != null);
}
return buildMessge.toString();
}
/**
* 拼接最终的日志格式
* 将日志前缀和输出时间线程名class信息以及自定义信息整合
*
* @param level 日志级别
* @param message 日志信息
* @param isNewLine 是否换行
* @return 日志字符串
*/
public static String appendMessage(String level, String message, boolean isNewLine) {
if (StringKit.isNullOrEmpty(logTemplate)) {
message = logTime() + logThreadName() + logClassInfo() + getEnd() + (isNewLine ? "\n" + message : message);
}
switch (getByProp(level)) {
case LOGGER_DEBUG :
message = Prefix.DEBUG + message;
break;
case LOGGER_ERROR :
message = Prefix.ERROR + message + COLOR_END.getProp();
break;
case LOGGER_WARN :
message = Prefix.WARN + message;
break;
case LOGGER_INFO :
default :
message = Prefix.INFO + message;
break;
}
return message;
}
/**
* 日志前缀, 在非Windows系统下彩色输出
*/
static class Prefix {
static String INFO = EnvKit.isNotWin() ? ColorKit.toWhiteBold(LOGGER_INFO.getContent()) : LOGGER_INFO.getContent() + COLOR_END.getProp();
static String DEBUG = EnvKit.isNotWin() ? ColorKit.toBuleBold(LOGGER_DEBUG.getContent()) : LOGGER_DEBUG.getContent() + COLOR_END.getProp();
static String ERROR = EnvKit.isNotWin() ? ColorKit.convertToColorNotEnd(COLOR_RED.getProp(), LOGGER_ERROR.getContent(), true) : LOGGER_ERROR.getContent();
static String WARN = EnvKit.isNotWin() ? ColorKit.toYellowBold(LOGGER_WARN.getContent()) : LOGGER_WARN.getContent() + COLOR_END.getProp();
}
}