From ddf73fe633963bef91eaf5e8418028ddc6c0810c Mon Sep 17 00:00:00 2001 From: huhaosumail <995483610@qq.com> Date: Mon, 1 Jul 2024 16:57:34 +0800 Subject: [PATCH] =?UTF-8?q?log=20=E5=92=8C=20=E5=BC=82=E5=B8=B8=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cffu-core/pom.xml | 24 ++ .../cffu/CompletableFutureUtils.java | 41 ++- .../cffu/logger/ConfigReportException.java | 85 ++++++ .../java/io/foldright/cffu/logger/Level.java | 43 +++ .../java/io/foldright/cffu/logger/Logger.java | 170 ++++++++++++ .../foldright/cffu/logger/LoggerAdapter.java | 65 +++++ .../foldright/cffu/logger/jdk/JdkLogger.java | 116 ++++++++ .../cffu/logger/jdk/JdkLoggerAdapter.java | 137 +++++++++ .../cffu/logger/log4j/Log4jLogger.java | 123 ++++++++ .../cffu/logger/log4j/Log4jLoggerAdapter.java | 145 ++++++++++ .../cffu/logger/log4j2/Log4j2Logger.java | 114 ++++++++ .../logger/log4j2/Log4j2LoggerAdapter.java | 107 +++++++ .../cffu/logger/slf4j/Slf4jLogger.java | 159 +++++++++++ .../cffu/logger/slf4j/Slf4jLoggerAdapter.java | 66 +++++ .../cffu/logger/support/FailsafeLogger.java | 262 ++++++++++++++++++ pom.xml | 17 ++ 16 files changed, 1659 insertions(+), 15 deletions(-) create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/ConfigReportException.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/Level.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/Logger.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/LoggerAdapter.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/jdk/JdkLogger.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/jdk/JdkLoggerAdapter.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/log4j/Log4jLogger.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/log4j/Log4jLoggerAdapter.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/log4j2/Log4j2Logger.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/log4j2/Log4j2LoggerAdapter.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/slf4j/Slf4jLogger.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/slf4j/Slf4jLoggerAdapter.java create mode 100644 cffu-core/src/main/java/io/foldright/cffu/logger/support/FailsafeLogger.java diff --git a/cffu-core/pom.xml b/cffu-core/pom.xml index 3e670f7b..80cfc32f 100644 --- a/cffu-core/pom.xml +++ b/cffu-core/pom.xml @@ -64,6 +64,30 @@ commons-lang3 test + + + org.slf4j + slf4j-api + true + + + + log4j + log4j + true + + + + org.apache.logging.log4j + log4j-api + true + + + org.apache.logging.log4j + log4j-core + true + + diff --git a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java index 16d334a0..9b0a0064 100644 --- a/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java +++ b/cffu-core/src/main/java/io/foldright/cffu/CompletableFutureUtils.java @@ -1,6 +1,7 @@ package io.foldright.cffu; import edu.umd.cs.findbugs.annotations.Nullable; +import io.foldright.cffu.logger.ConfigReportException; import io.foldright.cffu.tuple.Tuple2; import io.foldright.cffu.tuple.Tuple3; import io.foldright.cffu.tuple.Tuple4; @@ -1564,12 +1565,33 @@ public static Executor defaultExecutor() { return AsyncPoolHolder.ASYNC_POOL; } + // endregion + + //////////////////////////////////////////////////////////// + // region## unwrapCfException(static methods) + //////////////////////////////////////////////////////////// + /** + * A convenient util method for converting input package {@link Throwable} to root {@link Throwable}. + * @param throwable + */ + public static Throwable unwrapCfException(Throwable throwable) { + if (throwable instanceof CompletionException || throwable instanceof ExecutionException) { + if (throwable.getCause() != null) { + return throwable.getCause(); + } + } + return throwable; + } + // endregion // endregion + //////////////////////////////////////////////////////////////////////////////// // region# CF Instance Methods(including new enhanced + backport methods) //////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////// // region## Then-Multi-Actions(thenM*) Methods //////////////////////////////////////////////////////////// @@ -2888,7 +2910,7 @@ else delayedExecutor(0, TimeUnit.SECONDS, asyncExecutor) // use `cf.handle` method(instead of `whenComplete`) and return null, // in order to prevent below `exceptionally` reporting the handled argument exception in this action return null; - }).exceptionally(ex -> reportException("Exception occurred in the input cf whenComplete of hop executor:", ex)); + }).exceptionally(ex -> ConfigReportException.reportException("Exception occurred in the input cf whenComplete of hop executor:", ex)); return (C) ret; } @@ -2899,23 +2921,12 @@ private static void completeCf(CompletableFuture cf, Object value, @Null else cf.completeExceptionally(ex); } catch (Throwable t) { if (ex != null) t.addSuppressed(ex); - reportException("Exception occurred in completeCf:", t); + ConfigReportException.reportException("Exception occurred in completeCf:", t); throw t; // rethrow exception, report to caller } } - @Nullable - @SuppressWarnings("SameReturnValue") - private static T reportException(String msg, Throwable ex) { - StringWriter sw = new StringWriter(4096); - PrintWriter writer = new PrintWriter(sw); - - writer.println(msg); - ex.printStackTrace(writer); - System.err.println(sw); - return null; - } // endregion //////////////////////////////////////////////////////////// @@ -3005,7 +3016,7 @@ C peek(C cf, BiConsumer action) { requireNonNull(cf, "cf is null"); requireNonNull(action, "action is null"); - cf.whenComplete(action).exceptionally(ex -> reportException("Exception occurred in the action of peek:", ex)); + cf.whenComplete(action).exceptionally(ex -> ConfigReportException.reportException("Exception occurred in the action of peek:", ex)); return cf; } @@ -3056,7 +3067,7 @@ C peekAsync(C cf, BiConsumer action, Executor exec requireNonNull(executor, "executor is null"); cf.whenCompleteAsync(action, executor).exceptionally(ex -> - reportException("Exception occurred in the action of peekAsync:", ex)); + ConfigReportException.reportException("Exception occurred in the action of peekAsync:", ex)); return cf; } diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/ConfigReportException.java b/cffu-core/src/main/java/io/foldright/cffu/logger/ConfigReportException.java new file mode 100644 index 00000000..1cf4aa23 --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/ConfigReportException.java @@ -0,0 +1,85 @@ +package io.foldright.cffu.logger; + +import edu.umd.cs.findbugs.annotations.Nullable; +import io.foldright.cffu.logger.jdk.JdkLoggerAdapter; +import io.foldright.cffu.logger.log4j.Log4jLoggerAdapter; +import io.foldright.cffu.logger.log4j2.Log4j2LoggerAdapter; +import io.foldright.cffu.logger.slf4j.Slf4jLoggerAdapter; + + +public class ConfigReportException { + + private static Logger logger; + + /** + * cffu.uncaught.exception.report=none | oneline | short(default) | full + * corresponding system print|error|warn|info + * @param msg + * @param ex + * @param + * @return + */ + @Nullable + @SuppressWarnings("SameReturnValue") + public static T reportException(String msg, Throwable ex) { + + String loggerLevel = System.getProperty("cffu.uncaught.exception.report.log.level", "none"); + switch (loggerLevel){ + case "warn": + logger.warn(msg, ex); + break; + case "info": + logger.info(msg, ex); + break; + case "error": + logger.error(msg, ex); + break; + case "none": + default: + //no handle + break; + } + return null; + } + + static { + String appLogger = System.getProperty("cffu.uncaught.exception.report.log.type", "none"); + LoggerAdapter loggerAdapter; + switch (appLogger){ + case "log4j": + loggerAdapter = new Log4jLoggerAdapter(); + break; + case "log4j2": + loggerAdapter = new Log4j2LoggerAdapter(); + break; + case "slf4j": + loggerAdapter = new Slf4jLoggerAdapter(); + break; + case "none": + default: + loggerAdapter = new JdkLoggerAdapter(); + break; + } + logger = loggerAdapter.getLogger(ConfigReportException.class.getName()); + + String loggerLevel = System.getProperty("cffu.uncaught.exception.report.log.level", "none"); + switch (loggerLevel){ + case "warn": + loggerAdapter.setLevel(Level.WARN); + break; + case "info": + loggerAdapter.setLevel(Level.INFO); + break; + case "error": + loggerAdapter.setLevel(Level.ERROR); + break; + case "none": + default: + loggerAdapter.setLevel(Level.OFF); + //no handle + break; + } + + } + +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/Level.java b/cffu-core/src/main/java/io/foldright/cffu/logger/Level.java new file mode 100644 index 00000000..46ce792f --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/Level.java @@ -0,0 +1,43 @@ + +package io.foldright.cffu.logger; + +/** + * Level + */ +public enum Level { + + /** + * ALL + */ + ALL, + + /** + * TRACE + */ + TRACE, + + /** + * DEBUG + */ + DEBUG, + + /** + * INFO + */ + INFO, + + /** + * WARN + */ + WARN, + + /** + * ERROR + */ + ERROR, + + /** + * OFF + */ + OFF +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/Logger.java b/cffu-core/src/main/java/io/foldright/cffu/logger/Logger.java new file mode 100644 index 00000000..9241eb22 --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/Logger.java @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.foldright.cffu.logger; + +/** + * Logger interface + *

