Support arbitrary configuration properties file path for Sentinel (#804)
- Support customized log and configuration properties directory
This commit is contained in:
parent
c14e3296cb
commit
ff33de199a
|
|
@ -15,17 +15,13 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.config;
|
||||
|
||||
import com.alibaba.csp.sentinel.log.LogBase;
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
import com.alibaba.csp.sentinel.util.AppNameUtil;
|
||||
import com.alibaba.csp.sentinel.util.AssertUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* The universal local config center of Sentinel. The config is retrieved from command line arguments
|
||||
|
|
@ -64,7 +60,6 @@ public class SentinelConfig {
|
|||
try {
|
||||
initialize();
|
||||
loadProps();
|
||||
|
||||
resolveAppType();
|
||||
RecordLog.info("[SentinelConfig] Application type resolved: " + appType);
|
||||
} catch (Throwable ex) {
|
||||
|
|
@ -91,49 +86,19 @@ public class SentinelConfig {
|
|||
|
||||
private static void initialize() {
|
||||
// Init default properties.
|
||||
SentinelConfig.setConfig(CHARSET, DEFAULT_CHARSET);
|
||||
SentinelConfig.setConfig(SINGLE_METRIC_FILE_SIZE, String.valueOf(DEFAULT_SINGLE_METRIC_FILE_SIZE));
|
||||
SentinelConfig.setConfig(TOTAL_METRIC_FILE_COUNT, String.valueOf(DEFAULT_TOTAL_METRIC_FILE_COUNT));
|
||||
SentinelConfig.setConfig(COLD_FACTOR, String.valueOf(DEFAULT_COLD_FACTOR));
|
||||
SentinelConfig.setConfig(STATISTIC_MAX_RT, String.valueOf(DEFAULT_STATISTIC_MAX_RT));
|
||||
setConfig(CHARSET, DEFAULT_CHARSET);
|
||||
setConfig(SINGLE_METRIC_FILE_SIZE, String.valueOf(DEFAULT_SINGLE_METRIC_FILE_SIZE));
|
||||
setConfig(TOTAL_METRIC_FILE_COUNT, String.valueOf(DEFAULT_TOTAL_METRIC_FILE_COUNT));
|
||||
setConfig(COLD_FACTOR, String.valueOf(DEFAULT_COLD_FACTOR));
|
||||
setConfig(STATISTIC_MAX_RT, String.valueOf(DEFAULT_STATISTIC_MAX_RT));
|
||||
}
|
||||
|
||||
private static void loadProps() {
|
||||
// Resolve app name.
|
||||
AppNameUtil.resolveAppName();
|
||||
try {
|
||||
String appName = AppNameUtil.getAppName();
|
||||
if (appName == null) {
|
||||
appName = "";
|
||||
}
|
||||
// We first retrieve the properties from the property file.
|
||||
String fileName = LogBase.getLogBaseDir() + appName + ".properties";
|
||||
File file = new File(fileName);
|
||||
if (file.exists()) {
|
||||
RecordLog.info("[SentinelConfig] Reading config from " + fileName);
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
Properties fileProps = new Properties();
|
||||
fileProps.load(fis);
|
||||
fis.close();
|
||||
|
||||
for (Object key : fileProps.keySet()) {
|
||||
SentinelConfig.setConfig((String)key, (String)fileProps.get(key));
|
||||
}
|
||||
}
|
||||
} catch (Throwable ioe) {
|
||||
RecordLog.info(ioe.getMessage(), ioe);
|
||||
Properties properties = SentinelConfigLoader.getProperties();
|
||||
for (Object key : properties.keySet()) {
|
||||
setConfig((String) key, (String) properties.get(key));
|
||||
}
|
||||
|
||||
// JVM parameter override file config.
|
||||
for (Map.Entry<Object, Object> entry : new CopyOnWriteArraySet<>(System.getProperties().entrySet())) {
|
||||
String configKey = entry.getKey().toString();
|
||||
String configValue = entry.getValue().toString();
|
||||
String configValueOld = getConfig(configKey);
|
||||
SentinelConfig.setConfig(configKey, configValue);
|
||||
if (configValueOld != null) {
|
||||
RecordLog.info("[SentinelConfig] JVM parameter overrides {0}: {1} -> {2}", configKey, configValueOld, configValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -190,7 +155,7 @@ public class SentinelConfig {
|
|||
return Long.parseLong(props.get(SINGLE_METRIC_FILE_SIZE));
|
||||
} catch (Throwable throwable) {
|
||||
RecordLog.warn("[SentinelConfig] Parse singleMetricFileSize fail, use default value: "
|
||||
+ DEFAULT_SINGLE_METRIC_FILE_SIZE, throwable);
|
||||
+ DEFAULT_SINGLE_METRIC_FILE_SIZE, throwable);
|
||||
return DEFAULT_SINGLE_METRIC_FILE_SIZE;
|
||||
}
|
||||
}
|
||||
|
|
@ -200,7 +165,7 @@ public class SentinelConfig {
|
|||
return Integer.parseInt(props.get(TOTAL_METRIC_FILE_COUNT));
|
||||
} catch (Throwable throwable) {
|
||||
RecordLog.warn("[SentinelConfig] Parse totalMetricFileCount fail, use default value: "
|
||||
+ DEFAULT_TOTAL_METRIC_FILE_COUNT, throwable);
|
||||
+ DEFAULT_TOTAL_METRIC_FILE_COUNT, throwable);
|
||||
return DEFAULT_TOTAL_METRIC_FILE_COUNT;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed 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 com.alibaba.csp.sentinel.config;
|
||||
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
import com.alibaba.csp.sentinel.util.AppNameUtil;
|
||||
import com.alibaba.csp.sentinel.util.ConfigUtil;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import static com.alibaba.csp.sentinel.util.ConfigUtil.addSeparator;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* class responsible for loading the Sentinel Core configuration
|
||||
* </p>
|
||||
*
|
||||
* @author lianglin
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public class SentinelConfigLoader {
|
||||
|
||||
|
||||
private static final String DIR_NAME = "logs" + File.separator + "csp";
|
||||
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 Properties properties = new Properties();
|
||||
|
||||
static {
|
||||
load();
|
||||
}
|
||||
|
||||
|
||||
private static void load() {
|
||||
|
||||
String fileName = System.getProperty(SENTINEL_CONFIG);
|
||||
if (StringUtil.isBlank(fileName)) {
|
||||
fileName = DEFAULT_SENTINEL_CONFIG_FILE;
|
||||
}
|
||||
|
||||
Properties p = ConfigUtil.loadProperties(fileName);
|
||||
|
||||
//old version config file
|
||||
if (p == null) {
|
||||
String path = addSeparator(System.getProperty(USER_HOME)) + DIR_NAME + File.separator;
|
||||
fileName = path + AppNameUtil.getAppName() + ".properties";
|
||||
File file = new File(fileName);
|
||||
if (file.exists()) {
|
||||
p = ConfigUtil.loadProperties(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
if (p != null && !p.isEmpty()) {
|
||||
properties.putAll(p);
|
||||
}
|
||||
|
||||
for (Map.Entry<Object, Object> entry : new CopyOnWriteArraySet<>(System.getProperties().entrySet())) {
|
||||
String configKey = entry.getKey().toString();
|
||||
String newConfigValue = entry.getValue().toString();
|
||||
String oldConfigValue = properties.getProperty(configKey);
|
||||
properties.put(configKey, newConfigValue);
|
||||
if (oldConfigValue != null) {
|
||||
RecordLog.info("[SentinelConfig] JVM parameter overrides {0}: {1} -> {2}", configKey, oldConfigValue, newConfigValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -15,14 +15,16 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.log;
|
||||
|
||||
import com.alibaba.csp.sentinel.util.PidUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.alibaba.csp.sentinel.util.PidUtil;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
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.
|
||||
|
|
@ -34,67 +36,81 @@ import com.alibaba.csp.sentinel.util.StringUtil;
|
|||
*/
|
||||
public class LogBase {
|
||||
|
||||
public static final String LOG_CHARSET = "utf-8";
|
||||
|
||||
// Output biz log(RecordLog,CommandCenterLog) to file
|
||||
public static final String LOG_OUTPUT_TYPE_FILE = "file";
|
||||
// Output biz log(RecordLog,CommandCenterLog) to console
|
||||
public static final String LOG_OUTPUT_TYPE_CONSOLE = "console";
|
||||
|
||||
private static final String DIR_NAME = "logs" + File.separator + "csp";
|
||||
private static final String USER_HOME = "user.home";
|
||||
|
||||
// Output type of biz log(RecordLog,CommandCenterLog)
|
||||
public static final String LOG_OUTPUT_TYPE = "csp.sentinel.log.output.type";
|
||||
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_OUTPUT_TYPE = "csp.sentinel.log.output.type";
|
||||
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
|
||||
*/
|
||||
public static final String LOG_OUTPUT_TYPE_FILE = "file";
|
||||
/**
|
||||
* Output biz log(RecordLog,CommandCenterLog) to console
|
||||
*/
|
||||
public static final String LOG_OUTPUT_TYPE_CONSOLE = "console";
|
||||
public static final String LOG_CHARSET_UTF8 = "utf-8";
|
||||
|
||||
private static boolean logNameUsePid;
|
||||
private static String logOutputType;
|
||||
private static String logBaseDir;
|
||||
private static boolean logNameUsePid = false;
|
||||
private static String logCharSet;
|
||||
|
||||
|
||||
static {
|
||||
try {
|
||||
init();
|
||||
initialize();
|
||||
loadProperties();
|
||||
} catch (Throwable t) {
|
||||
System.err.println("[LogBase] FATAL ERROR when initializing log class");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void init() {
|
||||
logOutputType = System.getProperty(LOG_OUTPUT_TYPE);
|
||||
private static void initialize() {
|
||||
logNameUsePid = false;
|
||||
logOutputType = LOG_OUTPUT_TYPE_FILE;
|
||||
logBaseDir = addSeparator(System.getProperty(USER_HOME)) + DIR_NAME + File.separator;
|
||||
logCharSet = LOG_CHARSET_UTF8;
|
||||
}
|
||||
|
||||
// By default, output biz log(RecordLog,CommandCenterLog) to file
|
||||
if (StringUtil.isBlank(logOutputType)) {
|
||||
logOutputType = LOG_OUTPUT_TYPE_FILE;
|
||||
} else if (!LOG_OUTPUT_TYPE_FILE.equalsIgnoreCase(logOutputType) && !LOG_OUTPUT_TYPE_CONSOLE.equalsIgnoreCase(logOutputType)) {
|
||||
private static void loadProperties() {
|
||||
|
||||
Properties properties = LogConfigLoader.getProperties();
|
||||
|
||||
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)) {
|
||||
logOutputType = LOG_OUTPUT_TYPE_FILE;
|
||||
}
|
||||
System.out.println("INFO: log out type is: " + logOutputType);
|
||||
|
||||
// first use -D, then use user home.
|
||||
String logDir = System.getProperty(LOG_DIR);
|
||||
|
||||
if (logDir == null || logDir.isEmpty()) {
|
||||
logDir = System.getProperty(USER_HOME);
|
||||
logDir = addSeparator(logDir) + DIR_NAME + File.separator;
|
||||
}
|
||||
logDir = addSeparator(logDir);
|
||||
File dir = new File(logDir);
|
||||
logCharSet = properties.getProperty(LOG_CHARSET) == null ? logCharSet : properties.getProperty(LOG_CHARSET);
|
||||
System.out.println("INFO: log charset is: " + logCharSet);
|
||||
|
||||
|
||||
logBaseDir = properties.getProperty(LOG_DIR) == null ? logBaseDir : properties.getProperty(LOG_DIR);
|
||||
addSeparator(logBaseDir);
|
||||
File dir = new File(logBaseDir);
|
||||
if (!dir.exists()) {
|
||||
if (!dir.mkdirs()) {
|
||||
System.err.println("ERROR: create log base dir error: " + logDir);
|
||||
System.err.println("ERROR: create log base dir error: " + logBaseDir);
|
||||
}
|
||||
}
|
||||
// logBaseDir must end with File.separator
|
||||
logBaseDir = logDir;
|
||||
System.out.println("INFO: log base dir is: " + logBaseDir);
|
||||
|
||||
String usePid = System.getProperty(LOG_NAME_USE_PID, "");
|
||||
|
||||
String usePid = properties.getProperty(LOG_NAME_USE_PID);
|
||||
logNameUsePid = "true".equalsIgnoreCase(usePid);
|
||||
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.
|
||||
*
|
||||
|
|
@ -104,13 +120,34 @@ public class LogBase {
|
|||
return logNameUsePid;
|
||||
}
|
||||
|
||||
private static String addSeparator(String logDir) {
|
||||
if (!logDir.endsWith(File.separator)) {
|
||||
logDir += File.separator;
|
||||
}
|
||||
return logDir;
|
||||
/**
|
||||
* Get log file base directory path, the returned path is guaranteed end with {@link File#separator}
|
||||
*
|
||||
* @return log file base directory path.
|
||||
*/
|
||||
public static String getLogBaseDir() {
|
||||
return logBaseDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log file output type the default value is "file"
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getLogOutputType() {
|
||||
return logOutputType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log file charSet the default value is utf-8
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getLogCharset() {
|
||||
return logCharSet;
|
||||
}
|
||||
|
||||
|
||||
protected static void log(Logger logger, Handler handler, Level level, String detail, Object... params) {
|
||||
if (detail == null) {
|
||||
return;
|
||||
|
|
@ -131,14 +168,6 @@ public class LogBase {
|
|||
logger.log(level, detail, throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log file base directory path, the returned path is guaranteed end with {@link File#separator}
|
||||
*
|
||||
* @return log file base directory path.
|
||||
*/
|
||||
public static String getLogBaseDir() {
|
||||
return logBaseDir;
|
||||
}
|
||||
|
||||
protected static Handler makeLogger(String logName, Logger heliumRecordLog) {
|
||||
CspFormatter formatter = new CspFormatter();
|
||||
|
|
@ -155,7 +184,7 @@ public class LogBase {
|
|||
try {
|
||||
handler = new DateFileLogHandler(fileName + ".%d", 1024 * 1024 * 200, 4, true);
|
||||
handler.setFormatter(formatter);
|
||||
handler.setEncoding(LOG_CHARSET);
|
||||
handler.setEncoding(logCharSet);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
@ -164,7 +193,7 @@ public class LogBase {
|
|||
try {
|
||||
handler = new ConsoleHandler();
|
||||
handler.setFormatter(formatter);
|
||||
handler.setEncoding(LOG_CHARSET);
|
||||
handler.setEncoding(logCharSet);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
@ -179,4 +208,6 @@ public class LogBase {
|
|||
heliumRecordLog.setLevel(Level.ALL);
|
||||
return handler;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed 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 com.alibaba.csp.sentinel.log;
|
||||
|
||||
import com.alibaba.csp.sentinel.util.ConfigUtil;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* class responsible for loading the Log configuration.
|
||||
* </p>
|
||||
*
|
||||
* @author lianglin
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public class LogConfigLoader {
|
||||
|
||||
|
||||
public static final String LOG_CONFIG = "csp.sentinel.config.file";
|
||||
|
||||
private static final String DEFAULT_LOG_CONFIG_FILE = "classpath:sentinel.properties";
|
||||
|
||||
|
||||
private static final Properties properties = new Properties();
|
||||
|
||||
static {
|
||||
load();
|
||||
}
|
||||
|
||||
private static void load() {
|
||||
|
||||
String file = System.getProperty(LOG_CONFIG);
|
||||
if (StringUtil.isBlank(file)) {
|
||||
file = DEFAULT_LOG_CONFIG_FILE;
|
||||
}
|
||||
|
||||
Properties p = ConfigUtil.loadProperties(file);
|
||||
if (p != null && !p.isEmpty()) {
|
||||
properties.putAll(p);
|
||||
}
|
||||
|
||||
CopyOnWriteArraySet<Map.Entry<Object, Object>> copy = new CopyOnWriteArraySet<>(System.getProperties().entrySet());
|
||||
for (Map.Entry<Object, Object> entry : copy) {
|
||||
String configKey = entry.getKey().toString();
|
||||
String newConfigValue = entry.getValue().toString();
|
||||
String oldConfigValue = properties.getProperty(configKey);
|
||||
properties.put(configKey, newConfigValue);
|
||||
if (oldConfigValue != null) {
|
||||
System.out.println("[LogConfig] JVM parameter overrides: " + configKey + " " + oldConfigValue + " -> " + newConfigValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -15,10 +15,10 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Util class for getting application name. This class uses the flowing order to get app's name:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed 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 com.alibaba.csp.sentinel.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* util for loading config
|
||||
* </p>
|
||||
*
|
||||
* @author lianglin
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public final class ConfigUtil {
|
||||
|
||||
|
||||
public static final String CLASSPATH_FILE_FLAG = "classpath:";
|
||||
|
||||
/**
|
||||
* Return null if the file not exist
|
||||
*
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public static Properties loadProperties(String fileName) {
|
||||
if (StringUtil.isNotBlank(fileName)) {
|
||||
if (fileName.startsWith(File.separator)) {
|
||||
return loadPropertiesFromAbsoluteFile(fileName);
|
||||
} else if (fileName.startsWith(CLASSPATH_FILE_FLAG)) {
|
||||
return loadPropertiesFromClasspathFile(fileName);
|
||||
} else {
|
||||
return loadPropertiesFromRelativeFile(fileName);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Properties loadPropertiesFromAbsoluteFile(String fileName) {
|
||||
Properties properties = null;
|
||||
try {
|
||||
|
||||
File file = new File(fileName);
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FileInputStream input = new FileInputStream(file);
|
||||
try {
|
||||
properties = new Properties();
|
||||
properties.load(input);
|
||||
} finally {
|
||||
input.close();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
private static Properties loadPropertiesFromClasspathFile(String fileName) {
|
||||
|
||||
fileName = fileName.substring(CLASSPATH_FILE_FLAG.length()).trim();
|
||||
|
||||
List<URL> list = new ArrayList<URL>();
|
||||
try {
|
||||
Enumeration<URL> urls = getClassLoader().getResources(fileName);
|
||||
list = new ArrayList<URL>();
|
||||
while (urls.hasMoreElements()) {
|
||||
list.add(urls.nextElement());
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Properties properties = new Properties();
|
||||
for (URL url : list) {
|
||||
try {
|
||||
Properties p = new Properties();
|
||||
InputStream input = url.openStream();
|
||||
if (input != null) {
|
||||
try {
|
||||
p.load(input);
|
||||
properties.putAll(p);
|
||||
} finally {
|
||||
try {
|
||||
input.close();
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static Properties loadPropertiesFromRelativeFile(String fileName) {
|
||||
String userDir = System.getProperty("user.dir");
|
||||
String realFilePath = addSeparator(userDir) + fileName;
|
||||
return loadPropertiesFromAbsoluteFile(realFilePath);
|
||||
}
|
||||
|
||||
private static ClassLoader getClassLoader() {
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (classLoader == null) {
|
||||
classLoader = ConfigUtil.class.getClassLoader();
|
||||
}
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
public static String addSeparator(String dir) {
|
||||
if (!dir.endsWith(File.separator)) {
|
||||
dir += File.separator;
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,15 @@
|
|||
package com.alibaba.csp.sentinel.config;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.alibaba.csp.sentinel.config.SentinelConfig.*;
|
||||
import static com.alibaba.csp.sentinel.util.ConfigUtil.addSeparator;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
|
|
@ -20,7 +28,7 @@ public class SentinelConfigTest {
|
|||
assertEquals(SentinelConfig.DEFAULT_STATISTIC_MAX_RT, SentinelConfig.statisticMaxRt());
|
||||
}
|
||||
|
||||
// add JVM parameter
|
||||
// add JVM parameter
|
||||
// -Dcsp.sentinel.charset=gbk
|
||||
// -Dcsp.sentinel.metric.file.single.size=104857600
|
||||
// -Dcsp.sentinel.metric.file.total.count=10
|
||||
|
|
@ -58,4 +66,51 @@ public class SentinelConfigTest {
|
|||
SentinelConfig.setConfig(SentinelConfig.COLD_FACTOR, "4");
|
||||
assertEquals(4, SentinelConfig.coldFactor());
|
||||
}
|
||||
|
||||
|
||||
//add Jvm parameter
|
||||
//-Dcsp.sentinel.config.file=sentinel-propertiesTest.properties
|
||||
//-Dcsp.sentinel.flow.cold.factor=5
|
||||
//-Dcsp.sentinel.statistic.max.rt=1000
|
||||
//@Test
|
||||
public void testLoadProperties() throws IOException {
|
||||
|
||||
File file = null;
|
||||
String fileName = "sentinel-propertiesTest.properties";
|
||||
try {
|
||||
file = new File(addSeparator(System.getProperty("user.dir")) + "target/classes/" + fileName);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(file));
|
||||
out.write(buildPropertyStr(CHARSET, "utf-8"));
|
||||
out.write("\n");
|
||||
out.write(buildPropertyStr(SINGLE_METRIC_FILE_SIZE, "1000"));
|
||||
out.write("\n");
|
||||
out.write(buildPropertyStr(TOTAL_METRIC_FILE_COUNT, "20"));
|
||||
out.write("\n");
|
||||
out.write(buildPropertyStr(COLD_FACTOR, "123"));
|
||||
out.write("\n");
|
||||
out.write(buildPropertyStr(STATISTIC_MAX_RT, "6000"));
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
Assert.assertTrue(SentinelConfig.getConfig(CHARSET).equals("utf-8"));
|
||||
Assert.assertTrue(SentinelConfig.getConfig(SINGLE_METRIC_FILE_SIZE).equals("1000"));
|
||||
Assert.assertTrue(SentinelConfig.getConfig(TOTAL_METRIC_FILE_COUNT).equals("20"));
|
||||
Assert.assertTrue(SentinelConfig.getConfig(COLD_FACTOR).equals("5"));
|
||||
Assert.assertTrue(SentinelConfig.getConfig(STATISTIC_MAX_RT).equals("1000"));
|
||||
|
||||
} finally {
|
||||
if (file != null) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private String buildPropertyStr(String key, String value) {
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed 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 com.alibaba.csp.sentinel.log;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.alibaba.csp.sentinel.log.LogBase.*;
|
||||
import static com.alibaba.csp.sentinel.util.ConfigUtil.addSeparator;
|
||||
|
||||
/**
|
||||
* @author lianglin
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public class LogBaseTest {
|
||||
|
||||
|
||||
|
||||
//add Jvm parameter
|
||||
//-Dcsp.sentinel.config.file=log-propertiesTest.properties
|
||||
//-Dcsp.sentinel.log.charset="utf-8"
|
||||
//-Dcsp.sentinel.log.output.type="file"
|
||||
//@Test
|
||||
public void testLoadProperties() throws IOException {
|
||||
|
||||
File file = null;
|
||||
String fileName = "log-propertiesTest.properties";
|
||||
try {
|
||||
file = new File(addSeparator(System.getProperty("user.dir")) + "target/classes/" + fileName);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(file));
|
||||
out.write(buildPropertyStr(LOG_DIR, "/data/logs/"));
|
||||
out.write("\n");
|
||||
out.write(buildPropertyStr(LOG_NAME_USE_PID, "true"));
|
||||
out.write("\n");
|
||||
out.write(buildPropertyStr(LOG_OUTPUT_TYPE, "console"));
|
||||
out.write("\n");
|
||||
out.write(buildPropertyStr(LOG_CHARSET, "gbk"));
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
//test will make dir
|
||||
//Assert.assertTrue(LogBase.getLogBaseDir().equals("/data/logs/"));
|
||||
Assert.assertTrue(LogBase.isLogNameUsePid());
|
||||
Assert.assertTrue(LogBase.getLogOutputType().equals("file"));
|
||||
Assert.assertTrue(LogBase.getLogCharset().equals("utf-8"));
|
||||
} finally {
|
||||
if (file != null) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private String buildPropertyStr(String key, String value) {
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed 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 com.alibaba.csp.sentinel.util;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import static com.alibaba.csp.sentinel.log.LogBase.LOG_DIR;
|
||||
import static com.alibaba.csp.sentinel.log.LogBase.LOG_OUTPUT_TYPE;
|
||||
import static com.alibaba.csp.sentinel.util.ConfigUtil.addSeparator;
|
||||
|
||||
/**
|
||||
* @author lianglin
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public class ConfigUtilTest {
|
||||
|
||||
@Test
|
||||
public void testLoadProperties() throws IOException {
|
||||
|
||||
File file = null;
|
||||
String logOutputType = "utf-8",
|
||||
dir = "/data/logs/",
|
||||
fileName = "propertiesTest.properties";
|
||||
try {
|
||||
String userDir = System.getProperty("user.dir");
|
||||
file = new File(addSeparator(userDir) + "target/classes/" + fileName);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
BufferedWriter out = new BufferedWriter(new FileWriter(file));
|
||||
out.write(LOG_OUTPUT_TYPE + "=" + logOutputType);
|
||||
out.write("\n");
|
||||
out.write(LOG_DIR + "=" + dir);
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
//Load from absolutePath
|
||||
Properties properties = ConfigUtil.loadProperties(file.getAbsolutePath());
|
||||
Assert.assertTrue(logOutputType.equals(properties.getProperty(LOG_OUTPUT_TYPE)));
|
||||
Assert.assertTrue(dir.equals(properties.getProperty(LOG_DIR)));
|
||||
|
||||
|
||||
//Load from classPath
|
||||
properties = ConfigUtil.loadProperties(ConfigUtil.CLASSPATH_FILE_FLAG + fileName);
|
||||
Assert.assertTrue(logOutputType.equals(properties.getProperty(LOG_OUTPUT_TYPE)));
|
||||
Assert.assertTrue(dir.equals(properties.getProperty(LOG_DIR)));
|
||||
|
||||
|
||||
//Load from relativePath
|
||||
properties = ConfigUtil.loadProperties("target/classes/" + fileName);
|
||||
Assert.assertTrue(logOutputType.equals(properties.getProperty(LOG_OUTPUT_TYPE)));
|
||||
Assert.assertTrue(dir.equals(properties.getProperty(LOG_DIR)));
|
||||
|
||||
} finally {
|
||||
if (file != null) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue