io.github.kits.log.LoggerThread 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.ColorKit;
import io.github.kits.DateTimeKit;
import io.github.kits.EnvKit;
import io.github.kits.FileKit;
import io.github.kits.PropertiesKit;
import io.github.kits.StringKit;
import io.github.kits.enums.PropEnum;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import static io.github.kits.enums.PropEnum.COLOR_END;
import static io.github.kits.enums.PropEnum.DEFAULT_LOGGER_PROPERTIES;
/**
* 日志输出主线程
*
* @project: kits
* @created: with IDEA
* @author: kits
* @date: 2018 04 26 下午5:19 | 四月. 星期四
*/
public class LoggerThread implements Runnable {
private static OutputStream[] outputStreams;
private static ArrayBlockingQueue logQueue;
private static LoggerThread loggerThread;
static Thread mainLogThrad;
// @Value(prop = "logger", name = "LogPath", defaultValue = "{{WorkDir}}/logs/sysout.{{D}}.log")
public static String logPath;
// @Value(prop = "logger", name = "LogLevel", defaultValue = "INFO,WARN,ERROR")
static String logLevel;
/**
* Set logger output stream
*
* @param outputStream stream
*/
private static void setOutputStreams(OutputStream[] outputStream) {
outputStreams = outputStream;
}
static {
loggerThread = new LoggerThread();
logQueue = new ArrayBlockingQueue<>(10000);
logPath = PropertiesKit.getString(DEFAULT_LOGGER_PROPERTIES.getProp(), "LogPath").orElse("{{WorkDir}}/logs/sysout.{{D}}.log");
logLevel = PropertiesKit.getString(DEFAULT_LOGGER_PROPERTIES.getProp(), "LogLevel").orElse("INFO,WARN,ERROR");
}
/**
* add new log to queue, waiting for output
*
* @param message Log message
*/
static void addLogMessage(String message) {
logQueue.add(message);
}
/**
* logger output event
*/
@Override
public void run() {
String formatedMessage;
try {
while (true) {
Thread mainThread = EnvKit.getMainThread();
//优化日志输出事件
if(logQueue.size() == 0){
continue;
}
String message = logQueue.take();
if (StringKit.isNullOrEmpty(message)) {
continue;
}
formatedMessage = message + COLOR_END.getProp() + FileKit.getLineSeparator();
if (outputStreams != null) {
for (OutputStream outputStream : outputStreams) {
if (outputStream != null) {
if(outputStream != System.out) {
//文件写入踢出着色部分
String fileMessage = formatedMessage;
fileMessage = StringKit.replaceAll(fileMessage, "", "\033\\[0m", "\033\\[\\d{2}m", "\033\\[1;\\d{2}m", "\033\\[\\dm");
output(outputStream, fileMessage);
} else {
output(outputStream, formatedMessage);
}
}
}
}
//如果主线程结束,则日志线程也退出
if(mainThread != null && mainThread.getState() == Thread.State.TERMINATED){
EnvKit.sleep(100);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
assert outputStreams != null;
for (OutputStream outputStream : outputStreams) {
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* log output to file or console
*
* @param outputStream stream
* @param message log message
* @throws IOException IoException
*/
private static void output(OutputStream outputStream, String message) throws IOException {
outputStream.write(message.getBytes());
outputStream.flush();
}
/**
* get outputstream from properties,
* if properties logType include FILE,STDOUT
* then output to file and console
*
* @return outputStream
*/
private static OutputStream[] getOutputStreams() {
String loggerType = PropertiesKit.getString(PropEnum.DEFAULT_LOGGER_PROPERTIES.getProp(), "LogType").orElse("STDOUT");
String[] logTypes = loggerType.split(",");
OutputStream[] outputStreams = new OutputStream[logTypes.length];
for (int i = 0; i < logTypes.length; i++) {
String logType = logTypes[i].trim();
switch (logType) {
case "STDOUT":
outputStreams[i] = System.out;
break;
case "FILE":
File logFile = null;
try {
String contentPath = FileKit.getContentPath();
String now = DateTimeKit.format(new Date(), DateTimeKit.YYYYMMDD);
if (StringKit.isNullOrEmpty(logPath)) {
contentPath += "/logs";
} else {
String floder = logPath.substring(0, logPath.lastIndexOf("/"));
contentPath = StringKit.replaceAll(floder, contentPath, "\\{\\{WorkDir\\}\\}");
}
File file = new File(contentPath);
if (!file.exists()) {
file.mkdirs();
}
if (StringKit.isNotNullOrEmpty(logPath)) {
String time = logPath.substring(logPath.lastIndexOf("/"));
contentPath = StringKit.replaceAll(contentPath + time, now, "\\{\\{D\\}\\}");
} else {
contentPath += "/sysout." + now + ".log";
}
logFile = new File(contentPath);
outputStreams[i] = new FileOutputStream(logFile, true);
} catch (FileNotFoundException e) {
String message = "[ " + logFile + " ]";
logQueue.add(LoggerFomtter.appendMessage(PropEnum.LOGGER_WARN.getProp(),
EnvKit.isNotWin() ? ColorKit.toRedBold(message) : message, false) + " file is not found.");
}
break;
default:
break;
}
}
return outputStreams;
}
/**
* start this thread do output log
*/
synchronized static void start() {
if (mainLogThrad == null) {
setOutputStreams(getOutputStreams());
mainLogThrad = new Thread(loggerThread);
mainLogThrad.setName("LoggerThread");
mainLogThrad.start();
}
}
}