Enhance logger adapter to use a configured logger (#10952)
This commit is contained in:
parent
10082d3fa1
commit
247eeb39a5
|
|
@ -40,10 +40,12 @@
|
|||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class FastJson2Impl extends AbstractJSONImpl {
|
|||
try {
|
||||
Class<?> aClass = ClassUtils.forName("com.alibaba.fastjson2.JSON");
|
||||
return aClass != null;
|
||||
} catch (Throwable t) {
|
||||
} catch (Exception t) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,4 +70,14 @@ public interface LoggerAdapter {
|
|||
* @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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,25 +41,25 @@ public class LoggerFactory {
|
|||
|
||||
private static final ConcurrentMap<String, FailsafeLogger> LOGGERS = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<String, FailsafeErrorTypeAwareLogger> ERROR_TYPE_AWARE_LOGGERS = new ConcurrentHashMap<>();
|
||||
private static volatile LoggerAdapter LOGGER_ADAPTER;
|
||||
private static volatile LoggerAdapter loggerAdapter;
|
||||
|
||||
// search common-used logging frameworks
|
||||
static {
|
||||
String logger = System.getProperty("dubbo.application.logger", "");
|
||||
switch (logger) {
|
||||
case "slf4j":
|
||||
case Slf4jLoggerAdapter.NAME:
|
||||
setLoggerAdapter(new Slf4jLoggerAdapter());
|
||||
break;
|
||||
case "jcl":
|
||||
case JclLoggerAdapter.NAME:
|
||||
setLoggerAdapter(new JclLoggerAdapter());
|
||||
break;
|
||||
case "log4j":
|
||||
case Log4jLoggerAdapter.NAME:
|
||||
setLoggerAdapter(new Log4jLoggerAdapter());
|
||||
break;
|
||||
case "jdk":
|
||||
case JdkLoggerAdapter.NAME:
|
||||
setLoggerAdapter(new JdkLoggerAdapter());
|
||||
break;
|
||||
case "log4j2":
|
||||
case Log4j2LoggerAdapter.NAME:
|
||||
setLoggerAdapter(new Log4j2LoggerAdapter());
|
||||
break;
|
||||
default:
|
||||
|
|
@ -70,15 +70,44 @@ public class LoggerFactory {
|
|||
JclLoggerAdapter.class,
|
||||
JdkLoggerAdapter.class
|
||||
);
|
||||
boolean found = false;
|
||||
// try to use the first available adapter
|
||||
for (Class<? extends LoggerAdapter> clazz : candidates) {
|
||||
try {
|
||||
LoggerAdapter loggerAdapter = clazz.newInstance();
|
||||
LoggerAdapter loggerAdapter = clazz.getConstructor().newInstance();
|
||||
loggerAdapter.getLogger(LoggerFactory.class);
|
||||
if (loggerAdapter.isConfigured()) {
|
||||
setLoggerAdapter(loggerAdapter);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
} catch (Exception | LinkageError ignored) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
|
||||
System.err.println("Dubbo: Unable to find a proper configured logger to log out.");
|
||||
for (Class<? extends LoggerAdapter> clazz : candidates) {
|
||||
try {
|
||||
LoggerAdapter loggerAdapter = clazz.getConstructor().newInstance();
|
||||
loggerAdapter.getLogger(LoggerFactory.class);
|
||||
setLoggerAdapter(loggerAdapter);
|
||||
found = true;
|
||||
break;
|
||||
} catch (Throwable ignored) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
System.err.println("Dubbo: Using default logger: " + loggerAdapter.getClass().getName() + ". " +
|
||||
"If you cannot see any log, please configure -Ddubbo.application.logger property to your preferred logging framework.");
|
||||
} else {
|
||||
System.err.println("Dubbo: Unable to find any available logger adapter to log out. Dubbo logs will be ignored. " +
|
||||
"Please configure -Ddubbo.application.logger property and add corresponding logging library to classpath.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -98,13 +127,13 @@ public class LoggerFactory {
|
|||
*/
|
||||
public static void setLoggerAdapter(LoggerAdapter loggerAdapter) {
|
||||
if (loggerAdapter != null) {
|
||||
if (loggerAdapter == LOGGER_ADAPTER) {
|
||||
if (loggerAdapter == LoggerFactory.loggerAdapter) {
|
||||
return;
|
||||
}
|
||||
loggerAdapter.getLogger(LoggerFactory.class.getName());
|
||||
LoggerFactory.LOGGER_ADAPTER = loggerAdapter;
|
||||
LoggerFactory.loggerAdapter = loggerAdapter;
|
||||
for (Map.Entry<String, FailsafeLogger> entry : LOGGERS.entrySet()) {
|
||||
entry.getValue().setLogger(LOGGER_ADAPTER.getLogger(entry.getKey()));
|
||||
entry.getValue().setLogger(LoggerFactory.loggerAdapter.getLogger(entry.getKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -116,7 +145,7 @@ public class LoggerFactory {
|
|||
* @return logger
|
||||
*/
|
||||
public static Logger getLogger(Class<?> key) {
|
||||
return LOGGERS.computeIfAbsent(key.getName(), name -> new FailsafeLogger(LOGGER_ADAPTER.getLogger(name)));
|
||||
return LOGGERS.computeIfAbsent(key.getName(), name -> new FailsafeLogger(loggerAdapter.getLogger(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -126,7 +155,7 @@ public class LoggerFactory {
|
|||
* @return logger provider
|
||||
*/
|
||||
public static Logger getLogger(String key) {
|
||||
return LOGGERS.computeIfAbsent(key, k -> new FailsafeLogger(LOGGER_ADAPTER.getLogger(k)));
|
||||
return LOGGERS.computeIfAbsent(key, k -> new FailsafeLogger(loggerAdapter.getLogger(k)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -136,7 +165,7 @@ public class LoggerFactory {
|
|||
* @return error type aware logger
|
||||
*/
|
||||
public static ErrorTypeAwareLogger getErrorTypeAwareLogger(Class<?> key) {
|
||||
return ERROR_TYPE_AWARE_LOGGERS.computeIfAbsent(key.getName(), name -> new FailsafeErrorTypeAwareLogger(LOGGER_ADAPTER.getLogger(name)));
|
||||
return ERROR_TYPE_AWARE_LOGGERS.computeIfAbsent(key.getName(), name -> new FailsafeErrorTypeAwareLogger(loggerAdapter.getLogger(name)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -146,7 +175,7 @@ public class LoggerFactory {
|
|||
* @return error type aware logger
|
||||
*/
|
||||
public static ErrorTypeAwareLogger getErrorTypeAwareLogger(String key) {
|
||||
return ERROR_TYPE_AWARE_LOGGERS.computeIfAbsent(key, k -> new FailsafeErrorTypeAwareLogger(LOGGER_ADAPTER.getLogger(k)));
|
||||
return ERROR_TYPE_AWARE_LOGGERS.computeIfAbsent(key, k -> new FailsafeErrorTypeAwareLogger(loggerAdapter.getLogger(k)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -155,7 +184,7 @@ public class LoggerFactory {
|
|||
* @return logging level
|
||||
*/
|
||||
public static Level getLevel() {
|
||||
return LOGGER_ADAPTER.getLevel();
|
||||
return loggerAdapter.getLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -164,7 +193,7 @@ public class LoggerFactory {
|
|||
* @param level logging level
|
||||
*/
|
||||
public static void setLevel(Level level) {
|
||||
LOGGER_ADAPTER.setLevel(level);
|
||||
loggerAdapter.setLevel(level);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -173,7 +202,7 @@ public class LoggerFactory {
|
|||
* @return current logging file
|
||||
*/
|
||||
public static File getFile() {
|
||||
return LOGGER_ADAPTER.getFile();
|
||||
return loggerAdapter.getFile();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -191,10 +220,11 @@ public class LoggerFactory {
|
|||
List<String> result = new LinkedList<>();
|
||||
for (Map.Entry<Class<? extends LoggerAdapter>, String> entry : candidates.entrySet()) {
|
||||
try {
|
||||
LoggerAdapter loggerAdapter = entry.getKey().newInstance();
|
||||
LoggerAdapter loggerAdapter = entry.getKey().getConstructor().newInstance();
|
||||
loggerAdapter.getLogger(LoggerFactory.class);
|
||||
result.add(entry.getValue());
|
||||
} catch (Throwable ignored) {
|
||||
} catch (Exception ignored) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
@ -213,9 +243,9 @@ public class LoggerFactory {
|
|||
candidates.put(JclLoggerAdapter.class, "jcl");
|
||||
candidates.put(JdkLoggerAdapter.class, "jdk");
|
||||
|
||||
String name = candidates.get(LOGGER_ADAPTER.getClass());
|
||||
String name = candidates.get(loggerAdapter.getClass());
|
||||
if (name == null) {
|
||||
name = LOGGER_ADAPTER.getClass().getSimpleName();
|
||||
name = loggerAdapter.getClass().getSimpleName();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
import java.io.File;
|
||||
|
||||
public class JclLoggerAdapter implements LoggerAdapter {
|
||||
|
||||
public static final String NAME = "jcl";
|
||||
private Level level;
|
||||
private File file;
|
||||
|
||||
|
|
|
|||
|
|
@ -29,19 +29,23 @@ 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 (Throwable t) {
|
||||
} catch (Exception t) {
|
||||
System.err.println("Failed to load logging.properties in classpath for jdk logging config, cause: " + t.getMessage());
|
||||
}
|
||||
try {
|
||||
|
|
@ -56,7 +60,8 @@ public class JdkLoggerAdapter implements LoggerAdapter {
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
} catch (Exception ignored) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -133,7 +138,11 @@ public class JdkLoggerAdapter implements LoggerAdapter {
|
|||
|
||||
@Override
|
||||
public void setFile(File file) {
|
||||
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfigured() {
|
||||
return propertiesLoaded;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import java.util.Enumeration;
|
|||
|
||||
public class Log4jLoggerAdapter implements LoggerAdapter {
|
||||
|
||||
public static final String NAME = "log4j";
|
||||
private File file;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
@ -49,7 +50,8 @@ public class Log4jLoggerAdapter implements LoggerAdapter {
|
|||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
} catch (Exception t) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +128,32 @@ public class Log4jLoggerAdapter implements LoggerAdapter {
|
|||
|
||||
@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<Appender> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,11 @@ import org.apache.logging.log4j.LogManager;
|
|||
import java.io.File;
|
||||
|
||||
public class Log4j2LoggerAdapter implements LoggerAdapter {
|
||||
public static final String NAME = "log4j2";
|
||||
|
||||
private Level level;
|
||||
|
||||
public Log4j2LoggerAdapter() {
|
||||
|
||||
}
|
||||
|
||||
private static org.apache.logging.log4j.Level toLog4j2Level(Level level) {
|
||||
|
|
@ -103,5 +103,11 @@ public class Log4j2LoggerAdapter implements LoggerAdapter {
|
|||
|
||||
@Override
|
||||
public void setFile(File file) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfigured() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,11 +19,12 @@ package org.apache.dubbo.common.logger.slf4j;
|
|||
import org.apache.dubbo.common.logger.Level;
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerAdapter;
|
||||
import org.apache.dubbo.common.utils.ClassUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Slf4jLoggerAdapter implements LoggerAdapter {
|
||||
|
||||
public static final String NAME = "slf4j";
|
||||
private Level level;
|
||||
private File file;
|
||||
|
||||
|
|
@ -57,4 +58,14 @@ public class Slf4jLoggerAdapter implements LoggerAdapter {
|
|||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfigured() {
|
||||
try {
|
||||
ClassUtils.forName("org.slf4j.impl.StaticLoggerBinder");
|
||||
return true;
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
// ignore
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,5 +39,15 @@
|
|||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
Loading…
Reference in New Issue