+ * This interface is referred from commons-logging + */ +public interface Logger { + + /** + * Logs a message with trace log level. + * + * @param msg log this message + */ + void trace(String msg); + + /** + * Logs an error with trace log level. + * + * @param e log this cause + */ + void trace(Throwable e); + + /** + * Logs an error with trace log level. + * + * @param msg log this message + * @param e log this cause + */ + void trace(String msg, Throwable e); + + /** + * Logs a message with debug log level. + * + * @param msg log this message + */ + void debug(String msg); + + /** + * Logs an error with debug log level. + * + * @param e log this cause + */ + void debug(Throwable e); + + /** + * Logs an error with debug log level. + * + * @param msg log this message + * @param e log this cause + */ + void debug(String msg, Throwable e); + + /** + * Logs a message with info log level. + * + * @param msg log this message + */ + void info(String msg); + + /** + * Logs an error with info log level. + * + * @param e log this cause + */ + void info(Throwable e); + + /** + * Logs an error with info log level. + * + * @param msg log this message + * @param e log this cause + */ + void info(String msg, Throwable e); + + /** + * Logs a message with warn log level. + * + * @param msg log this message + */ + void warn(String msg); + + /** + * Logs a message with warn log level. + * + * @param e log this message + */ + void warn(Throwable e); + + /** + * Logs a message with warn log level. + * + * @param msg log this message + * @param e log this cause + */ + void warn(String msg, Throwable e); + + /** + * Logs a message with error log level. + * + * @param msg log this message + */ + void error(String msg); + + /** + * Logs an error with error log level. + * + * @param e log this cause + */ + void error(Throwable e); + + /** + * Logs an error with error log level. + * + * @param msg log this message + * @param e log this cause + */ + void error(String msg, Throwable e); + + /** + * Is trace logging currently enabled? + * + * @return true if trace is enabled + */ + boolean isTraceEnabled(); + + /** + * Is debug logging currently enabled? + * + * @return true if debug is enabled + */ + boolean isDebugEnabled(); + + /** + * Is info logging currently enabled? + * + * @return true if info is enabled + */ + boolean isInfoEnabled(); + + /** + * Is warn logging currently enabled? + * + * @return true if warn is enabled + */ + boolean isWarnEnabled(); + + /** + * Is error logging currently enabled? + * + * @return true if error is enabled + */ + boolean isErrorEnabled(); +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/LoggerAdapter.java b/cffu-core/src/main/java/io/foldright/cffu/logger/LoggerAdapter.java new file mode 100644 index 00000000..79bbed55 --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/LoggerAdapter.java @@ -0,0 +1,65 @@ +package io.foldright.cffu.logger; + + +import java.io.File; + + +/** + * Logger provider + */ +public interface LoggerAdapter { + + /** + * Get a logger + * + * @param key the returned logger will be named after clazz + * @return logger + */ + Logger getLogger(Class key); + + /** + * Get a logger + * + * @param key the returned logger will be named after key + * @return logger + */ + Logger getLogger(String key); + + /** + * Get the current logging level + * + * @return current logging level + */ + Level getLevel(); + + /** + * Set the current logging level + * + * @param level logging level + */ + void setLevel(Level level); + + /** + * Get the current logging file + * + * @return current logging file + */ + File getFile(); + + /** + * Set the current logging file + * + * @param file logging file + */ + void setFile(File file); + + /** + * Return is the current logger has been configured. + * Used to check if logger is available to use. + * + * @return true if the current logger has been configured + */ + default boolean isConfigured() { + return true; + } +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/jdk/JdkLogger.java b/cffu-core/src/main/java/io/foldright/cffu/logger/jdk/JdkLogger.java new file mode 100644 index 00000000..c89654be --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/jdk/JdkLogger.java @@ -0,0 +1,116 @@ + +package io.foldright.cffu.logger.jdk; + + +import io.foldright.cffu.logger.Logger; + +import java.util.logging.Level; + +public class JdkLogger implements Logger { + + private final java.util.logging.Logger logger; + + public JdkLogger(java.util.logging.Logger logger) { + this.logger = logger; + } + + @Override + public void trace(String msg) { + logger.log(Level.FINER, msg); + } + + @Override + public void trace(Throwable e) { + logger.log(Level.FINER, e.getMessage(), e); + } + + @Override + public void trace(String msg, Throwable e) { + logger.log(Level.FINER, msg, e); + } + + @Override + public void debug(String msg) { + logger.log(Level.FINE, msg); + } + + @Override + public void debug(Throwable e) { + logger.log(Level.FINE, e.getMessage(), e); + } + + @Override + public void debug(String msg, Throwable e) { + logger.log(Level.FINE, msg, e); + } + + @Override + public void info(String msg) { + logger.log(Level.INFO, msg); + } + + @Override + public void info(String msg, Throwable e) { + logger.log(Level.INFO, msg, e); + } + + @Override + public void warn(String msg) { + logger.log(Level.WARNING, msg); + } + + @Override + public void warn(String msg, Throwable e) { + logger.log(Level.WARNING, msg, e); + } + + @Override + public void error(String msg) { + logger.log(Level.SEVERE, msg); + } + + @Override + public void error(String msg, Throwable e) { + logger.log(Level.SEVERE, msg, e); + } + + @Override + public void error(Throwable e) { + logger.log(Level.SEVERE, e.getMessage(), e); + } + + @Override + public void info(Throwable e) { + logger.log(Level.INFO, e.getMessage(), e); + } + + @Override + public void warn(Throwable e) { + logger.log(Level.WARNING, e.getMessage(), e); + } + + @Override + public boolean isTraceEnabled() { + return logger.isLoggable(Level.FINER); + } + + @Override + public boolean isDebugEnabled() { + return logger.isLoggable(Level.FINE); + } + + @Override + public boolean isInfoEnabled() { + return logger.isLoggable(Level.INFO); + } + + @Override + public boolean isWarnEnabled() { + return logger.isLoggable(Level.WARNING); + } + + @Override + public boolean isErrorEnabled() { + return logger.isLoggable(Level.SEVERE); + } +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/jdk/JdkLoggerAdapter.java b/cffu-core/src/main/java/io/foldright/cffu/logger/jdk/JdkLoggerAdapter.java new file mode 100644 index 00000000..cbb4aa47 --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/jdk/JdkLoggerAdapter.java @@ -0,0 +1,137 @@ + +package io.foldright.cffu.logger.jdk; + + +import io.foldright.cffu.logger.Level; +import io.foldright.cffu.logger.Logger; +import io.foldright.cffu.logger.LoggerAdapter; + +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.util.logging.FileHandler; +import java.util.logging.Handler; +import java.util.logging.LogManager; + +public class JdkLoggerAdapter implements LoggerAdapter { + + public static final String NAME = "jdk"; + private static final String GLOBAL_LOGGER_NAME = "global"; + + private File file; + + private boolean propertiesLoaded = false; + + public JdkLoggerAdapter() { + try { + InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("logging.properties"); + if (in != null) { + LogManager.getLogManager().readConfiguration(in); + propertiesLoaded = true; + } else { + System.err.println("No such logging.properties in classpath for jdk logging config!"); + } + } catch (Exception t) { + System.err.println( + "Failed to load logging.properties in classpath for jdk logging config, cause: " + t.getMessage()); + } + try { + Handler[] handlers = + java.util.logging.Logger.getLogger(GLOBAL_LOGGER_NAME).getHandlers(); + for (Handler handler : handlers) { + if (handler instanceof FileHandler) { + FileHandler fileHandler = (FileHandler) handler; + Field field = fileHandler.getClass().getField("files"); + File[] files = (File[]) field.get(fileHandler); + if (files != null && files.length > 0) { + file = files[0]; + } + } + } + } catch (Exception ignored) { + // ignore + } + } + + private static java.util.logging.Level toJdkLevel(Level level) { + if (level == Level.ALL) { + return java.util.logging.Level.ALL; + } + if (level == Level.TRACE) { + return java.util.logging.Level.FINER; + } + if (level == Level.DEBUG) { + return java.util.logging.Level.FINE; + } + if (level == Level.INFO) { + return java.util.logging.Level.INFO; + } + if (level == Level.WARN) { + return java.util.logging.Level.WARNING; + } + if (level == Level.ERROR) { + return java.util.logging.Level.SEVERE; + } + // if (level == Level.OFF) + return java.util.logging.Level.OFF; + } + + private static Level fromJdkLevel(java.util.logging.Level level) { + if (level == java.util.logging.Level.ALL) { + return Level.ALL; + } + if (level == java.util.logging.Level.FINER) { + return Level.TRACE; + } + if (level == java.util.logging.Level.FINE) { + return Level.DEBUG; + } + if (level == java.util.logging.Level.INFO) { + return Level.INFO; + } + if (level == java.util.logging.Level.WARNING) { + return Level.WARN; + } + if (level == java.util.logging.Level.SEVERE) { + return Level.ERROR; + } + // if (level == java.util.logging.Level.OFF) + return Level.OFF; + } + + @Override + public Logger getLogger(Class key) { + return new JdkLogger(java.util.logging.Logger.getLogger(key == null ? "" : key.getName())); + } + + @Override + public Logger getLogger(String key) { + return new JdkLogger(java.util.logging.Logger.getLogger(key)); + } + + @Override + public Level getLevel() { + return fromJdkLevel( + java.util.logging.Logger.getLogger(GLOBAL_LOGGER_NAME).getLevel()); + } + + @Override + public void setLevel(Level level) { + java.util.logging.Logger.getLogger(GLOBAL_LOGGER_NAME).setLevel(toJdkLevel(level)); + } + + @Override + public File getFile() { + return file; + } + + @Override + public void setFile(File file) { + // ignore + } + + @Override + public boolean isConfigured() { + return propertiesLoaded; + } +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/log4j/Log4jLogger.java b/cffu-core/src/main/java/io/foldright/cffu/logger/log4j/Log4jLogger.java new file mode 100644 index 00000000..a8ce1b2e --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/log4j/Log4jLogger.java @@ -0,0 +1,123 @@ +package io.foldright.cffu.logger.log4j; + + +import io.foldright.cffu.logger.Logger; +import io.foldright.cffu.logger.support.FailsafeLogger; +import org.apache.log4j.Level; + + +public class Log4jLogger implements Logger { + + private static final String FQCN = FailsafeLogger.class.getName(); + + private final org.apache.log4j.Logger logger; + + public Log4jLogger(org.apache.log4j.Logger logger) { + this.logger = logger; + } + + @Override + public void trace(String msg) { + logger.log(FQCN, Level.TRACE, msg, null); + } + + @Override + public void trace(Throwable e) { + logger.log(FQCN, Level.TRACE, e == null ? null : e.getMessage(), e); + } + + @Override + public void trace(String msg, Throwable e) { + logger.log(FQCN, Level.TRACE, msg, e); + } + + @Override + public void debug(String msg) { + logger.log(FQCN, Level.DEBUG, msg, null); + } + + @Override + public void debug(Throwable e) { + logger.log(FQCN, Level.DEBUG, e == null ? null : e.getMessage(), e); + } + + @Override + public void debug(String msg, Throwable e) { + logger.log(FQCN, Level.DEBUG, msg, e); + } + + @Override + public void info(String msg) { + logger.log(FQCN, Level.INFO, msg, null); + } + + @Override + public void info(Throwable e) { + logger.log(FQCN, Level.INFO, e == null ? null : e.getMessage(), e); + } + + @Override + public void info(String msg, Throwable e) { + logger.log(FQCN, Level.INFO, msg, e); + } + + @Override + public void warn(String msg) { + logger.log(FQCN, Level.WARN, msg, null); + } + + @Override + public void warn(Throwable e) { + logger.log(FQCN, Level.WARN, e == null ? null : e.getMessage(), e); + } + + @Override + public void warn(String msg, Throwable e) { + logger.log(FQCN, Level.WARN, msg, e); + } + + @Override + public void error(String msg) { + logger.log(FQCN, Level.ERROR, msg, null); + } + + @Override + public void error(Throwable e) { + logger.log(FQCN, Level.ERROR, e == null ? null : e.getMessage(), e); + } + + @Override + public void error(String msg, Throwable e) { + logger.log(FQCN, Level.ERROR, msg, e); + } + + @Override + public boolean isTraceEnabled() { + return logger.isTraceEnabled(); + } + + @Override + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return logger.isInfoEnabled(); + } + + @Override + public boolean isWarnEnabled() { + return logger.isEnabledFor(Level.WARN); + } + + @Override + public boolean isErrorEnabled() { + return logger.isEnabledFor(Level.ERROR); + } + + // test purpose only + public org.apache.log4j.Logger getLogger() { + return logger; + } +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/log4j/Log4jLoggerAdapter.java b/cffu-core/src/main/java/io/foldright/cffu/logger/log4j/Log4jLoggerAdapter.java new file mode 100644 index 00000000..3e9e6449 --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/log4j/Log4jLoggerAdapter.java @@ -0,0 +1,145 @@ +package io.foldright.cffu.logger.log4j; + + + +import io.foldright.cffu.logger.Level; +import io.foldright.cffu.logger.Logger; +import io.foldright.cffu.logger.LoggerAdapter; +import org.apache.log4j.Appender; +import org.apache.log4j.FileAppender; +import org.apache.log4j.LogManager; + +import java.io.File; +import java.util.Enumeration; + + +public class Log4jLoggerAdapter implements LoggerAdapter { + + public static final String NAME = "log4j"; + private File file; + + @SuppressWarnings("unchecked") + public Log4jLoggerAdapter() { + try { + org.apache.log4j.Logger logger = LogManager.getRootLogger(); + if (logger != null) { + Enumeration appenders = logger.getAllAppenders(); + if (appenders != null) { + while (appenders.hasMoreElements()) { + Appender appender = appenders.nextElement(); + if (appender instanceof FileAppender) { + FileAppender fileAppender = (FileAppender) appender; + String filename = fileAppender.getFile(); + file = new File(filename); + break; + } + } + } + } + } catch (Exception t) { + // ignore + } + } + + private static org.apache.log4j.Level toLog4jLevel(Level level) { + if (level == Level.ALL) { + return org.apache.log4j.Level.ALL; + } + if (level == Level.TRACE) { + return org.apache.log4j.Level.TRACE; + } + if (level == Level.DEBUG) { + return org.apache.log4j.Level.DEBUG; + } + if (level == Level.INFO) { + return org.apache.log4j.Level.INFO; + } + if (level == Level.WARN) { + return org.apache.log4j.Level.WARN; + } + if (level == Level.ERROR) { + return org.apache.log4j.Level.ERROR; + } + // if (level == Level.OFF) + return org.apache.log4j.Level.OFF; + } + + private static Level fromLog4jLevel(org.apache.log4j.Level level) { + if (level == org.apache.log4j.Level.ALL) { + return Level.ALL; + } + if (level == org.apache.log4j.Level.TRACE) { + return Level.TRACE; + } + if (level == org.apache.log4j.Level.DEBUG) { + return Level.DEBUG; + } + if (level == org.apache.log4j.Level.INFO) { + return Level.INFO; + } + if (level == org.apache.log4j.Level.WARN) { + return Level.WARN; + } + if (level == org.apache.log4j.Level.ERROR) { + return Level.ERROR; + } + // if (level == org.apache.log4j.Level.OFF) + return Level.OFF; + } + + @Override + public Logger getLogger(Class key) { + return new Log4jLogger(LogManager.getLogger(key)); + } + + @Override + public Logger getLogger(String key) { + return new Log4jLogger(LogManager.getLogger(key)); + } + + @Override + public Level getLevel() { + return fromLog4jLevel(LogManager.getRootLogger().getLevel()); + } + + @Override + public void setLevel(Level level) { + LogManager.getRootLogger().setLevel(toLog4jLevel(level)); + } + + @Override + public File getFile() { + return file; + } + + @Override + public void setFile(File file) { + // ignore + } + + @Override + public boolean isConfigured() { + boolean hasAppender = false; + try { + org.apache.log4j.Logger logger = LogManager.getRootLogger(); + if (logger != null) { + Enumeration appenders = logger.getAllAppenders(); + if (appenders != null) { + while (appenders.hasMoreElements()) { + hasAppender = true; + Appender appender = appenders.nextElement(); + if (appender instanceof FileAppender) { + FileAppender fileAppender = (FileAppender) appender; + String filename = fileAppender.getFile(); + file = new File(filename); + break; + } + } + } + } + } catch (Exception t) { + // ignore + } + return hasAppender; + } +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/log4j2/Log4j2Logger.java b/cffu-core/src/main/java/io/foldright/cffu/logger/log4j2/Log4j2Logger.java new file mode 100644 index 00000000..666e2f3e --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/log4j2/Log4j2Logger.java @@ -0,0 +1,114 @@ +package io.foldright.cffu.logger.log4j2; + + +import io.foldright.cffu.logger.Logger; + + +public class Log4j2Logger implements Logger { + + private final org.apache.logging.log4j.Logger logger; + + public Log4j2Logger(org.apache.logging.log4j.Logger logger) { + this.logger = logger; + } + + @Override + public void trace(String msg) { + logger.trace(msg); + } + + @Override + public void trace(Throwable e) { + logger.trace(e == null ? null : e.getMessage(), e); + } + + @Override + public void trace(String msg, Throwable e) { + logger.trace(msg, e); + } + + @Override + public void debug(String msg) { + logger.debug(msg); + } + + @Override + public void debug(Throwable e) { + logger.debug(e == null ? null : e.getMessage(), e); + } + + @Override + public void debug(String msg, Throwable e) { + logger.debug(msg, e); + } + + @Override + public void info(String msg) { + logger.info(msg); + } + + @Override + public void info(Throwable e) { + logger.info(e == null ? null : e.getMessage(), e); + } + + @Override + public void info(String msg, Throwable e) { + logger.info(msg, e); + } + + @Override + public void warn(String msg) { + logger.warn(msg); + } + + @Override + public void warn(Throwable e) { + logger.warn(e == null ? null : e.getMessage(), e); + } + + @Override + public void warn(String msg, Throwable e) { + logger.warn(msg, e); + } + + @Override + public void error(String msg) { + logger.error(msg); + } + + @Override + public void error(Throwable e) { + logger.error(e == null ? null : e.getMessage(), e); + } + + @Override + public void error(String msg, Throwable e) { + logger.error(msg, e); + } + + @Override + public boolean isTraceEnabled() { + return logger.isTraceEnabled(); + } + + @Override + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return logger.isInfoEnabled(); + } + + @Override + public boolean isWarnEnabled() { + return logger.isWarnEnabled(); + } + + @Override + public boolean isErrorEnabled() { + return logger.isErrorEnabled(); + } +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/log4j2/Log4j2LoggerAdapter.java b/cffu-core/src/main/java/io/foldright/cffu/logger/log4j2/Log4j2LoggerAdapter.java new file mode 100644 index 00000000..750e8929 --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/log4j2/Log4j2LoggerAdapter.java @@ -0,0 +1,107 @@ +package io.foldright.cffu.logger.log4j2; + + + +import io.foldright.cffu.logger.Level; +import io.foldright.cffu.logger.Logger; +import io.foldright.cffu.logger.LoggerAdapter; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.config.Configurator; + +import java.io.File; + + +public class Log4j2LoggerAdapter implements LoggerAdapter { + public static final String NAME = "log4j2"; + + private Level level; + + public Log4j2LoggerAdapter() { + try { + org.apache.logging.log4j.Logger logger = LogManager.getRootLogger(); + this.level = fromLog4j2Level(logger.getLevel()); + } catch (Exception t) { + // ignore + } + } + + private static org.apache.logging.log4j.Level toLog4j2Level(Level level) { + if (level == Level.ALL) { + return org.apache.logging.log4j.Level.ALL; + } + if (level == Level.TRACE) { + return org.apache.logging.log4j.Level.TRACE; + } + if (level == Level.DEBUG) { + return org.apache.logging.log4j.Level.DEBUG; + } + if (level == Level.INFO) { + return org.apache.logging.log4j.Level.INFO; + } + if (level == Level.WARN) { + return org.apache.logging.log4j.Level.WARN; + } + if (level == Level.ERROR) { + return org.apache.logging.log4j.Level.ERROR; + } + return org.apache.logging.log4j.Level.OFF; + } + + private static Level fromLog4j2Level(org.apache.logging.log4j.Level level) { + if (level == org.apache.logging.log4j.Level.ALL) { + return Level.ALL; + } + if (level == org.apache.logging.log4j.Level.TRACE) { + return Level.TRACE; + } + if (level == org.apache.logging.log4j.Level.DEBUG) { + return Level.DEBUG; + } + if (level == org.apache.logging.log4j.Level.INFO) { + return Level.INFO; + } + if (level == org.apache.logging.log4j.Level.WARN) { + return Level.WARN; + } + if (level == org.apache.logging.log4j.Level.ERROR) { + return Level.ERROR; + } + return Level.OFF; + } + + @Override + public Logger getLogger(Class key) { + return new Log4j2Logger(LogManager.getLogger(key)); + } + + @Override + public Logger getLogger(String key) { + return new Log4j2Logger(LogManager.getLogger(key)); + } + + @Override + public Level getLevel() { + return level; + } + + @Override + public void setLevel(Level level) { + this.level = level; + Configurator.setLevel(LogManager.getRootLogger(), toLog4j2Level(level)); + } + + @Override + public File getFile() { + return null; + } + + @Override + public void setFile(File file) { + // ignore + } + + @Override + public boolean isConfigured() { + return true; + } +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/slf4j/Slf4jLogger.java b/cffu-core/src/main/java/io/foldright/cffu/logger/slf4j/Slf4jLogger.java new file mode 100644 index 00000000..3af04af4 --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/slf4j/Slf4jLogger.java @@ -0,0 +1,159 @@ +package io.foldright.cffu.logger.slf4j; + + +import io.foldright.cffu.logger.Level; +import io.foldright.cffu.logger.Logger; + +public class Slf4jLogger implements Logger { + + private final org.slf4j.Logger logger; + + + + public Slf4jLogger(org.slf4j.Logger logger) { +// if (logger instanceof LocationAwareLogger) { +// locationAwareLogger = (LocationAwareLogger) logger; +// } else { +// locationAwareLogger = null; +// } + this.logger = logger; + } + + @Override + public void trace(String msg) { + + logger.trace(msg); + } + + @Override + public void trace(Throwable e) { + + logger.trace(e.getMessage(), e); + } + + @Override + public void trace(String msg, Throwable e) { + + logger.trace(msg, e); + } + + @Override + public void debug(String msg) { + + logger.debug(msg); + } + + @Override + public void debug(Throwable e) { + + logger.debug(e.getMessage(), e); + } + + @Override + public void debug(String msg, Throwable e) { + + logger.debug(msg, e); + } + + @Override + public void info(String msg) { + + logger.info(msg); + } + + @Override + public void info(Throwable e) { + + logger.info(e.getMessage(), e); + } + + @Override + public void info(String msg, Throwable e) { + + logger.info(msg, e); + } + + @Override + public void warn(String msg) { + + logger.warn(msg); + } + + @Override + public void warn(Throwable e) { + + logger.warn(e.getMessage(), e); + } + + @Override + public void warn(String msg, Throwable e) { + + logger.warn(msg, e); + } + + @Override + public void error(String msg) { + + logger.error(msg); + } + + @Override + public void error(Throwable e) { + + logger.error(e.getMessage(), e); + } + + @Override + public void error(String msg, Throwable e) { + + logger.error(msg, e); + } + + @Override + public boolean isTraceEnabled() { + return logger.isTraceEnabled(); + } + + @Override + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + @Override + public boolean isInfoEnabled() { + return logger.isInfoEnabled(); + } + + @Override + public boolean isWarnEnabled() { + return logger.isWarnEnabled(); + } + + @Override + public boolean isErrorEnabled() { + return logger.isErrorEnabled(); + } + + public static Level getLevel(org.slf4j.Logger logger) { + if (logger.isTraceEnabled()) { + return Level.TRACE; + } + if (logger.isDebugEnabled()) { + return Level.DEBUG; + } + if (logger.isInfoEnabled()) { + return Level.INFO; + } + if (logger.isWarnEnabled()) { + return Level.WARN; + } + if (logger.isErrorEnabled()) { + return Level.ERROR; + } + return Level.OFF; + } + + public Level getLevel() { + return getLevel(logger); + } +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/slf4j/Slf4jLoggerAdapter.java b/cffu-core/src/main/java/io/foldright/cffu/logger/slf4j/Slf4jLoggerAdapter.java new file mode 100644 index 00000000..e017b0a1 --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/slf4j/Slf4jLoggerAdapter.java @@ -0,0 +1,66 @@ +package io.foldright.cffu.logger.slf4j; + + +import io.foldright.cffu.logger.Level; +import io.foldright.cffu.logger.Logger; +import io.foldright.cffu.logger.LoggerAdapter; +import org.slf4j.LoggerFactory; + +import java.io.File; + +public class Slf4jLoggerAdapter implements LoggerAdapter { + public static final String NAME = "slf4j"; + + private Level level; + private File file; + + private static final org.slf4j.Logger ROOT_LOGGER = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + + public Slf4jLoggerAdapter() { + this.level = Slf4jLogger.getLevel(ROOT_LOGGER); + } + + @Override + public Logger getLogger(String key) { + return new Slf4jLogger(LoggerFactory.getLogger(key)); + } + + @Override + public Logger getLogger(Class key) { + return new Slf4jLogger(LoggerFactory.getLogger(key)); + } + + @Override + public Level getLevel() { + return level; + } + + @Override + public void setLevel(Level level) { + System.err.printf( + "The level of slf4j logger current can not be set, using the default level: %s \n", + Slf4jLogger.getLevel(ROOT_LOGGER)); + this.level = level; + } + + @Override + public File getFile() { + return file; + } + + @Override + public void setFile(File file) { + this.file = file; + } + + @Override + public boolean isConfigured() { + try { + Class.forName("org.slf4j.impl.StaticLoggerBinder"); + return true; + } catch (ClassNotFoundException ignore) { + // ignore + } + return false; + } +} diff --git a/cffu-core/src/main/java/io/foldright/cffu/logger/support/FailsafeLogger.java b/cffu-core/src/main/java/io/foldright/cffu/logger/support/FailsafeLogger.java new file mode 100644 index 00000000..ea68ce31 --- /dev/null +++ b/cffu-core/src/main/java/io/foldright/cffu/logger/support/FailsafeLogger.java @@ -0,0 +1,262 @@ +package io.foldright.cffu.logger.support; + + +import io.foldright.cffu.logger.Logger; + + + +public class FailsafeLogger implements Logger { + + private Logger logger; + + private static boolean disabled = false; + + public FailsafeLogger(Logger logger) { + this.logger = logger; + } + + public static void setDisabled(boolean disabled) { + FailsafeLogger.disabled = disabled; + } + + static boolean getDisabled() { + return disabled; + } + + public Logger getLogger() { + return logger; + } + + public void setLogger(Logger logger) { + this.logger = logger; + } + + private String appendContextMessage(String msg) { + return " [cffu] " + msg ; + } + + @Override + public void trace(String msg, Throwable e) { + if (disabled) { + return; + } + try { + logger.trace(appendContextMessage(msg), e); + } catch (Throwable t) { + } + } + + @Override + public void trace(Throwable e) { + if (disabled) { + return; + } + try { + logger.trace(e); + } catch (Throwable t) { + } + } + + @Override + public void trace(String msg) { + if (disabled) { + return; + } + try { + logger.trace(appendContextMessage(msg)); + } catch (Throwable t) { + } + } + + @Override + public void debug(String msg, Throwable e) { + if (disabled) { + return; + } + try { + logger.debug(appendContextMessage(msg), e); + } catch (Throwable t) { + } + } + + @Override + public void debug(Throwable e) { + if (disabled) { + return; + } + try { + logger.debug(e); + } catch (Throwable t) { + } + } + + @Override + public void debug(String msg) { + if (disabled) { + return; + } + try { + logger.debug(appendContextMessage(msg)); + } catch (Throwable t) { + } + } + + @Override + public void info(String msg, Throwable e) { + if (disabled) { + return; + } + try { + logger.info(appendContextMessage(msg), e); + } catch (Throwable t) { + } + } + + @Override + public void info(String msg) { + if (disabled) { + return; + } + try { + logger.info(appendContextMessage(msg)); + } catch (Throwable t) { + } + } + + @Override + public void warn(String msg, Throwable e) { + if (disabled) { + return; + } + try { + logger.warn(appendContextMessage(msg), e); + } catch (Throwable t) { + } + } + + @Override + public void warn(String msg) { + if (disabled) { + return; + } + try { + logger.warn(appendContextMessage(msg)); + } catch (Throwable t) { + } + } + + @Override + public void error(String msg, Throwable e) { + if (disabled) { + return; + } + try { + logger.error(appendContextMessage(msg), e); + } catch (Throwable t) { + } + } + + @Override + public void error(String msg) { + if (disabled) { + return; + } + try { + logger.error(appendContextMessage(msg)); + } catch (Throwable t) { + } + } + + @Override + public void error(Throwable e) { + if (disabled) { + return; + } + try { + logger.error(e); + } catch (Throwable t) { + } + } + + @Override + public void info(Throwable e) { + if (disabled) { + return; + } + try { + logger.info(e); + } catch (Throwable t) { + } + } + + @Override + public void warn(Throwable e) { + if (disabled) { + return; + } + try { + logger.warn(e); + } catch (Throwable t) { + } + } + + @Override + public boolean isTraceEnabled() { + if (disabled) { + return false; + } + try { + return logger.isTraceEnabled(); + } catch (Throwable t) { + return false; + } + } + + @Override + public boolean isDebugEnabled() { + if (disabled) { + return false; + } + try { + return logger.isDebugEnabled(); + } catch (Throwable t) { + return false; + } + } + + @Override + public boolean isInfoEnabled() { + if (disabled) { + return false; + } + try { + return logger.isInfoEnabled(); + } catch (Throwable t) { + return false; + } + } + + @Override + public boolean isWarnEnabled() { + if (disabled) { + return false; + } + try { + return logger.isWarnEnabled(); + } catch (Throwable t) { + return false; + } + } + + @Override + public boolean isErrorEnabled() { + if (disabled) { + return false; + } + try { + return logger.isErrorEnabled(); + } catch (Throwable t) { + return false; + } + } +} diff --git a/pom.xml b/pom.xml index 538a0013..edf91483 100644 --- a/pom.xml +++ b/pom.xml @@ -80,6 +80,8 @@ 1.6 2.0.13 + 1.2.17 + 2.23.1 5.10.3 @@ -209,6 +211,21 @@ slf4j-api ${slf4j.version} + + log4j + log4j + ${log4j.version} + + + org.apache.logging.log4j + log4j-api + ${log4j2_version} + + + org.apache.logging.log4j + log4j-core + ${log4j2_version} + org.slf4j slf4j-simple