Skip to content

Commit

Permalink
Merge pull request #1 from supervate/dev/v1.1.0
Browse files Browse the repository at this point in the history
Dev/v1.1.0
  • Loading branch information
supervate authored May 13, 2024
2 parents 520505b + c88ad48 commit 817ae9a
Show file tree
Hide file tree
Showing 15 changed files with 357 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Release
# Run workflow on commits to the `main` branch
on:
release:
types: [published]
types: [released]
workflow_dispatch:

jobs:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ name: Run Tests

on:
push:
branches: [ "*" ]
branches: [ "**" ]
pull_request:
branches: [ "*" ]
branches: [ "**" ]

jobs:
test:
Expand Down
13 changes: 0 additions & 13 deletions src/main/java/io/github/supervate/vlog/Layout.java

This file was deleted.

53 changes: 49 additions & 4 deletions src/main/java/io/github/supervate/vlog/LoggerFactory.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package io.github.supervate.vlog;

import io.github.supervate.vlog.appender.AppenderCombiner;
import io.github.supervate.vlog.appender.DefaultFileAppender;
import io.github.supervate.vlog.appender.DefaultPrintStreamAppender;
import io.github.supervate.vlog.common.Constants;
import io.github.supervate.vlog.common.SystemUtils;
import io.github.supervate.vlog.appender.DefaultFileAppender;
import io.github.supervate.vlog.event.Level;
import io.github.supervate.vlog.event.LogEvent;
import io.github.supervate.vlog.layout.DefaultLineLayout;
import io.github.supervate.vlog.layout.Layout;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import static io.github.supervate.vlog.common.Constants.SYSTEM_PROPERTY_LOG_LAYOUT_IMPL;
import static io.github.supervate.vlog.common.SystemUtils.getSysProperty;

