| | |
| | | |
| | | import lombok.Data; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.slf4j.helpers.FormattingTuple; |
| | | import org.slf4j.helpers.MessageFormatter; |
| | | |
| | |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.Optional; |
| | | |
| | | /** |
| | | * news stories for vincent |
| | |
| | | private static final int DEFAULT_CAPACITY = 1024; |
| | | private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
| | | private static final NewsQueue<NewsDomain> NEWS_QUEUE = new NewsQueue<>(DEFAULT_CAPACITY); |
| | | private static final String NEWS_FQCN = News.class.getName(); |
| | | private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); |
| | | private static final ConcurrentHashMap<Class<?>, Logger> LOGGER_CACHE = new ConcurrentHashMap<>(); |
| | | |
| | | public static void main(String[] args) { |
| | | News.info("info{}", 1); |
| | |
| | | } |
| | | |
| | | public static void info(String format, Object... arguments) { |
| | | log.info(format, arguments); |
| | | offer(NewsLevel.INFO, format, arguments); |
| | | logWithCaller(NewsLevel.INFO, format, arguments); |
| | | } |
| | | |
| | | public static void warn(String format, Object... arguments) { |
| | | log.warn(format, arguments); |
| | | offer(NewsLevel.WARN, format, arguments); |
| | | logWithCaller(NewsLevel.WARN, format, arguments); |
| | | } |
| | | |
| | | public static void error(String format, Object... arguments) { |
| | | log.error(format, arguments); |
| | | offer(NewsLevel.ERROR, format, arguments); |
| | | logWithCaller(NewsLevel.ERROR, format, arguments); |
| | | } |
| | | |
| | | public static String printStr() { |
| | |
| | | LocalDateTime.now().format(DATE_FORMATTER))); |
| | | } |
| | | |
| | | private static void logWithCaller(NewsLevel level, String format, Object... arguments) { |
| | | Logger targetLogger = resolveCallerLogger(); |
| | | switch (level) { |
| | | case ERROR -> targetLogger.error(format, arguments); |
| | | case WARN -> targetLogger.warn(format, arguments); |
| | | default -> targetLogger.info(format, arguments); |
| | | } |
| | | offer(level, format, arguments); |
| | | } |
| | | |
| | | private static Logger resolveCallerLogger() { |
| | | Optional<Class<?>> callerClassOptional = STACK_WALKER |
| | | .walk(stream -> stream.dropWhile(frame -> frame.getClassName().equals(NEWS_FQCN)) |
| | | .findFirst() |
| | | .map(StackWalker.StackFrame::getDeclaringClass)); |
| | | Class<?> callerClass = callerClassOptional.orElse(News.class); |
| | | return LOGGER_CACHE.computeIfAbsent(callerClass, LoggerFactory::getLogger); |
| | | } |
| | | |
| | | private static String escapeJson(String value) { |
| | | if (value == null) { |
| | | return ""; |