diff --git a/client/pom.xml b/client/pom.xml
index 26c0923..6de7c96 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -18,19 +18,17 @@
1.4-SNAPSHOT
-
+
+
-
-
-
+
javax.servlet
servlet-api
diff --git a/client/src/main/java/com/jd/platform/jlog/client/TracerClientStarter.java b/client/src/main/java/com/jd/platform/jlog/client/TracerClientStarter.java
index d252b50..1f72fb1 100644
--- a/client/src/main/java/com/jd/platform/jlog/client/TracerClientStarter.java
+++ b/client/src/main/java/com/jd/platform/jlog/client/TracerClientStarter.java
@@ -1,15 +1,13 @@
package com.jd.platform.jlog.client;
+import com.alibaba.fastjson.JSON;
import com.jd.platform.jlog.client.mdc.Mdc;
import com.jd.platform.jlog.client.task.Monitor;
-import com.jd.platform.jlog.client.udp.HttpSender;
-import com.jd.platform.jlog.client.udp.UdpClient;
-import com.jd.platform.jlog.client.udp.UdpSender;
import com.jd.platform.jlog.common.tag.TagConfig;
-import com.jd.platform.jlog.common.utils.FastJsonUtils;
import com.jd.platform.jlog.core.Configurator;
import com.jd.platform.jlog.core.ConfiguratorFactory;
+import com.jd.platform.jlog.core.TagHandlerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -82,45 +80,34 @@ public class TracerClientStarter {
* 启动监听
*/
public void startPipeline() {
- // 校验和设置
- checkAndSetTagConfig();
-
- // TagHandler.build(tagConfig);
+ // 初始化配置
+ initJLogConfig();
Context.MDC = mdc;
Monitor starter = new Monitor();
starter.start();
- UdpClient udpClient = new UdpClient();
+ /* UdpClient udpClient = new UdpClient();
udpClient.start();
//开启发送
UdpSender.uploadToWorker();
//开启大对象http发送
- HttpSender.uploadToWorker();
+ HttpSender.uploadToWorker();*/
}
/**
* 如果未赋值,从配置器获取,底层是Properties
*/
- private void checkAndSetTagConfig(){
+ private void initJLogConfig(){
+ LOGGER.info("从主配置获取的tagConfig:{}", JSON.toJSONString(tagConfig));
Configurator configurator = ConfiguratorFactory.getInstance();
- if(tagConfig != null){
- LOGGER.info("从主配置获取的tagConfig:{}", tagConfig.toString());
- configurator.addConfigListener("/application.yml");
- return;
- }
- String reqTag = configurator.getConfig("reqTags");
- String logTag = configurator.getConfig("logTags");
- String regex = configurator.getConfig("regex");
- String delimiter = configurator.getConfig("delimiter");
- String join = configurator.getConfig("join");
- tagConfig = TagConfig.Builder.aTagConfig().reqTags(FastJsonUtils.toList(reqTag, String.class))
- .logTags(FastJsonUtils.toList(logTag, String.class))
- .regex(regex).delimiter(delimiter).join(join).build();
- LOGGER.info("从配置器获取的tagConfig:{}", tagConfig.toString());
+ TagHandlerBuilder.buildTagHandler(tagConfig, configurator);
+ configurator.addConfigListener("/application.properties");
+ // configurator.addConfigListener("/application.yml");
+
}
}
diff --git a/clientdemo/src/main/resources/jLog.properties b/clientdemo/src/main/resources/jLog.properties
deleted file mode 100644
index 3dd4dd0..0000000
--- a/clientdemo/src/main/resources/jLog.properties
+++ /dev/null
@@ -1 +0,0 @@
-reqTags=["AAA","CCC"]
\ No newline at end of file
diff --git a/common/src/main/java/com/jd/platform/jlog/common/constant/Constant.java b/common/src/main/java/com/jd/platform/jlog/common/constant/Constant.java
index 8673867..1c069f4 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/constant/Constant.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/constant/Constant.java
@@ -34,6 +34,11 @@ public class Constant {
*/
public static int TAG_NORMAL_KEY_MAX_LEN = 20;
+ /**
+ * 可供提取的日志最小长度
+ */
+ public static int EXTRACT_MIN_LEN = 5;
+
/**
* 符合正则但不构成kv结构的普通日志,如「xx查询为空」
*/
diff --git a/common/src/main/java/com/jd/platform/jlog/common/tag/CollectMode.java b/common/src/main/java/com/jd/platform/jlog/common/tag/CollectMode.java
index 5e1646c..191ece5 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/tag/CollectMode.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/tag/CollectMode.java
@@ -10,6 +10,11 @@ package com.jd.platform.jlog.common.tag;
public class CollectMode {
+ /**
+ * 挂起 不提取不压缩
+ */
+ public static final long SUSPEND = 0L;
+
/**
* 提取req
*/
@@ -31,12 +36,12 @@ public class CollectMode {
public static final long C_LOG = 1L << 4;
/**
- * 提取log
+ * 提取resp
*/
public static final long E_RESP = 1L << 5;
/**
- * 压缩log
+ * 压缩resp
*/
public static final long C_RESP = 1L << 6;
@@ -44,30 +49,56 @@ public class CollectMode {
/** ======================================= 下面是组合 ======================================= */
- /**
- * 提取req,压缩req
- */
- public static final long E_REQ_C_REQ = E_REQ | C_REQ;
+
/**
- * 提取log,压缩log
+ * 提取req+log
*/
- public static final long E_LOG_C_LOG = E_LOG | C_LOG;
+ public static final long EXTRACT_REQ_LOG = E_REQ | E_LOG;
/**
- * 提取req+log,压缩req
+ * 提取req+resp
*/
- public static final long E_REQ_E_LOG_C_REQ = E_REQ | E_LOG | C_REQ;
+ public static final long EXTRACT_REQ_REQP = E_REQ | E_RESP;
/**
- * 提取req+log,压缩log
+ * 提取req+resp
*/
- public static final long E_REQ_E_LOG_C_LOG = E_REQ | E_LOG | C_LOG;
+ public static final long EXTRACT_REQ_RESP = E_REQ | E_RESP;
/**
- * 提取req+log,压缩req+log
+ * 提取req+log+resp
*/
- public static final long E_REQ_E_LOG_C_REQ_E_LOG = E_REQ | E_LOG | C_REQ | E_LOG;
+ public static final long EXTRACT_ALL = E_REQ | E_LOG | E_RESP;
+ /**
+ * 压缩req+log
+ */
+ public static final long COMPRESS_REQ_LOG = C_REQ | C_LOG;
+
+ /**
+ * 压缩req+resp
+ */
+ public static final long COMPRESS_REQ_REQP = C_REQ | C_RESP;
+
+ /**
+ * 压缩req+resp
+ */
+ public static final long COMPRESS_REQ_C_RESP = C_REQ | C_RESP;
+
+ /**
+ * 压缩req+log+resp
+ */
+ public static final long COMPRESS_ALL = C_REQ | C_LOG | C_RESP;
+
+
+ public static void main(String[] args) {
+ System.out.println(isMatched(EXTRACT_REQ_LOG, EXTRACT_REQ_RESP));
+ }
+ public static boolean isMatched(long indicator, long position) {
+ return (indicator & position) == position;
+ }
+
}
+ // curl --location --request POST 'http://10.96.98.110:8058/app/flow/getappraiselist' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'token=DF9YcBVAaMiLCZtZEZCf6MunJX8I3jWGmQXwRzb-oQIszD1uAjEQgNG7fG1Gq5nx2I6nzBFygwSWn8ZIIKrV3h0hUb3ubUwlKYsuijCNNGE6WVVLCLOQ1uvoLTza6KrCDPJNJfn5RfgjQfgnw8vo7j6KqX-HC0dyCCu58bg974f1U-_CibQWrXlXC-FM8lWrqhZrvVYvCBcSQ7iSur8CAAD__w==' --data-urlencode 'cityID=55000116' --data-urlencode 'appVersion=2.0.28' --data-urlencode 'country=BR'
\ No newline at end of file
diff --git a/common/src/main/java/com/jd/platform/jlog/common/tag/TagConfig.java b/common/src/main/java/com/jd/platform/jlog/common/tag/TagConfig.java
index c71d20a..c6e53a7 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/tag/TagConfig.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/tag/TagConfig.java
@@ -3,6 +3,9 @@ package com.jd.platform.jlog.common.tag;
import java.io.Serializable;
import java.util.List;
+import static com.jd.platform.jlog.common.tag.CollectMode.COMPRESS_ALL;
+import static com.jd.platform.jlog.common.tag.CollectMode.EXTRACT_ALL;
+
/**
* @author tangbohu
* @version 1.0.0
@@ -37,14 +40,14 @@ public class TagConfig implements Serializable {
private String join = "=";
/**
- * 提取入参开关
+ * 提取策略
*/
- private Boolean extractReq = true;
+ private long extract = EXTRACT_ALL;
/**
- * 提取普通log开关
+ * 压缩策略
*/
- private Boolean extractLog = true;
+ private long compress = COMPRESS_ALL;
public List getReqTags() {
@@ -87,20 +90,20 @@ public class TagConfig implements Serializable {
this.join = join;
}
- public Boolean getExtractReq() {
- return extractReq;
+ public long getExtract() {
+ return extract;
}
- public void setExtractReq(Boolean extractReq) {
- this.extractReq = extractReq;
+ public void setExtract(long extract) {
+ this.extract = extract;
}
- public Boolean getExtractLog() {
- return extractLog;
+ public long getCompress() {
+ return compress;
}
- public void setExtractLog(Boolean extractLog) {
- this.extractLog = extractLog;
+ public void setCompress(long compress) {
+ this.compress = compress;
}
public static final class Builder {
@@ -109,8 +112,8 @@ public class TagConfig implements Serializable {
private String regex;
private String delimiter;
private String join;
- private Boolean extractReq;
- private Boolean extractLog;
+ private long extract;
+ private long compress;
public Builder() {
}
@@ -144,13 +147,13 @@ public class TagConfig implements Serializable {
return this;
}
- public Builder extractReq(Boolean extractReq) {
- this.extractReq = extractReq;
+ public Builder extract(long extract) {
+ this.extract = extract;
return this;
}
- public Builder extractLog(Boolean extractLog) {
- this.extractLog = extractLog;
+ public Builder compress(long compress) {
+ this.compress = compress;
return this;
}
@@ -161,8 +164,8 @@ public class TagConfig implements Serializable {
tagConfig.setRegex(regex);
tagConfig.setDelimiter(delimiter);
tagConfig.setJoin(join);
- tagConfig.setExtractReq(extractReq);
- tagConfig.setExtractLog(extractLog);
+ tagConfig.setExtract(extract);
+ tagConfig.setCompress(compress);
return tagConfig;
}
}
@@ -175,8 +178,8 @@ public class TagConfig implements Serializable {
", regex='" + regex + '\'' +
", delimiter='" + delimiter + '\'' +
", join='" + join + '\'' +
- ", extractReq='" + extractReq + '\'' +
- ", extractLog='" + extractLog + '\'' +
+ ", extract='" + extract + '\'' +
+ ", compress='" + compress + '\'' +
'}';
}
}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/tag/TagHandler.java b/common/src/main/java/com/jd/platform/jlog/common/tag/TagHandler.java
index f037e63..831a7bf 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/tag/TagHandler.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/tag/TagHandler.java
@@ -12,8 +12,12 @@ import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import static com.jd.platform.jlog.common.constant.Constant.EXTRACT_MIN_LEN;
import static com.jd.platform.jlog.common.constant.Constant.TAG_NORMAL_KEY;
import static com.jd.platform.jlog.common.constant.Constant.TAG_NORMAL_KEY_MAX_LEN;
+import static com.jd.platform.jlog.common.tag.CollectMode.*;
+import static com.jd.platform.jlog.common.tag.CollectMode.E_LOG;
+import static com.jd.platform.jlog.common.tag.CollectMode.E_REQ;
import static com.jd.platform.jlog.common.utils.ConfigUtil.RANDOM;
/**
@@ -28,12 +32,8 @@ public class TagHandler {
private Set reqTags;
- private boolean extractReq;
-
private Set logTags;
- private boolean extractLog;
-
private String delimiter = "|";
private int delimiterLen = delimiter.length();
@@ -42,22 +42,25 @@ public class TagHandler {
private Pattern pattern;
+ private long extract;
+
+ private long compress;
+
private static volatile TagHandler INSTANCE = null;
/**
* 构建标签处理器
* @param tagConfig 配置类
*/
- public static void build(TagConfig tagConfig) {
+ public static void buildHandler(TagConfig tagConfig) {
- if(!tagConfig.getExtractReq() && !tagConfig.getExtractLog()){
+ if(tagConfig.getExtract() == SUSPEND && tagConfig.getCompress() == SUSPEND ){
return;
}
TagHandler handler = new TagHandler();
-
- handler.extractReq = tagConfig.getExtractReq();
- handler.extractLog = tagConfig.getExtractLog();
+ handler.extract = tagConfig.getExtract();
+ handler.compress = tagConfig.getCompress();
handler.reqTags = new HashSet<>(tagConfig.getReqTags());
handler.logTags = new HashSet<>(tagConfig.getLogTags());
@@ -85,7 +88,9 @@ public class TagHandler {
*/
public static Map extractReqTag(Map params, @NotNull Map ext) {
- if(INSTANCE == null || !INSTANCE.extractReq){ return null; }
+ if(INSTANCE == null || !isMatched(INSTANCE.extract, E_REQ)){ return null; }
+
+ System.out.println("### INSTANCE.reqTags:"+JSON.toJSONString(INSTANCE.reqTags));
Map requestMap = new HashMap<>(INSTANCE.reqTags.size());
for (String tag : INSTANCE.reqTags) {
@@ -99,7 +104,7 @@ public class TagHandler {
requestMap.put(tag, params.get(tag)[0]);
}
}
-
+ System.out.println("提取到了请求入参日志标签:"+JSON.toJSONString(requestMap));
return requestMap;
}
@@ -110,7 +115,7 @@ public class TagHandler {
* @return tags
*/
public static Map extractLogTag(String content) {
- if(INSTANCE == null || !INSTANCE.extractLog || content.length() < 1){
+ if(INSTANCE == null || !isMatched(INSTANCE.extract, E_LOG) || content.length() < EXTRACT_MIN_LEN){
return null;
}
@@ -131,6 +136,7 @@ public class TagHandler {
}
}
}
+ System.out.println("提取到了请求log日志标签:"+JSON.toJSONString(tagMap));
return tagMap;
}
@@ -142,7 +148,7 @@ public class TagHandler {
*/
public synchronized static void refresh(TagConfig tagConfig) {
INSTANCE = null;
- build(tagConfig);
+ buildHandler(tagConfig);
}
@@ -154,6 +160,9 @@ public class TagHandler {
", delimiter='" + delimiter + '\'' +
", delimiterLen=" + delimiterLen +
", join='" + join + '\'' +
+ ", pattern=" + pattern +
+ ", extract=" + extract +
+ ", compress=" + compress +
'}';
}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/utils/CollectionUtil.java b/common/src/main/java/com/jd/platform/jlog/common/utils/CollectionUtil.java
index 5890083..87af2f6 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/utils/CollectionUtil.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/CollectionUtil.java
@@ -133,13 +133,87 @@ public class CollectionUtil {
public static void main(String[] args) {
- HashMap m1 = new HashMap<>();
- m1.put("t1",1);
- m1.put("t2",2);
+ int fail = 0;
+ int count = 10000;
+ Set set = new HashSet<>();
+ for (int i = 0; i < count; i++) {
+ int h = randomMac4Qemu().hashCode();
+ int val = indexFor(h);
+ boolean r = set.add(val);
+ // System.out.println(val);
+ if(!r){
+ fail++;
+ }
+ }
- HashMap m2 = new HashMap<>();
- m2.put("t2",2);
- m2.put("t3",3);
+ int fail2 = 0;
+ Set set2 = new HashSet<>();
+ for (int i = 0; i < count; i++) {
+ int h = randomMac4Qemu().hashCode();
+ Random rd = new Random(h);
+ int val = rd.nextInt(16385);
+ boolean r = set.add(val);
+ System.out.println(val);
+ if(!r){
+ fail2++;
+ }
+ }
+
+ System.out.println("11--》 "+fail);
+ System.out.println("22-》 "+ fail2);
+ }
+ static int indexFor(int h) {
+ return h & (16384-1);
+ }
+ public static String randomMac4Qemu() {
+ /* if(1==1){
+ return getRandomIp();
+ }*/
+ Random random = new Random();
+ String[] mac = {
+ /* String.format("%02x", 0x52),
+ String.format("%02x", 0x54),
+ String.format("%02x", 0x00),*/
+ String.format("%02x", random.nextInt(0xff)),
+ String.format("%02x", random.nextInt(0xff)),
+ String.format("%02x", random.nextInt(0xff))
+ };
+ return String.join(":", mac);
+ }
+
+
+ public static String getRandomIp(){
+
+ //ip范围
+ int[][] range = {{607649792,608174079},//36.56.0.0-36.63.255.255
+ {1038614528,1039007743},//61.232.0.0-61.237.255.255
+ {1783627776,1784676351},//106.80.0.0-106.95.255.255
+ {2035023872,2035154943},//121.76.0.0-121.77.255.255
+ {2078801920,2079064063},//123.232.0.0-123.235.255.255
+ {-1950089216,-1948778497},//139.196.0.0-139.215.255.255
+ {-1425539072,-1425014785},//171.8.0.0-171.15.255.255
+ {-1236271104,-1235419137},//182.80.0.0-182.92.255.255
+ {-770113536,-768606209},//210.25.0.0-210.47.255.255
+ {-569376768,-564133889}, //222.16.0.0-222.95.255.255
+ };
+
+ Random rdint = new Random();
+ int index = rdint.nextInt(10);
+ return num2ip(range[index][0]+new Random().nextInt(range[index][1]-range[index][0]));
+ }
+
+
+ public static String num2ip(int ip) {
+ int [] b=new int[4] ;
+ String x = "";
+
+ b[0] = (int)((ip >> 24) & 0xff);
+ b[1] = (int)((ip >> 16) & 0xff);
+ b[2] = (int)((ip >> 8) & 0xff);
+ b[3] = (int)(ip & 0xff);
+ x=Integer.toString(b[0])+"."+Integer.toString(b[1])+"."+Integer.toString(b[2])+"."+Integer.toString(b[3]);
+
+ return x;
}
}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/utils/ConfigUtil.java b/common/src/main/java/com/jd/platform/jlog/common/utils/ConfigUtil.java
index e74de5e..4e27fb8 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/utils/ConfigUtil.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/ConfigUtil.java
@@ -2,8 +2,12 @@ package com.jd.platform.jlog.common.utils;
import com.jd.platform.jlog.common.constant.Constant;
-import java.util.Enumeration;
-import java.util.Properties;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
/**
@@ -18,13 +22,14 @@ public class ConfigUtil {
private static final String SERVER_SUFFIX = "Server";
- public static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
+ public static final char MID_LINE = '-';
+ public static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
public static String escapeExprSpecialWord(String str) {
- if(str != null && str.length() > 0){
+ if (str != null && str.length() > 0) {
for (String s : Constant.SPECIAL_CHAR) {
if (str.contains(s)) {
str = str.replace(s, "\\" + s);
@@ -35,7 +40,6 @@ public class ConfigUtil {
}
-
public static String formatConfigStr(Properties properties) {
StringBuilder sb = new StringBuilder();
@@ -43,7 +47,7 @@ public class ConfigUtil {
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
Object property = properties.get(key);
- if(property != null){
+ if (property != null) {
property = String.valueOf(property);
}
sb.append(key).append("=").append(property).append("\n");
@@ -52,12 +56,41 @@ public class ConfigUtil {
}
-
public static byte[] formatConfigByte(Properties properties) {
return formatConfigStr(properties).getBytes();
}
+ //递归解析map对象
+ public static void loadRecursion(Map map, String key, Properties props) {
+ map.forEach((k, v) -> {
+ System.out.println("k => " + k + " v.class => " + v.getClass() + " val => " + v.toString() + " 是不是爸爸 => " + isParent(v));
+ if (isParent(v)) {
+ if (v instanceof Boolean || v instanceof List) {
+ props.put(key + "." + k, v);
+ } else {
+ Map nextValue = (Map) v;
+ loadRecursion(nextValue, (("".equals(key) ? "" : key + ".") + k), props);
+ }
+ } else {
+ props.put(key + "." + k, v);
+ }
+ });
+ }
+
+ //判断是否还有子节点
+ public static boolean isParent(Object o) {
+ if (!(o instanceof String || o instanceof Character || o instanceof Byte)) {
+ try {
+ Number n = (Number) o;
+ // System.out.println("isParent ==> "+n);
+ } catch (Exception e) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/*
public static ConfigCenterEnum getCenter(CenterConfig config) throws Exception {
@@ -86,4 +119,31 @@ public class ConfigUtil {
items[0] = (byte) ((char) items[0] - 'a' + 'A');
return new String(items);
}
+
+
+
+
+ public static String camelToMidline(String param) {
+ if (param == null || "".equals(param.trim())) {
+ return "";
+ }
+ int len = param.length();
+ StringBuilder sb = new StringBuilder(len);
+ for (int i = 0; i < len; i++) {
+ char c = param.charAt(i);
+ if (Character.isUpperCase(c)) {
+ sb.append("-");
+ sb.append(Character.toLowerCase(c));
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ public static String lowerFirst(String fromStr){
+ char[] chars = fromStr.toCharArray();
+ chars[0] += 32;
+ return String.valueOf(chars);
+ }
}
diff --git a/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConfigurator.java b/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConfigurator.java
index 803bd32..f0e6432 100644
--- a/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConfigurator.java
+++ b/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConfigurator.java
@@ -77,6 +77,26 @@ public class ApolloConfigurator implements Configurator {
return instance;
}
+ @Override
+ public String getString(String key) {
+ return null;
+ }
+
+ @Override
+ public Long getLong(String key) {
+ return null;
+ }
+
+ @Override
+ public List getList(String key) {
+ return null;
+ }
+
+ @Override
+ public T getObject(String key, Class clz) {
+ return null;
+ }
+
@Override
public String getConfig(String key) {
return config.getProperty(key,"");
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/Configurator.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/Configurator.java
index 36df609..4ae742d 100644
--- a/config/config-core/src/main/java/com/jd/platform/jlog/core/Configurator.java
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/Configurator.java
@@ -1,7 +1,6 @@
package com.jd.platform.jlog.core;
import java.util.List;
-import java.util.Map;
/**
* @author tangbohu
@@ -13,19 +12,34 @@ import java.util.Map;
public interface Configurator {
/**
- * 获取配置
+ * 获取string配置
* @param key key
* @return val
*/
- String getConfig(String key);
+ String getString(String key);
+
/**
- * 获取配置
+ * 获取LONG配置
* @param key key
- * @param timeoutMills timeoutMills
* @return val
*/
- String getConfig(String key, long timeoutMills);
+ Long getLong(String key);
+
+ /**
+ * 获取LIST类型配置
+ * @param key key
+ * @return val
+ */
+ List getList(String key);
+
+ /**
+ * 获取实体类型配置
+ * @param key key
+ * @return val
+ */
+ T getObject(String key, Class clz);
+
/**
* 设置配置
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfiguratorFactory.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfiguratorFactory.java
index 92e7795..c87087f 100644
--- a/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfiguratorFactory.java
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfiguratorFactory.java
@@ -32,8 +32,8 @@ public class ConfiguratorFactory {
synchronized (Configurator.class) {
if (instance == null) {
instance = buildConfiguration();
- LOGGER.info("构建总配置器单例完成 instance 获取reqTags结果:{}", instance.getConfig("reqTags"));
- LOGGER.info("构建总配置器单例完成 Base 获取serverAddr结果:{}", base.getConfig("serverAddr"));
+ LOGGER.info("构建总配置器单例完成 instance 获取类型结果:{}", instance.getType());
+ LOGGER.info("构建总配置器单例完成 Base 获取serverAddr结果:{}", base.getString("serverAddr"));
}
}
}
@@ -69,4 +69,19 @@ public class ConfiguratorFactory {
return base;
}
+
+
+ private static Configurator refreshBaseConfiguration() {
+
+ synchronized (Configurator.class){
+ try {
+ base = new FileConfigurator();
+ } catch (IOException e) {
+ LOGGER.info("文件配置器构建失败", e);
+ throw new RuntimeException("build file buildConfiguration fail", e);
+ }
+ }
+ return base;
+ }
+
}
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/Constant.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/Constant.java
index f40ea23..fb05839 100644
--- a/config/config-core/src/main/java/com/jd/platform/jlog/core/Constant.java
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/Constant.java
@@ -15,7 +15,7 @@ public class Constant {
/**
* 监听重读配置文件间隔 单位ms
*/
- static final long LISTENER_CONFIG_INTERVAL = 10000;
+ static final long LISTENER_CONFIG_INTERVAL = 3000;
static final String CONFIG_FILE_PROPERTIES = "/application.properties";
@@ -34,7 +34,7 @@ public class Constant {
public static final String SERVER_ADDR_KEY = "serverAddr";
-
+ public static final String NAMESPACE_KEY = "namespace";
/**
* 配置文件集合
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/FileConfigurator.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/FileConfigurator.java
index 20730b1..26450e5 100644
--- a/config/config-core/src/main/java/com/jd/platform/jlog/core/FileConfigurator.java
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/FileConfigurator.java
@@ -28,7 +28,7 @@ public class FileConfigurator implements Configurator {
private static final Logger LOGGER = LoggerFactory.getLogger(FileConfigurator.class);
- private static Properties PROPERTIES = new Properties();
+ private static JcProperties PROPERTIES = new JcProperties();
private static volatile FileListener FILELISTENER = null;
@@ -44,18 +44,19 @@ public class FileConfigurator implements Configurator {
for (String file : CONFIG_FILES) {
String fileName = StringUtil.isEmpty(env) ? file : file + "_" + env;
URL url = this.getClass().getResource(file);
- if(url != null){
- try (InputStream is = url.openStream()) {
- Properties props = new Properties();
- if (fileName.contains(YML)) {
- props.putAll(new Yaml().loadAs(is, Map.class));
- } else {
- props.load(is);
- }
- FILE_MODIFY_MAP.put(fileName, new FileWrapper(new File(url.getFile()).lastModified(), props));
- PROPERTIES.putAll(props);
- LOGGER.info("{}配置文件配置:{}", file, props.toString());
+ if(url == null){
+ continue;
+ }
+ try (InputStream is = url.openStream()) {
+ JcProperties props = new JcProperties();
+ if (fileName.contains(YML)) {
+ props.putAll(new Yaml().loadAs(is, Map.class));
+ } else {
+ props.load(is);
}
+ FILE_MODIFY_MAP.put(fileName, new FileWrapper(new File(url.getFile()).lastModified(), props));
+ PROPERTIES.putAll(props);
+ LOGGER.info("{}配置文件配置:{}", file, props.toString());
}
}
LOGGER.info("合并后的配置:{}",PROPERTIES.toString());
@@ -63,20 +64,24 @@ public class FileConfigurator implements Configurator {
@Override
- public String getConfig(String key) {
- Object val = PROPERTIES.get(key);
- if(val != null){
- return String.valueOf(val);
- }
- return null;
+ public String getString(String key) {
+ return PROPERTIES.getString(key);
}
-
@Override
- public String getConfig(String key, long timeoutMills) {
- return PROPERTIES.getProperty(key);
+ public Long getLong(String key) {
+ return PROPERTIES.getLong(key);
}
+ @Override
+ public List getList(String key) {
+ return PROPERTIES.getStrList(key);
+ }
+
+ @Override
+ public T getObject(String key, Class clz) {
+ return PROPERTIES.getBean(key, clz);
+ }
@Override
public boolean putConfig(String key, String content) { return false; }
@@ -106,7 +111,6 @@ public class FileConfigurator implements Configurator {
return;
}
String env = System.getenv(ENV);
-
for (String file : CONFIG_FILES) {
file = StringUtil.isEmpty(env) ? file : file + "_" + env;
if(node.equals(file)){
@@ -171,7 +175,8 @@ public class FileConfigurator implements Configurator {
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(),
new DefaultThreadFactory("fileListener", 1));
- FileListener() { }
+ FileListener() {
+ }
synchronized void addListener() {
FILELISTENER.onProcessEvent(new ConfigChangeEvent());
@@ -202,28 +207,30 @@ public class FileConfigurator implements Configurator {
* 检测文件最后修改时间 和重载文件
*/
private void checkAndConfigure(){
+
AtomicBoolean change = new AtomicBoolean(false);
Map newModifyMap = checkAndReload();
+
FILE_MODIFY_MAP.forEach((k, v)->{
FileWrapper newFile = newModifyMap.get(k);
if(newFile != null && newFile.change){
-
Set diffKeys = CollectionUtil.diffKeys(newFile.props, v.props);
if(!diffKeys.isEmpty()){
change.set(true);
- v.props = newFile.props;
-
for (String diffKey : diffKeys) {
- LOGGER.warn("文件 {} 配置变更 key={}变更事件:{}", k, diffKey, new ConfigChangeEvent(diffKey, v.props.get(diffKey).toString(), newFile.props.get(diffKey).toString()));
+ LOGGER.warn("文件 {} 配置变更 key={}变更事件:{}", k, diffKey, new ConfigChangeEvent(diffKey, String.valueOf(v.props.get(diffKey)), String.valueOf(newFile.props.get(diffKey))));
}
+ v.props = newFile.props;
+ v.lastModify= newFile.lastModify;
}
}
});
if(change.get()){
- LOGGER.info("变更之前的总配置:{}", JSON.toJSONString(PROPERTIES));
+ // LOGGER.info("变更之前的总配置:{}", JSON.toJSONString(PROPERTIES));
PROPERTIES.clear();
FILE_MODIFY_MAP.forEach((k,v)-> PROPERTIES.putAll(v.props));
LOGGER.info("变更之后的总配置:{}", JSON.toJSONString(PROPERTIES));
+ TagHandlerBuilder.refresh();
}
}
@@ -234,8 +241,10 @@ public class FileConfigurator implements Configurator {
private Map checkAndReload() {
Map fileWrapperMap = new ConcurrentHashMap<>(3);
+
for (String fileName : LISTENED_FILES) {
URL url = this.getClass().getResource(fileName);
+
if(url == null){
continue;
}
@@ -246,7 +255,7 @@ public class FileConfigurator implements Configurator {
if(curLastMod <= cacheLastMod){
continue;
}
- Properties props = new Properties();
+ JcProperties props = new JcProperties();
try (InputStream is = url.openStream()) {
if (fileName.contains(YML)) {
props.putAll(new Yaml().loadAs(is, Map.class));
@@ -269,14 +278,14 @@ public class FileConfigurator implements Configurator {
private boolean change;
- private Properties props;
+ private JcProperties props;
- FileWrapper(long lastModify, Properties props) {
+ FileWrapper(long lastModify, JcProperties props) {
this.lastModify = lastModify;
this.change = false;
this.props = props;
}
- FileWrapper(long lastModify, boolean change, Properties props) {
+ FileWrapper(long lastModify, boolean change, JcProperties props) {
this.lastModify = lastModify;
this.change = change;
this.props = props;
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/FileNode.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/FileNode.java
new file mode 100644
index 0000000..49634af
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/FileNode.java
@@ -0,0 +1,30 @@
+package com.jd.platform.jlog.core;
+
+import com.alibaba.fastjson.JSON;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName FileNode.java
+ * @Description TODO
+ * @createTime 2022年03月08日 16:32:00
+ */
+public final class FileNode {
+
+ private String fillPath;
+
+ private long lastModity;
+
+ public static void main(String[] args) throws IOException {
+ JcProperties properties = new JcProperties();
+ String path = "/Users/didi/Desktop/jlog/example/target/classes/application.properties";
+ properties.load(new FileInputStream(path));
+ System.out.println(JSON.toJSONString(properties));
+ Server bean = properties.getBean("server", Server.class);
+ System.out.println(JSON.toJSONString(bean));
+ }
+}
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/JcProperties.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/JcProperties.java
new file mode 100644
index 0000000..8bd02bd
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/JcProperties.java
@@ -0,0 +1,139 @@
+package com.jd.platform.jlog.core;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.common.utils.ConfigUtil;
+import com.jd.platform.jlog.common.utils.FastJsonUtils;
+import com.jd.platform.jlog.common.utils.StringUtil;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import static com.jd.platform.jlog.common.utils.ConfigUtil.lowerFirst;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName JcProperties.java
+ * @Description TODO
+ * @createTime 2022年03月07日 12:43:00
+ */
+public class JcProperties extends Properties {
+
+ public JcProperties() {
+ }
+
+ public String getString(String key) {
+ Object val = super.get(key);
+ if(val == null){
+ return null;
+ }
+ return String.valueOf(super.get(key));
+ }
+
+ public Long getLong(String key) {
+ String val = getString(key);
+ if(StringUtil.isEmpty(val)){
+ return null;
+ }
+ return Long.valueOf(val);
+ }
+
+ public List getStrList(String key) {
+ String val = getString(key);
+ if(StringUtil.isEmpty(val)){
+ return null;
+ }
+ return FastJsonUtils.toList(val, String.class);
+ }
+
+ public T getBean(String key, Class clz) {
+ T bean = FastJsonUtils.toBean(JSON.toJSONString(get(key)), clz);
+ if(bean != null){
+ return bean;
+ }
+ try {
+ T instance = clz.newInstance();
+ invoke(instance, this, "");
+ return instance;
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+
+ private void invoke(Object model, JcProperties properties, String prefix) throws
+ IllegalAccessException, ClassNotFoundException, InstantiationException, ParseException {
+
+ Class> clz = model.getClass();
+ Field[] fields = model.getClass().getDeclaredFields();
+ for (Field field : fields) {
+ String type = field.getGenericType().toString();
+ field.setAccessible(true);
+
+ String curObjName = ConfigUtil.camelToMidline(lowerFirst(clz.getSimpleName()));
+
+ prefix = StringUtil.isEmpty(prefix) ? curObjName : prefix;
+ String fillName = !curObjName.equals(prefix) ? prefix +"."+ curObjName + "." + field.getName() : curObjName + "." + field.getName();
+
+
+ switch (type){
+ case "class java.lang.String":
+ field.set(model, properties.getString(fillName)) ;
+ break;
+ case "byte":
+ field.setByte(model, Byte.valueOf(properties.getString(fillName)));
+ break;
+ case "short":
+ field.setShort(model, Short.valueOf(properties.getString(fillName)));
+ break;
+ case "int":
+ field.setInt(model, properties.getLong(fillName).intValue()) ;
+ break;
+ case "long":
+ field.setLong(model, properties.getLong(fillName));
+ break;
+ case "double":
+ field.setDouble(model, Double.valueOf(properties.getString(fillName)));
+ break;
+ case "float":
+ field.setFloat(model, Float.valueOf(properties.getString(fillName)));
+ break;
+ case "boolean":
+ field.setBoolean(model, Boolean.parseBoolean(properties.getString(fillName)));
+ break;
+ case "class java.util.Date":
+ Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(properties.getString(fillName));
+ field.set(model,date) ;
+ break;
+ default:
+ String tn = field.getType().getTypeName();
+ if("java.util.List".equals(tn)){
+ String val = properties.getString(fillName);
+ field.set(model,FastJsonUtils.toList(val, String.class));
+ }else if("java.util.Map".equals(tn)){
+ String val = properties.getString(fillName);
+ field.set(model,FastJsonUtils.toMap(val));
+ }else if(field.getType().isArray()){
+ String val = properties.getString(fillName);
+ field.set(model,FastJsonUtils.toArray(val));
+ }else{
+ String[] ar = type.split(" ");
+ Object tinyObj = Class.forName(ar[1]).newInstance();
+ invoke(tinyObj, properties, prefix);
+ field.set(model,tinyObj);
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/NodeBak.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/NodeBak.java
new file mode 100644
index 0000000..3a5d521
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/NodeBak.java
@@ -0,0 +1,142 @@
+package com.jd.platform.jlog.core;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.common.utils.StringUtil;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName Node.java 包装类 用于以后的支持key->node->[listener,properties]
+ * @createTime 2022年03月02日 20:37:00
+ */
+public class NodeBak implements Serializable {
+
+
+ private String name;
+
+ private ConfigChangeListener listener;
+
+ private Properties properties;
+
+ private String type;
+
+ private Object val;
+
+
+ static Properties newPro = new Properties();
+
+
+ public static void main(String[] args) throws IOException {
+
+ String path = "/Users/didi/Desktop/jlog/example/target/classes/application.properties";
+ // newPro.load();
+ read(path);
+
+ System.out.println(JSON.toJSONString(newPro));
+ }
+
+ protected static Map toMap(Properties properties) {
+ Map result = new HashMap<>(10);
+ Enumeration> propertyNames = properties.propertyNames();
+ while (propertyNames.hasMoreElements()) {
+ String name = (String) propertyNames.nextElement();
+ String value = properties.getProperty(name);
+ result.put(name, value);
+ }
+ return result;
+ }
+
+
+
+
+ public static void read(String path) {
+
+ FileReader fr = null;
+ LineNumberReader lnr = null;
+ String str;
+
+ try {
+ fr = new FileReader(path);
+ lnr = new LineNumberReader(fr);
+
+ Stack stack = new Stack<>();
+ HashMap tinyMap = new LinkedHashMap<>();
+ List