/**
* 日志工厂
* <p>
Expand All @@ -23,6 +30,8 @@
* 3. vt.vlog.file.retention 产生的日志文件存放时间,保留多少天,默认为7天.(单位天)
* <li>
* 4. vt.vlog.file.size 产生的日志文件大小,超过多少字节后,产生新的文件,默认为0,不限制.(单位字节)
* <li>
* 5. vt.vlog.layout.impl 日志格式输出实现类,默认是DefaultLineLayout,支持用户自定义.
*
* @author supervate
* @since 2024/04/27
Expand All @@ -33,15 +42,19 @@ public class LoggerFactory {

private static final ConcurrentHashMap<String, Logger> LOGGER_MAP = new ConcurrentHashMap<>();

private static final AppenderCombiner<LogEvent> APPENDER_COMBINER;
private static AppenderCombiner<LogEvent> APPENDER_COMBINER;

volatile private static Level LEVEL;

static {
init();
}

private static void init() {
// appender set
APPENDER_COMBINER = new AppenderCombiner<>();
DefaultPrintStreamAppender defaultPrintStreamAppender = new DefaultPrintStreamAppender(
new DefaultLayout(),
buildLayout(),
System.out,
System.err
);
Expand All @@ -51,7 +64,7 @@ public class LoggerFactory {
.getSysPropertyPath(Constants.SYSTEM_PROPERTY_LOG_DIR)
.ifPresent(path -> {
DefaultFileAppender defaultFileAppender = new DefaultFileAppender(
new DefaultLayout(),
buildLayout(),
path,
SystemUtils
.getSysPropertyInteger(Constants.SYSTEM_PROPERTY_LOG_FILE_RETENTION)
Expand All @@ -68,6 +81,38 @@ public class LoggerFactory {
LEVEL = getLevelConfig();
}

private static Layout<LogEvent> buildLayout() {
return getSysProperty(SYSTEM_PROPERTY_LOG_LAYOUT_IMPL).map(LoggerFactory::loadLayout).orElseGet(DefaultLineLayout::new);
}

@SuppressWarnings("unchecked")
private static Layout<LogEvent> loadLayout(String className) {
Class<?> layoutClazz;
Exception loadLayoutException = null;
try {
layoutClazz = Thread.currentThread().getContextClassLoader().loadClass(className);
if (Layout.class.isAssignableFrom(layoutClazz)) {
for (Type genericInterface : layoutClazz.getGenericInterfaces()) {
if (genericInterface instanceof ParameterizedType && ((ParameterizedType) genericInterface)
.getRawType()
.equals(Layout.class)) {
Type[] actualTypeArguments = ((ParameterizedType) genericInterface).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
if (actualTypeArgument.getTypeName().equals(LogEvent.class.getTypeName())) {
return (Layout<LogEvent>) layoutClazz.getConstructor().newInstance();
}
}
}
}
}
} catch (Exception e) {
loadLayoutException = e;
}
throw loadLayoutException != null
? new IllegalArgumentException("Invalid layout class: " + className, loadLayoutException)
: new IllegalArgumentException("Invalid layout class: " + className);
}

private static Level getLevelConfig() {
return Optional
.ofNullable(System.getProperty(Constants.SYSTEM_PROPERTY_LOG_LEVEL))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.github.supervate.vlog.appender;

import io.github.supervate.vlog.Layout;
import io.github.supervate.vlog.common.Constants;
import io.github.supervate.vlog.common.ThrowableUtils;
import io.github.supervate.vlog.common.Tuple2;
import io.github.supervate.vlog.exception.CreateAppenderException;
import io.github.supervate.vlog.event.LogEvent;
import io.github.supervate.vlog.layout.Layout;

import java.io.File;
import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.github.supervate.vlog.appender;

import io.github.supervate.vlog.exception.CreateAppenderException;
import io.github.supervate.vlog.Layout;
import io.github.supervate.vlog.layout.Layout;
import io.github.supervate.vlog.event.Level;
import io.github.supervate.vlog.event.LogEvent;

Expand Down
9 changes: 9 additions & 0 deletions src/main/java/io/github/supervate/vlog/common/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,21 @@ public class Constants {
public static final String SPACE = " ";
public static final String LEFT_MIDDLE_BRACKET = "[";
public static final String RIGHT_MIDDLE_BRACKET = "]";
public static final String LEFT_BIG_BRACKET = "{";
public static final char LEFT_BIG_BRACKET_CHAR = '{';
public static final String RIGHT_BIG_BRACKET = "}";
public static final char RIGHT_BIG_BRACKET_CHAR = '}';
public static final String EMPTY_OBJECT_SYMBOL = "{}";
public static final String DOUBLE_QUOTES = "\"";
public static final String COLON = ":";
public static final String COMMA = ",";
public static final String CAUSED_BY = "Caused by: ";

public static final String SYSTEM_PROPERTY_LOG_DIR = "vt.vlog.dir";
public static final String SYSTEM_PROPERTY_LOG_LEVEL = "vt.vlog.level";
public static final String SYSTEM_PROPERTY_LOG_FILE_RETENTION = "vt.vlog.file.retention";
public static final String SYSTEM_PROPERTY_LOG_FILE_SIZE = "vt.vlog.file.size";
public static final String SYSTEM_PROPERTY_LOG_LAYOUT_IMPL = "vt.vlog.layout.impl";

public static final int DEFAULT_LOG_FILE_RETENTION = 7;
public static final int DEFAULT_LOG_FILE_SIZE = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public static Optional<Integer> getSysPropertyInteger(String name) {
return Optional.ofNullable(System.getProperty(name)).map(Integer::parseInt);
}

public static Optional<String> getSysProperty(String name) {
return Optional.ofNullable(System.getProperty(name));
}

public static Path getSysTempDir() {
return Paths.get(System.getProperty("java.io.tmpdir"));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package io.github.supervate.vlog.layout;

import io.github.supervate.vlog.Logger;
import io.github.supervate.vlog.common.ThrowableUtils;
import io.github.supervate.vlog.event.LogEvent;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Optional;

import static io.github.supervate.vlog.common.Constants.*;


/**
* 默认日志格式化器
*
* @author supervate
* @since 2024/04/27
* <p>
* All rights Reserved.
*/
public class DefaultJsonLayout implements Layout<LogEvent> {

public static final String UN_DEFINE = "unDefine";

@Override
public String format(LogEvent event) {
if (event != null && event.getMessage() != null) {
Logger logger = event.getLogger();
StringBuilder sb = new StringBuilder();
sb.append(LEFT_BIG_BRACKET);

appendJsonItem(
"eventTime",
Optional
.ofNullable(event.getEventTime())
.map(eventTime -> LocalDateTime.ofInstant(Instant.ofEpochMilli(event.getEventTime()), ZoneId.systemDefault()))
.map(LocalDateTime::toString)
.orElse(UN_DEFINE),
sb
).append(COMMA);
appendJsonItem("threadName", Optional.ofNullable(event.getThreadName()).orElse(UN_DEFINE), sb).append(COMMA);
appendJsonItem("level", Optional.ofNullable(event.getLevel()).map(Enum::name).orElse(UN_DEFINE), sb).append(COMMA);
appendJsonItem("loggerName", Optional.ofNullable(logger).map(Logger::getName).orElse(UN_DEFINE), sb).append(COMMA);

appendJsonItem(
"message",
formatMessage(event.getMessage(), event.getArguments()),
sb
);
if (event.getThrowable() != null) {
sb.append(COMMA);
appendJsonItem("exception", ThrowableUtils.throwableToStr(event.getThrowable()), sb);
}
sb.append(RIGHT_BIG_BRACKET);
return sb.toString();
}
return EMPTY_OBJECT_SYMBOL;
}

private static StringBuilder appendJsonItem(String key, String value, StringBuilder sb) {
sb.append(DOUBLE_QUOTES);
sb.append(key);
sb.append(DOUBLE_QUOTES);
sb.append(COLON);
sb.append(DOUBLE_QUOTES);
sb.append(value);
sb.append(DOUBLE_QUOTES);
return sb;
}


}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.supervate.vlog;
package io.github.supervate.vlog.layout;

