Signed-off-by: Eric Zhao <sczyh16@gmail.com>master
@@ -24,8 +24,8 @@ import java.util.Properties; | |||||
import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||
/** | /** | ||||
* The universal local config center of Sentinel. The config is retrieved from command line arguments | |||||
* and {@code ${user.home}/logs/csp/${appName}.properties} file by default. | |||||
* The universal local configuration center of Sentinel. The config is retrieved from command line arguments | |||||
* and customized properties file by default. | |||||
* | * | ||||
* @author leyou | * @author leyou | ||||
* @author Eric Zhao | * @author Eric Zhao | ||||
@@ -49,7 +49,6 @@ public class SentinelConfig { | |||||
public static final String COLD_FACTOR = "csp.sentinel.flow.cold.factor"; | public static final String COLD_FACTOR = "csp.sentinel.flow.cold.factor"; | ||||
public static final String STATISTIC_MAX_RT = "csp.sentinel.statistic.max.rt"; | public static final String STATISTIC_MAX_RT = "csp.sentinel.statistic.max.rt"; | ||||
static final String DEFAULT_CHARSET = "UTF-8"; | static final String DEFAULT_CHARSET = "UTF-8"; | ||||
static final long DEFAULT_SINGLE_METRIC_FILE_SIZE = 1024 * 1024 * 50; | static final long DEFAULT_SINGLE_METRIC_FILE_SIZE = 1024 * 1024 * 50; | ||||
static final int DEFAULT_TOTAL_METRIC_FILE_COUNT = 6; | static final int DEFAULT_TOTAL_METRIC_FILE_COUNT = 6; | ||||
@@ -98,7 +97,6 @@ public class SentinelConfig { | |||||
for (Object key : properties.keySet()) { | for (Object key : properties.keySet()) { | ||||
setConfig((String) key, (String) properties.get(key)); | setConfig((String) key, (String) properties.get(key)); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
@@ -28,22 +28,19 @@ import java.util.concurrent.CopyOnWriteArraySet; | |||||
import static com.alibaba.csp.sentinel.util.ConfigUtil.addSeparator; | import static com.alibaba.csp.sentinel.util.ConfigUtil.addSeparator; | ||||
/** | /** | ||||
* <p> | |||||
* class responsible for loading the Sentinel Core configuration | |||||
* </p> | |||||
* <p>The loader that responsible for loading Sentinel common configurations.</p> | |||||
* | * | ||||
* @author lianglin | * @author lianglin | ||||
* @since 1.7.0 | * @since 1.7.0 | ||||
*/ | */ | ||||
public class SentinelConfigLoader { | |||||
public final class SentinelConfigLoader { | |||||
public static final String SENTINEL_CONFIG = "csp.sentinel.config.file"; | |||||
private static final String DIR_NAME = "logs" + File.separator + "csp"; | private static final String DIR_NAME = "logs" + File.separator + "csp"; | ||||
private static final String USER_HOME = "user.home"; | private static final String USER_HOME = "user.home"; | ||||
public static final String SENTINEL_CONFIG = "csp.sentinel.config.file"; | |||||
private static String DEFAULT_SENTINEL_CONFIG_FILE = "classpath:sentinel.properties"; | |||||
private static final String DEFAULT_SENTINEL_CONFIG_FILE = "classpath:sentinel.properties"; | |||||
private static Properties properties = new Properties(); | private static Properties properties = new Properties(); | ||||
@@ -51,9 +48,7 @@ public class SentinelConfigLoader { | |||||
load(); | load(); | ||||
} | } | ||||
private static void load() { | private static void load() { | ||||
String fileName = System.getProperty(SENTINEL_CONFIG); | String fileName = System.getProperty(SENTINEL_CONFIG); | ||||
if (StringUtil.isBlank(fileName)) { | if (StringUtil.isBlank(fileName)) { | ||||
fileName = DEFAULT_SENTINEL_CONFIG_FILE; | fileName = DEFAULT_SENTINEL_CONFIG_FILE; | ||||
@@ -61,7 +56,7 @@ public class SentinelConfigLoader { | |||||
Properties p = ConfigUtil.loadProperties(fileName); | Properties p = ConfigUtil.loadProperties(fileName); | ||||
//old version config file | |||||
// Compatible with legacy config file path. | |||||
if (p == null) { | if (p == null) { | ||||
String path = addSeparator(System.getProperty(USER_HOME)) + DIR_NAME + File.separator; | String path = addSeparator(System.getProperty(USER_HOME)) + DIR_NAME + File.separator; | ||||
fileName = path + AppNameUtil.getAppName() + ".properties"; | fileName = path + AppNameUtil.getAppName() + ".properties"; | ||||
@@ -72,6 +67,7 @@ public class SentinelConfigLoader { | |||||
} | } | ||||
if (p != null && !p.isEmpty()) { | if (p != null && !p.isEmpty()) { | ||||
RecordLog.info("[SentinelConfigLoader] Loading Sentinel config from " + fileName); | |||||
properties.putAll(p); | properties.putAll(p); | ||||
} | } | ||||
@@ -81,7 +77,8 @@ public class SentinelConfigLoader { | |||||
String oldConfigValue = properties.getProperty(configKey); | String oldConfigValue = properties.getProperty(configKey); | ||||
properties.put(configKey, newConfigValue); | properties.put(configKey, newConfigValue); | ||||
if (oldConfigValue != null) { | if (oldConfigValue != null) { | ||||
RecordLog.info("[SentinelConfig] JVM parameter overrides {0}: {1} -> {2}", configKey, oldConfigValue, newConfigValue); | |||||
RecordLog.info("[SentinelConfigLoader] JVM parameter overrides {0}: {1} -> {2}", | |||||
configKey, oldConfigValue, newConfigValue); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -27,39 +27,43 @@ import java.util.logging.Logger; | |||||
import static com.alibaba.csp.sentinel.util.ConfigUtil.addSeparator; | import static com.alibaba.csp.sentinel.util.ConfigUtil.addSeparator; | ||||
/** | /** | ||||
* Default log base dir is ${user.home}/logs/csp/, we can use {@link #LOG_DIR} System property to override it. | |||||
* Default log file name dose not contain pid, but if multi instances of the same app are running in the same | |||||
* machine, we may want to distinguish the log file by pid number, in this case, {@link #LOG_NAME_USE_PID} | |||||
* System property could be configured as "true" to turn on this switch. | |||||
* <p>The base class for logging.</p> | |||||
* | |||||
* <p> | |||||
* The default log base directory is {@code ${user.home}/logs/csp/}. We can use the {@link #LOG_DIR} | |||||
* property to override it. The default log file name dose not contain pid, but if multi-instances of the same service | |||||
* are running in the same machine, we may want to distinguish the log file by process ID number. | |||||
* In this case, {@link #LOG_NAME_USE_PID} property could be configured as "true" to turn on this switch. | |||||
* </p> | |||||
* | * | ||||
* @author leyou | * @author leyou | ||||
*/ | */ | ||||
public class LogBase { | public class LogBase { | ||||
private static final String DIR_NAME = "logs" + File.separator + "csp"; | |||||
public static final String LOG_DIR = "csp.sentinel.log.dir"; | public static final String LOG_DIR = "csp.sentinel.log.dir"; | ||||
public static final String LOG_NAME_USE_PID = "csp.sentinel.log.use.pid"; | public static final String LOG_NAME_USE_PID = "csp.sentinel.log.use.pid"; | ||||
public static final String LOG_OUTPUT_TYPE = "csp.sentinel.log.output.type"; | public static final String LOG_OUTPUT_TYPE = "csp.sentinel.log.output.type"; | ||||
public static final String LOG_CHARSET = "csp.sentinel.log.charset"; | public static final String LOG_CHARSET = "csp.sentinel.log.charset"; | ||||
public static final String USER_HOME = "user.home"; | |||||
/** | /** | ||||
* Output biz log(RecordLog,CommandCenterLog) to file | |||||
* Output biz log (e.g. RecordLog and CommandCenterLog) to file. | |||||
*/ | */ | ||||
public static final String LOG_OUTPUT_TYPE_FILE = "file"; | public static final String LOG_OUTPUT_TYPE_FILE = "file"; | ||||
/** | /** | ||||
* Output biz log(RecordLog,CommandCenterLog) to console | |||||
* Output biz log (e.g. RecordLog and CommandCenterLog) to console. | |||||
*/ | */ | ||||
public static final String LOG_OUTPUT_TYPE_CONSOLE = "console"; | public static final String LOG_OUTPUT_TYPE_CONSOLE = "console"; | ||||
public static final String LOG_CHARSET_UTF8 = "utf-8"; | public static final String LOG_CHARSET_UTF8 = "utf-8"; | ||||
private static final String DIR_NAME = "logs" + File.separator + "csp"; | |||||
private static final String USER_HOME = "user.home"; | |||||
private static boolean logNameUsePid; | private static boolean logNameUsePid; | ||||
private static String logOutputType; | private static String logOutputType; | ||||
private static String logBaseDir; | private static String logBaseDir; | ||||
private static String logCharSet; | private static String logCharSet; | ||||
static { | static { | ||||
try { | try { | ||||
initialize(); | initialize(); | ||||
@@ -78,15 +82,13 @@ public class LogBase { | |||||
} | } | ||||
private static void loadProperties() { | private static void loadProperties() { | ||||
Properties properties = LogConfigLoader.getProperties(); | Properties properties = LogConfigLoader.getProperties(); | ||||
logOutputType = properties.get(LOG_OUTPUT_TYPE) == null ? logOutputType : properties.getProperty(LOG_OUTPUT_TYPE); | logOutputType = properties.get(LOG_OUTPUT_TYPE) == null ? logOutputType : properties.getProperty(LOG_OUTPUT_TYPE); | ||||
if (!LOG_OUTPUT_TYPE_FILE.equalsIgnoreCase(logOutputType) && !LOG_OUTPUT_TYPE_CONSOLE.equalsIgnoreCase(logOutputType)) { | if (!LOG_OUTPUT_TYPE_FILE.equalsIgnoreCase(logOutputType) && !LOG_OUTPUT_TYPE_CONSOLE.equalsIgnoreCase(logOutputType)) { | ||||
logOutputType = LOG_OUTPUT_TYPE_FILE; | logOutputType = LOG_OUTPUT_TYPE_FILE; | ||||
} | } | ||||
System.out.println("INFO: log out type is: " + logOutputType); | |||||
System.out.println("INFO: log output type is: " + logOutputType); | |||||
logCharSet = properties.getProperty(LOG_CHARSET) == null ? logCharSet : properties.getProperty(LOG_CHARSET); | logCharSet = properties.getProperty(LOG_CHARSET) == null ? logCharSet : properties.getProperty(LOG_CHARSET); | ||||
System.out.println("INFO: log charset is: " + logCharSet); | System.out.println("INFO: log charset is: " + logCharSet); | ||||
@@ -106,48 +108,45 @@ public class LogBase { | |||||
String usePid = properties.getProperty(LOG_NAME_USE_PID); | String usePid = properties.getProperty(LOG_NAME_USE_PID); | ||||
logNameUsePid = "true".equalsIgnoreCase(usePid); | logNameUsePid = "true".equalsIgnoreCase(usePid); | ||||
System.out.println("INFO: log name use pid is: " + logNameUsePid); | System.out.println("INFO: log name use pid is: " + logNameUsePid); | ||||
} | } | ||||
/** | /** | ||||
* Whether log file name should contain pid. This switch is configured by {@link #LOG_NAME_USE_PID} System property. | |||||
* Whether log file name should contain pid. This switch is configured by {@link #LOG_NAME_USE_PID} system property. | |||||
* | * | ||||
* @return if log file name should contain pid, return true, otherwise return false. | |||||
* @return true if log file name should contain pid, return true, otherwise false | |||||
*/ | */ | ||||
public static boolean isLogNameUsePid() { | public static boolean isLogNameUsePid() { | ||||
return logNameUsePid; | return logNameUsePid; | ||||
} | } | ||||
/** | /** | ||||
* Get log file base directory path, the returned path is guaranteed end with {@link File#separator} | |||||
* Get the log file base directory path, which is guaranteed ended with {@link File#separator}. | |||||
* | * | ||||
* @return log file base directory path. | |||||
* @return log file base directory path | |||||
*/ | */ | ||||
public static String getLogBaseDir() { | public static String getLogBaseDir() { | ||||
return logBaseDir; | return logBaseDir; | ||||
} | } | ||||
/** | /** | ||||
* Get log file output type the default value is "file" | |||||
* Get the log file output type. | |||||
* | * | ||||
* @return | |||||
* @return log output type, "file" by default | |||||
*/ | */ | ||||
public static String getLogOutputType() { | public static String getLogOutputType() { | ||||
return logOutputType; | return logOutputType; | ||||
} | } | ||||
/** | /** | ||||
* Get log file charSet the default value is utf-8 | |||||
* Get the log file charset. | |||||
* | * | ||||
* @return | |||||
* @return the log file charset, "utf-8" by default | |||||
*/ | */ | ||||
public static String getLogCharset() { | public static String getLogCharset() { | ||||
return logCharSet; | return logCharSet; | ||||
} | } | ||||
protected static void log(Logger logger, Handler handler, Level level, String detail, Object... params) { | protected static void log(Logger logger, Handler handler, Level level, String detail, Object... params) { | ||||
if (detail == null) { | if (detail == null) { | ||||
return; | return; | ||||
@@ -209,5 +208,4 @@ public class LogBase { | |||||
return handler; | return handler; | ||||
} | } | ||||
} | } |
@@ -23,21 +23,17 @@ import java.util.Properties; | |||||
import java.util.concurrent.CopyOnWriteArraySet; | import java.util.concurrent.CopyOnWriteArraySet; | ||||
/** | /** | ||||
* <p> | |||||
* class responsible for loading the Log configuration. | |||||
* </p> | |||||
* <p>The loader that responsible for loading Sentinel log configurations.</p> | |||||
* | * | ||||
* @author lianglin | * @author lianglin | ||||
* @since 1.7.0 | * @since 1.7.0 | ||||
*/ | */ | ||||
public class LogConfigLoader { | public class LogConfigLoader { | ||||
public static final String LOG_CONFIG = "csp.sentinel.config.file"; | public static final String LOG_CONFIG = "csp.sentinel.config.file"; | ||||
private static final String DEFAULT_LOG_CONFIG_FILE = "classpath:sentinel.properties"; | private static final String DEFAULT_LOG_CONFIG_FILE = "classpath:sentinel.properties"; | ||||
private static final Properties properties = new Properties(); | private static final Properties properties = new Properties(); | ||||
static { | static { | ||||
@@ -45,7 +41,6 @@ public class LogConfigLoader { | |||||
} | } | ||||
private static void load() { | private static void load() { | ||||
String file = System.getProperty(LOG_CONFIG); | String file = System.getProperty(LOG_CONFIG); | ||||
if (StringUtil.isBlank(file)) { | if (StringUtil.isBlank(file)) { | ||||
file = DEFAULT_LOG_CONFIG_FILE; | file = DEFAULT_LOG_CONFIG_FILE; | ||||
@@ -60,19 +55,11 @@ public class LogConfigLoader { | |||||
for (Map.Entry<Object, Object> entry : copy) { | for (Map.Entry<Object, Object> entry : copy) { | ||||
String configKey = entry.getKey().toString(); | String configKey = entry.getKey().toString(); | ||||
String newConfigValue = entry.getValue().toString(); | String newConfigValue = entry.getValue().toString(); | ||||
String oldConfigValue = properties.getProperty(configKey); | |||||
properties.put(configKey, newConfigValue); | properties.put(configKey, newConfigValue); | ||||
if (oldConfigValue != null) { | |||||
System.out.println("[LogConfig] JVM parameter overrides: " + configKey + " " + oldConfigValue + " -> " + newConfigValue); | |||||
} | |||||
} | } | ||||
} | } | ||||
public static Properties getProperties() { | public static Properties getProperties() { | ||||
return properties; | return properties; | ||||
} | } | ||||
} | } |
@@ -26,7 +26,7 @@ import java.util.Properties; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
* util for loading config | |||||
* Util class for loading configuration from file or command arguments. | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author lianglin | * @author lianglin | ||||
@@ -34,14 +34,14 @@ import java.util.Properties; | |||||
*/ | */ | ||||
public final class ConfigUtil { | public final class ConfigUtil { | ||||
public static final String CLASSPATH_FILE_FLAG = "classpath:"; | public static final String CLASSPATH_FILE_FLAG = "classpath:"; | ||||
/** | /** | ||||
* Return null if the file not exist | |||||
* <p>Load the properties from provided file.</p> | |||||
* <p>Currently it supports reading from classpath file or local file.</p> | |||||
* | * | ||||
* @param fileName | |||||
* @return | |||||
* @param fileName valid file path | |||||
* @return the retrieved properties from the file; null if the file not exist | |||||
*/ | */ | ||||
public static Properties loadProperties(String fileName) { | public static Properties loadProperties(String fileName) { | ||||
if (StringUtil.isNotBlank(fileName)) { | if (StringUtil.isNotBlank(fileName)) { | ||||
@@ -66,12 +66,9 @@ public final class ConfigUtil { | |||||
return null; | return null; | ||||
} | } | ||||
FileInputStream input = new FileInputStream(file); | |||||
try { | |||||
try (FileInputStream input = new FileInputStream(file)) { | |||||
properties = new Properties(); | properties = new Properties(); | ||||
properties.load(input); | properties.load(input); | ||||
} finally { | |||||
input.close(); | |||||
} | } | ||||
} catch (Throwable e) { | } catch (Throwable e) { | ||||
e.printStackTrace(); | e.printStackTrace(); | ||||
@@ -81,13 +78,12 @@ public final class ConfigUtil { | |||||
private static Properties loadPropertiesFromClasspathFile(String fileName) { | private static Properties loadPropertiesFromClasspathFile(String fileName) { | ||||
fileName = fileName.substring(CLASSPATH_FILE_FLAG.length()).trim(); | fileName = fileName.substring(CLASSPATH_FILE_FLAG.length()).trim(); | ||||
List<URL> list = new ArrayList<URL>(); | |||||
List<URL> list = new ArrayList<>(); | |||||
try { | try { | ||||
Enumeration<URL> urls = getClassLoader().getResources(fileName); | Enumeration<URL> urls = getClassLoader().getResources(fileName); | ||||
list = new ArrayList<URL>(); | |||||
list = new ArrayList<>(); | |||||
while (urls.hasMoreElements()) { | while (urls.hasMoreElements()) { | ||||
list.add(urls.nextElement()); | list.add(urls.nextElement()); | ||||
} | } | ||||
@@ -143,5 +139,5 @@ public final class ConfigUtil { | |||||
return dir; | return dir; | ||||
} | } | ||||
private ConfigUtil() {} | |||||
} | } |