All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.kits.log.LoggerFomtter Maven / Gradle / Ivy

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();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy