properties反射读取

This commit is contained in:
liyunfeng 2022-03-09 23:40:20 +08:00
parent a3dfef58aa
commit 92c1b13ce1
46 changed files with 1174 additions and 244 deletions

View File

@ -18,19 +18,17 @@
<version>1.4-SNAPSHOT</version>
</dependency>
<dependency>
<!-- <dependency>
<groupId>com.jd.platfrom.jlog</groupId>
<artifactId>config-zk</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>
<!--
<dependency>
</dependency>-->
<!--<dependency>
<groupId>com.jd.platfrom.jlog</groupId>
<artifactId>config-nacos</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>-->
<!-- <dependency>
<!-- <dependency>
<groupId>com.jd.platfrom.jlog</groupId>
<artifactId>config-etcd</artifactId>
<version>1.4-SNAPSHOT</version>
@ -41,11 +39,11 @@
<artifactId>config-apollo</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>-->
<!-- <dependency>
<dependency>
<groupId>com.jd.platfrom.jlog</groupId>
<artifactId>config-core</artifactId>
<version>1.4-SNAPSHOT</version>
</dependency>-->
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>

View File

@ -1,15 +1,13 @@
package com.jd.platform.jlog.client;
import com.alibaba.fastjson.JSON;
import com.jd.platform.jlog.client.mdc.Mdc;
import com.jd.platform.jlog.client.task.Monitor;
import com.jd.platform.jlog.client.udp.HttpSender;
import com.jd.platform.jlog.client.udp.UdpClient;
import com.jd.platform.jlog.client.udp.UdpSender;
import com.jd.platform.jlog.common.tag.TagConfig;
import com.jd.platform.jlog.common.utils.FastJsonUtils;
import com.jd.platform.jlog.core.Configurator;
import com.jd.platform.jlog.core.ConfiguratorFactory;
import com.jd.platform.jlog.core.TagHandlerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -82,45 +80,34 @@ public class TracerClientStarter {
* 启动监听
*/
public void startPipeline() {
// 校验和设置
checkAndSetTagConfig();
// TagHandler.build(tagConfig);
// 初始化配置
initJLogConfig();
Context.MDC = mdc;
Monitor starter = new Monitor();
starter.start();
UdpClient udpClient = new UdpClient();
/* UdpClient udpClient = new UdpClient();
udpClient.start();
//开启发送
UdpSender.uploadToWorker();
//开启大对象http发送
HttpSender.uploadToWorker();
HttpSender.uploadToWorker();*/
}
/**
* 如果未赋值从配置器获取底层是Properties
*/
private void checkAndSetTagConfig(){
private void initJLogConfig(){
LOGGER.info("从主配置获取的tagConfig:{}", JSON.toJSONString(tagConfig));
Configurator configurator = ConfiguratorFactory.getInstance();
if(tagConfig != null){
LOGGER.info("从主配置获取的tagConfig:{}", tagConfig.toString());
configurator.addConfigListener("/application.yml");
return;
}
String reqTag = configurator.getConfig("reqTags");
String logTag = configurator.getConfig("logTags");
String regex = configurator.getConfig("regex");
String delimiter = configurator.getConfig("delimiter");
String join = configurator.getConfig("join");
tagConfig = TagConfig.Builder.aTagConfig().reqTags(FastJsonUtils.toList(reqTag, String.class))
.logTags(FastJsonUtils.toList(logTag, String.class))
.regex(regex).delimiter(delimiter).join(join).build();
LOGGER.info("从配置器获取的tagConfig:{}", tagConfig.toString());
TagHandlerBuilder.buildTagHandler(tagConfig, configurator);
configurator.addConfigListener("/application.properties");
// configurator.addConfigListener("/application.yml");
}
}

View File

@ -1 +0,0 @@
reqTags=["AAA","CCC"]

View File

@ -34,6 +34,11 @@ public class Constant {
*/
public static int TAG_NORMAL_KEY_MAX_LEN = 20;
/**
* 可供提取的日志最小长度
*/
public static int EXTRACT_MIN_LEN = 5;
/**
* 符合正则但不构成kv结构的普通日志xx查询为空
*/

View File

@ -10,6 +10,11 @@ package com.jd.platform.jlog.common.tag;
public class CollectMode {
/**
* 挂起 不提取不压缩
*/
public static final long SUSPEND = 0L;
/**
* 提取req
*/
@ -31,12 +36,12 @@ public class CollectMode {
public static final long C_LOG = 1L << 4;
/**
* 提取log
* 提取resp
*/
public static final long E_RESP = 1L << 5;
/**
* 压缩log
* 压缩resp
*/
public static final long C_RESP = 1L << 6;
@ -44,30 +49,56 @@ public class CollectMode {
/** ======================================= 下面是组合 ======================================= */
/**
* 提取req压缩req
*/
public static final long E_REQ_C_REQ = E_REQ | C_REQ;
/**
* 提取log压缩log
* 提取req+log
*/
public static final long E_LOG_C_LOG = E_LOG | C_LOG;
public static final long EXTRACT_REQ_LOG = E_REQ | E_LOG;
/**
* 提取req+log压缩req
* 提取req+resp
*/
public static final long E_REQ_E_LOG_C_REQ = E_REQ | E_LOG | C_REQ;
public static final long EXTRACT_REQ_REQP = E_REQ | E_RESP;
/**
* 提取req+log压缩log
* 提取req+resp
*/
public static final long E_REQ_E_LOG_C_LOG = E_REQ | E_LOG | C_LOG;
public static final long EXTRACT_REQ_RESP = E_REQ | E_RESP;
/**
* 提取req+log压缩req+log
* 提取req+log+resp
*/
public static final long E_REQ_E_LOG_C_REQ_E_LOG = E_REQ | E_LOG | C_REQ | E_LOG;
public static final long EXTRACT_ALL = E_REQ | E_LOG | E_RESP;
/**
* 压缩req+log
*/
public static final long COMPRESS_REQ_LOG = C_REQ | C_LOG;
/**
* 压缩req+resp
*/
public static final long COMPRESS_REQ_REQP = C_REQ | C_RESP;
/**
* 压缩req+resp
*/
public static final long COMPRESS_REQ_C_RESP = C_REQ | C_RESP;
/**
* 压缩req+log+resp
*/
public static final long COMPRESS_ALL = C_REQ | C_LOG | C_RESP;
public static void main(String[] args) {
System.out.println(isMatched(EXTRACT_REQ_LOG, EXTRACT_REQ_RESP));
}
public static boolean isMatched(long indicator, long position) {
return (indicator & position) == position;
}
}
// curl --location --request POST 'http://10.96.98.110:8058/app/flow/getappraiselist' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'token=DF9YcBVAaMiLCZtZEZCf6MunJX8I3jWGmQXwRzb-oQIszD1uAjEQgNG7fG1Gq5nx2I6nzBFygwSWn8ZIIKrV3h0hUb3ubUwlKYsuijCNNGE6WVVLCLOQ1uvoLTza6KrCDPJNJfn5RfgjQfgnw8vo7j6KqX-HC0dyCCu58bg974f1U-_CibQWrXlXC-FM8lWrqhZrvVYvCBcSQ7iSur8CAAD__w==' --data-urlencode 'cityID=55000116' --data-urlencode 'appVersion=2.0.28' --data-urlencode 'country=BR'

View File

@ -3,6 +3,9 @@ package com.jd.platform.jlog.common.tag;
import java.io.Serializable;
import java.util.List;
import static com.jd.platform.jlog.common.tag.CollectMode.COMPRESS_ALL;
import static com.jd.platform.jlog.common.tag.CollectMode.EXTRACT_ALL;
/**
* @author tangbohu
* @version 1.0.0
@ -37,14 +40,14 @@ public class TagConfig implements Serializable {
private String join = "=";
/**
* 提取入参开关
* 提取策略
*/
private Boolean extractReq = true;
private long extract = EXTRACT_ALL;
/**
* 提取普通log开关
* 压缩策略
*/
private Boolean extractLog = true;
private long compress = COMPRESS_ALL;
public List<String> getReqTags() {
@ -87,20 +90,20 @@ public class TagConfig implements Serializable {
this.join = join;
}
public Boolean getExtractReq() {
return extractReq;
public long getExtract() {
return extract;
}
public void setExtractReq(Boolean extractReq) {
this.extractReq = extractReq;
public void setExtract(long extract) {
this.extract = extract;
}
public Boolean getExtractLog() {
return extractLog;
public long getCompress() {
return compress;
}
public void setExtractLog(Boolean extractLog) {
this.extractLog = extractLog;
public void setCompress(long compress) {
this.compress = compress;
}
public static final class Builder {
@ -109,8 +112,8 @@ public class TagConfig implements Serializable {
private String regex;
private String delimiter;
private String join;
private Boolean extractReq;
private Boolean extractLog;
private long extract;
private long compress;
public Builder() {
}
@ -144,13 +147,13 @@ public class TagConfig implements Serializable {
return this;
}
public Builder extractReq(Boolean extractReq) {
this.extractReq = extractReq;
public Builder extract(long extract) {
this.extract = extract;
return this;
}
public Builder extractLog(Boolean extractLog) {
this.extractLog = extractLog;
public Builder compress(long compress) {
this.compress = compress;
return this;
}
@ -161,8 +164,8 @@ public class TagConfig implements Serializable {
tagConfig.setRegex(regex);
tagConfig.setDelimiter(delimiter);
tagConfig.setJoin(join);
tagConfig.setExtractReq(extractReq);
tagConfig.setExtractLog(extractLog);
tagConfig.setExtract(extract);
tagConfig.setCompress(compress);
return tagConfig;
}
}
@ -175,8 +178,8 @@ public class TagConfig implements Serializable {
", regex='" + regex + '\'' +
", delimiter='" + delimiter + '\'' +
", join='" + join + '\'' +
", extractReq='" + extractReq + '\'' +
", extractLog='" + extractLog + '\'' +
", extract='" + extract + '\'' +
", compress='" + compress + '\'' +
'}';
}
}

View File

@ -12,8 +12,12 @@ import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.jd.platform.jlog.common.constant.Constant.EXTRACT_MIN_LEN;
import static com.jd.platform.jlog.common.constant.Constant.TAG_NORMAL_KEY;
import static com.jd.platform.jlog.common.constant.Constant.TAG_NORMAL_KEY_MAX_LEN;
import static com.jd.platform.jlog.common.tag.CollectMode.*;
import static com.jd.platform.jlog.common.tag.CollectMode.E_LOG;
import static com.jd.platform.jlog.common.tag.CollectMode.E_REQ;
import static com.jd.platform.jlog.common.utils.ConfigUtil.RANDOM;
/**
@ -28,12 +32,8 @@ public class TagHandler {
private Set<String> reqTags;
private boolean extractReq;
private Set<String> logTags;
private boolean extractLog;
private String delimiter = "|";
private int delimiterLen = delimiter.length();
@ -42,22 +42,25 @@ public class TagHandler {
private Pattern pattern;
private long extract;
private long compress;
private static volatile TagHandler INSTANCE = null;
/**
* 构建标签处理器
* @param tagConfig 配置类
*/
public static void build(TagConfig tagConfig) {
public static void buildHandler(TagConfig tagConfig) {
if(!tagConfig.getExtractReq() && !tagConfig.getExtractLog()){
if(tagConfig.getExtract() == SUSPEND && tagConfig.getCompress() == SUSPEND ){
return;
}
TagHandler handler = new TagHandler();
handler.extractReq = tagConfig.getExtractReq();
handler.extractLog = tagConfig.getExtractLog();
handler.extract = tagConfig.getExtract();
handler.compress = tagConfig.getCompress();
handler.reqTags = new HashSet<>(tagConfig.getReqTags());
handler.logTags = new HashSet<>(tagConfig.getLogTags());
@ -85,7 +88,9 @@ public class TagHandler {
*/
public static Map<String, Object> extractReqTag(Map<String, String[]> params, @NotNull Map<String, Object> ext) {
if(INSTANCE == null || !INSTANCE.extractReq){ return null; }
if(INSTANCE == null || !isMatched(INSTANCE.extract, E_REQ)){ return null; }
System.out.println("### INSTANCE.reqTags:"+JSON.toJSONString(INSTANCE.reqTags));
Map<String, Object> requestMap = new HashMap<>(INSTANCE.reqTags.size());
for (String tag : INSTANCE.reqTags) {
@ -99,7 +104,7 @@ public class TagHandler {
requestMap.put(tag, params.get(tag)[0]);
}
}
System.out.println("提取到了请求入参日志标签:"+JSON.toJSONString(requestMap));
return requestMap;
}
@ -110,7 +115,7 @@ public class TagHandler {
* @return tags
*/
public static Map<String, Object> extractLogTag(String content) {
if(INSTANCE == null || !INSTANCE.extractLog || content.length() < 1){
if(INSTANCE == null || !isMatched(INSTANCE.extract, E_LOG) || content.length() < EXTRACT_MIN_LEN){
return null;
}
@ -131,6 +136,7 @@ public class TagHandler {
}
}
}
System.out.println("提取到了请求log日志标签"+JSON.toJSONString(tagMap));
return tagMap;
}
@ -142,7 +148,7 @@ public class TagHandler {
*/
public synchronized static void refresh(TagConfig tagConfig) {
INSTANCE = null;
build(tagConfig);
buildHandler(tagConfig);
}
@ -154,6 +160,9 @@ public class TagHandler {
", delimiter='" + delimiter + '\'' +
", delimiterLen=" + delimiterLen +
", join='" + join + '\'' +
", pattern=" + pattern +
", extract=" + extract +
", compress=" + compress +
'}';
}

View File

@ -133,13 +133,87 @@ public class CollectionUtil {
public static void main(String[] args) {
HashMap<String, Integer> m1 = new HashMap<>();
m1.put("t1",1);
m1.put("t2",2);
int fail = 0;
int count = 10000;
Set<Integer> set = new HashSet<>();
for (int i = 0; i < count; i++) {
int h = randomMac4Qemu().hashCode();
int val = indexFor(h);
boolean r = set.add(val);
// System.out.println(val);
if(!r){
fail++;
}
}
HashMap<String, Integer> m2 = new HashMap<>();
m2.put("t2",2);
m2.put("t3",3);
int fail2 = 0;
Set<Integer> 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;
}
}

View File

@ -2,8 +2,12 @@ package com.jd.platform.jlog.common.utils;
import com.jd.platform.jlog.common.constant.Constant;
import java.util.Enumeration;
import java.util.Properties;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
/**
@ -18,13 +22,14 @@ public class ConfigUtil {
private static final String SERVER_SUFFIX = "Server";
public static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
public static final char MID_LINE = '-';
public static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
public static String escapeExprSpecialWord(String str) {
if(str != null && str.length() > 0){
if (str != null && str.length() > 0) {
for (String s : Constant.SPECIAL_CHAR) {
if (str.contains(s)) {
str = str.replace(s, "\\" + s);
@ -35,7 +40,6 @@ public class ConfigUtil {
}
public static String formatConfigStr(Properties properties) {
StringBuilder sb = new StringBuilder();
@ -43,7 +47,7 @@ public class ConfigUtil {
while (enumeration.hasMoreElements()) {
String key = (String) enumeration.nextElement();
Object property = properties.get(key);
if(property != null){
if (property != null) {
property = String.valueOf(property);
}
sb.append(key).append("=").append(property).append("\n");
@ -52,12 +56,41 @@ public class ConfigUtil {
}
public static byte[] formatConfigByte(Properties properties) {
return formatConfigStr(properties).getBytes();
}
//递归解析map对象
public static void loadRecursion(Map<String, Object> 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<String, Object> nextValue = (Map<String, Object>) v;
loadRecursion(nextValue, (("".equals(key) ? "" : key + ".") + k), props);
}
} else {
props.put(key + "." + k, v);
}
});
}
//判断是否还有子节点
public static boolean isParent(Object o) {
if (!(o instanceof String || o instanceof Character || o instanceof Byte)) {
try {
Number n = (Number) o;
// System.out.println("isParent ==> "+n);
} catch (Exception e) {
return true;
}
}
return false;
}
/*
public static ConfigCenterEnum getCenter(CenterConfig config) throws Exception {
@ -86,4 +119,31 @@ public class ConfigUtil {
items[0] = (byte) ((char) items[0] - 'a' + 'A');
return new String(items);
}
public static String camelToMidline(String param) {
if (param == null || "".equals(param.trim())) {
return "";
}
int len = param.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = param.charAt(i);
if (Character.isUpperCase(c)) {
sb.append("-");
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
return sb.toString();
}
public static String lowerFirst(String fromStr){
char[] chars = fromStr.toCharArray();
chars[0] += 32;
return String.valueOf(chars);
}
}

View File

@ -77,6 +77,26 @@ public class ApolloConfigurator implements Configurator {
return instance;
}
@Override
public String getString(String key) {
return null;
}
@Override
public Long getLong(String key) {
return null;
}
@Override
public List<String> getList(String key) {
return null;
}
@Override
public <T> T getObject(String key, Class<T> clz) {
return null;
}
@Override
public String getConfig(String key) {
return config.getProperty(key,"");

View File

@ -1,7 +1,6 @@
package com.jd.platform.jlog.core;
import java.util.List;
import java.util.Map;
/**
* @author tangbohu
@ -13,19 +12,34 @@ import java.util.Map;
public interface Configurator {
/**
* 获取配置
* 获取string配置
* @param key key
* @return val
*/
String getConfig(String key);
String getString(String key);
/**
* 获取配置
* 获取LONG配置
* @param key key
* @param timeoutMills timeoutMills
* @return val
*/
String getConfig(String key, long timeoutMills);
Long getLong(String key);
/**
* 获取LIST类型配置
* @param key key
* @return val
*/
List<String> getList(String key);
/**
* 获取实体类型配置
* @param key key
* @return val
*/
<T> T getObject(String key, Class<T> clz);
/**
* 设置配置

View File

@ -32,8 +32,8 @@ public class ConfiguratorFactory {
synchronized (Configurator.class) {
if (instance == null) {
instance = buildConfiguration();
LOGGER.info("构建总配置器单例完成 instance 获取reqTags结果:{}", instance.getConfig("reqTags"));
LOGGER.info("构建总配置器单例完成 Base 获取serverAddr结果:{}", base.getConfig("serverAddr"));
LOGGER.info("构建总配置器单例完成 instance 获取类型结果:{}", instance.getType());
LOGGER.info("构建总配置器单例完成 Base 获取serverAddr结果:{}", base.getString("serverAddr"));
}
}
}
@ -69,4 +69,19 @@ public class ConfiguratorFactory {
return base;
}
private static Configurator refreshBaseConfiguration() {
synchronized (Configurator.class){
try {
base = new FileConfigurator();
} catch (IOException e) {
LOGGER.info("文件配置器构建失败", e);
throw new RuntimeException("build file buildConfiguration fail", e);
}
}
return base;
}
}

View File

@ -15,7 +15,7 @@ public class Constant {
/**
* 监听重读配置文件间隔 单位ms
*/
static final long LISTENER_CONFIG_INTERVAL = 10000;
static final long LISTENER_CONFIG_INTERVAL = 3000;
static final String CONFIG_FILE_PROPERTIES = "/application.properties";
@ -34,7 +34,7 @@ public class Constant {
public static final String SERVER_ADDR_KEY = "serverAddr";
public static final String NAMESPACE_KEY = "namespace";
/**
* 配置文件集合

View File

@ -28,7 +28,7 @@ public class FileConfigurator implements Configurator {
private static final Logger LOGGER = LoggerFactory.getLogger(FileConfigurator.class);
private static Properties PROPERTIES = new Properties();
private static JcProperties PROPERTIES = new JcProperties();
private static volatile FileListener FILELISTENER = null;
@ -44,18 +44,19 @@ public class FileConfigurator implements Configurator {
for (String file : CONFIG_FILES) {
String fileName = StringUtil.isEmpty(env) ? file : file + "_" + env;
URL url = this.getClass().getResource(file);
if(url != null){
try (InputStream is = url.openStream()) {
Properties props = new Properties();
if (fileName.contains(YML)) {
props.putAll(new Yaml().loadAs(is, Map.class));
} else {
props.load(is);
}
FILE_MODIFY_MAP.put(fileName, new FileWrapper(new File(url.getFile()).lastModified(), props));
PROPERTIES.putAll(props);
LOGGER.info("{}配置文件配置:{}", file, props.toString());
if(url == null){
continue;
}
try (InputStream is = url.openStream()) {
JcProperties props = new JcProperties();
if (fileName.contains(YML)) {
props.putAll(new Yaml().loadAs(is, Map.class));
} else {
props.load(is);
}
FILE_MODIFY_MAP.put(fileName, new FileWrapper(new File(url.getFile()).lastModified(), props));
PROPERTIES.putAll(props);
LOGGER.info("{}配置文件配置:{}", file, props.toString());
}
}
LOGGER.info("合并后的配置:{}",PROPERTIES.toString());
@ -63,20 +64,24 @@ public class FileConfigurator implements Configurator {
@Override
public String getConfig(String key) {
Object val = PROPERTIES.get(key);
if(val != null){
return String.valueOf(val);
}
return null;
public String getString(String key) {
return PROPERTIES.getString(key);
}
@Override
public String getConfig(String key, long timeoutMills) {
return PROPERTIES.getProperty(key);
public Long getLong(String key) {
return PROPERTIES.getLong(key);
}
@Override
public List<String> getList(String key) {
return PROPERTIES.getStrList(key);
}
@Override
public <T> T getObject(String key, Class<T> clz) {
return PROPERTIES.getBean(key, clz);
}
@Override
public boolean putConfig(String key, String content) { return false; }
@ -106,7 +111,6 @@ public class FileConfigurator implements Configurator {
return;
}
String env = System.getenv(ENV);
for (String file : CONFIG_FILES) {
file = StringUtil.isEmpty(env) ? file : file + "_" + env;
if(node.equals(file)){
@ -171,7 +175,8 @@ public class FileConfigurator implements Configurator {
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(),
new DefaultThreadFactory("fileListener", 1));
FileListener() { }
FileListener() {
}
synchronized void addListener() {
FILELISTENER.onProcessEvent(new ConfigChangeEvent());
@ -202,28 +207,30 @@ public class FileConfigurator implements Configurator {
* 检测文件最后修改时间 和重载文件
*/
private void checkAndConfigure(){
AtomicBoolean change = new AtomicBoolean(false);
Map<String, FileWrapper> newModifyMap = checkAndReload();
FILE_MODIFY_MAP.forEach((k, v)->{
FileWrapper newFile = newModifyMap.get(k);
if(newFile != null && newFile.change){
Set<String> diffKeys = CollectionUtil.diffKeys(newFile.props, v.props);
if(!diffKeys.isEmpty()){
change.set(true);
v.props = newFile.props;
for (String diffKey : diffKeys) {
LOGGER.warn("文件 {} 配置变更 key={}变更事件:{}", k, diffKey, new ConfigChangeEvent(diffKey, v.props.get(diffKey).toString(), newFile.props.get(diffKey).toString()));
LOGGER.warn("文件 {} 配置变更 key={}变更事件:{}", k, diffKey, new ConfigChangeEvent(diffKey, String.valueOf(v.props.get(diffKey)), String.valueOf(newFile.props.get(diffKey))));
}
v.props = newFile.props;
v.lastModify= newFile.lastModify;
}
}
});
if(change.get()){
LOGGER.info("变更之前的总配置:{}", JSON.toJSONString(PROPERTIES));
// LOGGER.info("变更之前的总配置:{}", JSON.toJSONString(PROPERTIES));
PROPERTIES.clear();
FILE_MODIFY_MAP.forEach((k,v)-> PROPERTIES.putAll(v.props));
LOGGER.info("变更之后的总配置:{}", JSON.toJSONString(PROPERTIES));
TagHandlerBuilder.refresh();
}
}
@ -234,8 +241,10 @@ public class FileConfigurator implements Configurator {
private Map<String, FileWrapper> checkAndReload() {
Map<String, FileWrapper> fileWrapperMap = new ConcurrentHashMap<>(3);
for (String fileName : LISTENED_FILES) {
URL url = this.getClass().getResource(fileName);
if(url == null){
continue;
}
@ -246,7 +255,7 @@ public class FileConfigurator implements Configurator {
if(curLastMod <= cacheLastMod){
continue;
}
Properties props = new Properties();
JcProperties props = new JcProperties();
try (InputStream is = url.openStream()) {
if (fileName.contains(YML)) {
props.putAll(new Yaml().loadAs(is, Map.class));
@ -269,14 +278,14 @@ public class FileConfigurator implements Configurator {
private boolean change;
private Properties props;
private JcProperties props;
FileWrapper(long lastModify, Properties props) {
FileWrapper(long lastModify, JcProperties props) {
this.lastModify = lastModify;
this.change = false;
this.props = props;
}
FileWrapper(long lastModify, boolean change, Properties props) {
FileWrapper(long lastModify, boolean change, JcProperties props) {
this.lastModify = lastModify;
this.change = change;
this.props = props;

View File

@ -0,0 +1,30 @@
package com.jd.platform.jlog.core;
import com.alibaba.fastjson.JSON;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @author tangbohu
* @version 1.0.0
* @ClassName FileNode.java
* @Description TODO
* @createTime 2022年03月08日 16:32:00
*/
public final class FileNode {
private String fillPath;
private long lastModity;
public static void main(String[] args) throws IOException {
JcProperties properties = new JcProperties();
String path = "/Users/didi/Desktop/jlog/example/target/classes/application.properties";
properties.load(new FileInputStream(path));
System.out.println(JSON.toJSONString(properties));
Server bean = properties.getBean("server", Server.class);
System.out.println(JSON.toJSONString(bean));
}
}

View File

@ -0,0 +1,139 @@
package com.jd.platform.jlog.core;
import com.alibaba.fastjson.JSON;
import com.jd.platform.jlog.common.utils.ConfigUtil;
import com.jd.platform.jlog.common.utils.FastJsonUtils;
import com.jd.platform.jlog.common.utils.StringUtil;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import static com.jd.platform.jlog.common.utils.ConfigUtil.lowerFirst;
/**
* @author tangbohu
* @version 1.0.0
* @ClassName JcProperties.java
* @Description TODO
* @createTime 2022年03月07日 12:43:00
*/
public class JcProperties extends Properties {
public JcProperties() {
}
public String getString(String key) {
Object val = super.get(key);
if(val == null){
return null;
}
return String.valueOf(super.get(key));
}
public Long getLong(String key) {
String val = getString(key);
if(StringUtil.isEmpty(val)){
return null;
}
return Long.valueOf(val);
}
public List<String> getStrList(String key) {
String val = getString(key);
if(StringUtil.isEmpty(val)){
return null;
}
return FastJsonUtils.toList(val, String.class);
}
public <T> T getBean(String key, Class<T> clz) {
T bean = FastJsonUtils.toBean(JSON.toJSONString(get(key)), clz);
if(bean != null){
return bean;
}
try {
T instance = clz.newInstance();
invoke(instance, this, "");
return instance;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
private void invoke(Object model, JcProperties properties, String prefix) throws
IllegalAccessException, ClassNotFoundException, InstantiationException, ParseException {
Class<?> clz = model.getClass();
Field[] fields = model.getClass().getDeclaredFields();
for (Field field : fields) {
String type = field.getGenericType().toString();
field.setAccessible(true);
String curObjName = ConfigUtil.camelToMidline(lowerFirst(clz.getSimpleName()));
prefix = StringUtil.isEmpty(prefix) ? curObjName : prefix;
String fillName = !curObjName.equals(prefix) ? prefix +"."+ curObjName + "." + field.getName() : curObjName + "." + field.getName();
switch (type){
case "class java.lang.String":
field.set(model, properties.getString(fillName)) ;
break;
case "byte":
field.setByte(model, Byte.valueOf(properties.getString(fillName)));
break;
case "short":
field.setShort(model, Short.valueOf(properties.getString(fillName)));
break;
case "int":
field.setInt(model, properties.getLong(fillName).intValue()) ;
break;
case "long":
field.setLong(model, properties.getLong(fillName));
break;
case "double":
field.setDouble(model, Double.valueOf(properties.getString(fillName)));
break;
case "float":
field.setFloat(model, Float.valueOf(properties.getString(fillName)));
break;
case "boolean":
field.setBoolean(model, Boolean.parseBoolean(properties.getString(fillName)));
break;
case "class java.util.Date":
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(properties.getString(fillName));
field.set(model,date) ;
break;
default:
String tn = field.getType().getTypeName();
if("java.util.List".equals(tn)){
String val = properties.getString(fillName);
field.set(model,FastJsonUtils.toList(val, String.class));
}else if("java.util.Map".equals(tn)){
String val = properties.getString(fillName);
field.set(model,FastJsonUtils.toMap(val));
}else if(field.getType().isArray()){
String val = properties.getString(fillName);
field.set(model,FastJsonUtils.toArray(val));
}else{
String[] ar = type.split(" ");
Object tinyObj = Class.forName(ar[1]).newInstance();
invoke(tinyObj, properties, prefix);
field.set(model,tinyObj);
}
}
}
}
}

View File

@ -0,0 +1,142 @@
package com.jd.platform.jlog.core;
import com.alibaba.fastjson.JSON;
import com.jd.platform.jlog.common.utils.StringUtil;
import org.yaml.snakeyaml.Yaml;
import java.io.*;
import java.util.*;
/**
* @author tangbohu
* @version 1.0.0
* @ClassName Node.java 包装类 用于以后的支持key->node->[listener,properties]
* @createTime 2022年03月02日 20:37:00
*/
public class NodeBak implements Serializable {
private String name;
private ConfigChangeListener listener;
private Properties properties;
private String type;
private Object val;
static Properties newPro = new Properties();
public static void main(String[] args) throws IOException {
String path = "/Users/didi/Desktop/jlog/example/target/classes/application.properties";
// newPro.load();
read(path);
System.out.println(JSON.toJSONString(newPro));
}
protected static Map<String, String> toMap(Properties properties) {
Map<String, String> result = new HashMap<>(10);
Enumeration<?> propertyNames = properties.propertyNames();
while (propertyNames.hasMoreElements()) {
String name = (String) propertyNames.nextElement();
String value = properties.getProperty(name);
result.put(name, value);
}
return result;
}
public static void read(String path) {
FileReader fr = null;
LineNumberReader lnr = null;
String str;
try {
fr = new FileReader(path);
lnr = new LineNumberReader(fr);
Stack<String> stack = new Stack<>();
HashMap<String, Object> tinyMap = new LinkedHashMap<>();
List<Object> tinyList = new ArrayList<>();
String temKey = "";
while ((str = lnr.readLine()) != null) {
if(StringUtil.isBlank(str) || !str.contains("=")){
continue;
}
String[] lineArr = str.split("=");
String key = lineArr[0];
String val = lineArr[1];
if(!key.contains(".")){
newPro.put(key,val.trim());
continue;
}
String[] keyArr = key.split("\\.");
String lastTinyKey = keyArr[keyArr.length - 1];
if(lastTinyKey.contains("[") & lastTinyKey.contains("]")){
String[] lastArr = lastTinyKey.split("\\[");
for (int i = 0; i < keyArr.length - 1; i++) {
stack.push(keyArr[i]);
}
stack.push(lastArr[0]);
/* if(!temKey.equals(lastArr[0])){
temKey = lastArr[0];
String out = stack.pop();
stack.push(temKey);
}*/
//list
tinyList.add(val);
newPro.put(keyArr[0],tinyList);
}else{
for (int i = 0; i < keyArr.length - 1; i++) {
if(stack.empty() || !stack.peek().equals(keyArr[i])){
stack.push(keyArr[i]);
}
}
/* if(!temKey.equals(lastTinyKey)){
temKey = lastTinyKey;
String out = stack.pop();
System.out.println("out==> "+ out +" temKey==> '"+temKey );
stack.push(temKey);
}*/
// map
tinyMap.put(keyArr[1],val.trim());
newPro.put(keyArr[0],tinyMap);
}
System.out.println(" -- stack==> " + JSON.toJSONString(stack) );
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (lnr != null) {
try {
lnr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

View File

@ -0,0 +1,45 @@
package com.jd.platform.jlog.core;
import java.util.List;
import java.util.Map;
public class ObjObj{
private int last;
private String max;
private List<String> ids;
private Map ms;
public int getLast() {
return last;
}
public void setLast(int last) {
this.last = last;
}
public String getMax() {
return max;
}
public void setMax(String max) {
this.max = max;
}
public List<String> getIds() {
return ids;
}
public void setIds(List<String> ids) {
this.ids = ids;
}
public Map getMs() {
return ms;
}
public void setMs(Map ms) {
this.ms = ms;
}
}

View File

@ -0,0 +1,32 @@
package com.jd.platform.jlog.core;
public class Server{
private int port;
private String addr;
private ObjObj objObj;
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public ObjObj getObjObj() {
return objObj;
}
public void setObjObj(ObjObj objObj) {
this.objObj = objObj;
}
}

View File

@ -0,0 +1,39 @@
package com.jd.platform.jlog.core;
import com.jd.platform.jlog.common.tag.TagConfig;
import com.jd.platform.jlog.common.tag.TagHandler;
/**
* @author tangbohu
* @version 1.0.0
* @ClassName TagHandlerBuilder.java
* @Description TODO
* @createTime 2022年03月05日 22:07:00
*/
public class TagHandlerBuilder {
public static void buildTagHandler(TagConfig tagConfig, Configurator configurator){
if(tagConfig == null){
tagConfig = buildTagConfigByConfigurator(configurator);
}
TagHandler.buildHandler(tagConfig);
}
public static void refresh(){
Configurator configurator = ConfiguratorFactory.getInstance();
if(configurator == null){
throw new RuntimeException("configurator is null");
}
TagHandler.refresh(buildTagConfigByConfigurator(configurator));
}
private static TagConfig buildTagConfigByConfigurator(Configurator configurator){
return configurator.getObject("tag-config", TagConfig.class);
}
}

View File

@ -1,6 +1,8 @@
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;
@ -39,7 +41,7 @@ public class EtcdConfigurator implements Configurator {
private static final Configurator FILE_CONFIG = ConfiguratorFactory.base;
private static final String PROPERTIES_PATH = "/jLog/properties";
private static final String PROPERTIES_PATH = "/jLog/jLog.properties";
private static Properties PROPERTIES = new Properties();
@ -56,7 +58,11 @@ public class EtcdConfigurator implements Configurator {
}
String val = keyValues.get(0).getValue().toStringUtf8();
if(StringUtil.isNotBlank(val)){
PROPERTIES.putAll((Map)JSON.parse(val));
try {
PROPERTIES.load(new StringReader(val));
} catch (IOException e) {
e.printStackTrace();
}
}
}
@ -73,6 +79,26 @@ public class EtcdConfigurator implements Configurator {
}
@Override
public String getString(String key) {
return null;
}
@Override
public Long getLong(String key) {
return null;
}
@Override
public List<String> getList(String key) {
return null;
}
@Override
public <T> T getObject(String key, Class<T> clz) {
return null;
}
@Override
public String getConfig(String key) {
Object val = PROPERTIES.get(key);

View File

@ -5,6 +5,7 @@ import com.ibm.etcd.api.Event;
import com.ibm.etcd.api.KeyValue;
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.core.ConfigChangeEvent;
import com.jd.platform.jlog.core.ConfigChangeListener;
import com.jd.platform.jlog.core.ConfigChangeType;
@ -30,19 +31,24 @@ public class EtcdListener implements ConfigChangeListener {
public EtcdListener(String node) {
iterator = EtcdConfigurator.client.getKvClient().watch(ByteString.copyFromUtf8(node)).start();
System.out.println("构造器EtcdListener");
iterator = EtcdConfigurator.client.getKvClient().watch(ByteString.copyFromUtf8(node)).asPrefix().start();
System.out.println("构造器EtcdListener"+node);
getExecutorService().submit(() -> {
while (iterator.hasNext()){
Event eve = iterator.next().getEvents().get(0);
KeyValue kv = eve.getKv();
Event.EventType eveType = eve.getType();
ConfigChangeType changeType = eveType.equals(Event.EventType.DELETE) ? ConfigChangeType.MODIFY : ConfigChangeType.DELETE;
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(node).setNewValue(kv.getValue().toStringUtf8()).setChangeType(changeType);
onChangeEvent(event);
}catch (RuntimeException e){
e.printStackTrace();
}
ConfigChangeEvent event = new ConfigChangeEvent();
event.setKey(node).setNewValue(kv.getValue().toStringUtf8()).setChangeType(changeType);
onChangeEvent(event);
}
});
}

View File

@ -20,7 +20,7 @@ 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.DEFAULT_TIMEOUT;
import static com.jd.platform.jlog.core.Constant.*;
import static com.jd.platform.jlog.nacos.NacosConstant.*;
@ -78,6 +78,26 @@ public class NacosConfigurator implements Configurator {
}
@Override
public String getString(String key) {
return null;
}
@Override
public Long getLong(String key) {
return null;
}
@Override
public List<String> getList(String key) {
return null;
}
@Override
public <T> T getObject(String key, Class<T> clz) {
return null;
}
@Override
public String getConfig(String key) {
return getConfig(key, DEFAULT_TIMEOUT);
@ -198,9 +218,18 @@ public class NacosConfigurator implements Configurator {
private static Properties getConfigProperties() {
Properties properties = new Properties();
String address = FILE_CONFIG.getConfig(PRO_SERVER_ADDR_KEY);
String address = FILE_CONFIG.getConfig(SERVER_ADDR_KEY);
if (address != null) {
properties.setProperty(PRO_SERVER_ADDR_KEY, address);
properties.setProperty(SERVER_ADDR_KEY, address);
}
String namespace = FILE_CONFIG.getConfig(NAMESPACE_KEY);
if (namespace != null) {
properties.setProperty(NAMESPACE_KEY, namespace);
}else{
if (System.getProperty(NAMESPACE_KEY) != null) {
properties.setProperty(NAMESPACE_KEY, System.getProperty(NAMESPACE_KEY));
}
}
return properties;
}

View File

@ -12,5 +12,4 @@ public class NacosConstant {
static final String JLOG_GROUP = "JLOG_GROUP";
static final String DEFAULT_DATA_ID = "jLog.properties";
static final String PRO_SERVER_ADDR_KEY = "serverAddr";
}

View File

@ -28,11 +28,11 @@ public class NacosTest {
NamingService naming = NamingFactory.createNamingService(serverAddr);
naming.registerInstance("nacos.test1", JLOG_GROUP,"172.22.216.105", 8888, "TEST1");
Thread.sleep(3000);
NacosListener server = new NacosListener(DEFAULT_DATA_ID);
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(DEFAULT_DATA_ID);
NacosListener nL = new NacosListener();
configService.addListener(dataId, group, nL);
System.out.println("新增完成");

View File

@ -39,10 +39,9 @@ public class ZkConfigurator implements Configurator {
public ZkConfigurator() throws Exception {
System.out.println("### SERVER_ADDR_KEY ===> "+FILE_CONFIG.getConfig(SERVER_ADDR_KEY));
if (zkClient == null) {
synchronized (ZkConfigurator.class) {
zkClient = CuratorFrameworkFactory.builder().connectString(FILE_CONFIG.getConfig(SERVER_ADDR_KEY))
zkClient = CuratorFrameworkFactory.builder().connectString(FILE_CONFIG.getString(SERVER_ADDR_KEY))
// 连接超时时间
.sessionTimeoutMs(6000)
// 会话超时时间
@ -65,30 +64,24 @@ public class ZkConfigurator implements Configurator {
@Override
public String getConfig(String key) {
return getConfig(key, DEFAULT_TIMEOUT);
public String getString(String key) {
return getString(key);
}
@Override
public String getConfig(String key, long timeoutMills) {
String value = PROPERTIES.getProperty(key);
if (value != null) {
return value;
}
value = System.getProperty(key);
if (value != null) {
return value;
}
try {
loadZkData();
} catch (Exception e) {
return null;
}
return PROPERTIES.getProperty(key);
public Long getLong(String key) {
return null;
}
@Override
public List<String> getList(String key) {
return null;
}
@Override
public <T> T getObject(String key, Class<T> clz) {
return null;
}
@Override
@ -140,8 +133,11 @@ public class ZkConfigurator implements Configurator {
throw new RuntimeException("no support");
}
LOGGER.info("ZK添加监听器, node:{}", node);
ZKLISTENER = new ZkListener(node);
ZKLISTENER.onProcessEvent(new ConfigChangeEvent());
if(ZKLISTENER == null){
synchronized (ZkConfigurator.class){
ZKLISTENER = new ZkListener(node);
}
}
}
@ -159,7 +155,7 @@ public class ZkConfigurator implements Configurator {
@Override
public List<String> getConfigByPrefix(String prefix) {
try {
String val = getConfig(prefix);
String val = getString(prefix);
return FastJsonUtils.toList(val,String.class);
} catch (Exception e) {
e.printStackTrace();

View File

@ -32,7 +32,6 @@ public class ZkListener implements ConfigChangeListener {
public ZkListener(String path) {
this.path = path;
cache = new NodeCache(zkClient, path);
LOGGER.info("构造ZkListener:{}",path);
try {
cache.start(true);
} catch (Exception e) {
@ -43,9 +42,9 @@ public class ZkListener implements ConfigChangeListener {
if(null!=cache.getCurrentData()){
value = new String(cache.getCurrentData().getData());
}
onChangeEvent(null);
System.out.println("=####====== "+value);
});
System.out.println("=####= SIZE===== "+cache.getListenable().size());
}
@ -62,19 +61,23 @@ public class ZkListener implements ConfigChangeListener {
@Override
public void onChangeEvent(ConfigChangeEvent event) {
LOGGER.info("ZK数据变更-当前监听器关注的path:{}", path);
Properties propsTmp = new Properties(PROPERTIES);
LOGGER.info("ZK数据变更-当前监听器关注的path:{} PROPERTIES:{}", path, JSON.toJSONString(PROPERTIES));
Properties props = new Properties();
props.putAll(PROPERTIES);
try {
LOGGER.info("ZK数据变更,旧Properties:{}", JSON.toJSONString(propsTmp));
LOGGER.info("ZK数据变更,旧Properties:{}", JSON.toJSONString(props));
loadZkData();
LOGGER.info("ZK数据变更,新Properties:{}", JSON.toJSONString(PROPERTIES));
} catch (Exception e) {
e.printStackTrace();
}
Set<String> diffKeys = CollectionUtil.diffKeys(propsTmp, PROPERTIES);
Set<String> diffKeys = CollectionUtil.diffKeys(props, PROPERTIES);
if(!diffKeys.isEmpty()){
for (String diffKey : diffKeys) {
LOGGER.warn("ZK {} 配置变更 key={} 变更事件:{}", path, diffKey, new ConfigChangeEvent(diffKey, propsTmp.get(diffKey).toString(), PROPERTIES.get(diffKey).toString()));
LOGGER.warn("ZK {} 配置变更 key={} 变更事件:{}", path, diffKey,
new ConfigChangeEvent(diffKey,
String.valueOf(props.get(diffKey)),
String.valueOf(PROPERTIES.get(diffKey).toString())));
}
}
}

View File

@ -3,13 +3,10 @@ package com.jd.platform.jlog.zk;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.jd.platform.jlog.zk.ZkConstant.SERVER_ADDR_KEY;
/**
* @author tangbohu
* @version 1.0.0

View File

@ -10,10 +10,10 @@
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jd.platfrom.jlog</groupId>
<artifactId>clientdemo</artifactId>
<artifactId>example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>clientdemo</name>
<description>Demo project for using JLog</description>
<name>example</name>
<description>example for using JLog</description>
<properties>
<java.version>1.8</java.version>
</properties>

View File

@ -11,11 +11,11 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* @date 2021-12-27
*/
@SpringBootApplication
public class ClientDemoApplication {
public class ExampleApplication {
public static void main(String[] args) {
try {
SpringApplication.run(ClientDemoApplication.class, args);
SpringApplication.run(ExampleApplication.class, args);
}catch (Exception e){
e.printStackTrace();
}

View File

@ -30,9 +30,9 @@ public class TracerLogbackAppender extends AppenderBase<ILoggingEvent> {
protected void append(ILoggingEvent iLoggingEvent) {
try {
long tracerId = TracerHolder.getTracerId();
/* if (0L == tracerId) {
if (0L == tracerId) {
return;
}*/
}
RunLogMessage logMessage = getLogMessage(iLoggingEvent);
UdpSender.offerLogger(logMessage);
} catch (Exception e) {
@ -62,7 +62,7 @@ public class TracerLogbackAppender extends AppenderBase<ILoggingEvent> {
String formattedMessage = getMessage(loggingEvent);
logMessage.setContent(formattedMessage);
Map<String, Object> map = TagHandler.extractLogTag(formattedMessage);
logMessage.setTagMap(map);
return logMessage;
}

View File

@ -1,25 +1,38 @@
package com.jd.platform.jlog.clientdemo.web;
import com.jd.platform.jlog.clientdemo.config.DemoConfig;
import com.jd.platform.jlog.common.model.TracerBean;
import com.jd.platform.jlog.common.tag.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.boot.context.properties.ConfigurationProperties;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
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
@ -39,7 +52,7 @@ public class TestController {
e.printStackTrace();
}
String val = configurator.getConfig("/test");
String val = configurator.getString("/test");
System.out.println("val ===> "+val);
RequestLog.info("哈哈哈哈哈哈");
@ -48,14 +61,16 @@ public class TestController {
@RequestMapping("/log")
public Object log() {
RequestLog.info("|tag3=val3||tag4=val4||这是随便的log|");
RequestLog.info("|errno=val3||node=val4||这是随便的log|");
return 1;
}
@PostMapping(value = "/test", consumes = MediaType.APPLICATION_JSON_VALUE)
public Object test(@RequestBody TestReq req) {
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;
}

View File

@ -0,0 +1,16 @@
server.port=8085
tag-config.delimiter="|"
tag-config.logConfig.limit=99
tag-config.logConfig.cfg[0]="AA"
tag-config.logConfig.cfg[1]="BB"
tag-config.logConfig.aa[0]="CC"
tag-config.logConfig.aa[1]="DD"
tag-config.reqTags[0]="AA"
tag-config.reqTags[1]="BB"
tag-config.logTags[0]="CC"
tag-config.logTags[1]="XSSX"

View File

@ -1,7 +1,9 @@
testKey: 111
serverAddr: 101.42.242.201:2181
serverAddr: http://101.42.242.201:8848
server:
port: 8085
test: true
workers:
- 111
- 222
@ -11,6 +13,7 @@ tag-config:
reqTags:
- uid
- ip
- newK
logTags:
- errno
- node

View File

@ -0,0 +1,6 @@
server.port=8085
tag-config.reqTags[0]="AA"
tag-config.reqTags[1]="BB"
tag-config.logTags[0]="CC"
tag-config.logTags[1]="DD"
tag-config.delimiter="|"

View File

@ -24,9 +24,9 @@ public class Common {
public static void getTest(Configurator configurator){
LOGGER.info("配置器类型:{}", configurator.getType());
String addr = configurator.getConfig("serverAddr");
String addr = configurator.getString("serverAddr");
LOGGER.info("配置器get addr{}", addr);
String reqTags = configurator.getConfig("reqTags");
String reqTags = configurator.getString("reqTags");
LOGGER.info("配置器get reqTags{}", reqTags);
List workers = configurator.getConfigByPrefix("workers");
LOGGER.info("配置器get workers{}", JSON.toJSONString(workers));

View File

@ -0,0 +1,91 @@
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<String> workers = configurator.getConfigByPrefix("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<String> workers2 = configurator.getConfigByPrefix("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.addConfigListener("/jLog");
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);
configurator.removeConfigListener("/jLog");
Thread.sleep(5000);
// LOGGER.info("移除监听器后:修改配置testKey = {}",i2);
// configurator.putConfig("testKey",i2 + "");
LOGGER.info("准备验证监听器是否停止 最新testKey={}", configurator.getString("testKey"));
configurator.addConfigListener("/jLog");
LOGGER.info("第二次添加监听器");
Thread.sleep(22000);
}
}

View File

@ -1,7 +1,7 @@
package com.jd.platform.jlog.test;
import com.alibaba.fastjson.JSON;
import com.jd.platform.jlog.clientdemo.ClientDemoApplication;
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;
@ -14,10 +14,8 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.yaml.snakeyaml.Yaml;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import static com.jd.platform.jlog.test.Common.getTest;
import static com.jd.platform.jlog.test.Common.modifyFile;
@ -30,7 +28,7 @@ import static com.jd.platform.jlog.test.Common.modifyFile;
* @Description TODO
* @createTime 2022年02月28日 19:45:00
*/
@SpringBootTest(classes = ClientDemoApplication.class)
@SpringBootTest(classes = ExampleApplication.class)
@RunWith(SpringRunner.class)
public class FileConfiguratorTest {
@ -52,8 +50,8 @@ public class FileConfiguratorTest {
@Test
public void testAddConfigListener() throws Exception {
configurator.addConfigListener("/application.yml");
String path = "/Users/didi/Desktop/jlog/clientdemo/target/classes/application.yml";
configurator.addConfigListener("/bakapplication.yml");
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")) {
@ -61,15 +59,25 @@ public class FileConfiguratorTest {
} else {
props.load(fis);
}
LOGGER.info("读取文件:{}最新配置:{}", path, JSON.toJSONString(props));
LOGGER.info("读取文件:{} 最新配置:{}", path, JSON.toJSONString(props));
modifyFile(path);
LOGGER.info("修改文件完毕 准备触发监听器");
Thread.sleep(1000);
LOGGER.info("睡醒了 应该更新了配置testKey{}",configurator.getConfig("testKey"));
LOGGER.info("移除监听器");
configurator.removeConfigListener("/application.yml");
Thread.sleep(2000);
LOGGER.info("睡醒了 应该更新了配置testKey{}",configurator.getString("testKey"));
Thread.sleep(12000);
LOGGER.info("移除监听器之前testKey{}",configurator.getString("testKey"));
configurator.removeConfigListener("/bakapplication.yml");
LOGGER.info("移除监听器之后testKey{}",configurator.getString("testKey"));
modifyFile(path);
LOGGER.info("修改文件完毕 准备验证监听器是否停止 最新testKey={}", configurator.getConfig("testKey"));
LOGGER.info("修改文件完毕 准备验证监听器是否停止 最新testKey={}", configurator.getString("testKey"));
LOGGER.info("再次添加监听器");
configurator.addConfigListener("/bakapplication.yml");
modifyFile(path);
LOGGER.info("修改文件完毕");
Thread.sleep(12000);
}

View File

@ -0,0 +1,87 @@
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<String> workers = configurator.getConfigByPrefix("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<String> workers2 = configurator.getConfigByPrefix("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.addConfigListener("bakjLog.properties");
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);
configurator.removeConfigListener("bakjLog.properties");
Thread.sleep(1000);
LOGGER.info("移除监听器后:修改配置testKey = {}",i2);
configurator.putConfig("testKey",i2 + "");
LOGGER.info("准备验证监听器是否停止 最新testKey={}", configurator.getString("testKey"));
Thread.sleep(35000);
}
}

View File

@ -2,7 +2,7 @@ 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;
@ -18,7 +18,7 @@ import java.util.*;
* @version 1.0
* @date 2021-12-27
*/
//@SpringBootTest(classes = ClientDemoApplication.class)
//@SpringBootTest(classes = ExampleApplication.class)
//@RunWith(SpringRunner.class)
public class TracerPacketTest {

View File

@ -1,7 +1,7 @@
package com.jd.platform.jlog.test;
import com.alibaba.fastjson.JSON;
import com.jd.platform.jlog.clientdemo.ClientDemoApplication;
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;
@ -11,17 +11,12 @@ 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.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import static com.jd.platform.jlog.test.Common.getTest;
import static com.jd.platform.jlog.test.Common.modifyFile;
/**
* @author tangbohu
@ -30,7 +25,7 @@ import static com.jd.platform.jlog.test.Common.modifyFile;
* @Description TODO
* @createTime 2022年03月01日 07:35:00
*/
@SpringBootTest(classes = ClientDemoApplication.class)
@SpringBootTest(classes = ExampleApplication.class)
@RunWith(SpringRunner.class)
public class ZKConfiguratorTest {
@ -53,7 +48,7 @@ public class ZKConfiguratorTest {
public void testUpdateCFG() throws Exception {
List<String> workers = configurator.getConfigByPrefix("workers");
LOGGER.info("初始化的workers{}", JSON.toJSONString(workers));
String myIp = "121.1.1.1";
String myIp = "121.1.1.0";
if(workers.contains(myIp)){
// do nothing
LOGGER.info("自己的IP还在配置list里 什么也不做");
@ -72,20 +67,22 @@ public class ZKConfiguratorTest {
int i1 = new Random().nextInt(2000);
int i2 = new Random().nextInt(2000);
String val1 = configurator.getConfig("testKey");
String val1 = configurator.getString("testKey");
LOGGER.info("初始化的testKey的val:{}", val1);
configurator.addConfigListener("/application.yml");
LOGGER.info("添加监听器:随机数:{}", i1);
configurator.putConfig("testKey",i1 + "");
configurator.addConfigListener("/bakjLog.properties");
LOGGER.info("添加监听器后, 修改配置testKey = {}", i1);
// configurator.putConfig("testKey",i1 + "");
LOGGER.info("修改完毕 准备触发监听器");
Thread.sleep(1000);
String val2 = configurator.getConfig("testKey");
LOGGER.info("修改后的的val:{}", val2);
LOGGER.info("移除监听器:随机数:{}",i2);
Thread.sleep(3000);
configurator.removeConfigListener("/application.yml");
String val2 = configurator.getString("testKey");
LOGGER.info("第一次修改后的的val:{}", val2);
Thread.sleep(1000);
configurator.putConfig("testKey",i2 + "");
LOGGER.info("准备验证监听器是否停止 最新testKey={}", configurator.getConfig("testKey"));
configurator.removeConfigListener("/bakjLog.properties");
Thread.sleep(1000);
LOGGER.info("移除监听器后:修改配置testKey = {}",i2);
// configurator.putConfig("testKey",i2 + "");
LOGGER.info("准备验证监听器是否停止 最新testKey={}", configurator.getString("testKey"));
Thread.sleep(35000);
}
}

View File

@ -16,7 +16,7 @@
<module>clientlog4j2</module>
<module>clientlogback</module>
<module>Dashboard</module>
<module>clientdemo</module>
<module>example</module>
<module>config</module>
</modules>