diff --git a/Dashboard/pom.xml b/Dashboard/pom.xml
index 6e391f160e74da2c7c9dcdae68eafaaf58c0517e..b921f02789475f68a1da26093e99b0abc6e9b6a6 100644
--- a/Dashboard/pom.xml
+++ b/Dashboard/pom.xml
@@ -55,11 +55,6 @@
zstd-jni
1.5.0-4
-
- com.jd.ump
- profiler
- 6.2.13
-
com.alibaba
fastjson
diff --git a/Dashboard/src/main/resources/logback-spring.xml b/Dashboard/src/main/resources/logback-spring.xml
index dce10afa58762b12e140c44c2cfc275dda0cf4ef..7202d5f34157b439b41614241a950ceacae66ab0 100644
--- a/Dashboard/src/main/resources/logback-spring.xml
+++ b/Dashboard/src/main/resources/logback-spring.xml
@@ -6,7 +6,7 @@ debug:当此属性设置为true时,将打印出logback内部日志信息,
-->
-
+
diff --git a/client/pom.xml b/client/pom.xml
index 6e43109fada9e5eb79201eb8799f212b4ed992cd..47d1a0ed8d2db0088f7b18d8a7002f6ccfcb59a7 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -18,6 +18,32 @@
1.4-SNAPSHOT
+
+
+
+
+
+ com.jd.platfrom.jlog
+ config-apollo
+ 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 f12bafd0b88b6b72c55f4f020c9bf775b580b9b1..32f41c3cccc548f1b07961bf02993d21f5a1aaa0 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,11 +1,16 @@
package com.jd.platform.jlog.client;
-import com.jd.platform.jlog.client.etcd.EtcdConfigFactory;
-import com.jd.platform.jlog.client.etcd.EtcdStarter;
+
+import com.alibaba.fastjson.JSON;
import com.jd.platform.jlog.client.mdc.Mdc;
-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.client.task.Monitor;
+import com.jd.platform.jlog.common.handler.TagConfig;
+import com.jd.platform.jlog.core.ClientHandlerBuilder;
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* TracerClientStarter
@@ -14,15 +19,22 @@ import com.jd.platform.jlog.client.udp.UdpSender;
* @date 2021-08-13
*/
public class TracerClientStarter {
- /**
- * etcd地址
- */
- private String etcdServer;
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(TracerClientStarter.class);
+
+
/**
* 机房
*/
private Mdc mdc;
+ /**
+ * 如果直接配置在app.properties/yaml等主配置文件
+ * 可以用ConfigurationProperties直接获取有值对象
+ */
+ private TagConfig tagConfig;
+
+
/**
* TracerClientStarter
*/
@@ -35,8 +47,8 @@ public class TracerClientStarter {
public static class Builder {
private String appName;
- private String etcdServer;
private Mdc mdc;
+ private TagConfig tagConfig;
public Builder() {
}
@@ -51,40 +63,48 @@ public class TracerClientStarter {
return this;
}
- public Builder setEtcdServer(String etcdServer) {
- this.etcdServer = etcdServer;
+ public Builder setTagConfig(TagConfig tagConfig) {
+ this.tagConfig = tagConfig;
return this;
}
public TracerClientStarter build() {
TracerClientStarter tracerClientStarter = new TracerClientStarter(appName);
- tracerClientStarter.etcdServer = etcdServer;
+ tracerClientStarter.tagConfig = tagConfig;
tracerClientStarter.mdc = mdc;
-
return tracerClientStarter;
}
}
/**
- * 启动监听etcd
+ * 启动监听
*/
public void startPipeline() {
- //设置ConfigCenter
- EtcdConfigFactory.buildConfigCenter(etcdServer);
+ // 初始化配置
+ initJLogConfig();
Context.MDC = mdc;
- EtcdStarter starter = new EtcdStarter();
- //与etcd相关的监听都开启
+ 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 initJLogConfig(){
+ LOGGER.info("从主配置获取的tagConfig:{}", JSON.toJSONString(tagConfig));
+ Configurator configurator = ConfiguratorFactory.getInstance();
+ ClientHandlerBuilder.buildHandler(tagConfig, configurator);
}
}
diff --git a/client/src/main/java/com/jd/platform/jlog/client/etcd/EtcdConfigFactory.java b/client/src/main/java/com/jd/platform/jlog/client/etcd/EtcdConfigFactory.java
deleted file mode 100644
index b2386b7fe8f822a9a59e59b54b2738302f52ecf0..0000000000000000000000000000000000000000
--- a/client/src/main/java/com/jd/platform/jlog/client/etcd/EtcdConfigFactory.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.jd.platform.jlog.client.etcd;
-
-
-import com.jd.platform.jlog.common.config.IConfigCenter;
-import com.jd.platform.jlog.common.config.etcd.JdEtcdBuilder;
-
-/**
- * @author wuweifeng wrote on 2020-01-07
- * @version 1.0
- */
-public class EtcdConfigFactory {
- private static IConfigCenter configCenter;
-
- private EtcdConfigFactory() {}
-
- public static IConfigCenter configCenter() {
- return configCenter;
- }
-
- public static void buildConfigCenter(String etcdServer) {
- //连接多个时,逗号分隔
- configCenter = JdEtcdBuilder.build(etcdServer);
- }
-}
diff --git a/client/src/main/java/com/jd/platform/jlog/client/filter/UserFilter.java b/client/src/main/java/com/jd/platform/jlog/client/filter/HttpFilter.java
similarity index 90%
rename from client/src/main/java/com/jd/platform/jlog/client/filter/UserFilter.java
rename to client/src/main/java/com/jd/platform/jlog/client/filter/HttpFilter.java
index 595dae500a5ef50ecf4838e8d07849c038988cc5..2fd16ba161b9b751c3b8b8aaba657598bd1e3a99 100644
--- a/client/src/main/java/com/jd/platform/jlog/client/filter/UserFilter.java
+++ b/client/src/main/java/com/jd/platform/jlog/client/filter/HttpFilter.java
@@ -8,7 +8,7 @@ import com.jd.platform.jlog.client.udp.UdpSender;
import com.jd.platform.jlog.common.model.TracerBean;
import com.jd.platform.jlog.common.utils.IdWorker;
import com.jd.platform.jlog.common.utils.IpUtils;
-import com.jd.platform.jlog.common.utils.ZstdUtils;
+import com.jd.platform.jlog.core.ClientHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -20,14 +20,14 @@ import java.io.PrintWriter;
import java.util.*;
/**
- * UserFilter
+ * HttpFilter
* http://blog.chinaunix.net/uid-20783755-id-4729930.html
*
* @author wuweifeng
* @version 1.0
* @date 2021-08-16
*/
-public class UserFilter implements Filter {
+public class HttpFilter implements Filter {
/**
* 获取切量百分比的
*/
@@ -38,11 +38,11 @@ public class UserFilter implements Filter {
/**
* 传入百分比实现类
*/
- public UserFilter(ITracerPercent iTracerPercent) {
+ public HttpFilter(ITracerPercent iTracerPercent) {
this.iTracerPercent = iTracerPercent;
}
- public UserFilter() {
+ public HttpFilter() {
iTracerPercent = new DefaultTracerPercentImpl();
}
@@ -127,12 +127,14 @@ public class UserFilter implements Filter {
filterChain.doFilter(servletRequest, mResp);
byte[] contentBytes = mResp.getContent();
String content = new String(contentBytes);
- //最终的要发往worker的response,经历了base64压缩
- byte[] bytes = ZstdUtils.compress(contentBytes);
- byte[] base64Bytes = Base64.getEncoder().encode(bytes);
-
Map responseMap = new HashMap<>(8);
- responseMap.put("response", base64Bytes);
+ Map map = new HashMap<>(1);
+ map.put("errno", 200);
+ ClientHandler.Outcome outcome = ClientHandler.processResp(contentBytes, map);
+ responseMap.put("response", outcome.getContent());
+ if(!outcome.getMap().isEmpty()){
+ responseMap.putAll(outcome.getMap());
+ }
tracerObject.add(responseMap);
//此处可以对content做处理,然后再把content写回到输出流中
@@ -150,7 +152,6 @@ public class UserFilter implements Filter {
long tracerId, String uri) {
//request的各个入参
Map params = servletRequest.getParameterMap();
- //将request信息保存
Map requestMap = new HashMap<>(params.size());
for (String key : params.keySet()) {
requestMap.put(key, params.get(key)[0]);
@@ -159,7 +160,7 @@ public class UserFilter implements Filter {
requestMap.put("serverIp", IpUtils.getIp());
requestMap.put("tracerId", tracerId);
requestMap.put("uri", uri);
- tracerObject.add(requestMap);
+ tracerObject.add(ClientHandler.processReq(requestMap));
}
@Override
diff --git a/client/src/main/java/com/jd/platform/jlog/client/jsf/JsfRequest.java b/client/src/main/java/com/jd/platform/jlog/client/jsf/JsfRequest.java
deleted file mode 100644
index 27e2559f4db55b7d47e7993acec031eb9d1a049f..0000000000000000000000000000000000000000
--- a/client/src/main/java/com/jd/platform/jlog/client/jsf/JsfRequest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.jd.platform.jlog.client.jsf;
-
-
-/**
- * jsf请求入参包装对象
- * @author wuweifeng
- * @version 1.0
- * @date 2021-10-26
- */
-public interface JsfRequest {
- /**
- * 请求的完整入参
- */
- String requestContent();
-
- /**
- * 接口名
- */
- String uri();
-
- /**
- * 用户pin
- */
- default String pin() {
- return "";
- }
-
- /**
- * 用户uuid
- */
- default String uuid() {
- return "";
- }
-
- /**
- * 用户ip
- */
- default String userIp() {
- return "";
- }
-}
diff --git a/client/src/main/java/com/jd/platform/jlog/client/jsf/JsfTracer.java b/client/src/main/java/com/jd/platform/jlog/client/jsf/JsfTracer.java
deleted file mode 100644
index faa0dc92d8dfd920b486699c8b73724c22a3bcca..0000000000000000000000000000000000000000
--- a/client/src/main/java/com/jd/platform/jlog/client/jsf/JsfTracer.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.jd.platform.jlog.client.jsf;
-
-import com.jd.platform.jlog.client.Context;
-import com.jd.platform.jlog.client.tracerholder.TracerHolder;
-import com.jd.platform.jlog.client.udp.UdpSender;
-import com.jd.platform.jlog.common.model.TracerBean;
-import com.jd.platform.jlog.common.utils.IdWorker;
-import com.jd.platform.jlog.common.utils.IpUtils;
-import com.jd.platform.jlog.common.utils.ZstdUtils;
-
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-
-/**
- * JsfTracer工具类
- *
- * @author wuweifeng
- * @version 1.0
- * @date 2021-10-26
- */
-public class JsfTracer {
-
- /**
- * 临时保存入参
- */
- private static Map TEMP_HOLDER = new HashMap<>(128);
-
- /**
- * 跟踪开启
- */
- public static void begin(JsfRequest jsfRequest) {
- long tracerId = IdWorker.nextId();
- TracerHolder.setTracerId(tracerId);
-
- TracerBean tracerBean = new TracerBean();
- tracerBean.setCreateTime(System.currentTimeMillis());
-
- List
+
io.protostuff
protostuff-core
@@ -40,41 +43,30 @@
${protostuff.version}
-
- cn.hutool
- hutool-all
- ${hutool.version}
-
-
- com.github.luben
- zstd-jni
- ${zstd.version}
-
org.xerial.snappy
snappy-java
${snappy.version}
+
- io.netty
- netty-all
- ${netty4.version}
+ com.github.luben
+ zstd-jni
+ ${zstd.version}
+
com.alibaba
fastjson
${fastjson.version}
+
- com.ibm.etcd
- etcd-java
- ${hp-etcd.version}
-
-
- com.github.ben-manes.caffeine
- guava
- ${caffeine.version}
+ io.netty
+ netty-all
+ ${netty4.version}
+
\ No newline at end of file
diff --git a/common/src/main/java/com/jd/platform/jlog/common/config/IConfigCenter.java b/common/src/main/java/com/jd/platform/jlog/common/config/IConfigCenter.java
deleted file mode 100644
index d5e28b617e43872fc09016342a458134e137e88c..0000000000000000000000000000000000000000
--- a/common/src/main/java/com/jd/platform/jlog/common/config/IConfigCenter.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.jd.platform.jlog.common.config;
-
-import com.ibm.etcd.api.KeyValue;
-import com.ibm.etcd.client.kv.KvClient;
-
-import java.util.List;
-
-/**
- * 配合中心接口
- *
- * @author wuweifeng wrote on 2019-12-09
- * @version 1.0
- */
-public interface IConfigCenter {
- /**
- * 存入key,value
- */
- void put(String key, String value);
-
- /**
- * 存入key、value,和租约id
- */
- void put(String key, String value, long leaseId);
-
- /**
- * 删除一个lease
- */
- void revoke(long leaseId);
-
- /**
- * 存入key、value,和过期时间,单位是秒
- */
- long putAndGrant(String key, String value, long ttl);
-
- /**
- * 给key设置新的leaseId
- */
- long setLease(String key, long leaseId);
-
- void delete(String key);
-
- /**
- * 根据key,获取value
- */
- String get(String key);
-
- /**
- * 获取指定前缀的所有key-value
- */
- List getPrefix(String key);
-
- /**
- * 监听key
- */
- KvClient.WatchIterator watch(String key);
-
- /**
- * 监听前缀为key的
- */
- KvClient.WatchIterator watchPrefix(String key);
-
- /**
- * 自动续约
- * @param frequencySecs 续约频率,最小是4秒,默认是5秒
- * @param minTtl 最小存活时间,最小是2秒,默认是10秒
- * @return 返回leaseId
- */
- long keepAlive(String key, String value, int frequencySecs, int minTtl) throws Exception;
-
- /**
- * 构建一个可自动续约的lease
- */
- long buildAliveLease(int frequencySecs, int minTtl) throws Exception;
-
- /**
- * 构建一个普通lease
- */
- long buildNormalLease(long ttl);
-
- /**
- * 判断剩余的过期时间
- */
- long timeToLive(long leaseId);
-
- /**
- * 根据key,获取value
- */
- KeyValue getKv(String key);
-}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/config/etcd/JdEtcdBuilder.java b/common/src/main/java/com/jd/platform/jlog/common/config/etcd/JdEtcdBuilder.java
deleted file mode 100644
index b9fef7e1e0d04235a905092953c69313f4ec448d..0000000000000000000000000000000000000000
--- a/common/src/main/java/com/jd/platform/jlog/common/config/etcd/JdEtcdBuilder.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.jd.platform.jlog.common.config.etcd;
-
-import com.ibm.etcd.client.EtcdClient;
-
-/**
- * etcd连接器
- * @author wuweifeng wrote on 2019-12-10
- * @version 1.0
- */
-public class JdEtcdBuilder {
-
- /**
- * @param endPoints 如https://127.0.0.1:2379 有多个时逗号分隔
- */
- public static JdEtcdClient build(String endPoints) {
- return new JdEtcdClient(EtcdClient.forEndpoints(endPoints).withPlainText().build());
- }
-}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/config/etcd/JdEtcdClient.java b/common/src/main/java/com/jd/platform/jlog/common/config/etcd/JdEtcdClient.java
deleted file mode 100644
index 9f2254c77d7270ec20f381d8dc6d7e0406835056..0000000000000000000000000000000000000000
--- a/common/src/main/java/com/jd/platform/jlog/common/config/etcd/JdEtcdClient.java
+++ /dev/null
@@ -1,165 +0,0 @@
-package com.jd.platform.jlog.common.config.etcd;
-
-import cn.hutool.core.collection.CollectionUtil;
-import com.google.protobuf.ByteString;
-import com.ibm.etcd.api.KeyValue;
-import com.ibm.etcd.api.LeaseGrantResponse;
-import com.ibm.etcd.api.RangeResponse;
-import com.ibm.etcd.client.KvStoreClient;
-import com.ibm.etcd.client.kv.KvClient;
-import com.ibm.etcd.client.lease.LeaseClient;
-import com.ibm.etcd.client.lease.PersistentLease;
-import com.ibm.etcd.client.lock.LockClient;
-import com.jd.platform.jlog.common.config.IConfigCenter;
-
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-
-import static java.util.concurrent.TimeUnit.SECONDS;
-
-/**
- * etcd客户端
- *
- * @author wuweifeng wrote on 2019-12-06
- * @version 1.0
- */
-public class JdEtcdClient implements IConfigCenter {
-
- private KvClient kvClient;
- private LeaseClient leaseClient;
- private LockClient lockClient;
-
-
- public JdEtcdClient(KvStoreClient kvStoreClient) {
- this.kvClient = kvStoreClient.getKvClient();
- this.leaseClient = kvStoreClient.getLeaseClient();
- this.lockClient = kvStoreClient.getLockClient();
- }
-
-
- public LeaseClient getLeaseClient() {
- return leaseClient;
- }
-
- public void setLeaseClient(LeaseClient leaseClient) {
- this.leaseClient = leaseClient;
- }
-
- public KvClient getKvClient() {
- return kvClient;
- }
-
- public void setKvClient(KvClient kvClient) {
- this.kvClient = kvClient;
- }
-
- public LockClient getLockClient() {
- return lockClient;
- }
-
- public void setLockClient(LockClient lockClient) {
- this.lockClient = lockClient;
- }
-
- @Override
- public void put(String key, String value) {
- kvClient.put(ByteString.copyFromUtf8(key), ByteString.copyFromUtf8(value)).sync();
- }
-
- @Override
- public void put(String key, String value, long leaseId) {
- kvClient.put(ByteString.copyFromUtf8(key), ByteString.copyFromUtf8(value), leaseId).sync();
- }
-
- @Override
- public void revoke(long leaseId) {
- leaseClient.revoke(leaseId);
- }
-
- @Override
- public long putAndGrant(String key, String value, long ttl) {
- LeaseGrantResponse lease = leaseClient.grant(ttl).sync();
- put(key, value, lease.getID());
- return lease.getID();
- }
-
- @Override
- public long setLease(String key, long leaseId) {
- kvClient.setLease(ByteString.copyFromUtf8(key), leaseId);
- return leaseId;
- }
-
- @Override
- public void delete(String key) {
- kvClient.delete(ByteString.copyFromUtf8(key)).sync();
- }
-
- @Override
- public String get(String key) {
- RangeResponse rangeResponse = kvClient.get(ByteString.copyFromUtf8(key)).sync();
- List keyValues = rangeResponse.getKvsList();
-
- if (CollectionUtil.isEmpty(keyValues)) {
- return null;
- }
- return keyValues.get(0).getValue().toStringUtf8();
- }
-
- @Override
- public KeyValue getKv(String key) {
- RangeResponse rangeResponse = kvClient.get(ByteString.copyFromUtf8(key)).sync();
- List keyValues = rangeResponse.getKvsList();
- if (CollectionUtil.isEmpty(keyValues)) {
- return null;
- }
- return keyValues.get(0);
- }
-
- @Override
- public List getPrefix(String key) {
- RangeResponse rangeResponse = kvClient.get(ByteString.copyFromUtf8(key)).asPrefix().sync();
- return rangeResponse.getKvsList();
- }
-
- @Override
- public KvClient.WatchIterator watch(String key) {
- return kvClient.watch(ByteString.copyFromUtf8(key)).start();
- }
-
- @Override
- public KvClient.WatchIterator watchPrefix(String key) {
- return kvClient.watch(ByteString.copyFromUtf8(key)).asPrefix().start();
- }
-
- @Override
- public long keepAlive(String key, String value, int frequencySecs, int minTtl) throws Exception {
- //minTtl秒租期,每frequencySecs秒续约一下
- PersistentLease lease = leaseClient.maintain().leaseId(System.currentTimeMillis()).keepAliveFreq(frequencySecs).minTtl(minTtl).start();
- long newId = lease.get(3L, SECONDS);
- put(key, value, newId);
- return newId;
- }
-
- @Override
- public long buildAliveLease(int frequencySecs, int minTtl) throws Exception {
- PersistentLease lease = leaseClient.maintain().leaseId(System.currentTimeMillis()).keepAliveFreq(frequencySecs).minTtl(minTtl).start();
-
- return lease.get(3L, SECONDS);
- }
-
- @Override
- public long buildNormalLease(long ttl) {
- LeaseGrantResponse lease = leaseClient.grant(ttl).sync();
- return lease.getID();
- }
-
- @Override
- public long timeToLive(long leaseId) {
- try {
- return leaseClient.ttl(leaseId).get().getTTL();
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- return 0L;
- }
- }
-}
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 6383e213081462f716c63bc316ea1fd1a1a4a659..71dbafcce03619ad63af878ace4daa05300281c7 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
@@ -1,5 +1,8 @@
package com.jd.platform.jlog.common.constant;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* 常量工具类Constant
*
@@ -24,4 +27,54 @@ public class Constant {
* 当客户端要删除某个key时,就往etcd里赋值这个value,设置1秒过期,就算删除了
*/
public static String DEFAULT_DELETE_VALUE = "#[DELETE]#";
+
+
+ /**
+ * 普通tag最大长度 超过则不会单独存储,不超过则会存入tag:{"normal" : "logContent"}
+ */
+ public static int TAG_NORMAL_KEY_MAX_LEN = 20;
+
+ /**
+ * 可供提取的日志最小长度
+ */
+ public static int EXTRACT_MIN_LEN = 5;
+
+ /**
+ * 符合正则但不构成kv结构的普通日志,如「xx查询为空」
+ */
+ public static final String TAG_NORMAL_KEY = "normal";
+
+ /**
+ * 小于1000不考虑压缩
+ */
+ public static final long MIN = 1000;
+
+
+ /**
+ * 默认大于10000才考虑压缩
+ */
+ public static final long THRESHOLD = 10000;
+
+
+ /**
+ * 正则里需要特殊处理的字符串
+ */
+ public static final Set SPECIAL_CHAR = new HashSet() {
+ {
+ add("*");
+ add(".");
+ add("?");
+ add("+");
+ add("$");
+ add("^");
+ add("[");
+ add("]");
+ add("(");
+ add(")");
+ add("{");
+ add("}");
+ add("|");
+ }
+ };
+
}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/handler/CollectMode.java b/common/src/main/java/com/jd/platform/jlog/common/handler/CollectMode.java
new file mode 100644
index 0000000000000000000000000000000000000000..da4d95422ef26ee559f2c61bd327bda3d8283a5d
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/handler/CollectMode.java
@@ -0,0 +1,100 @@
+package com.jd.platform.jlog.common.handler;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName CollectMode.java
+ * @Description 定义采集模式的组合 用于以后method级别的tag注解
+ * @createTime 2022年02月24日 23:10:00
+ */
+
+public class CollectMode {
+
+ /**
+ * 挂起 不提取不压缩
+ */
+ public static final long SUSPEND = 0L;
+
+ /**
+ * 提取req
+ */
+ public static final long E_REQ = 1L;
+
+ /**
+ * 压缩req
+ */
+ public static final long C_REQ = 1L << 2;
+
+ /**
+ * 提取log
+ */
+ public static final long E_LOG = 1L << 3;
+
+ /**
+ * 压缩log
+ */
+ public static final long C_LOG = 1L << 4;
+
+ /**
+ * 提取resp
+ */
+ public static final long E_RESP = 1L << 5;
+
+ /**
+ * 压缩resp
+ */
+ public static final long C_RESP = 1L << 6;
+
+
+
+ /** ======================================= 下面是组合 ======================================= */
+
+
+
+ /**
+ * 提取req+log
+ */
+ public static final long EXTRACT_REQ_LOG = E_REQ | E_LOG;
+
+ /**
+ * 提取req+resp
+ */
+ public static final long EXTRACT_REQ_REQP = E_REQ | E_RESP;
+
+ /**
+ * 提取req+resp
+ */
+ public static final long EXTRACT_REQ_RESP = E_REQ | E_RESP;
+
+ /**
+ * 提取req+log+resp
+ */
+ 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;
+
+ /**
+ * 压缩log+resp
+ */
+ public static final long COMPRESS_LOG_RESP = C_REQ | C_RESP;
+
+ /**
+ * 压缩req+log+resp
+ */
+ public static final long COMPRESS_ALL = C_REQ | C_LOG | C_RESP;
+
+
+ public static boolean isMatched(long indicator, long position) {
+ return (indicator & position) == position;
+ }
+
+}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/handler/CompressHandler.java b/common/src/main/java/com/jd/platform/jlog/common/handler/CompressHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d13f834c1532b2e0ef0afb04168b691150f8721
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/handler/CompressHandler.java
@@ -0,0 +1,97 @@
+package com.jd.platform.jlog.common.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.common.utils.ZstdUtils;
+import com.sun.istack.internal.NotNull;
+
+import java.util.Base64;
+import java.util.Map;
+
+import static com.jd.platform.jlog.common.constant.Constant.MIN;
+import static com.jd.platform.jlog.common.constant.Constant.THRESHOLD;
+import static com.jd.platform.jlog.common.handler.CollectMode.*;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName CompressHandler.java
+ * @Description TODO
+ * @createTime 2022年03月10日 20:52:00
+ */
+public class CompressHandler {
+
+ /**
+ * 压缩策略
+ */
+ private long compress;
+
+ /**
+ * 超过limit的才压缩
+ */
+ private long threshold;
+
+
+ private CompressHandler(long compress, long threshold){
+ this.compress = compress;
+ this.threshold = threshold;
+ }
+
+
+ private static volatile CompressHandler instance = null;
+
+
+ public static void buildCompressHandler(Long compress, Long threshold) {
+ if(compress == null || compress < 1){
+ compress = COMPRESS_LOG_RESP;
+ }
+ if( threshold == null || threshold < MIN){
+ threshold = THRESHOLD;
+ }
+ instance = new CompressHandler(compress, threshold);
+ }
+
+ public static void refresh(Long compress, Long threshold){
+ instance = null;
+ buildCompressHandler(compress, threshold);
+ }
+
+ public static Map compressReq(Map map){
+ if(instance == null || !isMatched(instance.compress, E_REQ)){
+ return map;
+ }
+
+ for (Map.Entry entry : map.entrySet()) {
+ map.put(entry.getKey(), doCompress(entry.getValue().toString().getBytes()));
+ }
+ return map;
+ }
+
+ public static byte[] compressLog(byte[] contentBytes){
+ if(instance == null || !isMatched(instance.compress, E_LOG)){ return contentBytes; }
+ return doCompress(contentBytes);
+ }
+
+ public static byte[] compressResp(byte[] contentBytes){
+ if(instance == null || !isMatched(instance.compress, E_RESP)){ return contentBytes; }
+ return doCompress(contentBytes);
+ }
+
+ private static byte[] doCompress(byte[] contentBytes){
+ if(contentBytes.length < instance.threshold){
+ return contentBytes;
+ }
+ //最终的要发往worker的response,经历了base64压缩
+ byte[] bytes = ZstdUtils.compress(contentBytes);
+ return Base64.getEncoder().encode(bytes);
+ }
+
+
+ public long getCompress() {
+ return compress;
+ }
+
+ public void setCompress(long compress) {
+ this.compress = compress;
+ }
+
+}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/handler/ExtractHandler.java b/common/src/main/java/com/jd/platform/jlog/common/handler/ExtractHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..b72207672570abec21a4371bc64541ced7f8a4fd
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/handler/ExtractHandler.java
@@ -0,0 +1,225 @@
+package com.jd.platform.jlog.common.handler;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.common.utils.CollectionUtil;
+import com.jd.platform.jlog.common.utils.ConfigUtil;
+import com.jd.platform.jlog.common.utils.StringUtil;
+import com.sun.istack.internal.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.handler.CollectMode.*;
+import static com.jd.platform.jlog.common.handler.CollectMode.E_LOG;
+import static com.jd.platform.jlog.common.handler.CollectMode.E_REQ;
+import static com.jd.platform.jlog.common.utils.ConfigUtil.RANDOM;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ExtractHandler.java
+ * @createTime 2022年02月12日 21:28:00
+ */
+public class ExtractHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ExtractHandler.class);
+
+ private List reqTags;
+
+ private List logTags;
+
+ private List respTags;
+
+ private String delimiter = "|";
+
+ private int delimiterLen = delimiter.length();
+
+ private String join = "=";
+
+ private Pattern pattern;
+
+ private long extract;
+
+ private static volatile ExtractHandler instance = null;
+
+ /**
+ * 构建标签处理器
+ * @param tagConfig 配置类
+ */
+ public static void buildExtractHandler(TagConfig tagConfig) {
+ if(tagConfig.getExtract() == SUSPEND){
+ return;
+ }
+
+ ExtractHandler handler = new ExtractHandler();
+ handler.extract = tagConfig.getExtract();
+ handler.reqTags = tagConfig.getReqTags();
+ handler.logTags = tagConfig.getLogTags();
+ handler.respTags = tagConfig.getRespTags();
+
+ String regex = tagConfig.getRegex();
+ if(StringUtil.isNotBlank(regex)){
+ handler.pattern = Pattern.compile(regex);
+ }else{
+ String escapeDelimiter = ConfigUtil.escapeExprSpecialWord(tagConfig.getDelimiter());
+ String str = String.format("(%s[\\w\\W]*?%s)", escapeDelimiter, escapeDelimiter);
+ handler.pattern = Pattern.compile(str);
+ }
+ handler.delimiter = tagConfig.getDelimiter();
+ handler.delimiterLen = tagConfig.getDelimiter().length();
+ handler.join = tagConfig.getJoin();
+ instance = handler;
+ LOGGER.info("构建标签处理器单例完成:{}",instance.toString());
+ }
+
+
+ /**
+ * 提取请求参数里的标签
+ * @param reqMap 额外附加的,如ip等
+ * @return tags
+ */
+ public static Map extractReqTag(Map reqMap) {
+
+ if(instance == null || !isMatched(instance.extract, E_REQ)){ return null; }
+
+ System.out.println("### REQ INSTANCE :"+instance.toString());
+
+ Map tagMap = new HashMap<>(instance.reqTags.size());
+ for (String tag : instance.reqTags) {
+ Object val = reqMap.get(tag);
+ if(val != null){
+ tagMap.put(tag, val);
+ }
+ }
+ System.out.println("提取到了请求入参日志标签:"+JSON.toJSONString(tagMap));
+ return tagMap;
+ }
+
+
+ /**
+ * 提取普通log里标签
+ * @param content 内容
+ * @return tags
+ */
+ public static Map extractLogTag(String content) {
+ if(instance == null || !isMatched(instance.extract, E_LOG) || content.length() < EXTRACT_MIN_LEN){
+ return null;
+ }
+
+ Map tagMap = new HashMap<>(3);
+ Matcher m = instance.pattern.matcher(content);
+ while (m.find()) {
+ String str = m.group().substring(instance.delimiterLen, m.group().length() - instance.delimiterLen);
+ if(str.contains(instance.join)){
+ String[] arr = str.split(instance.join);
+ if(instance.logTags.contains(arr[0])){
+ tagMap.put(arr[0], arr[1]);
+ }
+ }else if(str.length() < TAG_NORMAL_KEY_MAX_LEN){
+ tagMap.put(TAG_NORMAL_KEY, str);
+ }else{
+ if (RANDOM.nextInt(50) == 1) {
+ LOGGER.info("Some logs lack tags and are larger than 20 in length. Therefore, they are simply stored");
+ }
+ }
+ }
+ System.out.println("提取到了请求log日志标签:"+JSON.toJSONString(tagMap));
+ return tagMap;
+ }
+
+
+ /**
+ * 提取返回结果的tag
+ * @param resp 参数
+ * @return map
+ */
+ public static Map extractRespTag(Map resp) {
+
+ if(instance == null || !isMatched(instance.extract, E_REQ)){ return null; }
+
+ Map requestMap = new HashMap<>(instance.respTags.size());
+ for (String tag : instance.respTags) {
+ Object val = resp.get(tag);
+ if(val != null){
+ requestMap.put(tag, val);
+ }
+ }
+ System.out.println("提取到了请求出参日志标签:"+JSON.toJSONString(requestMap));
+ return requestMap;
+ }
+
+
+
+
+ /**
+ * 刷新标签处理器 加锁是为了防止极端情况下, 先到的config1覆盖后到的config2
+ * @param tagConfig 新的配置
+ */
+ public synchronized static void refresh(TagConfig tagConfig) {
+ instance = null;
+ buildExtractHandler(tagConfig);
+ }
+
+
+ @Override
+ public String toString() {
+ return "TagHandler{" +
+ "reqTags=" + reqTags +
+ ", logTags=" + logTags +
+ ", delimiter='" + delimiter + '\'' +
+ ", delimiterLen=" + delimiterLen +
+ ", join='" + join + '\'' +
+ ", pattern=" + pattern +
+ ", extract=" + extract +
+ '}';
+ }
+
+ // static Pattern BRACKET_PATTERN = Pattern.compile("(\\|[\\w\\W]*?\\|)");
+ public static List extractTest(String content) {
+
+ TagConfig cfg = new TagConfig();
+ cfg.setDelimiter("|");
+ cfg.setJoin("=");
+
+ buildExtractHandler(cfg);
+
+ List list = new ArrayList<>();
+ // Matcher m = BRACKET_PATTERN.matcher(content);
+ Matcher m = instance.pattern.matcher(content);
+ while (m.find()) {
+ list.add(m.group().substring(1, m.group().length() - 1));
+ // list.add(m.group().substring(2, m.group().length() - 2));
+
+ }
+ return list;
+ }
+
+
+ //static Pattern BRACKET_PATTERN = Pattern.compile("(\\{\\{[\\w\\W]*?\\}\\})");
+ // static Pattern BRACKET_PATTERN = Pattern.compile("(\\|\\|[\\w\\W]*?\\|\\|)");
+ static Pattern BRACKET_PATTERN = Pattern.compile("(\\|[\\w\\W]*?\\|)");
+
+ static String str1 = "|errno=val3||node=val4||这是随便的log|";
+ static String str2 = "||a=1||b=2||qwewe||";
+ static String str3 = "||a=1||eee||b=2";
+ static String str4 = "||a=1||eee||b=2||";
+
+
+ public static void main(String[] args) {
+
+
+ //### INSTANCE:TagHandler{reqTags=[uid, url], logTags=[node, bizType],
+ // delimiter='|', delimiterLen=1, join='"="', pattern="", extract=41}
+ //### .content:|errno=val3||node=val4||这是随便的log|
+ System.out.println("msgByRegular1==> "+JSON.toJSONString(extractTest(str1)));
+ /* System.out.println("msgByRegular2==> "+JSON.toJSONString(extractTest(str2)));
+ System.out.println("msgByRegular3==> "+JSON.toJSONString(extractTest(str3)));
+ System.out.println("msgByRegular4==> "+JSON.toJSONString(extractTest(str4)));*/
+ }
+}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/handler/JcProperties.java b/common/src/main/java/com/jd/platform/jlog/common/handler/JcProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a8e9ab4886dec8db8b0511b4de38073f0470b6f
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/handler/JcProperties.java
@@ -0,0 +1,93 @@
+package com.jd.platform.jlog.common.handler;
+
+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.lang.reflect.Field;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import static com.jd.platform.jlog.common.utils.ConfigUtil.invoke;
+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 = get(key);
+ if(val == null){
+ return null;
+ }
+ return String.valueOf(val);
+ }
+
+ public Long getLong(String key) {
+ String val = getString(key);
+ if(val == null){
+ return null;
+ }
+ return Long.parseLong(val);
+ }
+
+
+ public List getStrList(String key) {
+ if(StringUtil.isEmpty(key)){
+ return null;
+ }
+ String val = getString(key);
+ if(StringUtil.isNotEmpty(val)){
+ return FastJsonUtils.toList(val,String.class);
+ }
+ return null;
+ }
+
+ /* public List getStrList(String key) {
+ if(StringUtil.isEmpty(key)){
+ return null;
+ }
+ int index = 0;
+ String suffix;
+ String fastSuffix;
+ List list = new ArrayList<>();
+ do{
+ suffix = "["+index+"]";
+ fastSuffix = "["+(index+1)+"]";
+ list.add(getString(key+suffix));
+ index ++;
+ }while (getString(key + fastSuffix) != null);
+ return list;
+ }*/
+
+ 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;
+ }
+
+
+
+}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/handler/Tag.java b/common/src/main/java/com/jd/platform/jlog/common/handler/Tag.java
new file mode 100644
index 0000000000000000000000000000000000000000..979bea39fd8527cc58c869e172b14283d4fbf6f4
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/handler/Tag.java
@@ -0,0 +1,25 @@
+package com.jd.platform.jlog.common.handler;
+
+import java.lang.annotation.*;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName Tag.java
+ * @Description TODO 后续完善使用
+ * @createTime 2022年02月24日 20:21:00
+ */
+@Documented
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Tag {
+
+ boolean extractReq();
+
+ boolean compressReq();
+
+ boolean extractResp();
+
+ boolean compressResp();
+
+}
\ No newline at end of file
diff --git a/common/src/main/java/com/jd/platform/jlog/common/handler/TagConfig.java b/common/src/main/java/com/jd/platform/jlog/common/handler/TagConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..1240f34c3e66fc87ef0788e72a1174a0ce546c2f
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/handler/TagConfig.java
@@ -0,0 +1,123 @@
+package com.jd.platform.jlog.common.handler;
+
+import java.io.Serializable;
+import java.util.List;
+
+import static com.jd.platform.jlog.common.handler.CollectMode.COMPRESS_ALL;
+import static com.jd.platform.jlog.common.handler.CollectMode.EXTRACT_ALL;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName TagConfig.java
+ * @createTime 2022年02月13日 22:35:00
+ */
+public class TagConfig implements Serializable {
+
+ /**
+ * 入参的tag
+ */
+ private List reqTags;
+
+ /**
+ * 普通日志的tag
+ */
+ private List logTags;
+
+ /**
+ * 返参的tag
+ */
+ private List respTags;
+
+ /**
+ * 自定义正则 可为空
+ */
+ private String regex;
+
+ /**
+ * 分隔符 默认|
+ */
+ private String delimiter = "|";
+
+ /**
+ * 连接符 默认=
+ */
+ private String join = "=";
+
+ /**
+ * 提取策略
+ */
+ private long extract = EXTRACT_ALL;
+
+
+
+ public List getReqTags() {
+ return reqTags;
+ }
+
+ public void setReqTags(List reqTags) {
+ this.reqTags = reqTags;
+ }
+
+ public List getLogTags() {
+ return logTags;
+ }
+
+ public void setLogTags(List logTags) {
+ this.logTags = logTags;
+ }
+
+ public List getRespTags() {
+ return respTags;
+ }
+
+ public void setRespTags(List respTags) {
+ this.respTags = respTags;
+ }
+
+ public String getRegex() {
+ return regex;
+ }
+
+ public void setRegex(String regex) {
+ this.regex = regex;
+ }
+
+ public String getDelimiter() {
+ return delimiter;
+ }
+
+ public void setDelimiter(String delimiter) {
+ this.delimiter = delimiter;
+ }
+
+ public String getJoin() {
+ return join;
+ }
+
+ public void setJoin(String join) {
+ this.join = join;
+ }
+
+ public long getExtract() {
+ return extract;
+ }
+
+ public void setExtract(long extract) {
+ this.extract = extract;
+ }
+
+
+ @Override
+ public String toString() {
+ return "TagConfig{" +
+ "reqTags=" + reqTags +
+ ", logTags=" + logTags +
+ ", respTags=" + respTags +
+ ", regex='" + regex + '\'' +
+ ", delimiter='" + delimiter + '\'' +
+ ", join='" + join + '\'' +
+ ", extract='" + extract + '\'' +
+ '}';
+ }
+}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/model/RunLogMessage.java b/common/src/main/java/com/jd/platform/jlog/common/model/RunLogMessage.java
index 665c5ad6283da8895211ca73548ed08a791923c5..6af7ab79dec9d1f9bd303c9cbca725731c2fd61b 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/model/RunLogMessage.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/model/RunLogMessage.java
@@ -1,5 +1,7 @@
package com.jd.platform.jlog.common.model;
+import java.util.Map;
+
/**
* className:RunLogMessage
* description:
@@ -37,6 +39,11 @@ public class RunLogMessage {
*/
private String threadName;
+ /**
+ * 标签map
+ */
+ private Map tagMap;
+
public long getTracerId() {
return tracerId;
}
@@ -92,4 +99,12 @@ public class RunLogMessage {
public void setThreadName(String threadName) {
this.threadName = threadName;
}
+
+ public Map getTagMap() {
+ return tagMap;
+ }
+
+ public void setTagMap(Map tagMap) {
+ this.tagMap = tagMap;
+ }
}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/model/TracerBean.java b/common/src/main/java/com/jd/platform/jlog/common/model/TracerBean.java
index 66b2b2fb6efb54bc8e24c5ce4dcddf6f3d5eb5c1..ac6b03d01a7948c20b68e8fce1586d38b1a8065c 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/model/TracerBean.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/model/TracerBean.java
@@ -25,7 +25,7 @@ public class TracerBean implements Serializable {
private String tracerId;
/**
* tracer对象,里面放的是List>
- * 第一个元素是request对象,key为request,value为完整request入参,从中可找到pin、uuid
+ * 第一个元素是request对象,key为request,value为完整request入参,从中可找到uuid
* 最后一个元素是response响应,key为response,value为响应值byte[],可转为String入库
*/
private List> tracerObject;
diff --git a/common/src/main/java/com/jd/platform/jlog/common/utils/AsyncPool.java b/common/src/main/java/com/jd/platform/jlog/common/utils/AsyncPool.java
index bae815c65d0ae87fa3094fecb0a05df26415322c..11313ec4fcd7a8ca03b36a8e03e61cddf52143b8 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/utils/AsyncPool.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/AsyncPool.java
@@ -1,7 +1,10 @@
package com.jd.platform.jlog.common.utils;
+import java.util.Collection;
+import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
/**
* 异步线程池AsyncPool
@@ -19,4 +22,6 @@ public class AsyncPool {
public static void shutDown() {
threadPoolExecutor.shutdown();
}
+
+
}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/utils/AsyncWorker.java b/common/src/main/java/com/jd/platform/jlog/common/utils/AsyncWorker.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f340fd9d6490a9bfbca9299fde4c52ecfd82aed
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/AsyncWorker.java
@@ -0,0 +1,37 @@
+package com.jd.platform.jlog.common.utils;
+
+import java.util.Collection;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName AsyncWorker.java
+ * @Description TODO
+ * @createTime 2022年02月21日 17:10:00
+ */
+public class AsyncWorker {
+
+ public static int drain(BlockingQueue q, Collection super E> buffer, int numElements, long timeout, TimeUnit unit) throws Exception {
+ if(buffer == null){
+ throw new Exception("[Assertion failed] - the buffer argument cannot be null");
+ }
+ long deadline = System.nanoTime() + unit.toNanos(timeout);
+ int added = 0;
+
+ while(added < numElements) {
+ added += q.drainTo(buffer, numElements - added);
+ if (added < numElements) {
+ E e = q.poll(deadline - System.nanoTime(), TimeUnit.NANOSECONDS);
+ if (e == null) {
+ break;
+ }
+ buffer.add(e);
+ ++added;
+ }
+ }
+ return added;
+ }
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..87af2f6d1bb0cd0f5403f27809f865f10aac901d
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/CollectionUtil.java
@@ -0,0 +1,219 @@
+package com.jd.platform.jlog.common.utils;
+
+import com.alibaba.fastjson.JSON;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName CollectionUtil.java
+ * @Description TODO
+ * @createTime 2022年02月21日 17:14:00
+ */
+public class CollectionUtil {
+
+ public static boolean isEmpty(Collection> collection) {
+ return collection == null || collection.isEmpty();
+ }
+
+ public static boolean isNotEmpty(Collection> collection) {
+ return collection != null && collection.isEmpty();
+ }
+
+
+ public static boolean isEmpty(Map, ?> map) {
+ return !isNotEmpty(map);
+ }
+
+
+ public static boolean isNotEmpty(Map, ?> map) {
+ return map != null && !map.isEmpty();
+ }
+
+
+ public static boolean equals(List c1, List c2) {
+ if (c1 == null && c2 == null) {
+ return true;
+ } else if (c1 != null && c2 != null) {
+ if (c1.size() != c2.size()) {
+ return false;
+ } else {
+ for(int i = 0; i < c1.size(); ++i) {
+ if (!Objects.equals(c1.get(i), c2.get(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ public static boolean equals(Map c1, Map c2) {
+ if (c1 == null && c2 == null) {
+ return true;
+ } else if (c1 != null && c2 != null) {
+ if (c1.size() != c2.size()) {
+ return false;
+ } else {
+ Iterator var2 = c1.entrySet().iterator();
+
+ Object v1;
+ Object v2;
+ do {
+ if (!var2.hasNext()) {
+ return true;
+ }
+
+ Map.Entry entry = (Map.Entry)var2.next();
+ K k = entry.getKey();
+ v1 = entry.getValue();
+ v2 = c2.get(k);
+ } while(Objects.equals(v1, v2));
+
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+
+
+
+
+ public static Set diffKeys(Map m1, Map m2){
+
+ Set diff = new HashSet<>(1);
+
+ for (Map.Entry kvEntry : m1.entrySet()) {
+ V val = m2.get(kvEntry.getKey());
+ if(!kvEntry.getValue().equals(val)){
+ diff.add(kvEntry.getKey().toString());
+ }
+ }
+
+ for (Map.Entry kvEntry : m2.entrySet()) {
+ V val = m1.get(kvEntry.getKey());
+ if(!kvEntry.getValue().equals(val)){
+ diff.add(kvEntry.getKey().toString());
+ }
+ }
+ return diff;
+ }
+
+
+
+
+ public static HashMap diffMap(Map m1, Map m2){
+
+ HashMap diff = new HashMap<>(1);
+
+ for (Map.Entry kvEntry : m1.entrySet()) {
+ V val = m2.get(kvEntry.getKey());
+ if(!kvEntry.getValue().equals(val)){
+ diff.put(kvEntry.getKey(), kvEntry.getValue());
+ }
+ }
+
+ for (Map.Entry kvEntry : m2.entrySet()) {
+ V val = m1.get(kvEntry.getKey());
+ if(!kvEntry.getValue().equals(val)){
+ diff.put(kvEntry.getKey(), kvEntry.getValue());
+ }
+ }
+ return diff;
+ }
+
+
+ public static void main(String[] args) {
+ 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++;
+ }
+ }
+
+ 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
new file mode 100644
index 0000000000000000000000000000000000000000..48ef52f90f9ce1860acecad1bd7347d431315359
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/ConfigUtil.java
@@ -0,0 +1,236 @@
+package com.jd.platform.jlog.common.utils;
+
+import com.jd.platform.jlog.common.constant.Constant;
+import com.jd.platform.jlog.common.handler.JcProperties;
+
+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.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ConfigUtil.java
+ * @Description TODO
+ * @createTime 2022年02月13日 21:40:00
+ */
+public class ConfigUtil {
+
+
+ private static final String SERVER_SUFFIX = "Server";
+
+ 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) {
+ for (String s : Constant.SPECIAL_CHAR) {
+ if (str.contains(s)) {
+ str = str.replace(s, "\\" + s);
+ }
+ }
+ }
+ return str;
+ }
+
+
+ public static String formatConfigStr(Properties properties) {
+
+ StringBuilder sb = new StringBuilder();
+ Enumeration> enumeration = properties.propertyNames();
+ while (enumeration.hasMoreElements()) {
+ String key = (String) enumeration.nextElement();
+ Object property = properties.get(key);
+ if (property != null) {
+ property = String.valueOf(property);
+ }
+ sb.append(key).append("=").append(property).append("\n");
+ }
+ return sb.toString();
+ }
+
+
+ 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 {
+ Class> clz = config.getClass();
+ Field[] fields = clz.getDeclaredFields();
+
+ for (Field field : fields) {
+ Method m = clz.getMethod("get" + getMethodName(field.getName()));
+ String val = (String)m.invoke(config);
+ if (val != null) {
+ for (ConfigCenterEnum center : ConfigCenterEnum.values()) {
+ String fd = field.getName().replace(SERVER_SUFFIX, "");
+ if(center.name().equals(fd.toUpperCase())){
+ return center;
+ }
+ }
+ }
+ }
+ throw new Exception("Configuration center cannot be found");
+ }
+*/
+
+
+ private static String getMethodName(String fieldName) {
+ byte[] items = fieldName.getBytes();
+ 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);
+ }
+
+
+ /**
+ * 只支持简单的对象形配置
+ * @param model bean
+ * @param properties 配置
+ * @param prefix 前缀
+ */
+ @Deprecated
+ public static 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, Integer.parseInt(properties.getString(fillName))) ;
+ 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[] arr = fillName.split("\\[");
+ int index = 0;
+ String suffix;
+ String fastSuffix;
+ List list = new ArrayList<>();
+ do{
+ suffix = "["+index+"]";
+ fastSuffix = "["+(index+1)+"]";
+ list.add(properties.getString(arr[0]+suffix));
+ index ++;
+ }while (properties.getString(arr[0]+fastSuffix) != null);
+ field.set(model, list);
+ }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/common/src/main/java/com/jd/platform/jlog/common/utils/FastJsonUtils.java b/common/src/main/java/com/jd/platform/jlog/common/utils/FastJsonUtils.java
index 2b2ebe6a46154337a353dd389d6a8068e22554fa..976e1efacee182121986355e41deeecc476ef727 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/utils/FastJsonUtils.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/FastJsonUtils.java
@@ -72,7 +72,7 @@ public class FastJsonUtils {
/**
* json字符串转化为map
*/
- public static Map stringToCollect(String s) {
+ public static Map toMap(String s) {
return (Map) JSONObject.parseObject(s);
}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/utils/IdWorker.java b/common/src/main/java/com/jd/platform/jlog/common/utils/IdWorker.java
index 9cb37dc424a0efae181fb3a956989bbba1077c18..4b603051f2c13823b9b46c29a21329cda51264b0 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/utils/IdWorker.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/IdWorker.java
@@ -1,6 +1,6 @@
package com.jd.platform.jlog.common.utils;
-import com.google.common.base.Preconditions;
+import com.sun.tools.javac.util.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -86,14 +86,14 @@ public class IdWorker {
* @param workerId 工作进程Id
*/
private static void setWorkerId(final Long workerId) {
- Preconditions.checkArgument(workerId >= 0L && workerId < WORKER_ID_MAX_VALUE);
+ Assert.check(workerId >= 0L && workerId < WORKER_ID_MAX_VALUE);
IdWorker.workerId = workerId;
}
//下一个ID生成算法
public static long nextId() {
long time = System.currentTimeMillis();
- Preconditions.checkState(lastTime <= time, "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds", lastTime, time);
+ Assert.check(lastTime <= time, "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds"+lastTime);
if (lastTime == time) {
if (0L == (sequence = ++sequence & SEQUENCE_MASK)) {
time = waitUntilNextTime(time);
diff --git a/common/src/main/java/com/jd/platform/jlog/common/utils/StringUtil.java b/common/src/main/java/com/jd/platform/jlog/common/utils/StringUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..09aaa5f86c91e2649caf7cc05087d86956fa9f7c
--- /dev/null
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/StringUtil.java
@@ -0,0 +1,45 @@
+package com.jd.platform.jlog.common.utils;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName StringUtil.java
+ * @Description TODO
+ * @createTime 2022年02月21日 17:13:00
+ */
+public class StringUtil {
+
+
+ public StringUtil() {
+ }
+
+ public static boolean isEmpty(CharSequence cs) {
+ return cs == null || cs.length() == 0;
+ }
+
+ public static boolean isNotEmpty(CharSequence cs) {
+ return !isEmpty(cs);
+ }
+
+
+ public static boolean isBlank(CharSequence cs) {
+ int strLen;
+ if (cs != null && (strLen = cs.length()) != 0) {
+ for(int i = 0; i < strLen; ++i) {
+ if (!Character.isWhitespace(cs.charAt(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ } else {
+ return true;
+ }
+ }
+
+ public static boolean isNotBlank(CharSequence cs) {
+ return !isBlank(cs);
+ }
+
+
+}
diff --git a/common/src/main/java/com/jd/platform/jlog/common/utils/ZstdUtils.java b/common/src/main/java/com/jd/platform/jlog/common/utils/ZstdUtils.java
index 3a125d076041cfab919adfd3c3e1ed8720158341..d4757eb28d6148a989bb9429161413bd86519af1 100644
--- a/common/src/main/java/com/jd/platform/jlog/common/utils/ZstdUtils.java
+++ b/common/src/main/java/com/jd/platform/jlog/common/utils/ZstdUtils.java
@@ -2,6 +2,11 @@ package com.jd.platform.jlog.common.utils;
import com.github.luben.zstd.Zstd;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* zstd压缩工具类
*
@@ -39,4 +44,116 @@ public class ZstdUtils {
return ob;
}
+
+
+ /**
+ * 解压
+ */
+ public static byte[] decompressBytes2(byte[] bytes) {
+ int size = (int) Zstd.decompressedSize(bytes);
+ System.out.println("size-> "+size);
+ byte[] ob = new byte[size];
+ Zstd.decompress(ob, bytes);
+
+ return ob;
+ }
+
+ public static void main(String[] args) throws InterruptedException, ClassNotFoundException, IllegalAccessException, InstantiationException {
+
+ String s = "-75";
+ char firstChar = s.charAt(0);
+ System.out.println(firstChar);
+ if (firstChar < '0') { // Possible leading "+" or "-"
+ if (firstChar == '-') {
+ System.out.println("=========");
+ } else if (firstChar != '+')
+ System.out.println("eeee");
+
+ }
+ // System.out.println(Integer.parseInt("-75"));
+ String str1 = "1a";
+ String str2 = "0a";
+
+ String dbStr = Arrays.toString(compress(str1.getBytes()));
+ System.out.println(dbStr);
+ String[] arr0 = dbStr.split(",");
+
+ byte[] bt = new byte[arr0.length];
+ for (int i = 0; i < arr0.length; i++) {
+ if(i == 0){
+ String first = arr0[0].replace("[", "");
+ bt[i] = Byte.valueOf(first);
+ continue;
+ }
+ if(i == arr0.length-1){
+ String last = arr0[arr0.length-1].replace("]", "");
+ bt[i] = Byte.valueOf(last.trim());
+ continue;
+ }
+ System.out.println(arr0[i]+" len => "+arr0[i].length());
+ bt[i] = Byte.parseByte(arr0[i].trim());
+ }
+
+
+ System.out.println(Arrays.toString(bt));
+ // System.out.println(Arrays.toString(compress(str2.getBytes())));
+
+ AtomicInteger fail = new AtomicInteger(0);
+ AtomicInteger ok = new AtomicInteger(0);
+
+ for (int j = 0; j < 1; j++) {
+ new Thread(() -> {
+ for (int i = 0; i < 100; i++) {
+ int id = new Random().nextInt(99000000);
+ /* String ml = String.valueOf(getRandomChar()) +id+getRandomChar();
+ String ml2 = LocalDateTime.now().toString()+ getRandomChar();
+ ml = ml2 + ml;*/
+ // 压缩后的
+ String ml = ""+i;
+ byte[] mlc1= compress(ml.getBytes());
+
+ //存进去new String(mlc1)
+ byte[] resul = new String(mlc1).getBytes();
+ System.out.println(Arrays.toString(new String(mlc1).getBytes()));
+ byte[] arr = new byte[9];
+ arr[0] = 40;
+ arr[1] = -17;
+ arr[2] = -65;
+ arr[3] = -67;
+ arr[4] = 47;
+ arr[5] = -17;
+ arr[6] = -65;
+ arr[7] = -67;
+ arr[8] = 32;
+ // System.out.println(new String(arr));
+
+ if(resul[0]==40
+ && resul[1]==-17
+ && resul[2]==-65
+ && resul[3]==-67
+ && resul[4]==47
+ && resul[5]==-17
+ && resul[6]==-65
+ && resul[7]==-67
+ && resul[8]==32 ){
+ ok.incrementAndGet();
+ }else{
+ fail.incrementAndGet();
+ }
+ }
+ }).start();
+ }
+
+
+ Thread.sleep(30000);
+
+
+ System.out.println("ok == > "+ok.get());
+ System.out.println("fail == > "+fail.get());
+
+ }
+
+ public static char getRandomChar() {
+ return (char) (0x4e00 + (int) (Math.random() * (0x9fa5 - 0x4e00 + 1)));
+ }
}
\ No newline at end of file
diff --git a/config/config-apollo/pom.xml b/config/config-apollo/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dc41155f523804acd1ec8261a05d128208f854b9
--- /dev/null
+++ b/config/config-apollo/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+ com.jd.platfrom.jlog
+ config
+ 1.4-SNAPSHOT
+
+ 4.0.0
+ config-apollo
+ config-apollo
+
+
+
+ com.jd.platfrom.jlog
+ config-core
+ 1.4-SNAPSHOT
+
+
+ com.ctrip.framework.apollo
+ apollo-client
+ 1.9.2
+
+
+ slf4j-api
+ org.slf4j
+
+
+
+
+
+
+
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
new file mode 100644
index 0000000000000000000000000000000000000000..573999b82872a9275b90aa1b6b7bedc324b2a477
--- /dev/null
+++ b/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConfigurator.java
@@ -0,0 +1,165 @@
+package com.jd.platform.jlog.config.apollo;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.*;
+
+import com.alibaba.fastjson.JSON;
+import com.ctrip.framework.apollo.ConfigFile;
+import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
+import com.ctrip.framework.apollo.core.utils.StringUtils;
+import com.ctrip.framework.apollo.enums.PropertyChangeType;
+import com.ctrip.framework.apollo.model.ConfigChange;
+import com.jd.platform.jlog.common.handler.JcProperties;
+import com.jd.platform.jlog.common.handler.TagConfig;
+import com.jd.platform.jlog.common.utils.CollectionUtil;
+import com.jd.platform.jlog.common.utils.FastJsonUtils;
+import com.jd.platform.jlog.core.*;
+import com.ctrip.framework.apollo.Config;
+import com.ctrip.framework.apollo.ConfigService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+import static com.ctrip.framework.apollo.core.ApolloClientSystemConsts.APP_ID;
+import static com.jd.platform.jlog.common.utils.ConfigUtil.invoke;
+import static com.jd.platform.jlog.config.apollo.ApolloConstant.*;
+import static com.jd.platform.jlog.core.Constant.DEFAULT_NAMESPACE;
+
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @Description todo env and cluster
+ * @ClassName ApolloConfigurator.java
+ * @createTime 2022年02月21日 21:21:00
+ */
+public class ApolloConfigurator implements Configurator {
+
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ApolloConfigurator.class);
+
+
+ private static final Configurator FILE_CONFIG = ConfiguratorFactory.base;
+
+
+ /**
+ * 里面有resourceProperties 和 configProperties
+ */
+ private static volatile Config config;
+
+
+ private static volatile ApolloConfigurator instance;
+
+ private ApolloConfigurator() {
+ loadApolloServerConfig();
+ if (config == null) {
+ synchronized (ApolloConfigurator.class) {
+ if (config == null) {
+ // apollo的监听是按照namespace维度
+ config = ConfigService.getConfig(DEFAULT_NAMESPACE);
+ ApolloListener apolloListener = new ApolloListener();
+ config.addChangeListener(changeEvent -> {
+ LOGGER.info("Apollo收到事件变更, keys={}", changeEvent.changedKeys());
+ for (String key : changeEvent.changedKeys()) {
+ ConfigChange change = changeEvent.getChange(key);
+ ConfigChangeEvent event = new ConfigChangeEvent(key, change.getNamespace(), change.getOldValue(), change.getNewValue(), getChangeType(change.getChangeType()));
+ apolloListener.onProcessEvent(event);
+ }
+ });
+ }
+ }
+ }
+ LOGGER.info("Apollo配置器构建完成");
+ }
+
+
+ public static ApolloConfigurator getInstance() {
+ if (instance == null) {
+ synchronized (ApolloConfigurator.class) {
+ if (instance == null) {
+ instance = new ApolloConfigurator();
+ }
+ }
+ }
+ return instance;
+ }
+
+ @Override
+ public String getString(String key) {
+ return config.getProperty(key, null);
+ }
+
+ @Override
+ public Long getLong(String key) {
+ return config.getLongProperty(key,null);
+ }
+
+ @Override
+ public List getList(String key) {
+ return FastJsonUtils.toList(config.getProperty(key,""), String.class) ;
+ }
+
+ @Override
+ public T getObject(String key, Class clz) {
+ return FastJsonUtils.toBean(config.getProperty(key,""), clz);
+ }
+
+ @Override
+ public boolean putConfig(String key, String content) {
+ return false;
+ }
+
+ @Override
+ public boolean putConfig(String dataId, String content, long timeoutMills) {
+ return false;
+ }
+
+
+ @Override
+ public String getType() {
+ return "apollo";
+ }
+
+
+ private ConfigChangeType getChangeType(PropertyChangeType changeType) {
+ switch (changeType) {
+ case ADDED:
+ return ConfigChangeType.ADD;
+ case DELETED:
+ return ConfigChangeType.DELETE;
+ default:
+ return ConfigChangeType.MODIFY;
+ }
+ }
+
+
+ private void loadApolloServerConfig() {
+
+ Properties properties = System.getProperties();
+ if (!properties.containsKey(PROP_APP_ID)) {
+ System.setProperty(PROP_APP_ID, FILE_CONFIG.getString(APP_ID));
+ }
+ if (!properties.containsKey(PROP_APOLLO_META)) {
+ System.setProperty(PROP_APOLLO_META, FILE_CONFIG.getString(APOLLO_META));
+ }
+ if (!properties.containsKey(PROP_APOLLO_SECRET)) {
+ String secretKey = FILE_CONFIG.getString(APOLLO_SECRET);
+ if (!StringUtils.isBlank(secretKey)) {
+ System.setProperty(PROP_APOLLO_SECRET, secretKey);
+ }
+ }
+ if (!properties.containsKey(APOLLO_CLUSTER)) {
+ if (!StringUtils.isBlank(FILE_CONFIG.getString(APOLLO_CLUSTER))) {
+ System.setProperty(PROP_APOLLO_CLUSTER, FILE_CONFIG.getString(APOLLO_CLUSTER));
+ }
+ }
+ if (!properties.containsKey(APOLLO_CONFIG_SERVICE)) {
+ System.setProperty(PROP_APOLLO_CONFIG_SERVICE, FILE_CONFIG.getString(APOLLO_CONFIG_SERVICE));
+ }
+ }
+
+}
diff --git a/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConfiguratorProvider.java b/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConfiguratorProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fedf351f4043c51c31e4b1a9c4cb306b1c39f1a
--- /dev/null
+++ b/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConfiguratorProvider.java
@@ -0,0 +1,18 @@
+package com.jd.platform.jlog.config.apollo;
+
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorProvider;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ApolloConfiguratorProvider.java
+ * @createTime 2022年02月21日 21:26:00
+ */
+public class ApolloConfiguratorProvider implements ConfiguratorProvider {
+ @Override
+ public Configurator build() {
+ return ApolloConfigurator.getInstance();
+ }
+}
+
diff --git a/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConstant.java b/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConstant.java
new file mode 100644
index 0000000000000000000000000000000000000000..03c0faf910706de27476c617601daf6e90cd75ac
--- /dev/null
+++ b/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloConstant.java
@@ -0,0 +1,20 @@
+package com.jd.platform.jlog.config.apollo;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ApolloConstant.java
+ * @createTime 2022年02月22日 11:06:00
+ */
+public class ApolloConstant {
+
+ static final String APOLLO_META = "apolloMeta";
+ static final String APOLLO_SECRET = "apolloAccesskeySecret";
+ static final String APOLLO_CLUSTER = "jLog";
+ static final String APOLLO_CONFIG_SERVICE = "apollo.config-service";
+ static final String PROP_APP_ID = "app.id";
+ static final String PROP_APOLLO_META = "apollo.meta";
+ static final String PROP_APOLLO_CONFIG_SERVICE = "apollo.config-service";
+ static final String PROP_APOLLO_SECRET = "apollo.accesskey.secret";
+ static final String PROP_APOLLO_CLUSTER = "apollo.cluster";
+}
diff --git a/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloListener.java b/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..a550b3da588e23c6d675c83dced1cf5b9635b6fa
--- /dev/null
+++ b/config/config-apollo/src/main/java/com/jd/platform/jlog/config/apollo/ApolloListener.java
@@ -0,0 +1,19 @@
+package com.jd.platform.jlog.config.apollo;
+
+import com.jd.platform.jlog.core.ClientHandlerBuilder;
+import com.jd.platform.jlog.core.ConfigChangeEvent;
+import com.jd.platform.jlog.core.ConfigChangeListener;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ApolloListener.java
+ * @createTime 2022年02月22日 19:18:00
+ */
+public class ApolloListener implements ConfigChangeListener {
+
+ @Override
+ public void onChangeEvent(ConfigChangeEvent event) {
+ ClientHandlerBuilder.refresh();
+ }
+}
diff --git a/config/config-apollo/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider b/config/config-apollo/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider
new file mode 100644
index 0000000000000000000000000000000000000000..f46c96c8ffdc6fcb6706794f5312a3c4c5646489
--- /dev/null
+++ b/config/config-apollo/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider
@@ -0,0 +1 @@
+com.jd.platform.jlog.config.apollo.ApolloConfiguratorProvider
\ No newline at end of file
diff --git a/config/config-core/pom.xml b/config/config-core/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ca570b17d4eba305467f1b60a6560fe702b6b48d
--- /dev/null
+++ b/config/config-core/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ com.jd.platfrom.jlog
+ config
+ 1.4-SNAPSHOT
+
+ 4.0.0
+ config-core
+ config-core
+
+
+
+ com.jd.platfrom.jlog
+ common
+ 1.4-SNAPSHOT
+
+
+ org.yaml
+ snakeyaml
+ 1.28
+
+
+
+
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/ClientHandler.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/ClientHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..9621b0305343ea7b42693ae0713f9317e3b0234d
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/ClientHandler.java
@@ -0,0 +1,63 @@
+package com.jd.platform.jlog.core;
+
+import com.jd.platform.jlog.common.handler.CompressHandler;
+import com.jd.platform.jlog.common.handler.ExtractHandler;
+import java.util.Map;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ClientHandler.java
+ * @createTime 2022年03月13日 16:53:00
+ */
+public class ClientHandler {
+
+ public static Map processReq(Map reqMap){
+ Map map = ExtractHandler.extractReqTag(reqMap);
+ return CompressHandler.compressReq(map);
+ }
+
+
+ public static Outcome processLog(String content){
+ Map tagMap = ExtractHandler.extractLogTag(content);
+ return new Outcome(tagMap, null);
+ }
+
+
+ public static Outcome processResp(byte[] resp, Map respMap){
+ Map tagMap = ExtractHandler.extractRespTag(respMap);
+ byte[] newContent = CompressHandler.compressResp(resp);
+ return new Outcome(tagMap, newContent);
+ }
+
+
+
+
+
+ public static class Outcome{
+
+ Map map;
+ byte[] content;
+
+ public Outcome(Map map, byte[] content) {
+ this.map = map;
+ this.content = content;
+ }
+
+ public Map getMap() {
+ return map;
+ }
+
+ public void setMap(Map map) {
+ this.map = map;
+ }
+
+ public byte[] getContent() {
+ return content;
+ }
+
+ public void setContent(byte[] content) {
+ this.content = content;
+ }
+ }
+}
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/ClientHandlerBuilder.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/ClientHandlerBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..7af513013e717c232800c107dbf98f986d180b29
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/ClientHandlerBuilder.java
@@ -0,0 +1,44 @@
+package com.jd.platform.jlog.core;
+
+import com.jd.platform.jlog.common.handler.CompressHandler;
+import com.jd.platform.jlog.common.handler.ExtractHandler;
+import com.jd.platform.jlog.common.handler.TagConfig;
+
+import static com.jd.platform.jlog.common.constant.Constant.THRESHOLD;
+import static com.jd.platform.jlog.common.handler.CollectMode.COMPRESS_LOG_RESP;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ClientHandlerBuilder.java
+ * @Description TODO
+ * @createTime 2022年03月05日 22:07:00
+ */
+public class ClientHandlerBuilder {
+
+
+ public static void buildHandler(TagConfig tagConfig, Configurator configurator){
+ if(tagConfig == null){
+ tagConfig = buildTagConfigByConfigurator(configurator);
+ }
+ ExtractHandler.buildExtractHandler(tagConfig);
+ CompressHandler.buildCompressHandler(configurator.getLong("compress"), configurator.getLong("threshold"));
+ }
+
+
+ public static void refresh(){
+ Configurator configurator = ConfiguratorFactory.getInstance();
+ if(configurator == null){
+ throw new RuntimeException("configurator is null");
+ }
+ ExtractHandler.refresh(buildTagConfigByConfigurator(configurator));
+ CompressHandler.refresh(configurator.getLong("compress"), configurator.getLong("threshold") );
+ }
+
+
+
+
+ private static TagConfig buildTagConfigByConfigurator(Configurator configurator){
+ return configurator.getObject("tag-config", TagConfig.class);
+ }
+}
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfigChangeEvent.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfigChangeEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..de81b0557ea0ac25be3d5060ad7e739d2193bb15
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfigChangeEvent.java
@@ -0,0 +1,107 @@
+package com.jd.platform.jlog.core;
+
+
+import static com.jd.platform.jlog.core.Constant.DEFAULT_NAMESPACE;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ConfigChangeEvent.java
+ * @createTime 2022年02月16日 22:13:00
+ */
+public class ConfigChangeEvent {
+
+ private String key;
+ private String oldValue;
+ private String newValue;
+ private String namespace;
+ private ConfigChangeType changeType;
+
+
+ public ConfigChangeEvent(){
+
+ }
+
+ public ConfigChangeEvent(String key, String newValue) {
+ this(key, DEFAULT_NAMESPACE, null, newValue, ConfigChangeType.MODIFY);
+ }
+
+ public ConfigChangeEvent(String key, String oldValue, String newValue){
+ this(key, DEFAULT_NAMESPACE, oldValue, newValue, ConfigChangeType.MODIFY);
+ }
+
+ public ConfigChangeEvent(String key, String namespace, String oldValue, String newValue,
+ ConfigChangeType type) {
+ this.key = key;
+ this.namespace = namespace;
+ this.oldValue = oldValue;
+ this.newValue = newValue;
+ this.changeType = type;
+ }
+
+
+ public String getKey() {
+ return key;
+ }
+
+
+ public ConfigChangeEvent setKey(String key) {
+ this.key = key;
+ return this;
+ }
+
+
+ public String getOldValue() {
+ return oldValue;
+ }
+
+
+ public ConfigChangeEvent setOldValue(String oldValue) {
+ this.oldValue = oldValue;
+ return this;
+ }
+
+
+ public String getNewValue() {
+ return newValue;
+ }
+
+
+ public ConfigChangeEvent setNewValue(String newValue) {
+ this.newValue = newValue;
+ return this;
+ }
+
+
+ public ConfigChangeType getChangeType() {
+ return changeType;
+ }
+
+
+ public ConfigChangeEvent setChangeType(ConfigChangeType changeType) {
+ this.changeType = changeType;
+ return this;
+ }
+
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+
+ public ConfigChangeEvent setNamespace(String namespace) {
+ this.namespace = namespace;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "ConfigChangeEvent{" +
+ "key='" + key + '\'' +
+ ", oldValue='" + oldValue + '\'' +
+ ", newValue='" + newValue + '\'' +
+ ", namespace='" + namespace + '\'' +
+ ", changeType=" + changeType +
+ '}';
+ }
+}
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfigChangeListener.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfigChangeListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d337a2ed7a472174dccc68fa083e2cb18753a3a
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfigChangeListener.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 1999-2019 Seata.io Group.
+ *
+ * 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.jd.platform.jlog.core;
+
+
+import io.netty.util.concurrent.DefaultThreadFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.concurrent.*;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ConfigChangeListener.java
+ * @createTime 2022年02月16日 12:06:00
+ */
+public interface ConfigChangeListener {
+
+ Logger LOGGER = LoggerFactory.getLogger(ConfigChangeListener.class);
+
+
+ ExecutorService EXECUTOR_SERVICE = new ThreadPoolExecutor(1, 1,
+ Integer.MAX_VALUE, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), new DefaultThreadFactory("configListener", 1));
+
+
+ /**
+ * 事件具体处理
+ * @param event event
+ */
+ void onChangeEvent(ConfigChangeEvent event);
+
+
+ /**
+ * 处理变更事件
+ * @param event 事件
+ */
+ default void onProcessEvent(ConfigChangeEvent event) {
+ LOGGER.info("通用监听器配置处理器", event.toString());
+ getExecutorService().submit(() -> {
+ beforeEvent();
+ try {
+ onChangeEvent(event);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ afterEvent();
+ });
+ }
+
+ default void onShutDown() {
+ getExecutorService().shutdown();
+ }
+
+
+ default ExecutorService getExecutorService() {
+ return EXECUTOR_SERVICE;
+ }
+
+
+ default void beforeEvent() {
+
+ }
+
+
+ default void afterEvent() {
+
+ }
+}
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfigChangeType.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfigChangeType.java
new file mode 100644
index 0000000000000000000000000000000000000000..acdee80a471e75466bc0b15b4644d8a4628e6517
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfigChangeType.java
@@ -0,0 +1,14 @@
+package com.jd.platform.jlog.core;
+
+
+/**
+ * @author tangbohu
+ */
+public enum ConfigChangeType {
+
+ ADD,
+
+ MODIFY,
+
+ DELETE
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..ad4bdf46c697ab5e14fe9f7185de28b66bb38289
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/Configurator.java
@@ -0,0 +1,69 @@
+package com.jd.platform.jlog.core;
+
+import java.util.List;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @desc 参考log4J
+ * @ClassName Configurator.java
+ * @createTime 2022年02月15日 17:06:00
+ */
+public interface Configurator {
+
+ /**
+ * 获取string配置
+ * @param key key
+ * @return val
+ */
+ String getString(String key);
+
+
+ /**
+ * 获取LONG配置
+ * @param key key
+ * @return val
+ */
+ 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);
+
+
+ /**
+ * 设置配置
+ * @param key key
+ * @param content val
+ * @return content val
+ */
+ boolean putConfig(String key, String content);
+
+ /**
+ * 设置配置
+ * @param key key
+ * @return content val
+ * @param timeoutMills timeoutMills
+ * @param content content
+ */
+ boolean putConfig(String key, String content, long timeoutMills);
+
+
+ /**
+ * 获取配置器类型
+ * @return string example:apollo
+ */
+ String getType();
+
+
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..5be575dfc249ca03c69f08999f42aa3f84c62d31
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfiguratorFactory.java
@@ -0,0 +1,77 @@
+package com.jd.platform.jlog.core;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ServiceLoader;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @desc 参考log4J
+ * @ClassName ConfiguratorFactory.java
+ * @createTime 2022年02月15日 21:54:00
+ */
+public class ConfiguratorFactory {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ConfiguratorFactory.class);
+
+
+ private static volatile Configurator instance = null;
+
+
+ public static volatile Configurator base = null;
+
+
+ public static AtomicBoolean useFileConfig = new AtomicBoolean(true);
+
+
+
+ public static Configurator getInstance(){
+ if (instance == null) {
+ synchronized (Configurator.class) {
+ if (instance == null) {
+ instance = buildConfiguration();
+ LOGGER.info("构建总配置器单例完成 instance 获取类型结果:{}", instance.getType());
+ LOGGER.info("构建总配置器单例完成 Base 获取serverAddr结果:{}", base.getString("serverAddr"));
+ }
+ }
+ }
+ return instance;
+ }
+
+
+ /**
+ * SPI实现装载不同的配置器
+ * @return 配置器
+ */
+ private static Configurator buildConfiguration() {
+
+ try {
+ /*
+ 配置文件的配置器
+ */
+ base = new FileConfigurator();
+ } catch (IOException e) {
+ LOGGER.info("文件配置器构建失败", e);
+ throw new RuntimeException("build file buildConfiguration fail", e);
+ }
+
+ /*
+ 配置中心的配置器,如果没有就用文件配置器
+ */
+ ServiceLoader builders = ServiceLoader.load(ConfiguratorProvider.class);
+ //noinspection LoopStatementThatDoesntLoop
+ for (ConfiguratorProvider provider : builders) {
+ LOGGER.info("配置中心的配置器获取成功, 类型为:{}", provider.build().getType());
+ useFileConfig.set(false);
+ return provider.build();
+ }
+ return base;
+ }
+
+}
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfiguratorProvider.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfiguratorProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1ebb1329600d93766e20ecb50de538f6eb2291b
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/ConfiguratorProvider.java
@@ -0,0 +1,14 @@
+package com.jd.platform.jlog.core;
+
+
+/**
+ * @author tangbohu
+ */
+public interface ConfiguratorProvider {
+
+ /**
+ * 根据实现类构建配置器
+ * @return 配置器
+ */
+ Configurator build();
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..e5f78e4209620431644c4ab3e8bd3a9fd7b96f16
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/Constant.java
@@ -0,0 +1,52 @@
+package com.jd.platform.jlog.core;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName Constant.java
+ * @Description TODO
+ * @createTime 2022年02月26日 10:19:00
+ */
+public class Constant {
+
+ /**
+ * 监听重读配置文件间隔 单位ms
+ */
+ static final long LISTENER_CONFIG_INTERVAL = 10000;
+
+ static final String CONFIG_FILE_PROPERTIES = "/application.properties";
+
+ static final String CONFIG_FILE_YML = "/application.yml";
+
+ static final String JLOG_CONFIG_FILE = "/jLog.properties";
+
+
+ static final String ENV = "env";
+
+ static final String YML = "yml";
+
+ public static final long DEFAULT_TIMEOUT = 2 * 1000;
+
+ static final long AWAIT_TIME = 3 * 1000;
+
+ public static final String SERVER_ADDR_KEY = "serverAddr";
+
+ public static final String NAMESPACE_KEY = "namespace";
+
+ public static final String DEFAULT_NAMESPACE = "jLog";
+
+
+ /**
+ * 配置文件集合
+ */
+ public static final Set CONFIG_FILES = new HashSet() {
+ {
+ add(CONFIG_FILE_PROPERTIES);
+ add(CONFIG_FILE_YML);
+ add(JLOG_CONFIG_FILE);
+ }
+ };
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..325fb7c80323b9fc64578f476804c517b8ce48f1
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/FileConfigurator.java
@@ -0,0 +1,246 @@
+package com.jd.platform.jlog.core;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.common.handler.JcProperties;
+import com.jd.platform.jlog.common.utils.CollectionUtil;
+import com.jd.platform.jlog.common.utils.StringUtil;
+import io.netty.util.concurrent.DefaultThreadFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.*;
+import java.net.URL;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static com.jd.platform.jlog.core.ConfigChangeListener.EXECUTOR_SERVICE;
+import static com.jd.platform.jlog.core.ConfiguratorFactory.useFileConfig;
+import static com.jd.platform.jlog.core.Constant.*;
+
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName FileConfigurator.java
+ * @createTime 2022年02月17日 23:22:00
+ */
+public class FileConfigurator implements Configurator {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(FileConfigurator.class);
+
+ private static JcProperties PROPERTIES = new JcProperties();
+
+ private static volatile FileListener FILELISTENER = null;
+
+ private static final Set LISTENED_FILES = new CopyOnWriteArraySet<>();
+
+ private final Map FILE_MODIFY_MAP = new ConcurrentHashMap<>();
+
+
+ FileConfigurator() throws IOException{
+
+ String env = System.getenv(ENV);
+
+ for (String file : CONFIG_FILES) {
+ String fileName = StringUtil.isEmpty(env) ? file : file + "_" + env;
+ URL url = this.getClass().getResource(file);
+ 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());
+ for (String file : CONFIG_FILES) {
+ file = StringUtil.isEmpty(env) ? file : file + "_" + env;
+ LISTENED_FILES.add(file);
+ if(FILELISTENER == null){
+ synchronized (FileConfigurator.class){
+ FILELISTENER = new FileListener();
+ FILELISTENER.addListener();
+ }
+ }
+ }
+ }
+
+
+ @Override
+ public String getString(String key) {
+ return PROPERTIES.getString(key);
+ }
+
+ @Override
+ 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; }
+
+
+ @Override
+ public boolean putConfig(String key, String content, long timeoutMills) {
+ return false;
+ }
+
+
+ @Override
+ public String getType() {
+ return "file";
+ }
+
+
+
+ class FileListener implements ConfigChangeListener {
+
+ private final ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L,
+ TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(),
+ new DefaultThreadFactory("fileListener", 1));
+
+
+ FileListener() {}
+
+ synchronized void addListener() {
+ FILELISTENER.onProcessEvent(new ConfigChangeEvent());
+ }
+
+
+ @Override
+ public void onChangeEvent(ConfigChangeEvent event) {
+ for(; !getExecutorService().isShutdown() && !getExecutorService().isShutdown(); checkAndConfigure()) {
+ try {
+ if(!useFileConfig.get()){
+ LOGGER.info("装配了配置中心, 文件配置器关闭");
+ executor.shutdown();
+ if(!executor.awaitTermination(AWAIT_TIME, TimeUnit.MILLISECONDS)){
+ // 超时的时候向线程池中所有的线程发出中断(interrupted)。
+ executor.shutdownNow();
+ return;
+ }
+ }
+ Thread.sleep(LISTENER_CONFIG_INTERVAL);
+ } catch (InterruptedException ignored) {
+ }
+ }
+ }
+
+ @Override
+ public ExecutorService getExecutorService() {
+ return executor;
+ }
+
+ }
+
+
+
+
+ /**
+ * 检测文件最后修改时间 和重载文件
+ */
+ 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);
+ for (String diffKey : diffKeys) {
+ 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.debug("变更之前的总配置:{}", JSON.toJSONString(PROPERTIES));
+ PROPERTIES.clear();
+ FILE_MODIFY_MAP.forEach((k,v)-> PROPERTIES.putAll(v.props));
+ LOGGER.info("变更之后的总配置:{}", JSON.toJSONString(PROPERTIES));
+ ClientHandlerBuilder.refresh();
+ }
+ }
+
+
+ /**
+ * 检测文件最后修改时间 和重载文件
+ */
+ private Map checkAndReload() {
+
+ Map fileWrapperMap = new ConcurrentHashMap<>(3);
+
+ for (String fileName : LISTENED_FILES) {
+ URL url = this.getClass().getResource(fileName);
+
+ if(url == null){
+ continue;
+ }
+ File file = new File(url.getFile());
+ long curLastMod = file.lastModified();
+ FileWrapper wrapper = FILE_MODIFY_MAP.get(fileName);
+ Long cacheLastMod = wrapper.lastModify;
+ if(curLastMod <= cacheLastMod){
+ continue;
+ }
+ JcProperties props = new JcProperties();
+ try (InputStream is = url.openStream()) {
+ if (fileName.contains(YML)) {
+ props.putAll(new Yaml().loadAs(is, Map.class));
+ } else {
+ props.load(is);
+ }
+ fileWrapperMap.put(fileName, new FileWrapper(curLastMod, true, props));
+ LOGGER.info("定时任务监测到文件更新:{}最新配置:{}", fileName, JSON.toJSONString(props));
+ } catch (Exception e) {
+ LOGGER.error("定时任务load失败:{}配置文件配置重载失败", fileName, e);
+ }
+ }
+ return fileWrapperMap;
+ }
+
+
+ static class FileWrapper{
+
+ private long lastModify;
+
+ private boolean change;
+
+ private JcProperties props;
+
+ FileWrapper(long lastModify, JcProperties props) {
+ this.lastModify = lastModify;
+ this.change = false;
+ this.props = 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 0000000000000000000000000000000000000000..44b3c99c429f4d5d418c876c101ad115f0149b21
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/FileNode.java
@@ -0,0 +1,81 @@
+package com.jd.platform.jlog.core;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.common.handler.CollectMode;
+import com.jd.platform.jlog.common.handler.JcProperties;
+import com.jd.platform.jlog.common.handler.TagConfig;
+import com.jd.platform.jlog.common.utils.ZstdUtils;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Base64;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName FileNode.java
+ * @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 {
+
+ String a = "汉字";
+ System.out.println("a byte length:"+a.getBytes().length);
+
+ byte[] bt1 = ZstdUtils.compress(a.getBytes());
+ String ckStr = new String(bt1);
+ String newStr1 = ZstdUtils.decompress(bt1);
+ System.out.println("老 字符串 bt:"+ Arrays.toString(a.getBytes()));
+ System.out.println("新 字符串 bt:"+ Arrays.toString(ckStr.getBytes()));
+
+
+ System.out.println("新字符串:"+newStr1);
+ System.out.println("新字符串的byte长度:"+newStr1.getBytes().length);
+
+ String str = "这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是"+"{\"@level\":\"info\",\"@message\":\"response json: \",\"@module\":\"testing-platform.cfeature_plugin\",\"@timestamp\":\"2022-03-10T19:37:55.181928+08:00\",这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是这是实打实分身乏术的故事大哥大哥大哥算法算法发生大发DVD放v都是" +
+ "\"EXTRA_VALUE_AT_END\":{\"data\":{\"accountAddr\":\"bg\",\"accountArea\":\"\",\"accountBank\":\"012\",\"accountBankBranch\":\"\",\"accountBankBranchNo\":\"\",\"accountBankName\":\"BBVA BANCOMER SA\",\"accountBranch\":\"\",\"accountCardDigit\":\"\",\"accountCardType\":null,\"accountCardno\":\"012420015684144165\",\"accountCity\":\"\",\"accountCompany\":\"\",\"accountFirstName\":\"\",\"accountGrantPhoto\":{\"keys\":[\"do1_tQxmThhy446Wf8JLHK5E\"],\"urls\":[\"http://img1.didiglobal.com/static/sailing_private_b/do1_tQxmThhy446Wf8JLHK5E?expire=1647517074\\u0026signiture=iTo-tiI21Ysdn7n7Y6y2YGs36avRi0cfLUpRl0rlE-g=\"]},\"accountHolder\":\"test_accountHolder\",\"accountHolderId\":\"\",\"accountLastName\":null,\"accountType\":0,\"addr\":\"test_addr\",\"addrAlph\":\"\",\"applyId\":\"5764607808352618589\",\"applyStatus\":0,\"applyType\":1,\"areaName\":\"Area0\",\"arrBusinessAttr\":[\"140\"],\"arrTags\":[],\"authorizationInfo\":{\"payment\":{\"authorizedPics\":null," +
+ "\"extraFiles\":null,\"pics\":null},\"sign\":{\"authorizedPics\":null,\"extraFiles\":null,\"pics\":null}},\"autoSwitch\":\"0\",\"avgPrice\":{\"max\":0,\"min\":0},\"avgProduceTime\":600,\"bLicenseAddr\":\"\",\"bLicenseBrand\":\"\",\"bLicenseExpireFlag\":61,\"bLicenseExpireTime\":\"1970-01-01 08:00:00\",\"bLicenseId\":\"\",\"bLicenseLpName\":\"\",\"bLicensePic\":\"\",\"bLicensePicUrl\":\"\",\"bLicenseStartTime\":\"1970-01-01 08:00:00\",\"bLicenseStatus\":\"3\",\"bLicenseValidType\":0,\"bankAgentDigit\":\"\",\"bankAgentno\":\"\",\"bdName\":\"sim_data_01(simdata01_test_v)\",\"bdPhone\":\"\",\"bizDayTime\":null,\"bizDayTimeNonAffiliate\":\"\",\"bizStatus\":1,\"bizTime\":\"{\\\"day\\\":[1,1,1,1,1,1,1],\\\"time\\\":[{\\\"begin\\\":\\\"10:00\\\",\\\"end\\\":\\\"18:00\\\"}]}\",\"bizoppDocInfo\":{\"city\":{\"files\":null,\"licensePics\":null},\"corp\":{\"files\":null,\"licensePics\":null},\"health\":{\"files\":null,\"licensePics\":null},\"land\":{\"files\":null,\"" +
+ "licensePics\":null}},\"bizoppInfo\":{\"bussinessHours\":\"\",\"deliveryDistanceTime\":\"\",\"deliveryPrice\":0,\"itemCount\":null,\"minPrice\":0,\"priceRange\":null,\"ratingCount\":\"\",\"ratingValue\":\"\"},\"bizoppStatus\":5,\"blicenseShow\":1,\"brand\":\"\",\"brandId\":0,\"businessType\":1,\"button\":{\"addVisitButton\":1,\"applyOpenButton\":0,\"applySignButton\":0,\"approveButton\":0,\"batchAllotButton\":1,\"businessInformationViewButton\":1,\"cancelApplyButton\":0,\"conSignPadButton\":0,\"confirmButton\":0,\"controlOperationButton\":1,\"copyMsgGatherUrlButton\":0,\"deliveryPadButton\":1,\"deliverySettingButton\":1,\"editButton\":0,\"financialOperationButton\":1,\"giveUp\":0,\"msgGatherButton\":0,\"msgGatherEditButton\":0,\"msgGatherPlusButton\":0,\"orderInfoButton\":1,\"pickIn\":0,\"sendMsgGatherButton\":0,\"switchToNonAffiliateButton\":0,\"tagsButton\":1,\"topEatsButton\":0,\"updateAbnormalTagsButton\":1,\"updateAddressButton\":1,\"updateBusinessInfoButton\":1," +
+ "\"updateCategoryButton\":1,\"updateNormalTag\":1,\"updateShopBaseInfo\":1,\"updateShopInfo\":1,\"uploadPictureButton\":1,\"viewOpenButton\":1,\"visitListButton\":1},\"cLicenseAddr\":\"\",\"cLicenseBrand\":\"\",\"cLicenseExpireFlag\":61,\"cLicenseExpireTime\":\"1970-01-01 08:00:00\",\"cLicenseId\":\"\",\"cLicenseLpName\":\"\",\"cLicensePic\":\"\",\"cLicensePicUrl\":\"\",\"cLicenseStatus\":\"3\",\"cLicenseValidType\":0,\"category\":[],\"categoryIds\":[],\"channel\":1,\"checkStatus\":0,\"city\":52080200,\"cityId\":52080200,\"clicenseShow\":1,\"clusterId\":5764607713452294000,\"clusterName\":\"\",\"commissionJson\":[],\"competeBizTime\":[],\"competeItemMenuUrl\":[],\"completeStatus\":1,\"contactCallingCode\":\"\",\"contactName\":\"test_partyaContact\",\"contactPhone\":\"15512300000\",\"contractorId\":\"5764607748000712588\",\"contractorStatus\":3,\"cosTrans\":0,\"country\":\"MX\",\"countryCode\":\"\",\"createTime\":\"2022-02-16 19:39:42\",\"creatorUserName\":\"simdata01_test_v\"," +
+ "\"currency\":{\"display\":\"MX$0.00\",\"number\":\"0.00\",\"position\":0,\"sign\":\"\",\"symbol\":\"MX$\"},\"decorateId\":0,\"deliverDistance\":0,\"deliverType\":2,\"deviceFlagbin\":3,\"deviceFlagbinNeedPad\":1,\"displayable\":0,\"displayableNonAffiliate\":0,\"docFlagbin\":0,\"docId\":\"5764607687590152047\",\"docInfo\":{\"city\":{\"files\":null,\"licensePics\":null},\"corp\":{\"files\":null,\"licensePics\":null},\"health\":{\"files\":null,\"licensePics\":null},\"land\":{\"files\":null,\"licensePics\":null}},\"editTime\":\"2022-02-16 19:40:14\",\"environmentalPhoto\":[\"https://img0.didiglobal.com/static/soda_public/do1_QSl1NDnsiCYaB2A5gmis\"],\"extendMaterial\":\"\",\"extraInfo\":{\"bankFlow\":{\"files\":null,\"pics\":null},\"other\":{\"files\":null,\"pics\":null}},\"filterTags\":[{\"text\":\"正常门店\",\"type\":1}],\"filterTagsValue\":0,\"flagbin\":0,\"foodSafe\":\"\",\"foodSafePic\":\"\",\"foodSafePicUrl\":\"\",\"foodSafeShow\":1," +
+ "\"frontPhoto\":[\"https://img0.didiglobal.com/static/soda_public/do1_AMgzb2wxVwL4usmf4qHu\"],\"grade\":\"\",\"headImg\":\"\",\"isDeliverCash\":1,\"isEnableCash\":1,\"isEnablePaypay\":1,\"isEnablePos\":0,\"isFoodCity\":0,\"isIllegal\":0,\"isNeedPad\":0,\"isRate\":2,\"isScopeDelivery\":1,\"itemFiles\":null,\"itemPics\":[\"https://img0.didiglobal.com/static/soda_public/do1_iad8ykReSCUcGh7sUJye\"],\"ka\":1,\"kpContactTime\":null,\"kpDepartment\":\"\",\"kpEmail\":\"test_data_platform@didiglobal.com\",\"kpLastName\":\"\",\"kpLastNameAlph\":\"\",\"kpName\":\"test_kpName\",\"kpNameAlph\":\"\",\"kpOutId\":\"\",\"kpPhone\":\"15512300001\",\"kpPhoneExtra\":null,\"kpPics\":{\"keys\":[\"https://img0.didiglobal.com/static/soda_public/do1_BXtt9g8f8dfiecSHC1dZ\"],\"urls\":[false]},\"kpSource\":\"\",\"lat\":\"28.7370616\",\"lng\":\"-106.1306375\",\"localTaxId\":\"\",\"localTaxPayer\":\"\",\"localTaxPayerAddr\":\"\",\"localTaxPayerIdType\":0,\"localTaxPaymentMethod\":\"\"," +
+ "\"localTaxPics\":\"\",\"localTaxVatPayment\":0,\"logo\":\"https://img0.didiglobal.com/static/soda_public/do1_gLdUuwSCysHlKsPzYD9F\",\"logoImg\":\"https://img0.didiglobal.com/static/soda_public/do1_gLdUuwSCysHlKsPzYD9F\",\"lpLicenseId\":\"\",\"lpLicensePicBack\":\"\",\"lpLicensePicBackUrl\":\"\",\"lpLicensePicFront\":\"\",\"lpLicensePicFrontUrl\":\"\",\"lpLicensePics\":\"\",\"lpLicensePicsUrl\":\"\",\"lpLicenseStatus\":\"3\",\"lpLicenseType\":\"0\",\"lpName\":\"\",\"mainCategory\":\"\",\"manualCategory\":[],\"minPrice\":0,\"monthSales\":0,\"monthSold\":0,\"msgGatherUrl\":\"\",\"name\":\"test_1645011556_kFvjwPijhdxkmmgRXKC\",\"nameAlph\":\"\",\"notifyEmail\":\"\",\"notifyPhone\":\"\",\"objBusinessAttr\":[],\"objTags\":[],\"officialUrl\":\"\",\"open\":1,\"openCheck\":[{\"button\":\"已添加\",\"text\":\"联系电话\",\"type\":1},{\"button\":\"已填写\",\"text\":\"配送信息\",\"type\":1},{\"button\":\"已添加\",\"text\":\"门店头图\",\"type\":1},{\"button\":\"未完成\",\"text\":\"可售菜品数量\"," +
+ "\"type\":0},{\"button\":\"已通过\",\"text\":\"营业时间段\",\"type\":1},{\"button\":\"已添加\",\"text\":\"门店主营品类\",\"type\":1},{\"button\":\"已添加\",\"text\":\"出餐时长\",\"type\":1}],\"openCheckNonAffiliate\":null,\"orderConfirmMethod\":\"0\",\"padInfo\":{\"isNeedPad\":0,\"isPadOnlineSign\":1},\"padStatus\":0,\"payVerifyReason\":\"\",\"payVerifyStatus\":0,\"permAddr\":\"\",\"permNo\":\"\",\"phone\":\"164501155695\",\"poi\":\"ChIJOdOau5VB6oYR-LfkU_bfr_g\",\"poiId\":\"ChIJOdOau5VB6oYR-LfkU_bfr_g\",\"poiName\":\"Arcos de Terragona 16934, Villa del Nte, 31137 Chihuahua, Chih., México\",\"postCode\":\"\",\"produceTimeMax\":\"0\",\"rank\":5,\"repeatShopId\":\"\",\"reprePhone\":\"\",\"riderAreaName\":\"\",\"riderClusterId\":52080200,\"score\":0,\"secondCategory\":\"\",\"selectCityId\":52080200,\"settledStatus\":0,\"settledTags\":0,\"shopId\":\"5764607747732277132\",\"shopLayerLevel\":\"\",\"shopLevel\":\"\",\"shopOnlineStatus\":3,\"shopOnlineStatusDesc\":\"需手工开启营业\"," +
+ "\"shopOnlineStatusMsg\":\"歇业中\",\"shopPhone\":\"\",\"shopPics\":{\"environmentalPhoto\":[\"/static/soda_public/do1_QSl1NDnsiCYaB2A5gmis\"],\"frontPhoto\":[\"/static/soda_public/do1_AMgzb2wxVwL4usmf4qHu\"]},\"shopStatus\":3,\"shopTag\":0,\"signPic\":null,\"signType\":1,\"signedTime\":1645011613,\"source\":2,\"startupCost\":500000,\"startupCostLimit\":50000,\"startupCostNum\":0,\"startupCostProportion\":1000,\"startupExecWeek\":1,\"tags\":0,\"taxId\":\"234234123112\",\"taxIdType\":1,\"taxPayer\":\"\",\"taxPayerAddr\":\"\",\"taxPayerIdType\":0,\"taxPaymentMethod\":\"\",\"taxPics\":[\"https://img0.didiglobal.com/static/soda_public/do1_Gip4umImni45IUHPTvQQ\"],\"taxVatPayment\":0,\"thirdCategory\":\"\",\"timezone\":\"\",\"todayBizTime\":[],\"type\":1,\"updateTime\":\"2022-03-10 15:46:20\",\"visible\":false,\"visitStatus\":0},\"errmsg\":\"ok\",\"errno\":0,\"machine\":\"\",\"reqParams\":{\"locale\":\"zh-CN\",\"shopId\":\"5764607747732277132\"},\"time\":1646912275," +
+ "\"traceId\":\"s060310x1646912272\"},\"timestamp\":\"2022-03-10T19:37:55.180+0800\"}";
+ System.out.println("字符串长度: "+str.length());
+ System.out.println("字符串byte长度:"+str.getBytes().length);
+ byte[] bt = ZstdUtils.compress(str.getBytes());
+ String newStr = ZstdUtils.decompress(bt);
+ System.out.println("新字符串:"+newStr);
+ System.out.println("新字符串的byte长度:"+newStr.getBytes().length);
+
+ System.out.println("Zstd压缩后的byte长度:"+bt.length);
+
+ byte[] bs = GzipCompress.compress(str.getBytes());
+ System.out.println("Gzip压缩后的byte长度:"+bs.length);
+ System.out.println("Zstd压缩后的byte长度 + Gzip压缩后的byte长度:"+GzipCompress.compress(bt).length);
+
+
+ System.out.println("Base64 后的byte长度: "+Base64.getEncoder().encode(bt).length);
+
+ System.out.println("=======");
+ System.out.println(CollectMode.COMPRESS_LOG_RESP);
+ System.out.println(CollectMode.EXTRACT_ALL);
+
+ System.out.println();
+ 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));
+ TagConfig bean = properties.getBean("tag-config", TagConfig.class);
+ System.out.println(JSON.toJSONString(bean));
+ }
+
+}
diff --git a/config/config-core/src/main/java/com/jd/platform/jlog/core/GzipCompress.java b/config/config-core/src/main/java/com/jd/platform/jlog/core/GzipCompress.java
new file mode 100644
index 0000000000000000000000000000000000000000..22d75b6664dcca4cc733211f64a30f8694241d17
--- /dev/null
+++ b/config/config-core/src/main/java/com/jd/platform/jlog/core/GzipCompress.java
@@ -0,0 +1,49 @@
+package com.jd.platform.jlog.core;
+
+
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * The Data Compression Based on gzip.
+ *
+ */
+public class GzipCompress {
+
+ public static byte[] compress(byte[] data) throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ GZIPOutputStream gzip;
+
+ try {
+ gzip = new GZIPOutputStream(out);
+ gzip.write(data);
+ gzip.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return out.toByteArray();
+ }
+
+ public static byte[] uncompress(byte[] data) throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteArrayInputStream in = new ByteArrayInputStream(data);
+
+ try {
+ GZIPInputStream ungzip = new GZIPInputStream(in);
+ byte[] buffer = new byte[2048];
+ int n;
+ while ((n = ungzip.read(buffer)) >= 0) {
+ out.write(buffer, 0, n);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return out.toByteArray();
+ }
+}
diff --git a/config/config-etcd/pom.xml b/config/config-etcd/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4c6fa9e6b3b6ef5f92c3526a3fe7433915d11994
--- /dev/null
+++ b/config/config-etcd/pom.xml
@@ -0,0 +1,26 @@
+
+
+
+ com.jd.platfrom.jlog
+ config
+ 1.4-SNAPSHOT
+
+ 4.0.0
+ config-etcd
+ config-etcd
+
+
+
+ com.jd.platfrom.jlog
+ config-core
+ 1.4-SNAPSHOT
+
+
+ com.ibm.etcd
+ etcd-java
+ 0.0.16
+
+
+
+
diff --git a/config/config-etcd/src/main/java/com/jd/platform/jlog/etcd/EtcdConfigurationProvider.java b/config/config-etcd/src/main/java/com/jd/platform/jlog/etcd/EtcdConfigurationProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..09a5e2e6642a66aa9debc3532d3dc487af12ca58
--- /dev/null
+++ b/config/config-etcd/src/main/java/com/jd/platform/jlog/etcd/EtcdConfigurationProvider.java
@@ -0,0 +1,15 @@
+package com.jd.platform.jlog.etcd;
+
+
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorProvider;
+
+/**
+ * @author tangbohu
+ */
+public class EtcdConfigurationProvider implements ConfiguratorProvider {
+ @Override
+ public Configurator build() {
+ return EtcdConfigurator.getInstance();
+ }
+}
diff --git a/config/config-etcd/src/main/java/com/jd/platform/jlog/etcd/EtcdConfigurator.java b/config/config-etcd/src/main/java/com/jd/platform/jlog/etcd/EtcdConfigurator.java
new file mode 100644
index 0000000000000000000000000000000000000000..85e77b25b6cd1351eb33e33d042e13a126b538b8
--- /dev/null
+++ b/config/config-etcd/src/main/java/com/jd/platform/jlog/etcd/EtcdConfigurator.java
@@ -0,0 +1,123 @@
+package com.jd.platform.jlog.etcd;
+
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import com.alibaba.fastjson.JSON;
+import com.google.protobuf.ByteString;
+import com.ibm.etcd.api.KeyValue;
+import com.ibm.etcd.api.RangeResponse;
+import com.ibm.etcd.client.EtcdClient;
+import com.jd.platform.jlog.common.handler.JcProperties;
+import com.jd.platform.jlog.common.utils.CollectionUtil;
+import com.jd.platform.jlog.common.utils.StringUtil;
+import com.jd.platform.jlog.core.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.jd.platform.jlog.common.utils.ConfigUtil.formatConfigByte;
+import static com.jd.platform.jlog.common.utils.ConfigUtil.formatConfigStr;
+import static com.jd.platform.jlog.core.Constant.DEFAULT_TIMEOUT;
+import static com.jd.platform.jlog.core.Constant.SERVER_ADDR_KEY;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @desc 参考log4J
+ * @ClassName EtcdConfigurator.java
+ * @createTime 2022年02月21日 21:46:00
+ */
+public class EtcdConfigurator implements Configurator {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(EtcdConfigurator.class);
+
+ private static volatile EtcdConfigurator instance;
+
+ static volatile EtcdClient client;
+
+ private static final Configurator FILE_CONFIG = ConfiguratorFactory.base;
+
+ static final String ROOT = "/jLog";
+
+ static final String PROPERTIES_PATH = "/jLog/jLog.properties";
+
+ static JcProperties PROPERTIES = new JcProperties();
+
+ private EtcdConfigurator() {
+ LOGGER.info("开始构建etcd客户端, serverAddr:{}",FILE_CONFIG.getString(SERVER_ADDR_KEY));
+ client = EtcdClient.forEndpoints(FILE_CONFIG.getString(SERVER_ADDR_KEY)).withPlainText().build();
+ RangeResponse rangeResponse = client.getKvClient().get(ByteString.copyFromUtf8(PROPERTIES_PATH)).sync();
+ List keyValues = rangeResponse.getKvsList();
+ if (CollectionUtil.isEmpty(keyValues)) {
+ return;
+ }
+ String val = keyValues.get(0).getValue().toStringUtf8();
+ if(StringUtil.isNotBlank(val)){
+ try {
+ PROPERTIES.load(new StringReader(val));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ LOGGER.info("初始化etcd配置", JSON.toJSONString(PROPERTIES));
+ new EtcdListener().onProcessEvent(new ConfigChangeEvent());
+ }
+
+
+ public static EtcdConfigurator getInstance() {
+ if (instance == null) {
+ synchronized (EtcdConfigurator.class) {
+ if (instance == null) {
+ instance = new EtcdConfigurator();
+ }
+ }
+ }
+ return instance;
+ }
+
+ @Override
+ public String getString(String key) {
+ return PROPERTIES.getString(key);
+ }
+
+ @Override
+ 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 putConfig(key, content, DEFAULT_TIMEOUT);
+ }
+
+ @Override
+ public boolean putConfig(String key, String content, long timeoutMills) {
+ if(StringUtil.isEmpty(key) || StringUtil.isEmpty(content)){
+ return false;
+ }
+ PROPERTIES.setProperty(key, content);
+ client.getKvClient().put(ByteString.copyFromUtf8(PROPERTIES_PATH), ByteString.copyFromUtf8(formatConfigStr(PROPERTIES))).sync();
+ return true;
+ }
+
+
+ @Override
+ public String getType() {
+ return "etcd";
+ }
+
+}
diff --git a/config/config-etcd/src/main/java/com/jd/platform/jlog/etcd/EtcdListener.java b/config/config-etcd/src/main/java/com/jd/platform/jlog/etcd/EtcdListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6c172b437f773c3184dd4b8bbc048a13e27d7d1
--- /dev/null
+++ b/config/config-etcd/src/main/java/com/jd/platform/jlog/etcd/EtcdListener.java
@@ -0,0 +1,102 @@
+package com.jd.platform.jlog.etcd;
+
+import com.google.protobuf.ByteString;
+import com.ibm.etcd.api.Event;
+import com.ibm.etcd.api.KeyValue;
+import com.ibm.etcd.api.RangeResponse;
+import com.ibm.etcd.client.EtcdClient;
+import com.ibm.etcd.client.kv.KvClient;
+import com.ibm.etcd.client.kv.WatchUpdate;
+import com.jd.platform.jlog.common.handler.JcProperties;
+import com.jd.platform.jlog.common.utils.CollectionUtil;
+import com.jd.platform.jlog.common.utils.StringUtil;
+import com.jd.platform.jlog.core.ClientHandlerBuilder;
+import com.jd.platform.jlog.core.ConfigChangeEvent;
+import com.jd.platform.jlog.core.ConfigChangeListener;
+import com.jd.platform.jlog.core.ConfigChangeType;
+import io.netty.util.concurrent.DefaultThreadFactory;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import static com.jd.platform.jlog.etcd.EtcdConfigurator.PROPERTIES;
+import static com.jd.platform.jlog.etcd.EtcdConfigurator.PROPERTIES_PATH;
+import static com.jd.platform.jlog.etcd.EtcdConfigurator.ROOT;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName EtcdListener.java
+ * @Description TODO
+ * @createTime 2022年02月21日 23:34:00
+ */
+public class EtcdListener implements ConfigChangeListener {
+ private KvClient.WatchIterator iterator;
+
+ public EtcdListener() {
+
+ iterator = EtcdConfigurator.client.getKvClient().watch(ByteString.copyFromUtf8(ROOT)).asPrefix().start();
+ getExecutorService().submit(() -> {
+ while (iterator.hasNext()){
+ try {
+ WatchUpdate update = iterator.next();
+ Event eve = update.getEvents().get(0);
+ KeyValue kv = eve.getKv();
+ Event.EventType eveType = eve.getType();
+ ConfigChangeType changeType = eveType.equals(Event.EventType.DELETE) ? ConfigChangeType.MODIFY : ConfigChangeType.DELETE;
+ ConfigChangeEvent event = new ConfigChangeEvent();
+ event.setKey(kv.getKey().toStringUtf8()).setNewValue(kv.getValue().toStringUtf8()).setChangeType(changeType);
+ onChangeEvent(event);
+ }catch (RuntimeException e){
+ e.printStackTrace();
+ }
+
+ }
+ });
+ }
+
+
+ @Override
+ public void onShutDown() {
+ this.iterator.close();
+ getExecutorService().shutdownNow();
+ }
+
+
+ @Override
+ public void onChangeEvent(ConfigChangeEvent event) {
+
+ RangeResponse rangeResponse = EtcdConfigurator.client.getKvClient().get(ByteString.copyFromUtf8(PROPERTIES_PATH)).sync();
+ List keyValues = rangeResponse.getKvsList();
+ if (CollectionUtil.isEmpty(keyValues)) {
+ return;
+ }
+ String val = keyValues.get(0).getValue().toStringUtf8();
+ JcProperties props = new JcProperties();
+ if(StringUtil.isNotBlank(val)){
+ try {
+ props.load(new StringReader(val));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ Set diffKeys = CollectionUtil.diffKeys(props, PROPERTIES);
+ if(!diffKeys.isEmpty()){
+ PROPERTIES = props;
+ for (String diffKey : diffKeys) {
+ LOGGER.warn("NACOS {} 配置变更 key={} 变更事件:{}", event.getKey(), diffKey,
+ String.valueOf(props.get(diffKey)),
+ String.valueOf(PROPERTIES.get(diffKey)));
+ }
+ ClientHandlerBuilder.refresh();
+ }
+ }
+ }
+
+}
diff --git a/config/config-etcd/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider b/config/config-etcd/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider
new file mode 100644
index 0000000000000000000000000000000000000000..32851cde74737f0883dabb2bea3ab7f4b2394998
--- /dev/null
+++ b/config/config-etcd/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider
@@ -0,0 +1 @@
+com.jd.platform.jlog.etcd.EtcdConfigurationProvider
\ No newline at end of file
diff --git a/config/config-nacos/pom.xml b/config/config-nacos/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..911115ed75134e3af68a4197022776bda5497478
--- /dev/null
+++ b/config/config-nacos/pom.xml
@@ -0,0 +1,27 @@
+
+
+
+
+ com.jd.platfrom.jlog
+ config
+ 1.4-SNAPSHOT
+
+ 4.0.0
+ config-nacos
+ config-nacos
+
+
+
+ com.jd.platfrom.jlog
+ config-core
+ 1.4-SNAPSHOT
+
+
+ com.alibaba.nacos
+ nacos-client
+ 1.4.2
+
+
+
+
diff --git a/config/config-nacos/src/main/java/com/jd/platform/jlog/nacos/NacosConfigurator.java b/config/config-nacos/src/main/java/com/jd/platform/jlog/nacos/NacosConfigurator.java
new file mode 100644
index 0000000000000000000000000000000000000000..b74fdabd7852cad703965cd4328a3fd7e64a5764
--- /dev/null
+++ b/config/config-nacos/src/main/java/com/jd/platform/jlog/nacos/NacosConfigurator.java
@@ -0,0 +1,145 @@
+package com.jd.platform.jlog.nacos;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.exception.NacosException;
+
+import com.alibaba.nacos.common.utils.StringUtils;
+import com.jd.platform.jlog.common.handler.JcProperties;
+import com.jd.platform.jlog.common.utils.StringUtil;
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.jd.platform.jlog.common.utils.ConfigUtil.formatConfigStr;
+import static com.jd.platform.jlog.core.Constant.*;
+
+
+
+/**
+ * @author tangbohu
+ */
+public class NacosConfigurator implements Configurator {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(NacosConfigurator.class);
+
+ private static final Configurator FILE_CONFIG = ConfiguratorFactory.base;
+
+ private static volatile ConfigService configService;
+
+ static volatile JcProperties PROPERTIES = new JcProperties();
+
+ static final String JLOG_GROUP = "JLOG_GROUP";
+
+ static final String DEFAULT_DATA_ID = "jLog.properties";
+
+ static NacosListener NACOSLISTENER = new NacosListener();
+
+ private static volatile NacosConfigurator instance;
+
+
+ public static NacosConfigurator getInstance() {
+ if (instance == null) {
+ synchronized (NacosConfigurator.class) {
+ if (instance == null) {
+ instance = new NacosConfigurator();
+ }
+ }
+ }
+ return instance;
+ }
+
+
+ private NacosConfigurator() {
+ if (configService == null) {
+ try {
+ configService = NacosFactory.createConfigService(getConfigProperties());
+ String config = configService.getConfig(DEFAULT_DATA_ID, JLOG_GROUP, DEFAULT_TIMEOUT);
+ LOGGER.info("从NaCos获取配置进行初始化 config = {}", config);
+ if (StringUtils.isNotBlank(config)) {
+ PROPERTIES.load(new StringReader(config));
+ LOGGER.info("初始化本地缓存 props:{} ", JSON.toJSONString(PROPERTIES));
+ configService.addListener(DEFAULT_DATA_ID, JLOG_GROUP, NACOSLISTENER);
+ }
+ } catch (NacosException | IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+
+ @Override
+ public String getString(String key) {
+ return PROPERTIES.getString(key);
+ }
+
+ @Override
+ 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 putConfig(key, content, DEFAULT_TIMEOUT);
+ }
+
+
+ @Override
+ public boolean putConfig(String key, String content, long timeoutMills) {
+ boolean result = false;
+ if(StringUtil.isEmpty(key)){
+ return false;
+ }
+ try {
+ if (!PROPERTIES.isEmpty()) {
+ PROPERTIES.setProperty(key, content);
+ result = configService.publishConfig(DEFAULT_DATA_ID, JLOG_GROUP, formatConfigStr(PROPERTIES));
+ } else {
+ result = configService.publishConfig(DEFAULT_DATA_ID, JLOG_GROUP, content);
+ }
+ } catch (NacosException ex) {
+ LOGGER.error(ex.getErrMsg());
+ }
+ return result;
+ }
+
+
+
+ private static Properties getConfigProperties() {
+ Properties properties = new Properties();
+ String address = FILE_CONFIG.getString(SERVER_ADDR_KEY);
+ if (address != null) {
+ properties.setProperty(SERVER_ADDR_KEY, address);
+ }
+
+ properties.setProperty(NAMESPACE_KEY, DEFAULT_NAMESPACE);
+ return properties;
+ }
+
+
+
+ @Override
+ public String getType() {
+ return "nacos";
+ }
+
+
+}
diff --git a/config/config-nacos/src/main/java/com/jd/platform/jlog/nacos/NacosConfiguratorProvider.java b/config/config-nacos/src/main/java/com/jd/platform/jlog/nacos/NacosConfiguratorProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..f50b3f3603a2cedbc3cdcbb57056bd5cc3fa559b
--- /dev/null
+++ b/config/config-nacos/src/main/java/com/jd/platform/jlog/nacos/NacosConfiguratorProvider.java
@@ -0,0 +1,12 @@
+package com.jd.platform.jlog.nacos;
+
+
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorProvider;
+
+public class NacosConfiguratorProvider implements ConfiguratorProvider {
+ @Override
+ public Configurator build() {
+ return NacosConfigurator.getInstance();
+ }
+}
diff --git a/config/config-nacos/src/main/java/com/jd/platform/jlog/nacos/NacosListener.java b/config/config-nacos/src/main/java/com/jd/platform/jlog/nacos/NacosListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1e4cc63fe6069f69840450e53a63d148a25199e
--- /dev/null
+++ b/config/config-nacos/src/main/java/com/jd/platform/jlog/nacos/NacosListener.java
@@ -0,0 +1,76 @@
+package com.jd.platform.jlog.nacos;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.listener.Event;
+import com.alibaba.nacos.api.naming.listener.EventListener;
+import com.alibaba.nacos.common.utils.StringUtils;
+import com.jd.platform.jlog.common.handler.JcProperties;
+import com.jd.platform.jlog.common.utils.CollectionUtil;
+import com.jd.platform.jlog.core.ClientHandlerBuilder;
+import com.jd.platform.jlog.core.ConfigChangeEvent;
+import com.jd.platform.jlog.core.ConfigChangeListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.util.Properties;
+import java.util.Set;
+
+
+import static com.jd.platform.jlog.core.Constant.*;
+import static com.jd.platform.jlog.nacos.NacosConfigurator.*;
+
+
+/**
+ * @author tangbohu
+ */
+public class NacosListener extends AbstractSharedListener implements ConfigChangeListener, EventListener {
+
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(NacosListener.class);
+
+
+ public NacosListener() {}
+
+ @Override
+ public void innerReceive(String dataId, String group, String configInfo) {
+ LOGGER.debug("configInfo:{}", configInfo);
+ ConfigChangeEvent event = new ConfigChangeEvent().setKey(dataId).setNewValue(configInfo).setNamespace(group);
+ this.onProcessEvent(event);
+ }
+
+
+
+ @Override
+ public void onChangeEvent(ConfigChangeEvent event) {
+ LOGGER.debug("通用[配置]变更事件 event:{}",event);
+ JcProperties props = new JcProperties();
+ if (StringUtils.isNotBlank(event.getNewValue())) {
+ try {
+ props.load(new StringReader(event.getNewValue()));
+ } catch (IOException e) {
+ return;
+ }
+ }
+ Set diffKeys = CollectionUtil.diffKeys(props, PROPERTIES);
+ if(!diffKeys.isEmpty()){
+ PROPERTIES = props;
+ for (String diffKey : diffKeys) {
+ LOGGER.warn("NACOS {} 配置变更 key={} 变更事件:{}", DEFAULT_DATA_ID, diffKey,
+ String.valueOf(props.get(diffKey)),
+ String.valueOf(PROPERTIES.get(diffKey)));
+ }
+ ClientHandlerBuilder.refresh();
+ }
+ }
+
+
+ @Override
+ public void onEvent(Event event) {
+ LOGGER.info("通用[服务]事件 event:{}",event);
+ }
+
+}
diff --git a/config/config-nacos/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider b/config/config-nacos/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider
new file mode 100644
index 0000000000000000000000000000000000000000..6d982a37ac9992888c34b2be9f6a79a1e816e864
--- /dev/null
+++ b/config/config-nacos/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider
@@ -0,0 +1 @@
+com.jd.platform.jlog.nacos.NacosConfiguratorProvider
\ No newline at end of file
diff --git a/config/config-nacos/src/test/NacosTest.java b/config/config-nacos/src/test/NacosTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a67bceddddd7d681765c34a27a79704645987b5a
--- /dev/null
+++ b/config/config-nacos/src/test/NacosTest.java
@@ -0,0 +1,68 @@
+package com.jd.platform.jlog.nacos;
+
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.naming.NamingFactory;
+import com.alibaba.nacos.api.naming.NamingService;
+import com.alibaba.nacos.api.naming.listener.NamingEvent;
+
+import static com.jd.platform.jlog.nacos.NacosConstant.DEFAULT_DATA_ID;
+import static com.jd.platform.jlog.nacos.NacosConstant.JLOG_GROUP;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName NacosTest.java
+ * @Description TODO
+ * @createTime 2022年02月22日 22:04:00
+ */
+public class NacosTest {
+
+ public static void main(String[] args) throws NacosException, InterruptedException {
+ String serverAddr = "101.42.242.201:8848";
+ String dataId = DEFAULT_DATA_ID;
+ String group = JLOG_GROUP;
+ ConfigService configService = NacosFactory.createConfigService(serverAddr);
+
+ NamingService naming = NamingFactory.createNamingService(serverAddr);
+ naming.registerInstance("nacos.test1", JLOG_GROUP,"172.22.216.105", 8888, "TEST1");
+ Thread.sleep(3000);
+ NacosListener server = new NacosListener();
+ naming.subscribe("nacos.test1", JLOG_GROUP,server);
+ String content = configService.getConfig(dataId, group, 2000L);
+ System.out.println("content: "+content);
+ NacosListener nL = new NacosListener();
+ configService.addListener(dataId, group, nL);
+
+ System.out.println("新增完成");
+ Thread.sleep(20000);
+ System.out.println("移除开始");
+ configService.removeListener(dataId, group, nL);
+ System.out.println("移除结束");
+
+ naming.deregisterInstance("nacos.test1", JLOG_GROUP,"172.22.216.105", 8888, "TEST1");
+ Thread.sleep(5000);
+
+ System.out.println("睡眠结束");
+
+ /* System.out.println("移除开始222");
+ configService.removeListener(dataId, group, new Listener() {
+ @Override
+ public Executor getExecutor() {
+ return Executors.newSingleThreadExecutor();
+ }
+
+ @Override
+ public void receiveConfigInfo(String s) {
+ System.out.println("#### 移除开始222");
+ }
+ });*/
+
+ Thread.sleep(90000);
+ System.out.println("---------------------------睡眠结束");
+
+ }
+
+
+}
diff --git a/config/config-zk/pom.xml b/config/config-zk/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..93e9f4bc314242eaba8c3dc7bf83d64a0081785a
--- /dev/null
+++ b/config/config-zk/pom.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ com.jd.platfrom.jlog
+ config
+ 1.4-SNAPSHOT
+
+ 4.0.0
+ config-zk
+ config-zk
+
+
+
+ com.jd.platfrom.jlog
+ config-core
+ 1.4-SNAPSHOT
+
+
+ org.apache.curator
+ curator-recipes
+ 4.2.0
+
+
+
+
diff --git a/config/config-zk/src/main/java/com/jd/platform/jlog/zk/ZkConfigurator.java b/config/config-zk/src/main/java/com/jd/platform/jlog/zk/ZkConfigurator.java
new file mode 100644
index 0000000000000000000000000000000000000000..ebaa734d38665dc07c799dbe0de4771038e3f2be
--- /dev/null
+++ b/config/config-zk/src/main/java/com/jd/platform/jlog/zk/ZkConfigurator.java
@@ -0,0 +1,119 @@
+package com.jd.platform.jlog.zk;
+
+import java.io.ByteArrayInputStream;
+import java.util.List;
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.common.handler.JcProperties;
+import com.jd.platform.jlog.common.utils.StringUtil;
+import com.jd.platform.jlog.core.*;
+import org.apache.curator.framework.CuratorFramework;
+import org.apache.curator.framework.CuratorFrameworkFactory;
+import org.apache.curator.retry.ExponentialBackoffRetry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.jd.platform.jlog.common.utils.ConfigUtil.formatConfigByte;
+import static com.jd.platform.jlog.core.Constant.DEFAULT_TIMEOUT;
+import static com.jd.platform.jlog.core.Constant.DEFAULT_NAMESPACE;
+import static com.jd.platform.jlog.core.Constant.SERVER_ADDR_KEY;
+
+
+/**
+ * @author tangbohu
+ */
+public class ZkConfigurator implements Configurator {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(ZkConfigurator.class);
+
+ private static final Configurator FILE_CONFIG = ConfiguratorFactory.base;
+
+ static volatile CuratorFramework zkClient;
+
+ static volatile JcProperties PROPERTIES = new JcProperties();
+
+ private static final String DEFAULT_CONFIG_PATH = "/jLog.properties";
+
+
+ public ZkConfigurator() throws Exception {
+ if (zkClient == null) {
+ synchronized (ZkConfigurator.class) {
+ zkClient = CuratorFrameworkFactory.builder().connectString(FILE_CONFIG.getString(SERVER_ADDR_KEY))
+ // 连接超时时间
+ .sessionTimeoutMs(6000)
+ // 会话超时时间
+ .connectionTimeoutMs(2000)
+ .namespace(DEFAULT_NAMESPACE)
+ // 刚开始重试间隔为1秒,之后重试间隔逐渐增加,最多重试不超过三次
+ .retryPolicy(new ExponentialBackoffRetry(1000, 3))
+ .build();
+ zkClient.start();
+ }
+
+ loadZkData();
+ new ZkListener(DEFAULT_CONFIG_PATH);
+ LOGGER.info("初始化ZK,载入ZK数据完成 props:{}", JSON.toJSONString(PROPERTIES));
+ }
+ }
+
+
+ @Override
+ public String getString(String key) {
+ return PROPERTIES.getString(key);
+ }
+
+ @Override
+ 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 putConfig(key, content, DEFAULT_TIMEOUT);
+ }
+
+
+ @Override
+ public boolean putConfig(String key, String content, long timeoutMills) {
+ if(StringUtil.isEmpty(key) || StringUtil.isEmpty(content)){
+ return false;
+ }
+ PROPERTIES.setProperty(key, content);
+ try {
+ zkClient.setData().forPath(DEFAULT_CONFIG_PATH, formatConfigByte(PROPERTIES));
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+
+
+ @Override
+ public String getType() {
+ return "zk";
+ }
+
+
+
+ static void loadZkData() throws Exception {
+
+ byte[] bt = zkClient.getData().forPath(DEFAULT_CONFIG_PATH);
+ if (bt != null && bt.length > 0){
+ ByteArrayInputStream bArray = new ByteArrayInputStream(bt);
+ PROPERTIES.load(bArray);
+ }
+ LOGGER.info("# loadZkData # PROPERTIES:{}",JSON.toJSONString(PROPERTIES));
+ }
+
+}
diff --git a/config/config-zk/src/main/java/com/jd/platform/jlog/zk/ZkConfiguratorProvider.java b/config/config-zk/src/main/java/com/jd/platform/jlog/zk/ZkConfiguratorProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..e2355e5e319886e613e77d54478d2911a479bf1e
--- /dev/null
+++ b/config/config-zk/src/main/java/com/jd/platform/jlog/zk/ZkConfiguratorProvider.java
@@ -0,0 +1,20 @@
+package com.jd.platform.jlog.zk;
+
+
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorProvider;
+
+
+/**
+ * @author tangbohu
+ */
+public class ZkConfiguratorProvider implements ConfiguratorProvider {
+ @Override
+ public Configurator build() {
+ try {
+ return new ZkConfigurator();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/config/config-zk/src/main/java/com/jd/platform/jlog/zk/ZkListener.java b/config/config-zk/src/main/java/com/jd/platform/jlog/zk/ZkListener.java
new file mode 100644
index 0000000000000000000000000000000000000000..e41b07680c28164df3b1d8a9bf59cd398d2b69d9
--- /dev/null
+++ b/config/config-zk/src/main/java/com/jd/platform/jlog/zk/ZkListener.java
@@ -0,0 +1,70 @@
+package com.jd.platform.jlog.zk;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.common.utils.CollectionUtil;
+import com.jd.platform.jlog.core.ClientHandlerBuilder;
+import com.jd.platform.jlog.core.ConfigChangeEvent;
+import com.jd.platform.jlog.core.ConfigChangeListener;
+import com.jd.platform.jlog.core.ConfigChangeType;
+import org.apache.curator.framework.recipes.cache.ChildData;
+import org.apache.curator.framework.recipes.cache.NodeCache;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import static com.jd.platform.jlog.zk.ZkConfigurator.*;
+
+
+/**
+ * @author didi
+ */
+public class ZkListener implements ConfigChangeListener {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(ZkListener.class);
+
+ private NodeCache cache;
+
+ private String path;
+
+ public ZkListener(String path) {
+ this.path = path;
+ cache = new NodeCache(zkClient, path);
+ try {
+ cache.start(true);
+ cache.getListenable().addListener(() -> onChangeEvent(null));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
+
+ @Override
+ public void onChangeEvent(ConfigChangeEvent event) {
+ LOGGER.info("ZK数据变更-当前监听器关注的path:{} PROPERTIES:{}", path, JSON.toJSONString(PROPERTIES));
+ Properties props = new Properties();
+ props.putAll(PROPERTIES);
+ try {
+ LOGGER.debug("ZK数据变更,旧Properties:{}", JSON.toJSONString(props));
+ loadZkData();
+ LOGGER.debug("ZK数据变更,新Properties:{}", JSON.toJSONString(PROPERTIES));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ Set diffKeys = CollectionUtil.diffKeys(props, PROPERTIES);
+ if(!diffKeys.isEmpty()){
+ for (String diffKey : diffKeys) {
+ LOGGER.warn("ZK {} 配置变更 key={} 变更事件:{}", path, diffKey,
+ new ConfigChangeEvent(diffKey,
+ String.valueOf(props.get(diffKey)),
+ String.valueOf(PROPERTIES.get(diffKey))));
+ }
+ ClientHandlerBuilder.refresh();
+ }
+ }
+
+}
diff --git a/config/config-zk/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider b/config/config-zk/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider
new file mode 100644
index 0000000000000000000000000000000000000000..f8a41f9bd0a016a986ee9bd52f33d4399cd6d551
--- /dev/null
+++ b/config/config-zk/src/main/resources/META-INF/services/com.jd.platform.jlog.core.ConfiguratorProvider
@@ -0,0 +1 @@
+com.jd.platform.jlog.zk.ZkConfiguratorProvider
\ No newline at end of file
diff --git a/config/pom.xml b/config/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e9885c4a85282912405bbf89807a589666d29eac
--- /dev/null
+++ b/config/pom.xml
@@ -0,0 +1,36 @@
+
+
+
+
+ JLog
+ com.jd.platfrom.jlog
+ 1.4-SNAPSHOT
+
+ 4.0.0
+ config
+ pom
+ config
+
+ config-core
+ config-etcd
+ config-apollo
+ config-nacos
+ config-zk
+
+
diff --git a/clientdemo/pom.xml b/example/pom.xml
similarity index 54%
rename from clientdemo/pom.xml
rename to example/pom.xml
index 052e0c41e4f90bece80cbc4f2af9443f2cb286d7..b177a8e1bd2e30cdac701d1cee4a814aedcfb51a 100644
--- a/clientdemo/pom.xml
+++ b/example/pom.xml
@@ -10,10 +10,10 @@
com.jd.platfrom.jlog
- clientdemo
+ example
0.0.1-SNAPSHOT
- clientdemo
- Demo project for using JLog
+ example
+ example for using JLog
1.8
@@ -23,42 +23,71 @@
org.springframework.boot
spring-boot-starter-web
-
+
-
+
com.jd.platfrom.jlog
client
1.4-SNAPSHOT
-
org.springframework.boot
- spring-boot-starter-test
- test
+ spring-boot-configuration-processor
+ true
-
- com.jd.platfrom.jlog
- clientlog4j2
- 1.4-SNAPSHOT
+ org.springframework.boot
+ spring-boot-test
+ 2.5.5
+ test
junit
junit
- 4.12
+ 4.13.2
test
- junit
- junit
- 4.12
+ org.springframework
+ spring-test
+ 5.3.10
test
+
+ org.projectlombok
+ lombok
+ 1.18.20
+ test
+
+
+
diff --git a/clientdemo/src/main/java/com/jd/platform/jlog/clientdemo/ClientDemoApplication.java b/example/src/main/java/com/jd/platform/jlog/clientdemo/ExampleApplication.java
similarity index 63%
rename from clientdemo/src/main/java/com/jd/platform/jlog/clientdemo/ClientDemoApplication.java
rename to example/src/main/java/com/jd/platform/jlog/clientdemo/ExampleApplication.java
index fb1e00d689580ddfcb593245fff50052e638b5f6..fec83ce64b3657418c5055fa1e3deb651d65479b 100644
--- a/clientdemo/src/main/java/com/jd/platform/jlog/clientdemo/ClientDemoApplication.java
+++ b/example/src/main/java/com/jd/platform/jlog/clientdemo/ExampleApplication.java
@@ -11,9 +11,13 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* @date 2021-12-27
*/
@SpringBootApplication
-public class ClientDemoApplication {
+public class ExampleApplication {
public static void main(String[] args) {
- SpringApplication.run(ClientDemoApplication.class, args);
+ try {
+ SpringApplication.run(ExampleApplication.class, args);
+ }catch (Exception e){
+ e.printStackTrace();
+ }
}
}
diff --git a/example/src/main/java/com/jd/platform/jlog/clientdemo/appender/TracerLogbackAppender.java b/example/src/main/java/com/jd/platform/jlog/clientdemo/appender/TracerLogbackAppender.java
new file mode 100644
index 0000000000000000000000000000000000000000..96c4de78c8ab23833b01f6d414ec39ecfd47f9de
--- /dev/null
+++ b/example/src/main/java/com/jd/platform/jlog/clientdemo/appender/TracerLogbackAppender.java
@@ -0,0 +1,115 @@
+package com.jd.platform.jlog.clientdemo.appender;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.classic.spi.ThrowableProxy;
+import ch.qos.logback.core.AppenderBase;
+import com.jd.platform.jlog.client.log.LogExceptionStackTrace;
+import com.jd.platform.jlog.client.tracerholder.TracerHolder;
+import com.jd.platform.jlog.client.udp.UdpSender;
+import com.jd.platform.jlog.common.model.RunLogMessage;
+import com.jd.platform.jlog.core.ClientHandler;
+import org.slf4j.helpers.MessageFormatter;
+
+
+/**
+ * className:TracerLog4JAppender
+ *
+ * @author wuweifeng
+ * @version 1.0.0
+ */
+public class TracerLogbackAppender extends AppenderBase {
+ /**
+ * 日志的堆栈级别,如直接在类里使用logger.info,则该值为0. 如调用另一个日志类如CommonLogger打印,则该值为1
+ */
+ private int loggerStage;
+
+ @Override
+ protected void append(ILoggingEvent iLoggingEvent) {
+ try {
+ long tracerId = TracerHolder.getTracerId();
+ if (0L == tracerId) {
+ return;
+ }
+ RunLogMessage logMessage = getLogMessage(iLoggingEvent);
+ UdpSender.offerLogger(logMessage);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 转化为对象
+ */
+ private RunLogMessage getLogMessage(ILoggingEvent loggingEvent) {
+ RunLogMessage logMessage = new RunLogMessage();
+ //设置链路唯一id
+ logMessage.setTracerId(TracerHolder.getTracerId());
+ logMessage.setClassName(loggingEvent.getLoggerName());
+ logMessage.setThreadName(loggingEvent.getThreadName());
+
+ StackTraceElement stackTraceElement = loggingEvent.getCallerData()[loggerStage];
+
+ String method = stackTraceElement.getMethodName();
+ String line = String.valueOf(stackTraceElement.getLineNumber());
+ logMessage.setMethodName(method + "(" + stackTraceElement.getFileName() + ":" + line + ")");
+ logMessage.setLogLevel(loggingEvent.getLevel().toString());
+
+ logMessage.setCreateTime(loggingEvent.getTimeStamp());
+
+ String formattedMessage = getMessage(loggingEvent);
+ logMessage.setContent(formattedMessage);
+ ClientHandler.Outcome out = ClientHandler.processLog(formattedMessage);
+ logMessage.setTagMap(out.getMap());
+ return logMessage;
+ }
+
+ /**
+ * 日志正文信息
+ */
+ private String getMessage(ILoggingEvent logEvent) {
+ if (logEvent.getLevel() == Level.ERROR) {
+ if (logEvent.getThrowableProxy() != null) {
+ ThrowableProxy throwableProxy = (ThrowableProxy) logEvent.getThrowableProxy();
+ String[] args = new String[]{logEvent.getFormattedMessage() + "\n" + LogExceptionStackTrace.erroStackTrace(throwableProxy.getThrowable()).toString()};
+ return packageMessage("{}", args);
+ } else {
+ Object[] args = logEvent.getArgumentArray();
+ if (args != null) {
+ for (int i = 0; i < args.length; i++) {
+ if (args[i] instanceof Throwable) {
+ args[i] = LogExceptionStackTrace.erroStackTrace(args[i]);
+ }
+ }
+ return packageMessage(logEvent.getMessage(), args);
+ }
+ }
+ }
+ return logEvent.getFormattedMessage();
+ }
+
+ private String packageMessage(String message, Object[] args) {
+ if (message != null && message.contains("{}")) {
+ return MessageFormatter.arrayFormat(message, args).getMessage();
+ }
+ return packageMsg(message, args);
+ }
+
+ private String packageMsg(String message, Object[] args) {
+ StringBuilder builder = new StringBuilder(128);
+ builder.append(message);
+ for (Object arg : args) {
+ builder.append("\n").append(arg);
+ }
+ return builder.toString();
+ }
+
+
+ public int getLoggerStage() {
+ return loggerStage;
+ }
+
+ public void setLoggerStage(int loggerStage) {
+ this.loggerStage = loggerStage;
+ }
+}
diff --git a/clientdemo/src/main/java/com/jd/platform/jlog/clientdemo/config/DemoConfig.java b/example/src/main/java/com/jd/platform/jlog/clientdemo/config/DemoConfig.java
similarity index 52%
rename from clientdemo/src/main/java/com/jd/platform/jlog/clientdemo/config/DemoConfig.java
rename to example/src/main/java/com/jd/platform/jlog/clientdemo/config/DemoConfig.java
index 5b4e4237a18afda1967a265a911400d00ab73789..00a7fe81bfe54ddedb5aa107978c03d985106caf 100644
--- a/clientdemo/src/main/java/com/jd/platform/jlog/clientdemo/config/DemoConfig.java
+++ b/example/src/main/java/com/jd/platform/jlog/clientdemo/config/DemoConfig.java
@@ -1,12 +1,14 @@
package com.jd.platform.jlog.clientdemo.config;
import com.jd.platform.jlog.client.TracerClientStarter;
-import com.jd.platform.jlog.client.filter.UserFilter;
-import org.springframework.beans.factory.annotation.Value;
+import com.jd.platform.jlog.client.filter.HttpFilter;
+import com.jd.platform.jlog.common.handler.TagConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
+import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
@@ -16,24 +18,37 @@ import javax.annotation.PostConstruct;
* @version 1.0
* @date 2021-12-27
*/
-@Configuration
+@Component
+@ConfigurationProperties()
public class DemoConfig {
- @Value("${config.server}")
- private String etcdServer;
+ private Logger logger = LoggerFactory.getLogger(getClass());
+
+ private TagConfig tagConfig ;
+
+ public TagConfig getTagConfig() {
+ return tagConfig;
+ }
+
+ public void setTagConfig(TagConfig tagConfig) {
+ this.tagConfig = tagConfig;
+ }
@PostConstruct
- public void begin() {
+ public void begin() throws Exception {
+
TracerClientStarter tracerClientStarter = new TracerClientStarter.Builder()
.setAppName("demo")
- .setEtcdServer(etcdServer).build();
+ .setTagConfig(tagConfig)
+ .build();
+ logger.info("初始化tagConfig: {}",tagConfig);
tracerClientStarter.startPipeline();
}
@Bean
public FilterRegistrationBean urlFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
- UserFilter userFilter = new UserFilter();
+ HttpFilter userFilter = new HttpFilter();
registration.setFilter(userFilter);
registration.addUrlPatterns("/*");
diff --git a/clientdemo/src/main/java/com/jd/platform/jlog/clientdemo/web/TestController.java b/example/src/main/java/com/jd/platform/jlog/clientdemo/web/TestController.java
similarity index 30%
rename from clientdemo/src/main/java/com/jd/platform/jlog/clientdemo/web/TestController.java
rename to example/src/main/java/com/jd/platform/jlog/clientdemo/web/TestController.java
index 60929eaf0dbd1c7a7bf2d8303ca01fca303d21c0..0a3b3857aeaf5a9e1ba43814881edde886626357 100644
--- a/clientdemo/src/main/java/com/jd/platform/jlog/clientdemo/web/TestController.java
+++ b/example/src/main/java/com/jd/platform/jlog/clientdemo/web/TestController.java
@@ -1,19 +1,36 @@
package com.jd.platform.jlog.clientdemo.web;
+
import com.jd.platform.jlog.common.model.TracerBean;
+import com.jd.platform.jlog.common.handler.TagConfig;
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
/**
* @author shenkaiwen5
* @version 1.0
* @date 2021-12-27
*/
+@Component
+//@ConfigurationProperties()
@RestController
public class TestController {
+ private TagConfig tagConfig ;
+
+ public TagConfig getTagConfig() {
+ return tagConfig;
+ }
+
+ public void setTagConfig(TagConfig tagConfig) {
+ this.tagConfig = tagConfig;
+ }
+
/**
* do nothing
* just as an adapter for this project common log helper
@@ -22,13 +39,40 @@ public class TestController {
private static Logger RequestLog = LoggerFactory.getLogger("RequestLog");
@RequestMapping("/index")
- public Object index() {
+ public Object index() {
TracerBean tracerBean = new TracerBean();
tracerBean.setTracerId("11111");
+ Configurator configurator = ConfiguratorFactory.getInstance();
+ try{
+ configurator.putConfig("/test","val1");
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+
+ String val = configurator.getString("/test");
+ System.out.println("val ===> "+val);
RequestLog.info("哈哈哈哈哈哈");
return tracerBean;
}
+ @RequestMapping("/log")
+ public Object log() {
+ RequestLog.info("|errno=val3||node=val4||这是随便的log|");
+ return 1;
+ }
+
+
+ @PostMapping(value = "/test", consumes = MediaType.APPLICATION_JSON_VALUE)
+ public Object test(@RequestParam Integer uid, @RequestParam Integer newKey,@RequestBody TestReq req) {
+ String config = ConfiguratorFactory.getInstance().getString("reqTags");
+ // System.out.println("tagConfig ===> " + tagConfig.toString());
+ RequestLog.info("|errno=val3||node=val4||这是随便的log|");
+
+ return 1;
+ }
+
+
+
}
diff --git a/example/src/main/java/com/jd/platform/jlog/clientdemo/web/TestReq.java b/example/src/main/java/com/jd/platform/jlog/clientdemo/web/TestReq.java
new file mode 100644
index 0000000000000000000000000000000000000000..917c1b399369ebad2b51b0687f1213430dd6cdd7
--- /dev/null
+++ b/example/src/main/java/com/jd/platform/jlog/clientdemo/web/TestReq.java
@@ -0,0 +1,15 @@
+package com.jd.platform.jlog.clientdemo.web;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName TestReq.java
+ * @Description TODO
+ * @createTime 2022年02月17日 16:40:00
+ */
+public class TestReq {
+
+ private Integer id;
+
+ private String name;
+}
diff --git a/example/src/main/resources/application.properties b/example/src/main/resources/application.properties
new file mode 100644
index 0000000000000000000000000000000000000000..19b36d20b1fe750d5a73596aaa3efb7176c55f8c
--- /dev/null
+++ b/example/src/main/resources/application.properties
@@ -0,0 +1,6 @@
+server.port=8085
+serverAddr=101.42.242.201:2379
+
+apollo.meta=http://127.0.0.1:8080
+apollo.config-service=http://127.0.0.1:8080
+app.id=order
\ No newline at end of file
diff --git a/example/src/main/resources/bakapplication.yml b/example/src/main/resources/bakapplication.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2bb1bcb9c978226a2b11960f182c1eccdd65b2c1
--- /dev/null
+++ b/example/src/main/resources/bakapplication.yml
@@ -0,0 +1,24 @@
+workers: [1,2,3]
+compress: 68
+threshold: 10000
+
+serverAddr: 101.42.242.201:2181
+server:
+ port: 8085
+
+test: true
+
+
+tag-config:
+ reqTags:
+ - uid
+ - url
+ - newK
+ logTags:
+ - node
+ - bizType
+ respTags:
+ - errno
+ delimiter: "|"
+ join: "="
+
diff --git a/example/src/main/resources/bakjLog.properties b/example/src/main/resources/bakjLog.properties
new file mode 100644
index 0000000000000000000000000000000000000000..697d62781d37f9c0ae3b33f8a1337a501581612f
--- /dev/null
+++ b/example/src/main/resources/bakjLog.properties
@@ -0,0 +1,18 @@
+server.port=8085
+
+tag-config.reqTags[0]=uid
+tag-config.reqTags[1]=url
+
+tag-config.logTags[0]=node
+tag-config.logTags[1]=bizType
+
+tag-config.respTags[0]=errno
+tag-config.respTags[1]=msg
+tag-config.delimiter=|
+tag-config.join==
+tag-config.extract=41
+
+compress=68
+threshold=10000
+
+workers=[1,2,3]
diff --git a/example/src/main/resources/logback-spring.xml b/example/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8b56e11c64a693cc2c1b6bcb178ea11c0b17fb25
--- /dev/null
+++ b/example/src/main/resources/logback-spring.xml
@@ -0,0 +1,62 @@
+
+
+ logs
+
+
+
+
+
+
+
+
+
+
+
+ ${log.colorPattern}
+
+
+
+
+
+
+
+
+
+ ${log.path}/info/info.%d{yyyy-MM-dd}.log
+ ${log.maxHistory}
+
+
+ ${log.pattern}
+
+
+ INFO
+ ACCEPT
+ DENY
+
+
+
+
+
+ ${log.path}/error/error.%d{yyyy-MM-dd}.log
+
+
+ ${log.pattern}
+
+
+ ERROR
+ ACCEPT
+ DENY
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/example/src/test/java/com/jd/platform/jlog/test/Common.java b/example/src/test/java/com/jd/platform/jlog/test/Common.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6034fb01788e7e7e8e891def7e8147e91222b4a
--- /dev/null
+++ b/example/src/test/java/com/jd/platform/jlog/test/Common.java
@@ -0,0 +1,67 @@
+package com.jd.platform.jlog.test;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.common.handler.TagConfig;
+import com.jd.platform.jlog.core.Configurator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName Common.java
+ * @Description TODO
+ * @createTime 2022年03月01日 07:36:00
+ */
+public class Common {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(Common.class);
+
+
+ public static void getTest(Configurator configurator){
+
+ LOGGER.info("配置器类型:{}", configurator.getType());
+ String addr = configurator.getString("serverAddr");
+ LOGGER.info("配置器get addr:{}", addr);
+ TagConfig tagConfig = configurator.getObject("tag-config", TagConfig.class);
+ LOGGER.info("配置器get tagConfig:{}", tagConfig.toString());
+ List workers = configurator.getList("workers");
+ LOGGER.info("配置器get workers:{}", JSON.toJSONString(workers));
+ }
+
+
+ public static void modifyFile(String path)throws Exception{
+
+ String temp;
+ File file = new File(path);
+ FileInputStream fis = new FileInputStream(file);
+ InputStreamReader isr = new InputStreamReader(fis);
+ BufferedReader br = new BufferedReader(isr);
+ StringBuffer buf = new StringBuffer();
+
+ int id = new Random().nextInt(1000);
+ int num = 0;
+ // 保存该行前面的内容
+ while ((temp = br.readLine()) != null) {
+ if(num == 0){
+ buf = buf.append("testKey: ").append(id);
+ }else{
+ buf = buf.append(temp);
+ }
+ num++;
+ buf = buf.append(System.getProperty("line.separator"));
+ }
+
+ br.close();
+ FileOutputStream fos = new FileOutputStream(file);
+ PrintWriter pw = new PrintWriter(fos);
+ pw.write(buf.toString().toCharArray());
+ pw.flush();
+ pw.close();
+ }
+
+}
diff --git a/example/src/test/java/com/jd/platform/jlog/test/EtcdConfiguratorTest.java b/example/src/test/java/com/jd/platform/jlog/test/EtcdConfiguratorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..4a5b575bd2d6ad3091238a1ea767edff8482d1ec
--- /dev/null
+++ b/example/src/test/java/com/jd/platform/jlog/test/EtcdConfiguratorTest.java
@@ -0,0 +1,85 @@
+package com.jd.platform.jlog.test;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.clientdemo.ExampleApplication;
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+import java.util.Random;
+
+import static com.jd.platform.jlog.test.Common.getTest;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName EtcdConfiguratorTest.java
+ * @Description TODO
+ * @createTime 2022年03月03日 07:35:00
+ */
+@SpringBootTest(classes = ExampleApplication.class)
+@RunWith(SpringRunner.class)
+public class EtcdConfiguratorTest {
+
+
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(EtcdConfiguratorTest.class);
+
+
+ private Configurator configurator = null;
+
+
+
+ @Before
+ public void init() {
+ configurator = ConfiguratorFactory.getInstance();
+ getTest(configurator);
+ }
+
+ // @Test
+ public void testUpdateCFG() throws Exception {
+ List workers = configurator.getList("workers");
+ LOGGER.info("初始化的workers:{}", JSON.toJSONString(workers));
+ String myIp = "121.1.1.0";
+ if(workers.contains(myIp)){
+ // do nothing
+ LOGGER.info("自己的IP还在配置list里 什么也不做");
+ return;
+ }else{
+ LOGGER.info("自己的IP不在配置list里 添加进去并发布");
+ workers.add(myIp);
+ }
+ configurator.putConfig("workers",JSON.toJSONString(workers));
+ List workers2 = configurator.getList("workers");
+ LOGGER.info("最新的workers:{}", JSON.toJSONString(workers2));
+ }
+
+ @Test
+ public void testAddConfigListener() throws Exception {
+ int i1 = new Random().nextInt(2000);
+ int i2 = new Random().nextInt(2000);
+
+ String val1 = configurator.getString("testKey");
+ LOGGER.info("初始化的testKey的val:{}", val1);
+ LOGGER.info("添加监听器后, 修改配置testKey = {}", i1);
+ configurator.putConfig("testKey",i1 + "");
+ LOGGER.info("修改完毕 准备触发监听器");
+ Thread.sleep(5000);
+ String val2 = configurator.getString("testKey");
+ LOGGER.info("第一次修改后的的val:{}", val2);
+ Thread.sleep(5000);
+ // LOGGER.info("移除监听器后:修改配置testKey = {}",i2);
+ // configurator.putConfig("testKey",i2 + "");
+ LOGGER.info("准备验证监听器是否停止 最新testKey={}", configurator.getString("testKey"));
+ LOGGER.info("第二次添加监听器");
+ Thread.sleep(22000);
+
+ }
+}
diff --git a/example/src/test/java/com/jd/platform/jlog/test/FileConfiguratorTest.java b/example/src/test/java/com/jd/platform/jlog/test/FileConfiguratorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e3eca92b524eb4580530cba6525c6def267ea7f8
--- /dev/null
+++ b/example/src/test/java/com/jd/platform/jlog/test/FileConfiguratorTest.java
@@ -0,0 +1,69 @@
+package com.jd.platform.jlog.test;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.clientdemo.ExampleApplication;
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.*;
+import java.util.Map;
+import java.util.Properties;
+
+import static com.jd.platform.jlog.test.Common.getTest;
+import static com.jd.platform.jlog.test.Common.modifyFile;
+
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName FileConfiguratorTest.java
+ * @Description TODO
+ * @createTime 2022年02月28日 19:45:00
+ */
+@SpringBootTest(classes = ExampleApplication.class)
+@RunWith(SpringRunner.class)
+public class FileConfiguratorTest {
+
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(FileConfiguratorTest.class);
+
+
+ private Configurator configurator = null;
+
+
+
+ @Before
+ public void init() {
+ configurator = ConfiguratorFactory.getInstance();
+ getTest(configurator);
+ }
+
+
+
+ @Test
+ public void testAddConfigListener() throws Exception {
+ String path = "/Users/didi/Desktop/jlog/example/target/classes/bakapplication.yml";
+ Properties props = new Properties();
+ FileInputStream fis = new FileInputStream(new File(path));
+ if (path.contains("yml")) {
+ props.putAll(new Yaml().loadAs(fis, Map.class));
+ } else {
+ props.load(fis);
+ }
+ LOGGER.info("读取文件:{} 最新配置:{}", path, JSON.toJSONString(props));
+ modifyFile(path);
+ LOGGER.info("修改文件完毕 准备触发监听器");
+ Thread.sleep(10000);
+ }
+
+
+
+}
diff --git a/example/src/test/java/com/jd/platform/jlog/test/NacosConfiguratorTest.java b/example/src/test/java/com/jd/platform/jlog/test/NacosConfiguratorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..38c77c9c64747618f700a7f484e03afc928e4530
--- /dev/null
+++ b/example/src/test/java/com/jd/platform/jlog/test/NacosConfiguratorTest.java
@@ -0,0 +1,81 @@
+package com.jd.platform.jlog.test;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.clientdemo.ExampleApplication;
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+import java.util.Random;
+
+import static com.jd.platform.jlog.test.Common.getTest;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName NacosConfiguratorTest.java
+ * @Description TODO
+ * @createTime 2022年03月01日 07:35:00
+ */
+@SpringBootTest(classes = ExampleApplication.class)
+@RunWith(SpringRunner.class)
+public class NacosConfiguratorTest {
+
+
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(NacosConfiguratorTest.class);
+
+
+ private Configurator configurator = null;
+
+
+
+ @Before
+ public void init() {
+ configurator = ConfiguratorFactory.getInstance();
+ getTest(configurator);
+ }
+
+ @Test
+ public void testUpdateCFG() throws Exception {
+ List workers = configurator.getList("workers");
+ LOGGER.info("初始化的workers:{}", JSON.toJSONString(workers));
+ String myIp = "121.1.1.0";
+ if(workers.contains(myIp)){
+ // do nothing
+ LOGGER.info("自己的IP还在配置list里 什么也不做");
+ return;
+ }else{
+ LOGGER.info("自己的IP不在配置list里 添加进去并发布");
+ workers.add(myIp);
+ }
+ configurator.putConfig("workers",JSON.toJSONString(workers));
+ List workers2 = configurator.getList("workers");
+ LOGGER.info("最新的workers:{}", JSON.toJSONString(workers2));
+ }
+
+ @Test
+ public void testAddConfigListener() throws Exception {
+ int i1 = new Random().nextInt(2000);
+ int i2 = new Random().nextInt(2000);
+
+ String val1 = configurator.getString("testKey");
+ LOGGER.info("初始化的testKey的val:{}", val1);
+ // configurator.putConfig("testKey",i1 + "");
+ LOGGER.info("修改完毕 准备触发监听器");
+ Thread.sleep(1000);
+ String val2 = configurator.getString("testKey");
+ LOGGER.info("第一次修改后的的val:{}", val2);
+ configurator.putConfig("testKey",i2 + "");
+ LOGGER.info("准备验证监听器是否停止 最新testKey={}", configurator.getString("testKey"));
+
+ Thread.sleep(35000);
+ }
+}
diff --git a/clientdemo/src/test/java/com/jd/platform/jlog/test/TracerPacketTest.java b/example/src/test/java/com/jd/platform/jlog/test/TracerPacketTest.java
similarity index 87%
rename from clientdemo/src/test/java/com/jd/platform/jlog/test/TracerPacketTest.java
rename to example/src/test/java/com/jd/platform/jlog/test/TracerPacketTest.java
index e2a834341d761ffaad32a163cd091ddbe72afb7f..0ef5a231e35cef2cd0b2edccd80faf67e791d1c4 100644
--- a/clientdemo/src/test/java/com/jd/platform/jlog/test/TracerPacketTest.java
+++ b/example/src/test/java/com/jd/platform/jlog/test/TracerPacketTest.java
@@ -2,15 +2,11 @@ package com.jd.platform.jlog.test;
import com.alibaba.fastjson.JSON;
import com.jd.platform.jlog.client.udp.UdpSender;
-import com.jd.platform.jlog.clientdemo.ClientDemoApplication;
+import com.jd.platform.jlog.clientdemo.ExampleApplication;
import com.jd.platform.jlog.common.model.TracerBean;
import com.jd.platform.jlog.common.utils.IpUtils;
import com.jd.platform.jlog.common.utils.ZstdUtils;
import org.apache.tomcat.util.codec.binary.Base64;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
import java.nio.charset.StandardCharsets;
import java.util.*;
@@ -22,11 +18,11 @@ import java.util.*;
* @version 1.0
* @date 2021-12-27
*/
-@SpringBootTest(classes = ClientDemoApplication.class)
-@RunWith(SpringRunner.class)
+//@SpringBootTest(classes = ExampleApplication.class)
+//@RunWith(SpringRunner.class)
public class TracerPacketTest {
- @Test
+ //@Test
public void testSendUdp() {
TracerBean tracerBean = new TracerBean();
List> tracerObject = new ArrayList<>();
diff --git a/example/src/test/java/com/jd/platform/jlog/test/ZKConfiguratorTest.java b/example/src/test/java/com/jd/platform/jlog/test/ZKConfiguratorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..26582a433bec7c1f4894ab1524fee639f6ca4267
--- /dev/null
+++ b/example/src/test/java/com/jd/platform/jlog/test/ZKConfiguratorTest.java
@@ -0,0 +1,79 @@
+package com.jd.platform.jlog.test;
+
+import com.alibaba.fastjson.JSON;
+import com.jd.platform.jlog.clientdemo.ExampleApplication;
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorFactory;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.List;
+
+import java.util.Random;
+
+import static com.jd.platform.jlog.test.Common.getTest;
+
+/**
+ * @author tangbohu
+ * @version 1.0.0
+ * @ClassName ZKConfiguratorTest.java
+ * @Description TODO
+ * @createTime 2022年03月01日 07:35:00
+ */
+@SpringBootTest(classes = ExampleApplication.class)
+@RunWith(SpringRunner.class)
+public class ZKConfiguratorTest {
+
+
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(ZKConfiguratorTest.class);
+
+
+ private Configurator configurator = null;
+
+
+
+ @Before
+ public void init() {
+ configurator = ConfiguratorFactory.getInstance();
+ getTest(configurator);
+ }
+
+ @Test
+ public void testUpdateCFG() throws Exception {
+ List workers = configurator.getList("workers");
+ LOGGER.info("初始化的workers:{}", JSON.toJSONString(workers));
+ String myIp = "121.0";
+ if(workers.contains(myIp)){
+ LOGGER.info("自己的IP还在配置list里 什么也不做");
+ return;
+ }else{
+ LOGGER.info("自己的IP不在配置list里 添加进去并发布");
+ workers.add(myIp);
+ }
+ configurator.putConfig("workers",JSON.toJSONString(workers));
+ List workers2 = configurator.getList("workers");
+ LOGGER.info("最新的workers:{}", JSON.toJSONString(workers2));
+ }
+
+ @Test
+ public void testAddConfigListener() throws Exception {
+ int i1 = new Random().nextInt(2000);
+ int i2 = new Random().nextInt(2000);
+
+ String val1 = configurator.getString("testKey");
+ LOGGER.info("初始化的testKey的val:{}", val1);
+ LOGGER.info("添加监听器后, 修改配置testKey = {}", i1);
+ // configurator.putConfig("testKey",i1 + "");
+ LOGGER.info("修改完毕 准备触发监听器");
+ Thread.sleep(1000);
+ String val2 = configurator.getString("testKey");
+ LOGGER.info("第一次修改后的的val:{}", val2);
+ Thread.sleep(1000);
+ }
+}
diff --git a/pom.xml b/pom.xml
index 57bd6e24d557b98279985469e2dc7852912b2862..4c92e3e9002abfa8edba6caca244cdebebefa8ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,7 +16,8 @@
clientlog4j2
clientlogback
Dashboard
- clientdemo
+ example
+ config
diff --git a/worker/pom.xml b/worker/pom.xml
index 771b8f6fe310d4cc887583ceb163927f399e2afe..8e02fe62289fe29f13683f7e9b1e5da2df4e79b7 100644
--- a/worker/pom.xml
+++ b/worker/pom.xml
@@ -22,6 +22,11 @@
org.springframework.boot
spring-boot-starter-web
+
+ com.jd.platfrom.jlog
+ config-zk
+ 1.4-SNAPSHOT
+
org.springframework.boot
@@ -43,6 +48,12 @@
disruptor
3.4.1
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
diff --git a/worker/src/main/java/com/jd/platform/jlog/worker/Starter.java b/worker/src/main/java/com/jd/platform/jlog/worker/Starter.java
index 7c76876b3c416fb670e3651db570139ab5a84cf8..08ff060aec5ee2db88fa6fe0fbbdc96aa4dcbf59 100644
--- a/worker/src/main/java/com/jd/platform/jlog/worker/Starter.java
+++ b/worker/src/main/java/com/jd/platform/jlog/worker/Starter.java
@@ -1,6 +1,6 @@
package com.jd.platform.jlog.worker;
-import com.jd.platform.jlog.worker.config.EtcdStarter;
+import com.jd.platform.jlog.worker.config.CenterStarter;
import com.jd.platform.jlog.worker.store.TracerLogToDbStore;
import com.jd.platform.jlog.worker.store.TracerModelToDbStore;
import com.jd.platform.jlog.worker.udp.UdpServer;
@@ -42,7 +42,7 @@ public class Starter {
* etcd启动器
*/
@Resource
- private EtcdStarter etcdStarter;
+ private CenterStarter centerStarter;
@PostConstruct
public void start() {
@@ -58,7 +58,7 @@ public class Starter {
tracerLogToDbStore.beginIntoDb();
//上报自己ip到配置中心
- etcdStarter.uploadSelfInfo();
+ centerStarter.uploadSelfInfo();
}
}
diff --git a/worker/src/main/java/com/jd/platform/jlog/worker/config/EtcdStarter.java b/worker/src/main/java/com/jd/platform/jlog/worker/config/CenterStarter.java
similarity index 75%
rename from worker/src/main/java/com/jd/platform/jlog/worker/config/EtcdStarter.java
rename to worker/src/main/java/com/jd/platform/jlog/worker/config/CenterStarter.java
index 67aac4a397bf6fd7bfed00c0fabe838c0c018af9..9c234f4cd76880b358b366a11a8b5eef88a4a472 100644
--- a/worker/src/main/java/com/jd/platform/jlog/worker/config/EtcdStarter.java
+++ b/worker/src/main/java/com/jd/platform/jlog/worker/config/CenterStarter.java
@@ -1,12 +1,16 @@
package com.jd.platform.jlog.worker.config;
-import com.jd.platform.jlog.common.config.IConfigCenter;
+import com.alibaba.fastjson.JSON;
import com.jd.platform.jlog.common.constant.Constant;
import com.jd.platform.jlog.common.utils.IpUtils;
+import com.jd.platform.jlog.core.Configurator;
+import com.jd.platform.jlog.core.ConfiguratorFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -19,7 +23,7 @@ import java.util.concurrent.TimeUnit;
* @date 2021-08-12
*/
@Component
-public class EtcdStarter {
+public class CenterStarter {
/**
* 该worker为哪个app服务
*/
@@ -35,23 +39,23 @@ public class EtcdStarter {
*/
@Value("${config.mdc}")
private String mdc;
- /**
- * configCenter
- */
- @Resource
- private IConfigCenter configCenter;
+
/**
* 上报自己的ip到配置中心
*/
public void uploadSelfInfo() {
//开启上传worker信息
+ Configurator config = ConfiguratorFactory.getInstance();
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(() -> {
try {
- configCenter.putAndGrant(buildKey(), buildValue(), 8);
- configCenter.putAndGrant(buildSecondKey(), buildValue(), 8);
+ List list = config.getList("workers");
+ if(!list.contains(buildKey())){
+ list.add(buildValue());
+ config.putConfig("workers", JSON.toJSONString(list));
+ }
} catch (Exception e) {
//do nothing
e.printStackTrace();
@@ -68,14 +72,6 @@ public class EtcdStarter {
return Constant.WORKER_PATH + workerPath + "/" + hostName;
}
- /**
- * 在配置中心对应机房存放的key
- */
- private String buildSecondKey() {
- String hostName = IpUtils.getHostName();
- return Constant.WORKER_PATH + workerPath + "/" + mdc + "/" + hostName;
- }
-
/**
* 在配置中心存放的value
*/
diff --git a/worker/src/main/java/com/jd/platform/jlog/worker/config/EtcdConfig.java b/worker/src/main/java/com/jd/platform/jlog/worker/config/EtcdConfig.java
deleted file mode 100644
index 4195e9a94b3ffebf7b170aa0238cc0a9b13e1f6b..0000000000000000000000000000000000000000
--- a/worker/src/main/java/com/jd/platform/jlog/worker/config/EtcdConfig.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.jd.platform.jlog.worker.config;
-
-import com.jd.platform.jlog.common.config.IConfigCenter;
-import com.jd.platform.jlog.common.config.etcd.JdEtcdBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-
-/**
- * EtcdConfig
- * @author wuweifeng wrote on 2019-12-06
- * @version 1.0
- */
-@Configuration
-public class EtcdConfig {
- @Value("${config.server}")
- private String etcdServer;
-
- private Logger logger = LoggerFactory.getLogger(getClass());
-
- @Bean
- public IConfigCenter client() {
- logger.info("etcd address : " + etcdServer);
- //连接多个时,逗号分隔
- return JdEtcdBuilder.build(etcdServer);
- }
-
-}
diff --git a/worker/src/main/java/com/jd/platform/jlog/worker/config/IConfig.java b/worker/src/main/java/com/jd/platform/jlog/worker/config/IConfig.java
deleted file mode 100644
index 064182ae287c1d408849c26358ccc8994cff832a..0000000000000000000000000000000000000000
--- a/worker/src/main/java/com/jd/platform/jlog/worker/config/IConfig.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.jd.platform.jlog.worker.config;
-
-/**
- * 配置中心接口
- * @author wuweifeng
- * @version 1.0
- * @date 2021-08-13
- */
-public interface IConfig {
-}
diff --git a/worker/src/main/java/com/jd/platform/jlog/worker/controller/UserController.java b/worker/src/main/java/com/jd/platform/jlog/worker/controller/UserController.java
index 716799557bddc50fedd503db0d98df5fb063899b..98ebaf79c91c30de913afb38acee24a3d1fc5e47 100644
--- a/worker/src/main/java/com/jd/platform/jlog/worker/controller/UserController.java
+++ b/worker/src/main/java/com/jd/platform/jlog/worker/controller/UserController.java
@@ -1,6 +1,5 @@
package com.jd.platform.jlog.worker.controller;
-import cn.hutool.core.date.DateUtil;
import com.jd.platform.jlog.worker.db.Db;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -32,12 +31,12 @@ public class UserController {
Map map0 = new HashMap<>();
map0.put("clientType", 1);
map0.put("pin", "abcd");
- map0.put("createTime", DateUtil.formatDateTime(new Date()));
+ // map0.put("createTime", DateUtil.formatDateTime(new Date()));
Map map1 = new HashMap<>();
map1.put("clientType", 1);
map1.put("pin", "abcd");
- map1.put("createTime", DateUtil.formatDateTime(new Date()));
+ // map1.put("createTime", DateUtil.formatDateTime(new Date()));
datas.add(map0);
datas.add(map1);
diff --git a/worker/src/main/java/com/jd/platform/jlog/worker/disruptor/TracerConsumer.java b/worker/src/main/java/com/jd/platform/jlog/worker/disruptor/TracerConsumer.java
index 7469555bcde27020277d22865a8d7b11e2f358f3..167bcc0e17dfc65250385d0c4c0d1225494a51fa 100644
--- a/worker/src/main/java/com/jd/platform/jlog/worker/disruptor/TracerConsumer.java
+++ b/worker/src/main/java/com/jd/platform/jlog/worker/disruptor/TracerConsumer.java
@@ -1,6 +1,5 @@
package com.jd.platform.jlog.worker.disruptor;
-import cn.hutool.core.date.DateUtil;
import com.jd.platform.jlog.common.model.RunLogMessage;
import com.jd.platform.jlog.common.model.TracerBean;
import com.jd.platform.jlog.common.model.TracerData;
@@ -105,8 +104,8 @@ public class TracerConsumer implements WorkHandler {
map.put("threadName", runLogMessage.getThreadName());
map.put("methodName", runLogMessage.getMethodName());
map.put("logLevel", runLogMessage.getLogLevel());
- map.put("createTime", DateUtil.formatDateTime(new Date(runLogMessage.getCreateTime())));
map.put("content", runLogMessage.getContent());
+ map.putAll(runLogMessage.getTagMap());
tracerLogToDbStore.offer(map);
}
@@ -116,9 +115,12 @@ public class TracerConsumer implements WorkHandler {
* 处理filter里处理的出入参
*/
private void dealFilterModel(TracerBean tracerBean) {
+
List> mapList = tracerBean.getTracerObject();
Map requestMap = mapList.get(0);
+ Map map = new HashMap<>(requestMap);
+
long tracerId = requestMap.get("tracerId") == null ? 0 : Long.valueOf(requestMap.get("tracerId").toString());
//filter的出入参
Map responseMap = mapList.get(mapList.size() - 1);
@@ -128,59 +130,11 @@ public class TracerConsumer implements WorkHandler {
responseBytes = (byte[]) responseMap.get("response");
}
- Map map = new HashMap<>();
- //jsf的是用户自己设置的request入参,http的是从httpRequest读取的
- if (requestMap.get("wholeRequest") == null) {
- map.put("requestContent", FastJsonUtils.collectToString(requestMap));
- } else {
- map.put("requestContent", requestMap.get("wholeRequest"));
- }
-
- //此处做了一个base64编码,否则原编码直接进去,取出来后是String,直接getBytes后无法用Zstd解压
map.put("responseContent", responseBytes);
- map.put("createTime", DateUtil.formatDateTime(new Date(tracerBean.getCreateTime())));
map.put("costTime", tracerBean.getCostTime());
-
-
map.put("tracerId", tracerId);
-
- String pin = requestMap.get("pin") == null ? "" : requestMap.get("pin").toString();
- map.put("pin", pin);
-
- String uri = requestMap.get("uri") == null ? "" : requestMap.get("uri").toString();
- map.put("uri", uri);
-
- //appName
- String appName = requestMap.get("appName") == null ? "" : requestMap.get("appName").toString();
- map.put("appName", appName);
-
- String openudid = requestMap.get("openudid") == null ? "" : requestMap.get("openudid").toString();
-
- if (StringUtil.isNullOrEmpty(openudid)) {
- String uuid = requestMap.get("uuid") == null ? "" : requestMap.get("uuid").toString();
- map.put("uuid", uuid);
- } else {
- map.put("uuid", openudid);
- }
-
- String client = requestMap.get("client") == null ? "" : requestMap.get("client").toString();
- int clientType = 0;
- if ("apple".equals(client)) {
- clientType = 2;
- } else if ("android".equals(client)) {
- clientType = 1;
- }
- map.put("clientType", clientType);
- String clientVersion = requestMap.get("clientVersion") == null ? "" : requestMap.get("clientVersion").toString();
- map.put("clientVersion", clientVersion);
-
- String userIp = requestMap.get("ip") == null ? "" : requestMap.get("ip").toString();
- map.put("userIp", userIp);
- String serverIp = requestMap.get("serverIp") == null ? "" : requestMap.get("serverIp").toString();
- map.put("serverIp", serverIp);
-
- map.put("intoDbTime", DateUtil.formatDateTime(new Date(tracerBean.getCreateTime())));
-
+ responseMap.remove("response");
+ map.putAll(responseMap);
tracerModelToDbStore.offer(map);
}
diff --git a/worker/src/main/java/com/jd/platform/jlog/worker/entity/TracerModel.java b/worker/src/main/java/com/jd/platform/jlog/worker/entity/TracerModel.java
deleted file mode 100644
index b359adef09c623c1008480451fbc1a06c1e8adf6..0000000000000000000000000000000000000000
--- a/worker/src/main/java/com/jd/platform/jlog/worker/entity/TracerModel.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package com.jd.platform.jlog.worker.entity;
-
-
-import java.io.Serializable;
-
-/**
- * 入库、检索时用的对象
- *
- * @author wuweifeng
- * @version 1.0
- * @date 2021-08-20
- */
-public class TracerModel implements Serializable {
- /**
- * tracerId
- */
- private long tracerId;
- /**
- * 请求的入参
- */
- private String requestContent;
- /**
- * 响应的出参
- */
- private String responseContent;
- /**
- * 日志请求时间(数据库里存的是DateTime,2021-08-24 19:47:30.0)
- */
- private long createTime;
- /**
- * 请求耗时(即响应时间戳减去请求时间戳)
- */
- private int costTime;
- /**
- * 用户pin
- */
- private String pin;
- /**
- * 用户uuid
- */
- private String uuid;
- /**
- * Android=1、ios=2
- */
- private int clientType;
- /**
- * 客户端版本号,9.3.6
- */
- private String clientVersion;
- /**
- * 用户ip
- */
- private String userIp;
- /**
- * 服务端ip
- */
- private String serverIp;
- /**
- * 入库时间
- */
- private long intoDbTime;
-
-
- public long getIntoDbTime() {
- return intoDbTime;
- }
-
- public void setIntoDbTime(long intoDbTime) {
- this.intoDbTime = intoDbTime;
- }
-
- public String getRequestContent() {
- return requestContent;
- }
-
- public void setRequestContent(String requestContent) {
- this.requestContent = requestContent;
- }
-
- public String getResponseContent() {
- return responseContent;
- }
-
- public void setResponseContent(String responseContent) {
- this.responseContent = responseContent;
- }
-
- public long getTracerId() {
- return tracerId;
- }
-
- public void setTracerId(long tracerId) {
- this.tracerId = tracerId;
- }
-
- public long getCreateTime() {
- return createTime;
- }
-
- public void setCreateTime(long createTime) {
- this.createTime = createTime;
- }
-
- public int getCostTime() {
- return costTime;
- }
-
- public void setCostTime(int costTime) {
- this.costTime = costTime;
- }
-
- public String getPin() {
- return pin;
- }
-
- public void setPin(String pin) {
- this.pin = pin;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- public void setUuid(String uuid) {
- this.uuid = uuid;
- }
-
- public int getClientType() {
- return clientType;
- }
-
- public void setClientType(int clientType) {
- this.clientType = clientType;
- }
-
- public String getClientVersion() {
- return clientVersion;
- }
-
- public void setClientVersion(String clientVersion) {
- this.clientVersion = clientVersion;
- }
-
-
- public String getUserIp() {
- return userIp;
- }
-
- public void setUserIp(String userIp) {
- this.userIp = userIp;
- }
-
- public String getServerIp() {
- return serverIp;
- }
-
- public void setServerIp(String serverIp) {
- this.serverIp = serverIp;
- }
-}
diff --git a/worker/src/main/java/com/jd/platform/jlog/worker/store/TracerLogToDbStore.java b/worker/src/main/java/com/jd/platform/jlog/worker/store/TracerLogToDbStore.java
index e226b6d6bde2b8eb19c923716fbdca6b0a5e3a75..fa8b5fc1efa447918971847923292c8021cbf117 100644
--- a/worker/src/main/java/com/jd/platform/jlog/worker/store/TracerLogToDbStore.java
+++ b/worker/src/main/java/com/jd/platform/jlog/worker/store/TracerLogToDbStore.java
@@ -1,8 +1,8 @@
package com.jd.platform.jlog.worker.store;
-import cn.hutool.core.collection.CollectionUtil;
-import com.google.common.collect.Queues;
+
import com.jd.platform.jlog.common.utils.AsyncPool;
+import com.jd.platform.jlog.common.utils.AsyncWorker;
import com.jd.platform.jlog.worker.db.Db;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -94,8 +94,8 @@ public class TracerLogToDbStore {
try {
List> tempModels = new ArrayList<>();
//每1s入库一次
- Queues.drain(logQueue, tempModels, Integer.valueOf(batchSize), interval, TimeUnit.SECONDS);
- if (CollectionUtil.isEmpty(tempModels)) {
+ AsyncWorker.drain(logQueue, tempModels, Integer.valueOf(batchSize), interval, TimeUnit.SECONDS);
+ if (tempModels.size() == 0) {
continue;
}
diff --git a/worker/src/main/java/com/jd/platform/jlog/worker/store/TracerModelToDbStore.java b/worker/src/main/java/com/jd/platform/jlog/worker/store/TracerModelToDbStore.java
index 4ad9d8f5193963733971632e27c07bc38ac1fdb4..8a54550fabf5dece5a05e689de45eb4cb191a9af 100644
--- a/worker/src/main/java/com/jd/platform/jlog/worker/store/TracerModelToDbStore.java
+++ b/worker/src/main/java/com/jd/platform/jlog/worker/store/TracerModelToDbStore.java
@@ -1,8 +1,8 @@
package com.jd.platform.jlog.worker.store;
-import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Queues;
import com.jd.platform.jlog.common.utils.AsyncPool;
+import com.jd.platform.jlog.common.utils.CollectionUtil;
import com.jd.platform.jlog.worker.db.Db;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/worker/src/main/resources/application.yml b/worker/src/main/resources/application.yml
index 019ac4818a2cef6bb4a16782217c5511c84b0867..924c7ae31707ccf0c3ce3c310d774b814ec85b6f 100644
--- a/worker/src/main/resources/application.yml
+++ b/worker/src/main/resources/application.yml
@@ -6,10 +6,8 @@ queue:
maxSize: ${queueSize:16384}
preDbSize: ${preDbSize:10000}
#etcd的地址,如有多个用逗号分隔
-config:
- mdc: ${mdc:default}
- server: ${etcdServer:http://127.0.0.1:2379} #etcd的地址,重要!!!
- workerPath: ${workerPath:default} #该worker放到哪个path下,譬如放/app1下,则该worker只能被app1使用,不会为其他client提供服务
+serverAddr: 101.42.242.201:2181
+
server:
port: 8080
#ck信息,自行修改
diff --git a/worker/src/main/resources/logback-spring.xml b/worker/src/main/resources/logback-spring.xml
index 557bfde559b2441b8711f9df1d58c4f9a99ca898..31d2e3426adddbd35c4f5992a7e8c3d951c5b1bb 100644
--- a/worker/src/main/resources/logback-spring.xml
+++ b/worker/src/main/resources/logback-spring.xml
@@ -6,7 +6,7 @@ debug:当此属性设置为true时,将打印出logback内部日志信息,
-->
-
+