import io.github.supervate.vlog.Logger;
import io.github.supervate.vlog.common.ThrowableUtils;
import io.github.supervate.vlog.event.LogEvent;

Expand All @@ -19,7 +20,7 @@
* <p>
* All rights Reserved.
*/
public class DefaultLayout implements Layout<LogEvent> {
public class DefaultLineLayout implements Layout<LogEvent> {

public static final String UN_DEFINE = "unDefine";

Expand All @@ -41,7 +42,7 @@ public String format(LogEvent event) {
appendItem(Optional.ofNullable(logger).map(Logger::getName).orElse(UN_DEFINE), sb);
sb.append("-");
sb.append(SPACE);
sb.append(String.format(event.getMessage(), event.getArguments()));
sb.append(formatMessage(event.getMessage(), event.getArguments()));
if (event.getThrowable() != null) {
sb.append(System.lineSeparator());
sb.append(ThrowableUtils.throwableToStr(event.getThrowable()));
Expand Down
47 changes: 47 additions & 0 deletions src/main/java/io/github/supervate/vlog/layout/Layout.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package io.github.supervate.vlog.layout;

import static io.github.supervate.vlog.common.Constants.*;

/**
* 日志格式化器
*
* @author supervate
* @since 2024/04/27
* <p>
* All rights Reserved.
*/
public interface Layout<E> {

String format(E event);

default String formatMessage(String message, Object... args) {
if (args == null || args.length == 0) {
return message;
}
int matchedArgIndex = 0;
char[] charArray = message.toCharArray();
StringBuilder messageBuilder = new StringBuilder();
boolean leftBracketMatched = false;
for (char c : charArray) {
if (leftBracketMatched) {
// clear left flag
leftBracketMatched = false;
// try to match argument
if (c == RIGHT_BIG_BRACKET_CHAR) {
// append message
messageBuilder.append(matchedArgIndex < args.length ? args[matchedArgIndex++] : EMPTY_OBJECT_SYMBOL);
continue;
} else {
messageBuilder.append(LEFT_BIG_BRACKET);
}
}
if (c == LEFT_BIG_BRACKET_CHAR) {
leftBracketMatched = true;
continue;
}
messageBuilder.append(c);
}
return messageBuilder.toString();
}

}
20 changes: 16 additions & 4 deletions src/test/java/io/github/supervate/vlog/BaseLoggerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import java.lang.reflect.Constructor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
Expand All @@ -32,12 +35,15 @@
* <p>
* All rights Reserved.
*/
@SuppressWarnings({ "resource", "BusyWait" })
@SuppressWarnings({ "resource" })
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BaseLoggerTest {

protected static final Level TEST_DEFAULT_LEVEL = INFO;
protected static final Path LOG_DIR = SystemUtils.getSysTempDir().resolve("test").resolve(BaseLoggerTest.class.getSimpleName());
protected static final Path LOG_DIR = SystemUtils
.getSysTempDir()
.resolve("test")
.resolve(BaseLoggerTest.class.getSimpleName());

@BeforeAll
public static void beforeAll() throws IOException {
Expand Down Expand Up @@ -80,6 +86,12 @@ protected static Logger newLogger(String name, Appender<?> appender, Level level
}
}

protected static String getLogEventTimeStr(LogEvent logEvent) {
return LocalDateTime
.ofInstant(Instant.ofEpochMilli(logEvent.getEventTime()), ZoneId.systemDefault())
.toString();
}

protected static void waitingForLoggerFactoryAsyncAppend() throws IllegalAccessException, InterruptedException {
List<Appender<?>> appenders = getFieldValue(
getFieldValue(LoggerFactory.class, "APPENDER_COMBINER", true),
Expand Down Expand Up @@ -111,10 +123,10 @@ protected static void waitingForAsyncAppend(AsyncAppender<?> asyncAppender) thro
.get(asyncAppender);
if (queue != null) {
while (!queue.isEmpty()) {
Thread.sleep(1);
Thread.yield();
}
}
Thread.sleep(1);
Thread.sleep(5);
}

protected static void makeLevelLogs(Logger logger) {
Expand Down
Loading

0 comments on commit 817ae9a

Please sign in to comment.