From d65ea6e7bdcd3d818608aba5a86c6142958400ea Mon Sep 17 00:00:00 2001 From: Eyre_S Date: Sat, 27 Jul 2024 11:05:23 +0800 Subject: [PATCH] add new Appender and Message API - deprecated old Message, add new IMessage API. - deprecated old Logger.appends, uses new AppenderProvider API to provide Appenders to Logger. - add a context on Log. - deprecated field read on Log, use method to read those. - add name on Logger. - add codepoint output for SimpleFormatter. --- README.md | 2 +- build.gradle | 13 +++ gradle.properties | 2 +- .../messiva/appender/AppenderProvider.java | 13 +++ .../appender/AppenderRestrictableByLevel.java | 2 +- .../messiva/appender/ConsoleAppender.java | 26 +---- .../sukazyo/messiva/appender/IAppender.java | 5 + .../appender/StaticAppenderProvider.java | 23 +++++ .../appender/impl/ConsoleAppender.java | 32 ++++++ .../messiva/formatter/SimpleFormatter.java | 44 +++++++-- .../cc/sukazyo/messiva/log/ILogLevelImpl.java | 16 +-- src/main/java/cc/sukazyo/messiva/log/Log.java | 98 +++++++++++++++++-- .../java/cc/sukazyo/messiva/log/Message.java | 17 +++- .../sukazyo/messiva/log/message/IMessage.java | 15 +++ .../messiva/log/message/TextMessage.java | 23 +++++ .../cc/sukazyo/messiva/logger/Logger.java | 96 ++++++++++++------ .../cc/sukazyo/messiva/utils/StackUtils.java | 14 --- 17 files changed, 343 insertions(+), 98 deletions(-) create mode 100644 src/main/java/cc/sukazyo/messiva/appender/AppenderProvider.java create mode 100644 src/main/java/cc/sukazyo/messiva/appender/StaticAppenderProvider.java create mode 100644 src/main/java/cc/sukazyo/messiva/appender/impl/ConsoleAppender.java create mode 100644 src/main/java/cc/sukazyo/messiva/log/message/IMessage.java create mode 100644 src/main/java/cc/sukazyo/messiva/log/message/TextMessage.java delete mode 100644 src/main/java/cc/sukazyo/messiva/utils/StackUtils.java diff --git a/README.md b/README.md index b942184..b9c50c4 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ dependencies { Set up your own logger: ```java import cc.sukazyo.messiva.logger.Logger; -import cc.sukazyo.messiva.appender.ConsoleAppender; +import cc.sukazyo.messiva.appender.impl.ConsoleAppender; import cc.sukazyo.messiva.formatter.SimpleFormatter; // currently only implementation within messiva diff --git a/build.gradle b/build.gradle index e466e7b..c18fb40 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,14 @@ plugins { repositories { mavenCentral() + maven { + name "wsReleases" + url "https://mvn.sukazyo.cc/releases" + } + maven { + name "wsSnapshots" + url "https://mvn.sukazyo.cc/snapshots" + } } group 'cc.sukazyo' @@ -16,6 +24,7 @@ project.ext.artifactId = 'messiva' dependencies { compileOnlyApi "com.github.spotbugs:spotbugs-annotations:${libSpotbugsVersion}" + implementation "cc.sukazyo:da4a:0.2.0-SNAPSHOT" // implementation "org.jline:jline:${libJLineVersion}" // implementation "org.fusesource.jansi:jansi:${libJansiVersion}" @@ -52,6 +61,10 @@ tasks.test { useJUnitPlatform() } +configurations.configureEach { + resolutionStrategy.cacheChangingModulesFor 1, 'seconds' +} + publishing { repositories{ maven { diff --git a/gradle.properties b/gradle.properties index 894aa5a..41d3267 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ ## Messiva -PROJECT_VERSION = 0.2.0 +PROJECT_VERSION = 0.3.0 ## dependencies diff --git a/src/main/java/cc/sukazyo/messiva/appender/AppenderProvider.java b/src/main/java/cc/sukazyo/messiva/appender/AppenderProvider.java new file mode 100644 index 0000000..afd9140 --- /dev/null +++ b/src/main/java/cc/sukazyo/messiva/appender/AppenderProvider.java @@ -0,0 +1,13 @@ +package cc.sukazyo.messiva.appender; + +import cc.sukazyo.std.contexts.GivenContext; + +import javax.annotation.Nonnull; +import java.util.List; + +public interface AppenderProvider { + + @Nonnull + List findAppends (@Nonnull GivenContext context); + +} diff --git a/src/main/java/cc/sukazyo/messiva/appender/AppenderRestrictableByLevel.java b/src/main/java/cc/sukazyo/messiva/appender/AppenderRestrictableByLevel.java index e842981..2edea7c 100644 --- a/src/main/java/cc/sukazyo/messiva/appender/AppenderRestrictableByLevel.java +++ b/src/main/java/cc/sukazyo/messiva/appender/AppenderRestrictableByLevel.java @@ -34,7 +34,7 @@ public abstract class AppenderRestrictableByLevel extends Appender { } public void pushLog (@Nonnull Log log) { - if (!levelSetting.checkLevel(log.level)) return; + if (!levelSetting.checkLevel(log.level())) return; pushLogChecked(log); } diff --git a/src/main/java/cc/sukazyo/messiva/appender/ConsoleAppender.java b/src/main/java/cc/sukazyo/messiva/appender/ConsoleAppender.java index 9820bc7..8b5a74b 100644 --- a/src/main/java/cc/sukazyo/messiva/appender/ConsoleAppender.java +++ b/src/main/java/cc/sukazyo/messiva/appender/ConsoleAppender.java @@ -1,33 +1,17 @@ package cc.sukazyo.messiva.appender; import cc.sukazyo.messiva.formatter.ILogFormatter; -import cc.sukazyo.messiva.log.Log; -import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Objects; -import java.util.concurrent.locks.ReentrantLock; - -public class ConsoleAppender extends AppenderRestrictableByLevel { - - @Nonnull private final ReentrantLock syncLock; +/** + * @deprecated moved. use {@link cc.sukazyo.messiva.appender.impl.ConsoleAppender} instead. + */ +@Deprecated +public class ConsoleAppender extends cc.sukazyo.messiva.appender.impl.ConsoleAppender { public ConsoleAppender (@Nullable ILogFormatter formatter) { super(formatter); - syncLock = new ReentrantLock(); - } - - public ConsoleAppender () { - this(null); - } - - @Override - public void pushLogChecked (@Nonnull Log log) { - if (formatter == null) return; - syncLock.lock(); - System.out.println(formatter.format(log)); - syncLock.unlock(); } } diff --git a/src/main/java/cc/sukazyo/messiva/appender/IAppender.java b/src/main/java/cc/sukazyo/messiva/appender/IAppender.java index ddade53..84f2d24 100644 --- a/src/main/java/cc/sukazyo/messiva/appender/IAppender.java +++ b/src/main/java/cc/sukazyo/messiva/appender/IAppender.java @@ -8,4 +8,9 @@ public interface IAppender { void pushLog (@Nonnull Log log); + @Nonnull + default AppenderProvider asProvider () { + return new StaticAppenderProvider(this); + } + } diff --git a/src/main/java/cc/sukazyo/messiva/appender/StaticAppenderProvider.java b/src/main/java/cc/sukazyo/messiva/appender/StaticAppenderProvider.java new file mode 100644 index 0000000..72d10dc --- /dev/null +++ b/src/main/java/cc/sukazyo/messiva/appender/StaticAppenderProvider.java @@ -0,0 +1,23 @@ +package cc.sukazyo.messiva.appender; + +import cc.sukazyo.std.contexts.GivenContext; + +import javax.annotation.Nonnull; +import java.util.Collections; +import java.util.List; + +public class StaticAppenderProvider implements AppenderProvider { + + @Nonnull final IAppender appender; + + public StaticAppenderProvider (@Nonnull IAppender appender) { + this.appender = appender; + } + + @Nonnull + @Override + public List findAppends (@Nonnull GivenContext context) { + return Collections.singletonList(appender); + } + +} diff --git a/src/main/java/cc/sukazyo/messiva/appender/impl/ConsoleAppender.java b/src/main/java/cc/sukazyo/messiva/appender/impl/ConsoleAppender.java new file mode 100644 index 0000000..84e9e06 --- /dev/null +++ b/src/main/java/cc/sukazyo/messiva/appender/impl/ConsoleAppender.java @@ -0,0 +1,32 @@ +package cc.sukazyo.messiva.appender.impl; + +import cc.sukazyo.messiva.appender.AppenderRestrictableByLevel; +import cc.sukazyo.messiva.formatter.ILogFormatter; +import cc.sukazyo.messiva.log.Log; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.concurrent.locks.ReentrantLock; + +public class ConsoleAppender extends AppenderRestrictableByLevel { + + @Nonnull private final ReentrantLock syncLock; + + public ConsoleAppender (@Nullable ILogFormatter formatter) { + super(formatter); + syncLock = new ReentrantLock(); + } + + public ConsoleAppender () { + this(null); + } + + @Override + public void pushLogChecked (@Nonnull Log log) { + if (formatter == null) return; + syncLock.lock(); + System.out.println(formatter.format(log)); + syncLock.unlock(); + } + +} diff --git a/src/main/java/cc/sukazyo/messiva/formatter/SimpleFormatter.java b/src/main/java/cc/sukazyo/messiva/formatter/SimpleFormatter.java index 43c7c7b..258b3c6 100644 --- a/src/main/java/cc/sukazyo/messiva/formatter/SimpleFormatter.java +++ b/src/main/java/cc/sukazyo/messiva/formatter/SimpleFormatter.java @@ -9,28 +9,54 @@ public class SimpleFormatter implements ILogFormatter { @Nonnull public String startTimestamp = "["; @Nonnull public String endTimestamp = "]"; + @Nonnull public String startThreadName = "["; @Nonnull public String endThreadName = "]"; + + @Nonnull public String startCodePoint = "["; + @Nonnull public String endCodePoint = "]"; + @Nonnull public String startLevelTag = "["; @Nonnull public String endLevelTag = "]"; + public char followingLineFillChar = '\''; + @Nonnull public String messageSeparator = " "; @Nonnull @Override public String format (@Nonnull Log log) { + final StringBuilder message = new StringBuilder(); - message.append(startTimestamp).append(log.timestamp).append(endTimestamp) - .append(startThreadName).append(log.thread.getName()).append(endThreadName); - final String promptNewline = StringUtils.repeatChar(followingLineFillChar, message.length()); - message.append(startLevelTag).append(log.level.tag()).append(endLevelTag) - .append(messageSeparator).append(log.message.message[0]); - for (int i = 1; i < log.message.message.length; i++) { - message.append('\n').append(promptNewline) - .append(startLevelTag).append(log.level.tag()).append(endLevelTag) - .append(messageSeparator).append(log.message.message[i]); + + final String formattedTime = startTimestamp + this.formatTimestamp(log) + endTimestamp; + final String formattedThread = startThreadName + log.thread().getName() + endThreadName; + final String formattedCodePoint = startCodePoint + this.formatCodepoint(log) + endCodePoint; + final String formattedLevel = startLevelTag + log.level().tag() + endLevelTag; + + final String formattedPromptOnlyNewline = formattedTime + formattedCodePoint + formattedThread; + final String formattedPrompt = formattedPromptOnlyNewline + formattedLevel; + final String formattedPromptFollowing = StringUtils.repeatChar(followingLineFillChar, formattedPromptOnlyNewline.length()) + formattedLevel; + + message.append(formattedPrompt) + .append(messageSeparator).append(log.message().getLines()[0]); + for (int i = 1; i < log.message().getLines().length; i++) { + message.append('\n').append(formattedPromptFollowing) + .append(messageSeparator).append(log.message().getLines()[i]); } + return message.toString(); + + } + + @Nonnull + protected String formatTimestamp (@Nonnull Log log) { + return String.valueOf(log.timestamp()); + } + + @Nonnull + protected String formatCodepoint (@Nonnull Log log) { + return log.stackTrace()[0].getClassName() + "#" + log.stackTrace()[0].getMethodName(); } } diff --git a/src/main/java/cc/sukazyo/messiva/log/ILogLevelImpl.java b/src/main/java/cc/sukazyo/messiva/log/ILogLevelImpl.java index b07f5e4..2d35369 100644 --- a/src/main/java/cc/sukazyo/messiva/log/ILogLevelImpl.java +++ b/src/main/java/cc/sukazyo/messiva/log/ILogLevelImpl.java @@ -1,5 +1,7 @@ package cc.sukazyo.messiva.log; +import cc.sukazyo.messiva.log.message.IMessage; + import javax.annotation.Nonnull; public interface ILogLevelImpl { @@ -18,18 +20,18 @@ public interface ILogLevelImpl { void fatal (@Nonnull String message); - void trace (@Nonnull Message message); + void trace (@Nonnull IMessage message); - void debug (@Nonnull Message message); + void debug (@Nonnull IMessage message); - void info (@Nonnull Message message); + void info (@Nonnull IMessage message); - void warn (@Nonnull Message message); + void warn (@Nonnull IMessage message); - void warning (@Nonnull Message message); + void warning (@Nonnull IMessage message); - void error (@Nonnull Message message); + void error (@Nonnull IMessage message); - void fatal (@Nonnull Message message); + void fatal (@Nonnull IMessage message); } diff --git a/src/main/java/cc/sukazyo/messiva/log/Log.java b/src/main/java/cc/sukazyo/messiva/log/Log.java index 2420c5d..66ab6a1 100644 --- a/src/main/java/cc/sukazyo/messiva/log/Log.java +++ b/src/main/java/cc/sukazyo/messiva/log/Log.java @@ -3,16 +3,82 @@ package cc.sukazyo.messiva.log; import javax.annotation.Nonnegative; import javax.annotation.Nonnull; -import cc.sukazyo.messiva.utils.StackUtils; +import cc.sukazyo.messiva.log.message.IMessage; +import cc.sukazyo.std.contexts.GivenContext; +import cc.sukazyo.std.stacks.StacksExtensions; +import cc.sukazyo.std.stacks.WithCurrentStack; + +import java.util.Arrays; +import java.util.function.Consumer; public class Log { - @Nonnull public final Message message; - @Nonnull public final ILogLevel level; - public final long timestamp; - @Nonnull public final Thread thread; - @Nonnull public final StackTraceElement[] stackTrace; + public static class Initializing {} + + public static class StackOffset { + public int value = 0; + } + + /** @deprecated Will be private. Use method with the same name instead. */ + @Deprecated @Nonnull public final IMessage message; + /** @deprecated Will be private. Use method with the same name instead. */ + @Deprecated @Nonnull public final ILogLevel level; + /** @deprecated Will be private. Use method with the same name instead. */ + @Deprecated public final long timestamp; + /** @deprecated Will be private. Use method with the same name instead. */ + @Deprecated @Nonnull public final Thread thread; + /** @deprecated Will be private. Use method with the same name instead. */ + @Deprecated @Nonnull public final StackTraceElement[] stackTrace; + @Nonnull private final GivenContext context = GivenContext.apply(); + { context.ownedBy(Initializing.class).provide(StackOffset.class, new StackOffset()); } + + @Nonnull public IMessage message () { return this.message; } + @Nonnull public ILogLevel level () { return this.level; } + @Nonnegative public long timestamp () { return this.timestamp; } + @Nonnull public Thread thread () { return this.thread; } + @Nonnull public StackTraceElement[] stackTrace () { + return Arrays.copyOfRange( + this.stackTrace, + this.context.ownedBy(Initializing.class).getUnsafe(StackOffset.class).value, + this.stackTrace.length + ); + } + @Nonnull public GivenContext context () { return this.context; } + + private Log ( + @Nonnull IMessage message, @Nonnull ILogLevel level, + @Nonnull Thread thread, long timestamp, @Nonnull StackTraceElement[] stackTrace + ) { + this.message = message; + this.level = level; + this.thread = thread; + this.timestamp = timestamp; + this.stackTrace = stackTrace; + } + + public Log ( + @Nonnull IMessage message, @Nonnull ILogLevel level, + @Nonnull Thread thread, long timestamp + ) { + this( + message, level, thread, timestamp, + StacksExtensions.dropWhileClass(Log.class, WithCurrentStack.getStackTrace(0)) + ); + } + + public Log (@Nonnull IMessage message, @Nonnull ILogLevel level, @Nonnull Thread thread) { + this(message, level, thread, System.currentTimeMillis()); + } + + public Log (@Nonnull IMessage message, @Nonnull ILogLevel level) { + this(message, level, Thread.currentThread()); + } + + /// #block old_constructors + /// for old Message + + @Deprecated public Log (@Nonnull Message message, @Nonnull ILogLevel level, @Nonnull Thread thread,long timestamp, @Nonnull StackTraceElement[] stackTrace) { this.message = message; @@ -22,35 +88,47 @@ public class Log { this.stackTrace = stackTrace; } + @Deprecated public Log (@Nonnegative int stackOffset, @Nonnull Message message, @Nonnull ILogLevel level, @Nonnull Thread thread, long timestamp) { - this(message, level, thread, timestamp, StackUtils.getStackTrace(stackOffset+1)); + this(message, level, thread, timestamp, WithCurrentStack.getStackTrace(stackOffset+2)); } + @Deprecated public Log (@Nonnull Message message, @Nonnull ILogLevel level, @Nonnull Thread thread, long timestamp) { this(1, message, level, thread, timestamp); } + @Deprecated public Log (@Nonnegative int stackOffset, @Nonnull Message message, @Nonnull ILogLevel level, @Nonnull Thread thread) { this(stackOffset+1, message, level, thread, System.currentTimeMillis()); } + @Deprecated public Log (@Nonnull Message message, @Nonnull ILogLevel level, @Nonnull Thread thread) { this(1, message, level, thread); } - public Log (@Nonnegative int stackOffset, - @Nonnull Message message, @Nonnull ILogLevel level) { - this(stackOffset+1, message, level, Thread.currentThread()); + @Deprecated + public Log( @Nonnegative int stackOffset, @Nonnull Message message, @Nonnull ILogLevel level){ + this(stackOffset + 1, message, level, Thread.currentThread()); } + @Deprecated public Log (@Nonnull Message message, @Nonnull ILogLevel level) { this(1, message, level); } + /// #endblock old_constructors + + public Log withContext (@Nonnull Consumer consumer) { + consumer.accept(this.context()); + return this; + } + } diff --git a/src/main/java/cc/sukazyo/messiva/log/Message.java b/src/main/java/cc/sukazyo/messiva/log/Message.java index 50dd88b..4c0f9a6 100644 --- a/src/main/java/cc/sukazyo/messiva/log/Message.java +++ b/src/main/java/cc/sukazyo/messiva/log/Message.java @@ -1,15 +1,26 @@ package cc.sukazyo.messiva.log; +import cc.sukazyo.messiva.log.message.TextMessage; + import javax.annotation.Nonnull; import javax.annotation.Nullable; -public class Message { +/** + * @deprecated API changed. Use {@link cc.sukazyo.messiva.log.message.IMessage} or {@link TextMessage} + * instead. + */ +@Deprecated +public class Message extends TextMessage { + /** + * Due to API changes, this field is no longer used and will always be empty. + */ @Nonnull - public final String[] message; + @Deprecated + public final String[] message = new String[]{}; public Message(@Nullable String message) { - this.message = message == null ? new String[]{} : message.split("\n"); + super(message); } } diff --git a/src/main/java/cc/sukazyo/messiva/log/message/IMessage.java b/src/main/java/cc/sukazyo/messiva/log/message/IMessage.java new file mode 100644 index 0000000..e255aba --- /dev/null +++ b/src/main/java/cc/sukazyo/messiva/log/message/IMessage.java @@ -0,0 +1,15 @@ +package cc.sukazyo.messiva.log.message; + +import java.util.Arrays; + +public interface IMessage { + + default String getText () { + return Arrays.stream(getLines()) + .reduce((a, b) -> a + "\n" + b) + .orElse(""); + } + + String[] getLines (); + +} diff --git a/src/main/java/cc/sukazyo/messiva/log/message/TextMessage.java b/src/main/java/cc/sukazyo/messiva/log/message/TextMessage.java new file mode 100644 index 0000000..ea0ac43 --- /dev/null +++ b/src/main/java/cc/sukazyo/messiva/log/message/TextMessage.java @@ -0,0 +1,23 @@ +package cc.sukazyo.messiva.log.message; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class TextMessage implements IMessage { + + @Nonnull String[] message; + + public TextMessage (@Nullable String message) { + this.message = message != null ? message.split("\\n") : new String[]{}; + } + + public TextMessage (@Nonnull String[] messageLines) { + this.message = messageLines; + } + + @Override + public String[] getLines () { + return message; + } + +} diff --git a/src/main/java/cc/sukazyo/messiva/logger/Logger.java b/src/main/java/cc/sukazyo/messiva/logger/Logger.java index a613106..9badf00 100644 --- a/src/main/java/cc/sukazyo/messiva/logger/Logger.java +++ b/src/main/java/cc/sukazyo/messiva/logger/Logger.java @@ -1,28 +1,49 @@ package cc.sukazyo.messiva.logger; +import cc.sukazyo.messiva.appender.AppenderProvider; import cc.sukazyo.messiva.component.LevelRestrictComponent; import cc.sukazyo.messiva.appender.IAppender; import cc.sukazyo.messiva.log.*; +import cc.sukazyo.messiva.log.message.IMessage; +import cc.sukazyo.messiva.log.message.TextMessage; +import cc.sukazyo.std.contexts.GivenContext; +import cc.sukazyo.std.stacks.WithCurrentStack; +import scala.reflect.ClassTag; import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; public class Logger implements ILogLevelImpl { - @Nonnull public final List appends; + /** + * @deprecated API changes. use {@link #appenderProviders} instead. This field will always + * be empty. + */ + @Deprecated + @Nonnull public final List appends = Collections.emptyList(); + + @Nonnull public final String name; + @Nonnull public final List appenderProviders; @Nonnull public LevelRestrictComponent levelSetting; public Logger () { levelSetting = new LevelRestrictComponent(); - appends = new ArrayList<>(); + appenderProviders = new ArrayList<>(); + this.name = WithCurrentStack.getStackTrace(1)[0].getClass().getSimpleName(); } public Logger (@Nonnull IAppender... appends) { this(); - this.appends.addAll(Arrays.asList(appends)); + this.appenderProviders.addAll( + Arrays.stream(appends) + .map(IAppender::asProvider) + .collect(Collectors.toList()) + ); } @Nonnull @@ -38,74 +59,87 @@ public class Logger implements ILogLevelImpl { } public void trace (@Nonnull String message) { - pushToAllAppender(new Log(1, new Message(message), LogLevels.TRACE)); + pushToAllAppender(createNewLog(new TextMessage(message), LogLevels.TRACE)); } public void debug (@Nonnull String message) { - pushToAllAppender(new Log(1, new Message(message), LogLevels.DEBUG)); + pushToAllAppender(createNewLog(new TextMessage(message), LogLevels.DEBUG)); } public void info (@Nonnull String message) { - pushToAllAppender(new Log(1, new Message(message), LogLevels.INFO)); + pushToAllAppender(createNewLog(new TextMessage(message), LogLevels.INFO)); } public void warn (@Nonnull String message) { - pushToAllAppender(new Log(1, new Message(message), LogLevels.WARN)); + pushToAllAppender(createNewLog(new TextMessage(message), LogLevels.WARN)); } public void warning (@Nonnull String message) { - pushToAllAppender(new Log(1, new Message(message), LogLevels.WARN)); + pushToAllAppender(createNewLog(new TextMessage(message), LogLevels.WARN)); } public void error (@Nonnull String message) { - pushToAllAppender(new Log(1, new Message(message), LogLevels.ERROR)); + pushToAllAppender(createNewLog(new TextMessage(message), LogLevels.ERROR)); } public void fatal (@Nonnull String message) { - pushToAllAppender(new Log(1, new Message(message), LogLevels.FATAL)); + pushToAllAppender(createNewLog(new TextMessage(message), LogLevels.FATAL)); } - public void trace (@Nonnull Message message) { - pushToAllAppender(new Log(1, message, LogLevels.TRACE)); + public void trace (@Nonnull IMessage message) { + pushToAllAppender(createNewLog(message, LogLevels.TRACE)); } - public void debug (@Nonnull Message message) { - pushToAllAppender(new Log(1, message, LogLevels.DEBUG)); + public void debug (@Nonnull IMessage message) { + pushToAllAppender(createNewLog(message, LogLevels.DEBUG)); } - public void info (@Nonnull Message message) { - pushToAllAppender(new Log(1, message, LogLevels.INFO)); + public void info (@Nonnull IMessage message) { + pushToAllAppender(createNewLog(message, LogLevels.INFO)); } - public void warn (@Nonnull Message message) { - pushToAllAppender(new Log(1, message, LogLevels.WARN)); + public void warn (@Nonnull IMessage message) { + pushToAllAppender(createNewLog(message, LogLevels.WARN)); } - public void warning (@Nonnull Message message) { - pushToAllAppender(new Log(1, message, LogLevels.WARN)); + public void warning (@Nonnull IMessage message) { + pushToAllAppender(createNewLog(message, LogLevels.WARN)); } - public void error (@Nonnull Message message) { - pushToAllAppender(new Log(1, message, LogLevels.ERROR)); + public void error (@Nonnull IMessage message) { + pushToAllAppender(createNewLog(message, LogLevels.ERROR)); } - public void fatal (@Nonnull Message message) { - pushToAllAppender(new Log(1, message, LogLevels.FATAL)); + public void fatal (@Nonnull IMessage message) { + pushToAllAppender(createNewLog(message, LogLevels.FATAL)); } public void log (@Nonnull String message, @Nonnull ILogLevel level) { - pushToAllAppender(new Log(1, new Message(message), level)); + pushToAllAppender(createNewLog(new TextMessage(message), level)); } - public void log (@Nonnull Message message, @Nonnull ILogLevel level) { - pushToAllAppender(new Log(1, message, level)); + public void log (@Nonnull IMessage message, @Nonnull ILogLevel level) { + pushToAllAppender(createNewLog(message, level)); + } + + protected Log createNewLog (@Nonnull IMessage message, ILogLevel level) { + return new Log(message, level) + .withContext(cxt -> cxt.ownedBy(Log.Initializing.class).getUnsafe(Log.StackOffset.class).value+=2); } protected void pushToAllAppender (@Nonnull Log log) { - if (!levelSetting.checkLevel(log.level)) return; - for (IAppender appender : appends) { - appender.pushLog(log); - } + if (!levelSetting.checkLevel(log.level())) return; + this.findAppends(log) + .forEach(appender -> appender.pushLog(log)); + } + + protected List findAppends (@Nonnull Log log) { + final GivenContext context = GivenContext.apply(); + context.provide(this, ClassTag.apply(AppenderProvider.class)); + context.provide(log, ClassTag.apply(Log.class)); + return this.appenderProviders.stream() + .flatMap(provider -> provider.findAppends(context).stream()) + .collect(Collectors.toList()); } } diff --git a/src/main/java/cc/sukazyo/messiva/utils/StackUtils.java b/src/main/java/cc/sukazyo/messiva/utils/StackUtils.java deleted file mode 100644 index 3bf5976..0000000 --- a/src/main/java/cc/sukazyo/messiva/utils/StackUtils.java +++ /dev/null @@ -1,14 +0,0 @@ -package cc.sukazyo.messiva.utils; - -import java.util.Arrays; - -public class StackUtils { - - public static StackTraceElement[] getStackTrace (int offset) { - offset += 2; - StackTraceElement[] origins = Thread.currentThread().getStackTrace(); - origins = Arrays.copyOfRange(origins, offset, origins.length); - return origins; - } - -}