From 9c0ee8ca9e7eb2ac27fecf08ac301b6760604a4c Mon Sep 17 00:00:00 2001 From: dongxs16 Date: Fri, 2 Jun 2023 10:39:39 +0800 Subject: [PATCH] [#noissue] The dynamic control pinpoint(Master switch, sampling rate, the level of logging, etc) --- .../main/resources/profiles/local/log4j.xml | 5 + .../main/resources/profiles/release/log4j.xml | 5 + .../profiles/release/pinpoint-env.config | 10 +- .../config/DefaultProfilerConfig.java | 58 ++- .../bootstrap/config/ProfilerConfig.java | 6 + .../pinpoint/bootstrap/AgentIdResolver.java | 10 +- .../bootstrap/AgentIdResolverBuilder.java | 4 +- .../pinpoint/bootstrap/AgentIds.java | 8 +- .../pinpoint/bootstrap/AgentOption.java | 2 + .../pinpoint/bootstrap/AgentProperties.java | 18 +- .../bootstrap/DefaultAgentOption.java | 9 +- .../pinpoint/bootstrap/PinpointStarter.java | 7 +- .../config/ProfilePropertyLoader.java | 10 +- .../bootstrap/AgentBootLoaderTest.java | 2 +- .../pinpoint/common/util/HttpUtils.java | 65 ++++ .../pinpoint/common/util/PropertyUtils.java | 11 +- pom.xml | 6 +- .../test/MockApplicationContextFactory.java | 2 +- .../pinpoint/test/OverrideModuleFactory.java | 5 + .../MockApplicationContextModuleTest.java | 4 +- .../test/monitor/AgentStatMonitorTest.java | 2 +- profiler/pom.xml | 10 + .../pinpoint/profiler/AgentInfoSender.java | 21 +- .../profiler/context/module/AgentLicence.java | 15 + .../module/ApplicationContextModule.java | 13 +- .../ApplicationContextModuleFactory.java | 9 +- .../module/DefaultApplicationContext.java | 121 +++++- .../context/module/ModuleFactory.java | 1 + .../context/module/config/ConfigModule.java | 15 +- .../provider/sampler/SamplerProvider.java | 2 +- .../pinpoint/profiler/monitor/CollectJob.java | 68 +++- .../monitor/DefaultAgentStatMonitor.java | 23 +- .../monitor/DefaultRemoteConfigMonitor.java | 357 ++++++++++++++++++ .../profiler/monitor/RemoteConfigMonitor.java | 13 + .../metric/AgentStatMetricSnapshot.java | 7 + .../monitor/processor/ConfigProcessor.java | 16 + .../monitor/processor/PropertiesKey.java | 33 ++ .../ReSetConfigProcessorFactory.java | 157 ++++++++ .../changehoststat/StatBatchProcessor.java | 57 +++ .../changelog/LogLevelChangeProcessor.java | 123 ++++++ .../datesender/AgentDataSenderProcessor.java | 132 +++++++ .../datesender/SpanDataSenderProcessor.java | 105 ++++++ .../datesender/StatDataSenderProcessor.java | 106 ++++++ .../sampler/AgentEnableConfigProcessor.java | 61 +++ .../sampler/SamplerConfigProcessor.java | 91 +++++ .../profiler/sampler/SamplerFactory.java | 11 +- .../profiler/sampler/SamplingRateSampler.java | 33 +- .../MockApplicationContextFactory.java | 2 +- .../context/graph/DependencyGraph.java | 2 +- .../module/DefaultApplicationContextTest.java | 2 +- .../profiler/sampler/SimpleSamplerTest.java | 4 +- .../pinpoint/rpc/util/ClientFactoryUtils.java | 12 +- 52 files changed, 1785 insertions(+), 86 deletions(-) create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/AgentLicence.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultRemoteConfigMonitor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/RemoteConfigMonitor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/ConfigProcessor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/PropertiesKey.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/ReSetConfigProcessorFactory.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/changehoststat/StatBatchProcessor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/changelog/LogLevelChangeProcessor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/AgentDataSenderProcessor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/SpanDataSenderProcessor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/StatDataSenderProcessor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/sampler/AgentEnableConfigProcessor.java create mode 100644 profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/sampler/SamplerConfigProcessor.java diff --git a/agent/src/main/resources/profiles/local/log4j.xml b/agent/src/main/resources/profiles/local/log4j.xml index 91786f0314ee..3caf93fcebbc 100644 --- a/agent/src/main/resources/profiles/local/log4j.xml +++ b/agent/src/main/resources/profiles/local/log4j.xml @@ -37,6 +37,11 @@ + + + + + diff --git a/agent/src/main/resources/profiles/release/log4j.xml b/agent/src/main/resources/profiles/release/log4j.xml index 6549d547ea07..8dd71d7ff16b 100644 --- a/agent/src/main/resources/profiles/release/log4j.xml +++ b/agent/src/main/resources/profiles/release/log4j.xml @@ -37,6 +37,11 @@ + + + + + diff --git a/agent/src/main/resources/profiles/release/pinpoint-env.config b/agent/src/main/resources/profiles/release/pinpoint-env.config index 25fb02b50b62..cf74a0b72ea2 100644 --- a/agent/src/main/resources/profiles/release/pinpoint-env.config +++ b/agent/src/main/resources/profiles/release/pinpoint-env.config @@ -1121,4 +1121,12 @@ profiler.jdk.concurrent.completable-future=true # which package of runnable(callable) instance can be thread plugin trace # Set the package name to track # eg) profiler.thread.match.package=com.company.shopping.cart, com.company.payment -profiler.thread.match.package= \ No newline at end of file +profiler.thread.match.package= + +profiler.remote.config.init.enable=true +profiler.remote.config.addr=127.0.0.1\:8848,127.0.0.2\:8848,127.0.0.3\:8848 +profiler.remote.config.additional.enable=true +profiler.remote.config.additional.type=2 +profiler.remote.config.additional.type1.gap=86400000 +profiler.remote.config.additional.type2.gap=300000 +profiler.agent.enable=true \ No newline at end of file diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/DefaultProfilerConfig.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/DefaultProfilerConfig.java index 3e52a37b4804..a37be762dbc1 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/DefaultProfilerConfig.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/DefaultProfilerConfig.java @@ -46,7 +46,7 @@ public class DefaultProfilerConfig implements ProfilerConfig { // TestAgent only public static final String IMPORT_PLUGIN = "profiler.plugin.import-plugin"; - private final Properties properties; + private Properties properties; public static final String INSTRUMENT_ENGINE_ASM = "ASM"; @@ -166,6 +166,11 @@ private static Properties loadProperties(String pinpointConfigFileName) throws I private boolean customMetricEnable = false; private int customMetricLimitSize = 10; + private boolean remoteEnable = false; + private String remoteAddr = ""; + private String remoteType = ""; + private long remoteType1Gap; + private long remoteType2Gap; public DefaultProfilerConfig() { this.properties = new Properties(); @@ -173,6 +178,9 @@ public DefaultProfilerConfig() { } public DefaultProfilerConfig(Properties properties) { + resetDefaultProfilerConfig(properties); + } + public void resetDefaultProfilerConfig(Properties properties) { if (properties == null) { throw new NullPointerException("properties"); } @@ -674,6 +682,32 @@ public int getCustomMetricLimitSize() { return customMetricLimitSize; } + @Override + public boolean getRemoteEnable() { + return remoteEnable; + } + @Override + public String getRemoteAddr() { + return remoteAddr; + } + @Override + public String getRemoteType() { + return remoteType; + } + @Override + public long getRemoteType1Gap() { + return remoteType1Gap; + } + @Override + public long getRemoteType2Gap() { + return remoteType2Gap; + } + + @Override + public Properties getProperties() { + return properties; + } + // for test void readPropertyValues() { @@ -771,9 +805,21 @@ void readPropertyValues() { this.customMetricEnable = readBoolean("profiler.custommetric.enable", false); this.customMetricLimitSize = readInt("profiler.custommetric.limit.size", 10); + buildAndSetRemoteConfig(); + logger.info("configuration loaded successfully."); } + private void buildAndSetRemoteConfig(){ + this.remoteEnable = readBoolean("profiler.remote.config.additional.enable", false); + if(this.remoteEnable){ + this.remoteAddr = readString("profiler.remote.config.addr", ""); + this.remoteType =readString("profiler.remote.config.additional.type", "1"); + this.remoteType1Gap =readLong("profiler.remote.config.additional.type1.gap", 86400000); + this.remoteType2Gap =readLong("profiler.remote.config.additional.type2.gap", 300000); + } + } + private ThriftTransportConfig readThriftTransportConfig(DefaultProfilerConfig profilerConfig) { DefaultThriftTransportConfig binaryTransportConfig = new DefaultThriftTransportConfig(); binaryTransportConfig.read(profilerConfig); @@ -785,7 +831,7 @@ private ThriftTransportConfig readThriftTransportConfig(DefaultProfilerConfig pr public String readString(String propertyName, String defaultValue) { return readString(propertyName, defaultValue, BypassResolver.RESOLVER); } - + @Override public String readString(String propertyName, String defaultValue, ValueResolver valueResolver) { if (valueResolver == null) { throw new NullPointerException("valueResolver"); @@ -840,10 +886,13 @@ public long readLong(String propertyName, long defaultValue) { @Override public List readList(String propertyName) { String value = properties.getProperty(propertyName); - if (StringUtils.isEmpty(value)) { + return readListFromParam(value); + } + public static List readListFromParam(String param){ + if (StringUtils.isEmpty(param)) { return Collections.emptyList(); } - return StringUtils.tokenizeToStringList(value, ","); + return StringUtils.tokenizeToStringList(param, ","); } @Override @@ -876,7 +925,6 @@ public Map readPattern(String propertyNamePatternRegex) { return result; } - @Override public String toString() { final StringBuilder sb = new StringBuilder("DefaultProfilerConfig{"); diff --git a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfig.java b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfig.java index 07d09c2185aa..f0d24e9397fd 100644 --- a/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfig.java +++ b/bootstrap-core/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilerConfig.java @@ -309,4 +309,10 @@ interface ValueResolver { String resolve(String value, Properties properties); } + boolean getRemoteEnable(); + String getRemoteAddr(); + String getRemoteType(); + long getRemoteType1Gap(); + long getRemoteType2Gap(); + Properties getProperties(); } diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIdResolver.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIdResolver.java index 3cbe8494a551..5a007d170679 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIdResolver.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIdResolver.java @@ -27,10 +27,12 @@ public class AgentIdResolver { public static final String APPLICATION_NAME = "applicationName"; public static final String AGENT_ID = "agentId"; + public static final String AGENT_LICENCE = "licence"; public static final String SYSTEM_PROPERTY_PREFIX = "pinpoint."; public static final String APPLICATION_NAME_SYSTEM_PROPERTY = SYSTEM_PROPERTY_PREFIX + "applicationName"; public static final String AGENT_ID_SYSTEM_PROPERTY = SYSTEM_PROPERTY_PREFIX + "agentId"; + public static final String LICENCE_PROPERTY = SYSTEM_PROPERTY_PREFIX + "licence"; private final BootLogger logger = BootLogger.getLogger(this.getClass().getName()); @@ -55,6 +57,8 @@ public AgentIds resolve() { touch = true; } + final String licenceName = agentProperty.getLicenceName(); + if (touch) { if (StringUtils.isEmpty(agentId)) { String error = agentProperty.getType() + " agentId is missing"; @@ -66,7 +70,11 @@ public AgentIds resolve() { logger.warn(error); return null; } - return new AgentIds(agentProperty.getType(), agentId, applicationName); + if (StringUtils.isEmpty(licenceName)) { + String error = agentProperty.getType() + " licenceName is missing"; + logger.warn(error); + } + return new AgentIds(agentProperty.getType(), agentId, applicationName, licenceName); } } diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIdResolverBuilder.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIdResolverBuilder.java index 09bf72a80e9c..6d51b74f6600 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIdResolverBuilder.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIdResolverBuilder.java @@ -33,7 +33,7 @@ public void addSystemProperties(Properties system) { Assert.requireNonNull(system, "system"); AgentProperties systemProperties = new AgentProperties(AgentIdSourceType.SYSTEM, system, - AgentIdResolver.AGENT_ID_SYSTEM_PROPERTY, AgentIdResolver.APPLICATION_NAME_SYSTEM_PROPERTY); + AgentIdResolver.AGENT_ID_SYSTEM_PROPERTY, AgentIdResolver.APPLICATION_NAME_SYSTEM_PROPERTY, AgentIdResolver.LICENCE_PROPERTY); this.agentProperties.add(systemProperties); } @@ -41,7 +41,7 @@ public void addAgentArgument(Map agentArguments) { Assert.requireNonNull(agentArguments, "agentArguments"); AgentProperties agentArgument = new AgentProperties(AgentIdSourceType.AGENT_ARGUMENT, agentArguments, - AgentIdResolver.AGENT_ID, AgentIdResolver.APPLICATION_NAME); + AgentIdResolver.AGENT_ID, AgentIdResolver.APPLICATION_NAME, AgentIdResolver.AGENT_LICENCE); this.agentProperties.add(agentArgument); } diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIds.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIds.java index 91cb7af91630..430f3b101b99 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIds.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentIds.java @@ -25,11 +25,13 @@ public class AgentIds { private final String agentId; private final String applicationName; private final AgentIdSourceType type; + private final String agentLicence; - public AgentIds(AgentIdSourceType type, String agentId, String applicationName) { + public AgentIds(AgentIdSourceType type, String agentId, String applicationName, String agentLicence) { this.type = Assert.requireNonNull(type, "type"); this.agentId = Assert.requireNonNull(agentId, "agentId"); this.applicationName = Assert.requireNonNull(applicationName, "applicationName"); + this.agentLicence = agentLicence; } public AgentIdSourceType getSourceType() { @@ -43,4 +45,8 @@ public String getAgentId() { public String getApplicationName() { return applicationName; } + + public String getAgentLicence() { + return agentLicence; + } } diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentOption.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentOption.java index 77f12c909f6c..7383b549caa6 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentOption.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentOption.java @@ -28,6 +28,8 @@ public interface AgentOption { Instrumentation getInstrumentation(); + String getAgentLicence(); + String getAgentId(); String getApplicationName(); diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentProperties.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentProperties.java index 8e42c84421b0..394ccfb1d160 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentProperties.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/AgentProperties.java @@ -29,12 +29,20 @@ public class AgentProperties { private final Properties properties; private final String agentKey; private final String applicationNameKey; + private final String licenceNameKey; - public AgentProperties(AgentIdSourceType type, Properties properties, String agentKey, String applicationNameKey) { + public AgentProperties(AgentIdSourceType type, Properties properties, String agentKey, String applicationNameKey, String licenceNameKey) { this.type = Assert.requireNonNull(type, "type"); this.properties = Assert.requireNonNull(properties, "properties"); this.agentKey = Assert.requireNonNull(agentKey, "agentKey"); this.applicationNameKey = Assert.requireNonNull(applicationNameKey, "applicationNameKey"); + this.licenceNameKey = licenceNameKey; + } + public AgentProperties(AgentIdSourceType type, Map properties, String agentKey, String applicationNameKey, String licenceNameKey) { + this(type, toProperties(properties), agentKey, applicationNameKey, licenceNameKey); + } + public AgentProperties(AgentIdSourceType type, Properties properties, String agentKey, String applicationNameKey) { + this(type, properties, agentKey, applicationNameKey, ""); } public AgentProperties(AgentIdSourceType type, Map properties, String agentKey, String applicationNameKey) { @@ -69,6 +77,14 @@ public String getApplicationNameKey() { return applicationNameKey; } + public String getLicenceName() { + return trim(this.properties.getProperty(licenceNameKey)); + } + + public String getLicenceNameKey() { + return licenceNameKey; + } + private String trim(String string) { if (string == null) { return null; diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/DefaultAgentOption.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/DefaultAgentOption.java index 491a25e79601..29d4871aad42 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/DefaultAgentOption.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/DefaultAgentOption.java @@ -30,6 +30,7 @@ public class DefaultAgentOption implements AgentOption { private final Instrumentation instrumentation; + private final String agentLicence; private final String agentId; private final String applicationName; private final boolean isContainer; @@ -38,8 +39,9 @@ public class DefaultAgentOption implements AgentOption { private final List pluginJars; private final List bootstrapJarPaths; - public DefaultAgentOption(final Instrumentation instrumentation, String agentId, String applicationName, final boolean isContainer, final ProfilerConfig profilerConfig, final List pluginJars, final List bootstrapJarPaths) { + public DefaultAgentOption(final Instrumentation instrumentation, String agentLicence, String agentId, String applicationName, final boolean isContainer, final ProfilerConfig profilerConfig, final List pluginJars, final List bootstrapJarPaths) { this.instrumentation = Assert.requireNonNull(instrumentation, "instrumentation"); + this.agentLicence = agentLicence; this.agentId = Assert.requireNonNull(agentId, "agentId"); this.applicationName = Assert.requireNonNull(applicationName, "applicationName"); this.isContainer = isContainer; @@ -57,6 +59,11 @@ public Instrumentation getInstrumentation() { return this.instrumentation; } + @Override + public String getAgentLicence() { + return agentLicence; + } + @Override public String getAgentId() { return agentId; diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointStarter.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointStarter.java index d0e4582added..347159c33e2c 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointStarter.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/PinpointStarter.java @@ -102,6 +102,7 @@ boolean start() { if (applicationName == null) { return false; } + final String licenceName = agentIds.getAgentLicence(); final ContainerResolver containerResolver = new ContainerResolver(); final boolean isContainer = containerResolver.isContainer(); @@ -128,7 +129,7 @@ boolean start() { logger.info(String.format("pinpoint agent [%s] starting...", bootClass)); final List pluginJars = agentDirectory.getPlugins(); - AgentOption option = createAgentOption(agentId, applicationName, isContainer, profilerConfig, instrumentation, pluginJars, agentDirectory); + AgentOption option = createAgentOption(licenceName, agentId, applicationName, isContainer, profilerConfig, instrumentation, pluginJars, agentDirectory); Agent pinpointAgent = agentBootLoader.boot(option); pinpointAgent.start(); pinpointAgent.registerStopHandler(); @@ -206,13 +207,13 @@ private String getAgentType() { } - private AgentOption createAgentOption(String agentId, String applicationName, boolean isContainer, + private AgentOption createAgentOption(String agentLicence, String agentId, String applicationName, boolean isContainer, ProfilerConfig profilerConfig, Instrumentation instrumentation, List pluginJars, AgentDirectory agentDirectory) { List bootstrapJarPaths = agentDirectory.getBootDir().toList(); - return new DefaultAgentOption(instrumentation, agentId, applicationName, isContainer, profilerConfig, pluginJars, bootstrapJarPaths); + return new DefaultAgentOption(instrumentation, agentLicence, agentId, applicationName, isContainer, profilerConfig, pluginJars, bootstrapJarPaths); } // for test diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilePropertyLoader.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilePropertyLoader.java index 2f8be060f418..bcbbd51caddd 100644 --- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilePropertyLoader.java +++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/config/ProfilePropertyLoader.java @@ -31,7 +31,7 @@ * @author yjqg6666 * @author Woonduk Kang(emeroad) */ -class ProfilePropertyLoader implements PropertyLoader { +public class ProfilePropertyLoader implements PropertyLoader { private static final String SEPARATOR = File.separator; @@ -124,6 +124,14 @@ private void loadFileProperties(Properties properties, String filePath) { throw new IllegalStateException(String.format("%s load fail Caused by:%s", filePath, e.getMessage())); } } + public static void loadFilePropertiesByProfileStr(Properties properties, String profileStr) { + try { + PropertyUtils.FileInputStreamFactory fileInputStreamFactory = new PropertyUtils.FileInputStreamFactory(profileStr, Boolean.TRUE); + PropertyUtils.loadProperty(properties, fileInputStreamFactory, PropertyUtils.DEFAULT_ENCODING); + } catch (Exception e) { + throw new IllegalStateException(String.format("remote properties load fail Caused by:%s", e.getMessage())); + } + } private void loadSystemProperties(Properties dstProperties) { Set stringPropertyNames = this.systemProperty.stringPropertyNames(); diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/AgentBootLoaderTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/AgentBootLoaderTest.java index 5347f528e079..f38740e907a6 100644 --- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/AgentBootLoaderTest.java +++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/AgentBootLoaderTest.java @@ -42,7 +42,7 @@ public void boot() { ClassLoader classLoader = AgentBootLoaderTest.class.getClassLoader(); AgentBootLoader agentBootLoader = new AgentBootLoader("com.navercorp.pinpoint.bootstrap.DummyAgent", classLoader); Instrumentation instrumentation = mock(Instrumentation.class); - AgentOption option = new DefaultAgentOption(instrumentation, "testCaseAgent", "testCaseAppName", false, new DefaultProfilerConfig(), Collections.emptyList(), null); + AgentOption option = new DefaultAgentOption(instrumentation, "licencen","testCaseAgent", "testCaseAppName", false, new DefaultProfilerConfig(), Collections.emptyList(), null); Agent boot = agentBootLoader.boot(option); boot.start(); boot.stop(); diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/HttpUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/HttpUtils.java index 489a7538e213..3c4bb05bbda3 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/HttpUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/HttpUtils.java @@ -18,6 +18,14 @@ import com.navercorp.pinpoint.common.Charsets; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + /** * @author emeroad */ @@ -54,4 +62,61 @@ public static String parseContentTypeCharset(String contentType, String defaultC return contentType.trim(); } + + public static String doGet(String httpUrl, int connectTimeout, int readTimeout) throws IOException { + //链接 + HttpURLConnection connection=null; + InputStream is=null; + BufferedReader br = null; + StringBuffer result=new StringBuffer(); + try { + //创建连接 + URL url=new URL(httpUrl); + connection= (HttpURLConnection) url.openConnection(); + //设置请求方式 + connection.setRequestMethod("GET"); + //设置连接超时时间 + connection.setConnectTimeout(connectTimeout); + //设置读取超时时间 + connection.setReadTimeout(readTimeout); + //开始连接 + connection.connect(); + //获取响应数据 + if(connection.getResponseCode()==200){ + //获取返回的数据 + is=connection.getInputStream(); + if(is!=null){ + br=new BufferedReader(new InputStreamReader(is,"UTF-8")); + String temp = null; + while ((temp=br.readLine())!=null){ + result.append(temp+"\r\n"); + } + } + } + } catch (MalformedURLException e) { + throw e; + } catch (IOException e) { + throw e; + }finally { + if(br!=null){ + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if(is!=null){ + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + connection.disconnect();// 关闭远程连接 + } + return result.toString(); + } + public static String doGet(String httpUrl) throws IOException { + return doGet(httpUrl, 3000, 2000); + } } diff --git a/commons/src/main/java/com/navercorp/pinpoint/common/util/PropertyUtils.java b/commons/src/main/java/com/navercorp/pinpoint/common/util/PropertyUtils.java index e76cb498dae5..22c0e53d6187 100644 --- a/commons/src/main/java/com/navercorp/pinpoint/common/util/PropertyUtils.java +++ b/commons/src/main/java/com/navercorp/pinpoint/common/util/PropertyUtils.java @@ -102,16 +102,21 @@ public static Properties loadProperty(Properties properties, InputStreamFactory public static class FileInputStreamFactory implements InputStreamFactory { private final String filePath; + private final Boolean isPropertiesStr; public FileInputStreamFactory(String filePath) { - if (filePath == null) { + this(filePath, Boolean.FALSE); + } + public FileInputStreamFactory(String propertiesStr, Boolean isPropertiesStr) { + if (propertiesStr == null) { throw new NullPointerException("filePath"); } - this.filePath = filePath; + this.filePath = propertiesStr; + this.isPropertiesStr = isPropertiesStr; } @Override public InputStream openInputStream() throws IOException { - return new FileInputStream(filePath); + return isPropertiesStr ? new ByteArrayInputStream(filePath.getBytes()) : new FileInputStream(filePath); } } diff --git a/pom.xml b/pom.xml index 32034e7467e4..7d195b21d1eb 100644 --- a/pom.xml +++ b/pom.xml @@ -735,7 +735,11 @@ guice 4.1.0 - + + com.alibaba.nacos + nacos-client + 2.2.0 + diff --git a/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockApplicationContextFactory.java b/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockApplicationContextFactory.java index 2ec65775c41c..e5f0b97370df 100644 --- a/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockApplicationContextFactory.java +++ b/profiler-test/src/main/java/com/navercorp/pinpoint/test/MockApplicationContextFactory.java @@ -83,7 +83,7 @@ public DefaultApplicationContext build(ProfilerConfig config, ModuleFactory modu String mockAgent = "mockAgent"; String mockApplicationName = "mockApplicationName"; - AgentOption agentOption = new DefaultAgentOption(instrumentation, mockAgent, mockApplicationName, false, config, Collections.emptyList(), + AgentOption agentOption = new DefaultAgentOption(instrumentation, "mockLicence", mockAgent, mockApplicationName, false, config, Collections.emptyList(), null); return new DefaultApplicationContext(agentOption, moduleFactory); } diff --git a/profiler-test/src/main/java/com/navercorp/pinpoint/test/OverrideModuleFactory.java b/profiler-test/src/main/java/com/navercorp/pinpoint/test/OverrideModuleFactory.java index 46b35c13084c..0b67a3cb4906 100644 --- a/profiler-test/src/main/java/com/navercorp/pinpoint/test/OverrideModuleFactory.java +++ b/profiler-test/src/main/java/com/navercorp/pinpoint/test/OverrideModuleFactory.java @@ -22,6 +22,7 @@ import com.navercorp.pinpoint.bootstrap.config.DefaultProfilerConfig; import com.navercorp.pinpoint.bootstrap.config.TransportModule; import com.navercorp.pinpoint.common.util.Assert; +import com.navercorp.pinpoint.profiler.context.module.ApplicationContext; import com.navercorp.pinpoint.profiler.context.module.ApplicationContextModuleFactory; import com.navercorp.pinpoint.profiler.context.module.ModuleFactory; import com.navercorp.pinpoint.test.rpc.MockRpcModule; @@ -56,4 +57,8 @@ protected Module newRpcModule(AgentOption agentOption) { Module module = moduleFactory.newModule(agentOption); return Modules.override(module).with(overrideModule); } + @Override + public Module newModule(AgentOption agentOption, ApplicationContext applicationContext) { + return newModule(agentOption); + } } diff --git a/profiler-test/src/test/java/com/navercorp/pinpoint/test/MockApplicationContextModuleTest.java b/profiler-test/src/test/java/com/navercorp/pinpoint/test/MockApplicationContextModuleTest.java index 5e5fef02b921..e53a80892be1 100644 --- a/profiler-test/src/test/java/com/navercorp/pinpoint/test/MockApplicationContextModuleTest.java +++ b/profiler-test/src/test/java/com/navercorp/pinpoint/test/MockApplicationContextModuleTest.java @@ -49,7 +49,7 @@ public void test() { Instrumentation instrumentation = Mockito.mock(Instrumentation.class); AgentOption agentOption = new DefaultAgentOption(instrumentation, - "mockAgent", "mockApplicationName", false, profilerConfig, Collections.emptyList(), + "mockLicence", "mockAgent", "mockApplicationName", false, profilerConfig, Collections.emptyList(), null); PluginTestAgent pluginTestAgent = new PluginTestAgent(agentOption); @@ -67,7 +67,7 @@ public void testMockApplicationContext() { Instrumentation instrumentation = Mockito.mock(Instrumentation.class); AgentOption agentOption = new DefaultAgentOption(instrumentation, - "mockAgent", "mockApplicationName", false, profilerConfig, Collections.emptyList(), + "mockLicence", "mockAgent", "mockApplicationName", false, profilerConfig, Collections.emptyList(), null); Module pluginModule = new PluginApplicationContextModule(); diff --git a/profiler-test/src/test/java/com/navercorp/pinpoint/test/monitor/AgentStatMonitorTest.java b/profiler-test/src/test/java/com/navercorp/pinpoint/test/monitor/AgentStatMonitorTest.java index e76fc7f556a3..6484902e7acb 100644 --- a/profiler-test/src/test/java/com/navercorp/pinpoint/test/monitor/AgentStatMonitorTest.java +++ b/profiler-test/src/test/java/com/navercorp/pinpoint/test/monitor/AgentStatMonitorTest.java @@ -81,7 +81,7 @@ public void testAgentStatMonitor() throws InterruptedException { // When AgentStatMonitor monitor = new DefaultAgentStatMonitor(this.dataSender, "agentId", System.currentTimeMillis(), - agentStatCollector, null, mockProfilerConfig); + agentStatCollector, null, mockProfilerConfig, null, null, null); monitor.start(); Thread.sleep(totalTestDurationMs); monitor.stop(); diff --git a/profiler/pom.xml b/profiler/pom.xml index 5b33c14bbf7f..a11229de0068 100644 --- a/profiler/pom.xml +++ b/profiler/pom.xml @@ -212,6 +212,16 @@ junit test + + com.alibaba.nacos + nacos-client + + + slf4j-api + org.slf4j + + + diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInfoSender.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInfoSender.java index 71d5ee619c5d..9c76e0e4d487 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInfoSender.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/AgentInfoSender.java @@ -20,9 +20,11 @@ import java.util.TimerTask; import java.util.concurrent.atomic.AtomicInteger; +import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; import com.navercorp.pinpoint.common.util.Assert; import com.navercorp.pinpoint.profiler.context.thrift.MessageConverter; import com.navercorp.pinpoint.profiler.metadata.AgentInfo; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; import com.navercorp.pinpoint.profiler.sender.ResultResponse; import com.navercorp.pinpoint.profiler.util.AgentInfoFactory; import com.navercorp.pinpoint.rpc.DefaultFuture; @@ -54,6 +56,7 @@ public class AgentInfoSender { private final int maxTryPerAttempt; private final Scheduler scheduler; private final MessageConverter messageConverter; + private final ProfilerConfig profilerConfig; private AgentInfoSender(Builder builder) { this.dataSender = builder.dataSender; @@ -63,6 +66,7 @@ private AgentInfoSender(Builder builder) { this.maxTryPerAttempt = builder.maxTryPerAttempt; this.scheduler = new Scheduler(); this.messageConverter = builder.messageConverter; + this.profilerConfig = builder.profilerConfig; } public void start() { @@ -163,9 +167,15 @@ public void run() { this.cancel(); return; } - boolean isSuccessful = sendAgentInfo(); - if (isSuccessful) { - logger.info("AgentInfo sent."); + if(ReSetConfigProcessorFactory.isEnableCollect(profilerConfig)){ + boolean isSuccessful = sendAgentInfo(); + if (isSuccessful) { + logger.info("AgentInfo sent."); + this.cancel(); + taskHandler.onSuccess(); + } + }else{ + logger.info("AgentInfo don't sent."); this.cancel(); taskHandler.onSuccess(); } @@ -211,6 +221,7 @@ public static class Builder { private long sendIntervalMs = DEFAULT_AGENT_INFO_SEND_INTERVAL_MS; private int maxTryPerAttempt = DEFAULT_MAX_TRY_COUNT_PER_ATTEMPT; private MessageConverter messageConverter; + private ProfilerConfig profilerConfig; public Builder(EnhancedDataSender dataSender, AgentInfoFactory agentInfoFactory) { this.dataSender = Assert.requireNonNull(dataSender, "dataSender"); @@ -236,6 +247,10 @@ public Builder setMessageConverter(MessageConverter messageConve this.messageConverter = messageConverter; return this; } + public Builder setProfilerConfig(ProfilerConfig profilerConfig) { + this.profilerConfig = profilerConfig; + return this; + } public AgentInfoSender build() { if (this.refreshIntervalMs <= 0) { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/AgentLicence.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/AgentLicence.java new file mode 100644 index 000000000000..a055ef4e93ed --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/AgentLicence.java @@ -0,0 +1,15 @@ +package com.navercorp.pinpoint.profiler.context.module; + +import com.google.inject.BindingAnnotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@BindingAnnotation +@Target(PARAMETER) +@Retention(RUNTIME) +public @interface AgentLicence { +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java index ebd9b8e6d5e5..7dc54e6a2a47 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModule.java @@ -107,10 +107,7 @@ import com.navercorp.pinpoint.profiler.metadata.ApiMetaDataService; import com.navercorp.pinpoint.profiler.metadata.SqlMetaDataService; import com.navercorp.pinpoint.profiler.metadata.StringMetaDataService; -import com.navercorp.pinpoint.profiler.monitor.AgentStatMonitor; -import com.navercorp.pinpoint.profiler.monitor.DeadlockMonitor; -import com.navercorp.pinpoint.profiler.monitor.DeadlockThreadRegistry; -import com.navercorp.pinpoint.profiler.monitor.DefaultAgentStatMonitor; +import com.navercorp.pinpoint.profiler.monitor.*; import com.navercorp.pinpoint.profiler.monitor.metric.response.ResponseTimeCollector; import com.navercorp.pinpoint.profiler.monitor.metric.response.ReuseResponseTimeCollector; import com.navercorp.pinpoint.profiler.objectfactory.ObjectBinderFactory; @@ -137,6 +134,11 @@ public class ApplicationContextModule extends AbstractModule { public ApplicationContextModule() { } + private ApplicationContext applicationContext; + + public ApplicationContextModule(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } @Override protected void configure() { @@ -146,6 +148,8 @@ protected void configure() { binder().requireAtInjectOnConstructors(); binder().disableCircularProxies(); + bind(ApplicationContext.class).toInstance(applicationContext); + bind(ServiceType.class).annotatedWith(ApplicationServerType.class).toProvider(ApplicationServerTypeProvider.class).in(Scopes.SINGLETON); bind(ServerMetaDataRegistryService.class).toProvider(ServerMetaDataRegistryServiceProvider.class).in(Scopes.SINGLETON); @@ -206,6 +210,7 @@ protected void configure() { bind(DeadlockMonitor.class).toProvider(DeadlockMonitorProvider.class).in(Scopes.SINGLETON); bind(AgentInfoSender.class).toProvider(AgentInfoSenderProvider.class).in(Scopes.SINGLETON); bind(AgentStatMonitor.class).to(DefaultAgentStatMonitor.class).in(Scopes.SINGLETON); + bind(RemoteConfigMonitor.class).to(DefaultRemoteConfigMonitor.class).in(Scopes.SINGLETON); } private void bindTraceComponent() { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModuleFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModuleFactory.java index 946df71b200a..2b36ed565935 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModuleFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/ApplicationContextModuleFactory.java @@ -30,19 +30,24 @@ */ public class ApplicationContextModuleFactory implements ModuleFactory { private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private ApplicationContext applicationContext; @Override public Module newModule(AgentOption agentOption) { final Module config = new ConfigModule(agentOption); final Module pluginModule = new PluginModule(); - final Module applicationContextModule = new ApplicationContextModule(); + final Module applicationContextModule = new ApplicationContextModule(applicationContext); final Module rpcModule = newRpcModule(agentOption); final Module statsModule = new StatsModule(); final Module thriftStatsModule = new ThriftStatsModule(); return Modules.combine(config, pluginModule, applicationContextModule, rpcModule, statsModule, thriftStatsModule); } - + @Override + public Module newModule(AgentOption agentOption, ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + return newModule(agentOption); + } protected Module newRpcModule(AgentOption agentOption) { ProfilerConfig profilerConfig = agentOption.getProfilerConfig(); final TransportModule transportModule = profilerConfig.getTransportModule(); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContext.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContext.java index 99157e62e50e..5e1d3d31351e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContext.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContext.java @@ -16,15 +16,17 @@ package com.navercorp.pinpoint.profiler.context.module; +import com.alibaba.nacos.api.NacosFactory; +import com.alibaba.nacos.api.config.ConfigService; import com.navercorp.pinpoint.bootstrap.AgentOption; +import com.navercorp.pinpoint.bootstrap.config.DefaultProfilerConfig; +import com.navercorp.pinpoint.bootstrap.config.ProfilePropertyLoader; import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; import com.navercorp.pinpoint.bootstrap.context.TraceContext; import com.navercorp.pinpoint.bootstrap.instrument.DynamicTransformTrigger; import com.navercorp.pinpoint.bootstrap.module.ClassFileTransformModuleAdaptor; import com.navercorp.pinpoint.bootstrap.module.JavaModuleFactory; -import com.navercorp.pinpoint.common.util.Assert; -import com.navercorp.pinpoint.common.util.JvmUtils; -import com.navercorp.pinpoint.common.util.JvmVersion; +import com.navercorp.pinpoint.common.util.*; import com.navercorp.pinpoint.profiler.AgentInfoSender; import com.navercorp.pinpoint.profiler.AgentInformation; import com.navercorp.pinpoint.profiler.context.ServerMetaDataRegistryService; @@ -37,6 +39,9 @@ import com.navercorp.pinpoint.profiler.interceptor.registry.InterceptorRegistryBinder; import com.navercorp.pinpoint.profiler.monitor.AgentStatMonitor; import com.navercorp.pinpoint.profiler.monitor.DeadlockMonitor; +import com.navercorp.pinpoint.profiler.monitor.DefaultRemoteConfigMonitor; +import com.navercorp.pinpoint.profiler.monitor.RemoteConfigMonitor; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; import com.navercorp.pinpoint.profiler.sender.DataSender; import com.google.inject.Guice; @@ -51,6 +56,7 @@ import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.Instrumentation; import java.lang.reflect.Constructor; +import java.util.Properties; /** * @author Woonduk Kang(emeroad) @@ -64,6 +70,7 @@ public class DefaultApplicationContext implements ApplicationContext { private final DeadlockMonitor deadlockMonitor; private final AgentInfoSender agentInfoSender; private final AgentStatMonitor agentStatMonitor; + private final RemoteConfigMonitor remoteConfigMonitor; private final TraceContext traceContext; @@ -80,6 +87,8 @@ public class DefaultApplicationContext implements ApplicationContext { private final Injector injector; + private ConfigService configService; + public DefaultApplicationContext(AgentOption agentOption, ModuleFactory moduleFactory) { Assert.requireNonNull(agentOption, "agentOption"); Assert.requireNonNull(moduleFactory, "moduleFactory"); @@ -90,7 +99,7 @@ public DefaultApplicationContext(AgentOption agentOption, ModuleFactory moduleFa logger.info("DefaultAgent classLoader:{}", this.getClass().getClassLoader()); } - final Module applicationContextModule = moduleFactory.newModule(agentOption); + final Module applicationContextModule = moduleFactory.newModule(agentOption, this); this.injector = Guice.createInjector(Stage.PRODUCTION, applicationContextModule); this.profilerConfig = injector.getInstance(ProfilerConfig.class); @@ -129,6 +138,109 @@ public DefaultApplicationContext(AgentOption agentOption, ModuleFactory moduleFa this.deadlockMonitor = injector.getInstance(DeadlockMonitor.class); this.agentInfoSender = injector.getInstance(AgentInfoSender.class); this.agentStatMonitor = injector.getInstance(AgentStatMonitor.class); + this.remoteConfigMonitor = injector.getInstance(RemoteConfigMonitor.class); + initRemoteConfig(agentOption); + initNacosConfigService(); + } + private void initRemoteConfig(AgentOption agentOption){ + try { + Properties propertiesOrigin = profilerConfig.getProperties(); + Object remoteEnable = propertiesOrigin.get("profiler.remote.config.init.enable"); + if(remoteEnable !=null && Boolean.parseBoolean(remoteEnable.toString())){ + logger.info("activate the remote initialization configuration"); + //get remote properties + String remoteConfigStr = loadAndSetRemoteProfile(propertiesOrigin, agentOption.getAgentLicence(), agentOption.getApplicationName()); + if(null != remoteConfigStr && !"".equals(remoteConfigStr) && !"null".equals(remoteConfigStr)){ + //reset profilerConfig + ((DefaultProfilerConfig)profilerConfig).resetDefaultProfilerConfig(propertiesOrigin); + //reinit some config + ReSetConfigProcessorFactory reSetConfigProcessorFactory = ((DefaultRemoteConfigMonitor) this.remoteConfigMonitor).getReSetConfigProcessorFactory(); + reSetConfigProcessorFactory.dealConfigInfo(remoteConfigStr); + } + }else{ + logger.info("skip the remote initialization configuration"); + } + } catch (Exception e) { + logger.error("initRemoteConfig error:"+e.getMessage()); + } + } + private void initNacosConfigService(){ + try { + //init configService + if(DefaultRemoteConfigMonitor.startRemoteMonitorIsBeginNacos(this.profilerConfig)){ + Properties nacosProperties = DefaultRemoteConfigMonitor.getNacosProperties(this.profilerConfig); + this.configService = NacosFactory.createConfigService(nacosProperties); + }else{ + logger.info("Uninitialized nacos"); + } + } catch (Exception e) { + logger.error("initNacosConfigService error:"+e.getMessage()); + } + } + private static final String NACOS_USERNAME="username"; + private static final String NACOS_PASSWORD="password"; + private static final String NACOS_NAMESPANCE="namespaceCenter"; + + private String loadAndSetRemoteProfile(Properties defaultProperties, String licence, String appName){ + String profileStr = null; + String nacosUrl = "http://%s/nacos/v1/cs/configs?username="+NACOS_USERNAME+"&password="+NACOS_PASSWORD+"&tenant="+NACOS_NAMESPANCE+"&dataId=%s&group=%s"; + + if(!StringUtils.isEmpty(licence) + && !StringUtils.isEmpty(appName) + && null!=defaultProperties + && !StringUtils.isEmpty(defaultProperties.getProperty("profiler.remote.config.addr")) + ){ + String remoteAddrRoot = defaultProperties.getProperty("profiler.remote.config.addr"); + int connectTimeout = 3000; + int readTimeout = 2000; + try { + connectTimeout = Integer.parseInt(defaultProperties.getProperty("profiler.remote.config.connectTimeout", "3000")); + readTimeout = Integer.parseInt(defaultProperties.getProperty("profiler.remote.config.readTimeout", "2000")); + } catch (Exception e) { + } + int forSize = remoteAddrRoot.contains(",") ? remoteAddrRoot.split(",").length : 1; + for(int i=0; i agentStats; + private ProfilerConfig profilerConfig; + private Properties properties; + private final Sampler sampler; + private final String licence; + private final String appName; public CollectJob(DataSender dataSender, - String agentId, long agentStartTimestamp, - AgentStatMetricCollector agentStatCollector, - int numCollectionsPerBatch) { + String agentId, long agentStartTimestamp, + AgentStatMetricCollector agentStatCollector, + int numCollectionsPerBatch, ProfilerConfig profilerConfig + , Sampler sampler, String licence, String appName) { if (dataSender == null) { throw new NullPointerException("dataSender"); } @@ -57,10 +70,22 @@ public CollectJob(DataSender dataSender, this.agentStatCollector = agentStatCollector; this.numCollectionsPerBatch = numCollectionsPerBatch; this.agentStats = new ArrayList(numCollectionsPerBatch); + + this.profilerConfig=profilerConfig; + if(profilerConfig != null && profilerConfig instanceof DefaultProfilerConfig){ + properties = ((DefaultProfilerConfig)profilerConfig).getProperties(); + } + this.sampler=sampler; + this.licence=licence; + this.appName=appName; } @Override public void run() { + if(!ReSetConfigProcessorFactory.isEnableCollect(profilerConfig)){ + logger.info("CollectJob is disabled."); + return; + } final long currentCollectionTimestamp = System.currentTimeMillis(); final long collectInterval = currentCollectionTimestamp - this.prevCollectionTimestamp; try { @@ -69,6 +94,7 @@ public void run() { agentStat.setCollectInterval(collectInterval); this.agentStats.add(agentStat); if (++this.collectCount >= numCollectionsPerBatch) { + setMoreAgentInfos(agentStat); sendAgentStats(); this.collectCount = 0; } @@ -78,6 +104,38 @@ public void run() { this.prevCollectionTimestamp = currentCollectionTimestamp; } } + private static Boolean isFirst = Boolean.TRUE; + public void setMoreAgentInfos(AgentStatMetricSnapshot agentStat){ + try { + if(isFirst){ + LogLevelChangeProcessor logLevelChangeProcessor = new LogLevelChangeProcessor(properties); + logLevelChangeProcessor.resetConfig(properties); + LogLevelChangeProcessor.setLogLevel(properties); + isFirst = Boolean.FALSE; + } + Map propertiesMap = new HashMap(PropertiesKey.values().length+1); + for(PropertiesKey propertiesKey : PropertiesKey.values()) { + propertiesMap.put(propertiesKey.key, properties.get(propertiesKey.key)); + } + //追加licence回去 + propertiesMap.put("profiler.licence", this.licence); + propertiesMap.put("profiler.appName", this.appName); + propertiesMap.put("profiler.agentId", this.agentId); + propertiesMap.put("profiler.collectTime", agentStat.getTimestamp()); + propertiesMap.put("profiler.remote.config.addr", profilerConfig.getRemoteAddr()); + + String reservedField = agentStat.getReservedField(); + ObjectMapper objectMapper = new ObjectMapper(); + Map reservedFieldMap = new HashMap(2); + if(!StringUtils.isEmpty(reservedField)){ + reservedFieldMap = objectMapper.readValue(reservedField, Map.class); + } + reservedFieldMap.put("properties", propertiesMap); + agentStat.setReservedField(objectMapper.writeValueAsString(reservedFieldMap)); + } catch (Exception ex) { + logger.warn("setMoreAgentInfos failed. Caused:{}", ex.getMessage(), ex); + } + } private void sendAgentStats() { // prepare TAgentStat object. diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultAgentStatMonitor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultAgentStatMonitor.java index aa8585b0e5b2..36b00639688c 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultAgentStatMonitor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultAgentStatMonitor.java @@ -18,10 +18,9 @@ import com.navercorp.pinpoint.bootstrap.config.DefaultProfilerConfig; import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; +import com.navercorp.pinpoint.bootstrap.sampler.Sampler; import com.navercorp.pinpoint.common.profiler.concurrent.PinpointThreadFactory; -import com.navercorp.pinpoint.profiler.context.module.AgentId; -import com.navercorp.pinpoint.profiler.context.module.AgentStartTime; -import com.navercorp.pinpoint.profiler.context.module.StatDataSender; +import com.navercorp.pinpoint.profiler.context.module.*; import com.navercorp.pinpoint.profiler.context.monitor.metric.CustomMetricRegistryService; import com.navercorp.pinpoint.profiler.monitor.collector.AgentCustomMetricCollector; import com.navercorp.pinpoint.profiler.monitor.collector.AgentStatMetricCollector; @@ -60,12 +59,18 @@ public class DefaultAgentStatMonitor implements AgentStatMonitor { private final StatMonitorJob statMonitorJob; + private final String licence; + private final String appName; + @Inject public DefaultAgentStatMonitor(@StatDataSender DataSender dataSender, @AgentId String agentId, @AgentStartTime long agentStartTimestamp, @Named("AgentStatCollector") AgentStatMetricCollector agentStatCollector, CustomMetricRegistryService customMetricRegistryService, - ProfilerConfig profilerConfig) { + ProfilerConfig profilerConfig, + Sampler sampler, + @AgentLicence String licence, + @ApplicationName String appName) { if (dataSender == null) { throw new NullPointerException("dataSender"); } @@ -89,10 +94,12 @@ public DefaultAgentStatMonitor(@StatDataSender DataSender dataSender, numCollectionsPerBatch = DEFAULT_NUM_COLLECTIONS_PER_SEND; } this.collectionIntervalMs = collectionIntervalMs; + this.licence = licence; + this.appName = appName; List runnableList = new ArrayList(); - Runnable statCollectingJob = new CollectJob(dataSender, agentId, agentStartTimestamp, agentStatCollector, numCollectionsPerBatch); + Runnable statCollectingJob = new CollectJob(dataSender, agentId, agentStartTimestamp, agentStatCollector, numCollectionsPerBatch, profilerConfig, sampler, licence, appName); runnableList.add(statCollectingJob); if (profilerConfig.isCustomMetricEnable() && customMetricRegistryService != null) { @@ -102,7 +109,7 @@ public DefaultAgentStatMonitor(@StatDataSender DataSender dataSender, this.statMonitorJob = new StatMonitorJob(runnableList); - preLoadClass(agentId, agentStartTimestamp, agentStatCollector); + preLoadClass(agentId, agentStartTimestamp, agentStatCollector, profilerConfig, sampler); } // https://github.com/naver/pinpoint/issues/2881 @@ -110,9 +117,9 @@ public DefaultAgentStatMonitor(@StatDataSender DataSender dataSender, // prevent deadlock for JDK6 // Single thread execution is more safe than multi thread execution. // eg) executor.scheduleAtFixedRate(collectJob, 0(initialDelay is zero), this.collectionIntervalMs, TimeUnit.MILLISECONDS); - private void preLoadClass(String agentId, long agentStartTimestamp, AgentStatMetricCollector agentStatCollector) { + private void preLoadClass(String agentId, long agentStartTimestamp, AgentStatMetricCollector agentStatCollector, ProfilerConfig profilerConfig, Sampler sampler) { logger.debug("pre-load class start"); - CollectJob collectJob = new CollectJob(EmptyDataSender.INSTANCE, agentId, agentStartTimestamp, agentStatCollector, 1); + CollectJob collectJob = new CollectJob(EmptyDataSender.INSTANCE, agentId, agentStartTimestamp, agentStatCollector, 1, profilerConfig, sampler, licence, appName); // It is called twice to initialize some fields. collectJob.run(); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultRemoteConfigMonitor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultRemoteConfigMonitor.java new file mode 100644 index 000000000000..5dac0213305a --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/DefaultRemoteConfigMonitor.java @@ -0,0 +1,357 @@ +package com.navercorp.pinpoint.profiler.monitor; + +import com.alibaba.nacos.api.config.ConfigService; +import com.alibaba.nacos.api.config.listener.Listener; +import com.alibaba.nacos.api.exception.NacosException; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; +import com.navercorp.pinpoint.bootstrap.context.TraceContext; +import com.navercorp.pinpoint.bootstrap.sampler.Sampler; +import com.navercorp.pinpoint.common.util.Assert; +import com.navercorp.pinpoint.common.util.HttpUtils; +import com.navercorp.pinpoint.common.util.StringUtils; +import com.navercorp.pinpoint.profiler.context.module.*; +import com.navercorp.pinpoint.profiler.context.storage.StorageFactory; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; +import com.navercorp.pinpoint.profiler.sender.DataSender; +import com.navercorp.pinpoint.profiler.sender.EnhancedDataSender; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.*; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author dongdd + * @description: + */ +public class DefaultRemoteConfigMonitor implements RemoteConfigMonitor{ + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final ProfilerConfig profilerConfig; + private final Sampler sampler; + private ConfigService configService; + private final String dataId; + private final String group; + private final String GROUP_DEFAULT="default"; + private final Set nacosConfigSet= new HashSet(); + private ReSetConfigProcessorFactory reSetConfigProcessorFactory; + private final int retry = 2; + private final String REMOTETYPE_TIMEDTASK = "1"; + private static final String REMOTETYPE_LONGCONNECTION = "2"; + + private Scheduler scheduler; + private final long refreshIntervalMs; + private final long sendIntervalMs; + private final int maxTryPerAttempt; + + private final DataSender statDataSender; + private final DataSender spanDataSender; + private final DataSender tcpDataSender; + + private static final String NACOS_USERNAME="username"; + private static final String NACOS_PASSWORD="password"; + private static final String NACOS_NAMESPANCE="namespace"; + + public ReSetConfigProcessorFactory getReSetConfigProcessorFactory(){ + return this.reSetConfigProcessorFactory; + } + + @Inject + public DefaultRemoteConfigMonitor(ProfilerConfig profilerConfig, Sampler sampler, @AgentLicence String agentLicence, @ApplicationName String applicationName + , @StatDataSender DataSender statDataSender , @SpanDataSender DataSender spanDataSender, @AgentDataSender EnhancedDataSender tcpDataSenderProvider + , Provider traceContextProvider + , Provider storageFactoryProvider + ){ + this.profilerConfig = profilerConfig; + this.sampler = sampler; + this.dataId = agentLicence; + this.group = applicationName; + this.maxTryPerAttempt = 3; + this.refreshIntervalMs = profilerConfig.getRemoteType1Gap(); + this.sendIntervalMs = profilerConfig.getRemoteType1Gap(); + + this.statDataSender = statDataSender; + this.spanDataSender = spanDataSender; + this.tcpDataSender = tcpDataSenderProvider; + TraceContext traceContext = traceContextProvider.get(); + StorageFactory storageFactory = storageFactoryProvider.get(); + reSetConfigProcessorFactory = new ReSetConfigProcessorFactory(this.profilerConfig, this.sampler, this.statDataSender, this.spanDataSender, this.tcpDataSender, traceContext, storageFactory); + } + @Override + public void start(ConfigService configService) { + startRemoteMonitor(configService); + } + private void startRemoteMonitor(ConfigService configService){ + try { + if(null != profilerConfig && profilerConfig.getRemoteEnable() && !StringUtils.isEmpty(profilerConfig.getRemoteAddr())){ + if(REMOTETYPE_TIMEDTASK.equals(profilerConfig.getRemoteType())){ + this.scheduler = new Scheduler(); + scheduler.start(); + }else if(startRemoteMonitorIsBeginNacos(profilerConfig)){ + this.configService = configService; + addListener(dataId, group+"-listener"); + addListener(dataId, GROUP_DEFAULT+"-listener"); + logger.info("AgentRemoteConfig started"); + }else{ + this.configService = null; + logger.info("AgentRemoteConfig not start!"); + } + }else{ + logger.info("Ban connection nacos!"); + } + } catch (Throwable e) { + logger.warn("AgentRemoteConfig start error: ", e); + } + } + public static Properties getNacosProperties(ProfilerConfig profilerConfig){ + Properties nacosProperties = new Properties(); + nacosProperties.put("serverAddr", profilerConfig.getRemoteAddr()); + nacosProperties.put("username", NACOS_USERNAME); + nacosProperties.put("password", NACOS_PASSWORD); + nacosProperties.put("namespace", NACOS_NAMESPANCE); + return nacosProperties; + } + public static boolean startRemoteMonitorIsBeginNacos(ProfilerConfig profilerConfig){ + boolean result = false; + if(null != profilerConfig && profilerConfig.getRemoteEnable() && !StringUtils.isEmpty(profilerConfig.getRemoteAddr()) && + REMOTETYPE_LONGCONNECTION.equals(profilerConfig.getRemoteType())){ + result = true; + } + return result; + } + + private boolean isConnected(String ip, int port){ + boolean result = false; + Socket connect = new Socket(); + try { + connect.connect(new InetSocketAddress(ip, port),1500); + result = connect.isConnected(); + } catch (IOException e) { + } + return result; + } + + @Override + public void stop() { + if(profilerConfig.getRemoteEnable()){ + if(REMOTETYPE_TIMEDTASK.equals(profilerConfig.getRemoteType())){ + scheduler.stop(); + }else if(REMOTETYPE_LONGCONNECTION.equals(profilerConfig.getRemoteType())){ + for(NacosConfig item : nacosConfigSet){ + configService.removeListener(item.dataId, item.group, item.listener); + } + } + } + } + private void addListener(String dataId, String group) throws NacosException { + Listener defaultListener = getDefaultListener(); + configService.addListener(dataId, group, defaultListener); + nacosConfigSet.add(new NacosConfig(dataId, group, defaultListener)); + } + + private Listener getDefaultListener(){ + Listener result = new Listener() { + @Override + public void receiveConfigInfo(String configInfo) { + if(logger.isDebugEnabled()){ + logger.debug("recieve remote configInfo : [{}]", configInfo); + } + if(StringUtils.isEmpty(configInfo) || null == reSetConfigProcessorFactory){ + return; + } + try { + reSetConfigProcessorFactory.dealConfigInfo(configInfo); + } catch (Exception e) { + logger.error("deal remote configInfo error: ", e); + } + } + + @Override + public Executor getExecutor() { + return null; + } + }; + return result; + } + + class NacosConfig{ + private String dataId; + private String group; + private Listener listener; + + NacosConfig(String dataId, String group, Listener listener) { + this.dataId = dataId; + this.group = group; + this.listener = listener; + } + + public String getDataId() { + return dataId; + } + + public void setDataId(String dataId) { + this.dataId = dataId; + } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + public Listener getListener() { + return listener; + } + + public void setListener(Listener listener) { + this.listener = listener; + } + } + + private interface SuccessListener { + void onSuccess(); + + SuccessListener NO_OP = new SuccessListener() { + @Override + public void onSuccess() { + // noop + } + }; + } + + private class Scheduler { + + private static final long IMMEDIATE = 0L; + private final Timer timer = new Timer("Pinpoint-RemoteConfig-Timer", true); + private final Object lock = new Object(); + // protected by lock's monitor + private boolean isRunning = true; + + private Scheduler() { + // preload + GetRemoteConfigTask task = new GetRemoteConfigTask(SuccessListener.NO_OP); + task.run(); + } + + public void start() { + final SuccessListener successListener = new SuccessListener() { + @Override + public void onSuccess() { + schedule(this, maxTryPerAttempt, refreshIntervalMs, sendIntervalMs); + } + }; + if (logger.isDebugEnabled()) { + logger.debug("Start scheduler of remoteConfigGetter"); + } + schedule(successListener, Integer.MAX_VALUE, IMMEDIATE, sendIntervalMs); + } + + public void refresh() { + if (logger.isDebugEnabled()) { + logger.debug("Refresh scheduler of remoteConfigGetter"); + } + schedule(SuccessListener.NO_OP, maxTryPerAttempt, IMMEDIATE, sendIntervalMs); + } + + private void schedule(SuccessListener successListener, int retryCount, long delay, long period) { + synchronized (lock) { + if (isRunning) { + GetRemoteConfigTask task = new GetRemoteConfigTask(successListener, retryCount); + timer.scheduleAtFixedRate(task, delay, period); + } + } + } + + public void stop() { + synchronized (lock) { + isRunning = false; + timer.cancel(); + } + } + } + private class GetRemoteConfigTask extends TimerTask { + private final SuccessListener taskHandler; + private final int retryCount; + private AtomicInteger counter; + private int connectTimeout = 3000; + private int readTimeout = 2000; + + private GetRemoteConfigTask(SuccessListener taskHandler) { + this(taskHandler, 0); + } + + private GetRemoteConfigTask(SuccessListener taskHandler, int retryCount) { + this.taskHandler = Assert.requireNonNull(taskHandler, "taskHandler"); + this.retryCount = retryCount; + this.counter = new AtomicInteger(0); + try { + String connectTimeoutStr = profilerConfig.getProperties().getProperty("profiler.remote.config.connectTimeout", "3000"); + String readTimeoutStr = profilerConfig.getProperties().getProperty("profiler.remote.config.readTimeout", "2000"); + this.connectTimeout = Integer.parseInt(connectTimeoutStr); + this.readTimeout = Integer.parseInt(readTimeoutStr); + } catch (Exception e) { + } + } + + @Override + public void run() { + try { + getAndSetRemoteConfig(); + } catch (Exception e) { + } finally { + //成功后取消当前timer + this.cancel(); + //回调onSuccess + taskHandler.onSuccess(); + } + } + private boolean getAndSetRemoteConfig(){ + try { + loadAndSetRemoteProfile(); + } catch (IOException e) { + logger.error("getAndSetRemoteConfig error! e=", e); + return false; + } + return true; + } + private void loadAndSetRemoteProfile() throws IOException { + String nacosUrl = "http://%s/nacos/v1/cs/configs?username="+NACOS_USERNAME+"&password="+NACOS_PASSWORD+"&tenant="+NACOS_NAMESPANCE+"&dataId=%s&group=%s"; + + //精准匹配licence和appName dataId=licence&&group=appName-listener + String level = dataId+":"+ group+"-listener"; + int forSize = profilerConfig.getRemoteAddr().contains(",") ? profilerConfig.getRemoteAddr().split(",").length : 1; + for(int i=0; i configProcessorSets = new HashSet(); + private Properties properties; + private static boolean agentEnable = Boolean.TRUE; + + public ReSetConfigProcessorFactory(ProfilerConfig profilerConfig, Sampler sampler + , DataSender statDataSender, DataSender spanDataSender, DataSender tcpDataSender + , TraceContext traceContext + , StorageFactory storageFactory) { + properties = ((DefaultProfilerConfig)profilerConfig).getProperties(); + try { + agentEnable = properties == null ? + Boolean.TRUE : + properties.containsKey(PropertiesKey.AGENT_ENABLE.key) ? + Boolean.parseBoolean(properties.get(PropertiesKey.AGENT_ENABLE.key)+"") : Boolean.TRUE; + } catch (Exception e) { + } + //add new ConfigProcessor + initSampleConfigProcessor(sampler); + initStatDataSenderProcessor(statDataSender); + initSpanDataSenderProcessor(spanDataSender); + initAgentDataSenderProcessor(tcpDataSender); + initAgentEnableConfigProcessor(properties); + initStatBatchProcessor(properties); + initLogLevelChangeProcessor(properties); + if (logger.isDebugEnabled()) { + logger.debug("Successful initialization ReSetConfigProcessorFactory, configProcessorSets.size: {}", configProcessorSets.size()); + } + } + public void dealConfigInfo(String configStr){ + for(ConfigProcessor item : configProcessorSets){ + if(item.isReset(configStr)){ + item.resetConfig(configStr); + item.resetProperties(properties); + } + } + } + + /** + * 添加处理器 + * @param sampler + */ + private void initSampleConfigProcessor(Sampler sampler){ + SamplerConfigProcessor samplerConfigProcessor = new SamplerConfigProcessor(sampler); + configProcessorSets.add(samplerConfigProcessor); + if (logger.isDebugEnabled()) { + logger.debug("add SamplerConfigProcessor successfully"); + } + } + private void initStatDataSenderProcessor(DataSender statDataSender){ + StatDataSenderProcessor statDataSenderProcessor = new StatDataSenderProcessor(statDataSender); + configProcessorSets.add(statDataSenderProcessor); + if (logger.isDebugEnabled()) { + logger.debug("add StatDataSenderProcessor successfully"); + } + } + private void initSpanDataSenderProcessor(DataSender spanDataSender){ + SpanDataSenderProcessor spanDataSenderProcessor = new SpanDataSenderProcessor(spanDataSender); + configProcessorSets.add(spanDataSenderProcessor); + if (logger.isDebugEnabled()) { + logger.debug("add SpanDataSenderProcessor successfully"); + } + } + private void initAgentDataSenderProcessor(DataSender agentDataSender) { + AgentDataSenderProcessor agentDataSenderProcessor = new AgentDataSenderProcessor(agentDataSender); + configProcessorSets.add(agentDataSenderProcessor); + if (logger.isDebugEnabled()) { + logger.debug("add AgentDataSenderProcessor successfully"); + } + } + private void initAgentEnableConfigProcessor(Properties properties){ + AgentEnableConfigProcessor agentEnableConfigProcessor = new AgentEnableConfigProcessor(properties); + configProcessorSets.add(agentEnableConfigProcessor); + if (logger.isDebugEnabled()) { + logger.debug("add AgentEnableConfigProcessor successfully"); + } + } + private void initStatBatchProcessor(Properties properties){ + StatBatchProcessor statBatchProcessor = new StatBatchProcessor(properties); + configProcessorSets.add(statBatchProcessor); + if (logger.isDebugEnabled()) { + logger.debug("add StatBatchProcessor successfully"); + } + } + + private void initLogLevelChangeProcessor(Properties properties){ + LogLevelChangeProcessor logLevelChangeProcessor = new LogLevelChangeProcessor(properties); + configProcessorSets.add(logLevelChangeProcessor); + if (logger.isDebugEnabled()) { + logger.debug("add logLevelChangeProcessor successfully"); + } + } + + public static Properties configStr2Properties(String configStr) throws IOException { + Properties result = new Properties(); + result.load(new ByteArrayInputStream(configStr.getBytes())); + return result; + } + + public static Object getHostOrPort(Object newObj, Object originObj){ + if(newObj != null){ + return newObj; + }else if(newObj == null && originObj!=null){ + return originObj; + }else{ + throw new RuntimeException("getHostOrPort error,newObj="+newObj+" originObj="+originObj); + } + } + + public static boolean isEnableCollect(ProfilerConfig profilerConfig){ + return agentEnable; + } + public static void setEnableCollect(boolean agentEnableNew){ + agentEnable = agentEnableNew; + } + + public static Map fieldToMap(Field[] traceContextFields){ + Map objectObjectHashMap = null; + if(traceContextFields != null && traceContextFields.length>0){ + objectObjectHashMap = new HashMap(traceContextFields.length); + for(Field item : traceContextFields){ + objectObjectHashMap.put(item.getName(), item); + } + } + return objectObjectHashMap; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/changehoststat/StatBatchProcessor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/changehoststat/StatBatchProcessor.java new file mode 100644 index 000000000000..ca7e8244132f --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/changehoststat/StatBatchProcessor.java @@ -0,0 +1,57 @@ +package com.navercorp.pinpoint.profiler.monitor.processor.changehoststat; + +import com.navercorp.pinpoint.profiler.monitor.processor.ConfigProcessor; +import com.navercorp.pinpoint.profiler.monitor.processor.PropertiesKey; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Properties; + +/** + * @author dongdd + */ +public class StatBatchProcessor implements ConfigProcessor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Properties properties; + + public StatBatchProcessor(Properties properties){ + this.properties = properties; + } + @Override + public boolean isReset(String configStr) { + Properties properties = null; + try { + properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + } catch (Exception e) { + return false; + } + if(null != configStr && null!=properties + && (properties.containsKey(PropertiesKey.STAT_BATCH_COUNR.key)) + ){ + return true; + } + return false; + } + + @Override + public void resetConfig(String configStr) { + try { + Properties properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + + Integer batchCountNew = properties.containsKey(PropertiesKey.STAT_BATCH_COUNR.key) ? Integer.parseInt(properties.get(PropertiesKey.STAT_BATCH_COUNR.key)+"") : null; + Integer batchCountOld = Integer.parseInt(this.properties.get(PropertiesKey.STAT_BATCH_COUNR.key)+""); + + if(batchCountNew!=null && !batchCountNew.equals(batchCountOld)){ + this.properties.put(PropertiesKey.STAT_BATCH_COUNR.key, batchCountNew); + } + } catch (Exception e) { + logger.error("StatBatchProcessor resetConfig {} error, configStr=[{}], e=[{}]!", PropertiesKey.STAT_BATCH_COUNR.key, configStr, e); + } + } + @Override + public void resetProperties(Properties properties){ + //resetConfig已经设置值到properties + return; + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/changelog/LogLevelChangeProcessor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/changelog/LogLevelChangeProcessor.java new file mode 100644 index 000000000000..79f65dcd7ad2 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/changelog/LogLevelChangeProcessor.java @@ -0,0 +1,123 @@ +package com.navercorp.pinpoint.profiler.monitor.processor.changelog; + +import com.navercorp.pinpoint.profiler.monitor.processor.ConfigProcessor; +import com.navercorp.pinpoint.profiler.monitor.processor.PropertiesKey; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; +import org.apache.log4j.Level; +import org.apache.log4j.LogManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * @author zy + */ +public class LogLevelChangeProcessor implements ConfigProcessor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Properties properties; + private static final String WANT_PACKAGE ="com.navercorp.pinpoint"; + private static final String NACOS_PACKAGE ="com.alibaba.nacos"; + public LogLevelChangeProcessor(Properties properties){ + this.properties = properties; + } + public static final List logKeyList = new ArrayList(){{ + add(PropertiesKey.LOG_LEVEL_GLOBAL.key); + add(PropertiesKey.LOG_LEVEL_PINPOINT.key); + add(PropertiesKey.LOG_LEVEL_NACOS.key); + }}; + @Override + public boolean isReset(String configStr) { + Properties properties = null; + try { + properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + } catch (Exception e) { + return false; + } + if(null != configStr && null!=properties + && isContainerLogLevelKey(properties) + ){ + return true; + } + return false; + } + private boolean isContainerLogLevelKey(Properties properties){ + for(String keySet : logKeyList){ + if(properties.containsKey(keySet)){ + return true; + } + } + return false; + } + public void resetConfig(Properties properties){ + try { + String logGlobalLevel = properties.containsKey(PropertiesKey.LOG_LEVEL_GLOBAL.key) ? String.valueOf(properties.get(PropertiesKey.LOG_LEVEL_GLOBAL.key)):null; + String logPinpointLevel = properties.containsKey(PropertiesKey.LOG_LEVEL_PINPOINT.key) ? String.valueOf(properties.get(PropertiesKey.LOG_LEVEL_PINPOINT.key)):null; + String logNacosLevel = properties.containsKey(PropertiesKey.LOG_LEVEL_NACOS.key) ? String.valueOf(properties.get(PropertiesKey.LOG_LEVEL_NACOS.key)):null; + + if(logGlobalLevel!=null&&!"".equals(logGlobalLevel)){ + changeLogLevel(logGlobalLevel); + } + if(logPinpointLevel!=null&&!"".equals(logPinpointLevel)){ + changeLogLevel(logPinpointLevel,WANT_PACKAGE); + } + if(logNacosLevel!=null&&!"".equals(logNacosLevel)){ + changeLogLevel(logNacosLevel,NACOS_PACKAGE); + } + } catch (Exception e) { + logger.error("LogLevelChangeProcessor resetConfig {} error, configStr=[properties], e=[{}]!", PropertiesKey.LOG_LEVEL_GLOBAL.key, e); + } + } + + @Override + public void resetConfig(String configStr) { + try { + Properties properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + resetConfig(properties); + } catch (Exception e) { + logger.error("LogLevelChangeProcessor resetConfig {} error, configStr=[{}], e=[{}]!", PropertiesKey.LOG_LEVEL_GLOBAL.key, configStr, e); + } + } + @Override + public void resetProperties(Properties properties){ + setLogLevel(properties); + return; + } + public static void setLogLevel(Properties properties){ + try { + Level rootLevel = LogManager.getRootLogger().getLevel(); + if(rootLevel!=null){ + properties.put(PropertiesKey.LOG_LEVEL_GLOBAL.key, rootLevel.toString()); + } + Level pinpointLevel = LogManager.getLogger(WANT_PACKAGE).getLevel(); + if(pinpointLevel!=null){ + properties.put(PropertiesKey.LOG_LEVEL_PINPOINT.key, pinpointLevel.toString()); + } + Level nacosLevel = LogManager.getLogger(NACOS_PACKAGE).getLevel(); + if(nacosLevel!=null){ + properties.put(PropertiesKey.LOG_LEVEL_NACOS.key, nacosLevel.toString()); + } + } catch (Exception e) { + } + } + + public void changeLogLevel(String wantLevel){ + try { + Level level = Level.toLevel(wantLevel); + LogManager.getRootLogger().setLevel(level); + } catch (Exception e) { + logger.error("LogLevelChangeProcessor resetConfig {} error, configStr=[{}], e=[{}]!", PropertiesKey.LOG_LEVEL_GLOBAL.key, wantLevel, e); + } + } + + public void changeLogLevel(String wantLevel,String wantPackage){ + try { + Level level = Level.toLevel(wantLevel); + LogManager.getLogger(wantPackage).setLevel(level); + } catch (Exception e) { + logger.error("LogLevelChangeProcessor resetConfig {} error, configStr=[{}], e=[{}]!", PropertiesKey.LOG_LEVEL_PINPOINT.key, wantLevel, e); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/AgentDataSenderProcessor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/AgentDataSenderProcessor.java new file mode 100644 index 000000000000..c65ce04e3acf --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/AgentDataSenderProcessor.java @@ -0,0 +1,132 @@ +package com.navercorp.pinpoint.profiler.monitor.processor.datesender; + +import com.navercorp.pinpoint.profiler.monitor.processor.ConfigProcessor; +import com.navercorp.pinpoint.profiler.monitor.processor.PropertiesKey; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; +import com.navercorp.pinpoint.profiler.sender.DataSender; +import com.navercorp.pinpoint.profiler.sender.TcpDataSender; +import com.navercorp.pinpoint.rpc.client.DefaultPinpointClientFactory; +import com.navercorp.pinpoint.rpc.client.DnsSocketAddressProvider; +import com.navercorp.pinpoint.rpc.client.PinpointClient; +import com.navercorp.pinpoint.rpc.util.ClientFactoryUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.util.Properties; + +/** + * @author dongdd + * @description:TCP-agent + */ +public class AgentDataSenderProcessor implements ConfigProcessor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private DataSender agentDataSender; + + public AgentDataSenderProcessor(DataSender agentDataSender){ + this.agentDataSender = agentDataSender; + } + @Override + public boolean isReset(String configStr) { + Properties properties = null; + try { + properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + } catch (Exception e) { + return false; + } + if(null != configStr && null!=properties + && (properties.containsKey(PropertiesKey.AGENT_SENDER_IP.key) || properties.containsKey(PropertiesKey.AGENT_SENDER_PORT.key)) + ){ + return true; + } + return false; + } + + @Override + public void resetConfig(String configStr) { + try { + Properties properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + if(agentDataSender != null && properties != null){ + if(agentDataSender instanceof TcpDataSender){ + Object hostNewObj = properties.get(PropertiesKey.AGENT_SENDER_IP.key); + Object portNewObj = properties.get(PropertiesKey.AGENT_SENDER_PORT.key); + Object hostOrigin = null; + Object portOrigin = null; + Field field = agentDataSender.getClass().getDeclaredField("clientProvider"); + if(field != null){ + field.setAccessible(true); + Object clientProviderObj = field.get(agentDataSender); + ClientFactoryUtils.PinpointClientProvider clientProvider = null; + if(clientProviderObj != null + &&clientProviderObj instanceof ClientFactoryUtils.PinpointClientProvider){ + clientProvider = (ClientFactoryUtils.PinpointClientProvider)clientProviderObj; + String addressAsString = clientProvider.getAddressAsString(); + hostOrigin = addressAsString.split(":")[0]; + portOrigin = addressAsString.split(":")[1]; + }else{ + logger.error("clientProviderObj is error, return!"); + return; + } + String host = String.valueOf(ReSetConfigProcessorFactory.getHostOrPort(hostNewObj, hostOrigin)); + Integer port = Integer.parseInt(ReSetConfigProcessorFactory.getHostOrPort(portNewObj, portOrigin)+""); + if((!host.equals(hostOrigin) || !(""+port).equals(portOrigin)) + && clientProvider!=null){ + PinpointClient pinpointClient = clientProvider.get(host, port); + if(pinpointClient != null && pinpointClient.isConnected()){ + hostResult = host; + portResult = port; + Field fieldClient = agentDataSender.getClass().getDeclaredField("client"); + if(fieldClient != null){ + fieldClient.setAccessible(true); + fieldClient.set(agentDataSender, pinpointClient); + Field clientFactoryField = clientProvider.getClass().getDeclaredField("clientFactory"); + if(clientFactoryField != null){ + clientFactoryField.setAccessible(true); + Object clientFactoryObj = clientFactoryField.get(clientProvider); + if(clientFactoryObj != null && clientFactoryObj instanceof DefaultPinpointClientFactory){ + Field socketAddressScheduledProviderField = clientFactoryObj.getClass().getDeclaredField("socketAddressScheduledProvider"); + socketAddressScheduledProviderField.setAccessible(true); + Object socketAddressScheduledProviderObj = socketAddressScheduledProviderField.get(clientFactoryObj); + if(socketAddressScheduledProviderObj != null && socketAddressScheduledProviderObj instanceof DnsSocketAddressProvider){ + Field hostScheduled = socketAddressScheduledProviderObj.getClass().getDeclaredField("host"); + Field portScheduled = socketAddressScheduledProviderObj.getClass().getDeclaredField("port"); + hostScheduled.setAccessible(true); + portScheduled.setAccessible(true); + hostScheduled.set(socketAddressScheduledProviderObj, host); + portScheduled.set(socketAddressScheduledProviderObj, port); + } + } + }else{ + logger.warn("clientProvider class clientFactory field is null, return!"); + } + }else{ + logger.warn("agentDataSender class client field is null, return!"); + } + }else{ + logger.warn("tcp connect fail!{}:{}", host, port); + } + } + }else{ + logger.warn("TcpDataSender class clientProvider field is null, return!"); + } + }else{ + logger.info("agent sender is not TcpDataSender"); + } + } + } catch (Exception e) { + logger.error("agentDataSenderProcessor resetConfig {} error, configStr=[{}-{}], e=[{}]!", PropertiesKey.AGENT_SENDER_IP.key, PropertiesKey.AGENT_SENDER_PORT.key, configStr, e); + } + } + + private static String hostResult; + private static Integer portResult; + @Override + public void resetProperties(Properties properties){ + if(hostResult != null){ + properties.put(PropertiesKey.AGENT_SENDER_IP.key, hostResult); + } + if(portResult != null) { + properties.put(PropertiesKey.AGENT_SENDER_PORT.key, portResult); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/SpanDataSenderProcessor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/SpanDataSenderProcessor.java new file mode 100644 index 000000000000..d910453e0ec1 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/SpanDataSenderProcessor.java @@ -0,0 +1,105 @@ +package com.navercorp.pinpoint.profiler.monitor.processor.datesender; + +import com.navercorp.pinpoint.profiler.monitor.processor.ConfigProcessor; +import com.navercorp.pinpoint.profiler.monitor.processor.PropertiesKey; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; +import com.navercorp.pinpoint.profiler.sender.DataSender; +import com.navercorp.pinpoint.profiler.sender.RefreshStrategy; +import com.navercorp.pinpoint.profiler.sender.UdpDataSender; +import com.navercorp.pinpoint.rpc.client.DnsSocketAddressProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.util.Properties; + +/** + * @author dongdd + * @description:UDP-span + */ +public class SpanDataSenderProcessor implements ConfigProcessor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private DataSender spanDataSender; + + public SpanDataSenderProcessor(DataSender spanDataSender){ + this.spanDataSender = spanDataSender; + } + @Override + public boolean isReset(String configStr) { + Properties properties = null; + try { + properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + } catch (Exception e) { + return false; + } + if(null != configStr && null!=properties && + (properties.containsKey(PropertiesKey.SPAN_SENDER_IP.key) || properties.containsKey(PropertiesKey.SPAN_SENDER_PORT.key)) + ){ + return true; + } + return false; + } + + @Override + public void resetConfig(String configStr) { + try { + Properties properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + if(spanDataSender != null && properties != null){ + if(spanDataSender instanceof UdpDataSender){ + Object hostNewObj = properties.get(PropertiesKey.SPAN_SENDER_IP.key); + Object portNewObj = properties.get(PropertiesKey.SPAN_SENDER_PORT.key); + Object hostOrigin = null; + Object portOrigin = null; + Field field = spanDataSender.getClass().getDeclaredField("socketAddressProvider"); + if(field != null){ + field.setAccessible(true); + Object socketAddressProviderObj = field.get(spanDataSender); + if(socketAddressProviderObj != null + &&socketAddressProviderObj instanceof RefreshStrategy){ + Field socketAddressProviderField = socketAddressProviderObj.getClass().getDeclaredField("socketAddressProvider"); + if(socketAddressProviderField != null){ + socketAddressProviderField.setAccessible(true); + Object dnsSocketAddressProviderObj = socketAddressProviderField.get(socketAddressProviderObj); + if(dnsSocketAddressProviderObj != null && dnsSocketAddressProviderObj instanceof DnsSocketAddressProvider){ + Field host = dnsSocketAddressProviderObj.getClass().getDeclaredField("host"); + Field port = dnsSocketAddressProviderObj.getClass().getDeclaredField("port"); + if(host != null){ + host.setAccessible(true); + hostOrigin = host.get(dnsSocketAddressProviderObj); + } + if(port != null){ + port.setAccessible(true); + portOrigin = port.get(dnsSocketAddressProviderObj); + } + } + } + } + String host = String.valueOf(ReSetConfigProcessorFactory.getHostOrPort(hostNewObj, hostOrigin)); + Integer port = Integer.parseInt(ReSetConfigProcessorFactory.getHostOrPort(portNewObj, portOrigin)+""); + if(!host.equals(hostOrigin) || !(""+port).equals(portOrigin)){ + hostResult = host; + portResult = port; + field.set(spanDataSender, new RefreshStrategy(new DnsSocketAddressProvider(host, port))); + } + } + }else{ + logger.warn("span sender is not UdpDataSender"); + } + } + } catch (Exception e) { + logger.error("SpanDataSenderProcessor resetConfig {} error, configStr=[{}-{}], e=[{}]!", PropertiesKey.SPAN_SENDER_IP.key, PropertiesKey.SPAN_SENDER_PORT.key, configStr, e); + } + } + + private static String hostResult; + private static Integer portResult; + @Override + public void resetProperties(Properties properties){ + if(hostResult != null){ + properties.put(PropertiesKey.SPAN_SENDER_IP.key, hostResult); + } + if(portResult != null) { + properties.put(PropertiesKey.SPAN_SENDER_PORT.key, portResult); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/StatDataSenderProcessor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/StatDataSenderProcessor.java new file mode 100644 index 000000000000..07553797d02d --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/datesender/StatDataSenderProcessor.java @@ -0,0 +1,106 @@ +package com.navercorp.pinpoint.profiler.monitor.processor.datesender; + +import com.navercorp.pinpoint.profiler.monitor.processor.ConfigProcessor; +import com.navercorp.pinpoint.profiler.monitor.processor.PropertiesKey; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; +import com.navercorp.pinpoint.profiler.sender.DataSender; +import com.navercorp.pinpoint.profiler.sender.RefreshStrategy; +import com.navercorp.pinpoint.profiler.sender.UdpDataSender; +import com.navercorp.pinpoint.rpc.client.DnsSocketAddressProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.util.Properties; + +/** + * @author dongdd + */ +public class StatDataSenderProcessor implements ConfigProcessor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private DataSender statDataSender; + + public StatDataSenderProcessor(DataSender statDataSender){ + this.statDataSender = statDataSender; + } + @Override + public boolean isReset(String configStr) { + Properties properties = null; + try { + properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + } catch (Exception e) { + return false; + } + if(null != configStr && null!=properties && + (properties.containsKey(PropertiesKey.STAT_SENDER_IP.key) || properties.containsKey(PropertiesKey.STAT_SENDER_PORT.key)) + ){ + return true; + } + return false; + } + + @Override + public void resetConfig(String configStr) { + try { + Properties properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + if(statDataSender != null && properties != null){ + if(statDataSender instanceof UdpDataSender){ + Object hostNewObj = properties.get(PropertiesKey.STAT_SENDER_IP.key); + Object portNewObj = properties.get(PropertiesKey.STAT_SENDER_PORT.key); + Object hostOrigin = null; + Object portOrigin = null; + Field field = statDataSender.getClass().getDeclaredField("socketAddressProvider"); + if(field != null){ + field.setAccessible(true); + Object socketAddressProviderObj = field.get(statDataSender); + if(socketAddressProviderObj != null + &&socketAddressProviderObj instanceof RefreshStrategy){ + Field socketAddressProviderField = socketAddressProviderObj.getClass().getDeclaredField("socketAddressProvider"); + if(socketAddressProviderField != null){ + socketAddressProviderField.setAccessible(true); + Object dnsSocketAddressProviderObj = socketAddressProviderField.get(socketAddressProviderObj); + if(dnsSocketAddressProviderObj != null && dnsSocketAddressProviderObj instanceof DnsSocketAddressProvider){ + Field host = dnsSocketAddressProviderObj.getClass().getDeclaredField("host"); + Field port = dnsSocketAddressProviderObj.getClass().getDeclaredField("port"); + if(host != null){ + host.setAccessible(true); + hostOrigin = host.get(dnsSocketAddressProviderObj); + } + if(port != null){ + port.setAccessible(true); + portOrigin = port.get(dnsSocketAddressProviderObj); + } + } + } + } + String host = String.valueOf(ReSetConfigProcessorFactory.getHostOrPort(hostNewObj, hostOrigin)); + Integer port = Integer.parseInt(ReSetConfigProcessorFactory.getHostOrPort(portNewObj, portOrigin)+""); + if(!host.equals(hostOrigin) || !(""+port).equals(portOrigin)){ + hostResult = host; + portResult = port; + field.set(statDataSender, new RefreshStrategy(new DnsSocketAddressProvider(host, port))); + } + }else{ + logger.warn("statDataSender class socketAddressProvider field is null, return!"); + } + }else{ + logger.warn("stat sender is not UdpDataSender"); + } + } + } catch (Exception e) { + logger.error("StatDataSenderProcessor resetConfig {} error, configStr=[{}-{}], e=[{}]!", PropertiesKey.STAT_SENDER_IP.key, PropertiesKey.STAT_SENDER_PORT.key, configStr, e); + } + } + + private static String hostResult; + private static Integer portResult; + @Override + public void resetProperties(Properties properties){ + if(hostResult != null){ + properties.put(PropertiesKey.STAT_SENDER_IP.key, hostResult); + } + if(portResult != null) { + properties.put(PropertiesKey.STAT_SENDER_PORT.key, portResult); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/sampler/AgentEnableConfigProcessor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/sampler/AgentEnableConfigProcessor.java new file mode 100644 index 000000000000..d3bb7acf755f --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/sampler/AgentEnableConfigProcessor.java @@ -0,0 +1,61 @@ +package com.navercorp.pinpoint.profiler.monitor.processor.sampler; + +import com.navercorp.pinpoint.profiler.monitor.processor.ConfigProcessor; +import com.navercorp.pinpoint.profiler.monitor.processor.PropertiesKey; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Properties; + +/** + * @author dongdd + * @description:采样率处理器 + */ +public class AgentEnableConfigProcessor implements ConfigProcessor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Properties properties; + public AgentEnableConfigProcessor(Properties properties){ + this.properties = properties; + } + @Override + public boolean isReset(String configStr) { + Properties properties = null; + try { + properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + } catch (Exception e) { + return false; + } + if(null != configStr && null!=properties + && (properties.containsKey(PropertiesKey.AGENT_ENABLE.key)) + ){ + return true; + } + return false; + } + + @Override + public void resetConfig(String configStr) { + try { + Properties sampleProperties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + + Boolean agentEnableNew = sampleProperties.containsKey(PropertiesKey.AGENT_ENABLE.key) ? Boolean.parseBoolean(sampleProperties.get(PropertiesKey.AGENT_ENABLE.key)+"") : null; + Boolean agentEnableOld = properties.containsKey(PropertiesKey.AGENT_ENABLE.key) ? Boolean.parseBoolean(properties.get(PropertiesKey.AGENT_ENABLE.key)+"") : null; + + if(agentEnableNew != null && !agentEnableNew.equals(agentEnableOld)){ + ReSetConfigProcessorFactory.setEnableCollect(agentEnableNew.booleanValue()); + agentEnableNewValue = agentEnableNew.booleanValue(); + } + + } catch (Exception e) { + logger.error("AgentEnableConfigProcessor resetConfig {} error, configStr=[{}], e=[{}]!", PropertiesKey.AGENT_ENABLE.key, configStr, e); + } + } + private Boolean agentEnableNewValue; + @Override + public void resetProperties(Properties properties){ + if(agentEnableNewValue!=null){ + properties.put(PropertiesKey.AGENT_ENABLE.key, agentEnableNewValue.booleanValue()); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/sampler/SamplerConfigProcessor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/sampler/SamplerConfigProcessor.java new file mode 100644 index 000000000000..34a521d24e53 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/monitor/processor/sampler/SamplerConfigProcessor.java @@ -0,0 +1,91 @@ +package com.navercorp.pinpoint.profiler.monitor.processor.sampler; + +import com.navercorp.pinpoint.bootstrap.sampler.Sampler; +import com.navercorp.pinpoint.profiler.monitor.processor.ConfigProcessor; +import com.navercorp.pinpoint.profiler.monitor.processor.PropertiesKey; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; +import com.navercorp.pinpoint.profiler.sampler.SamplingRateSampler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.util.Properties; + +/** + * @author dongdd + * @description:采样率处理器 + */ +public class SamplerConfigProcessor implements ConfigProcessor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Sampler sampler; + public SamplerConfigProcessor(Sampler sampler){ + this. sampler = sampler; + } + @Override + public boolean isReset(String configStr) { + Properties properties = null; + try { + properties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + } catch (Exception e) { + return false; + } + if(null != configStr && null!=properties + && null != sampler && sampler instanceof SamplingRateSampler + && (properties.containsKey(PropertiesKey.SAMPLE_RATE.key) || properties.containsKey(PropertiesKey.SAMPLE_ENABLE.key)) + ){ + return true; + } + return false; + } + + @Override + public void resetConfig(String configStr) { + try { + Properties sampleProperties = ReSetConfigProcessorFactory.configStr2Properties(configStr); + + Integer samplingRate = sampleProperties.containsKey(PropertiesKey.SAMPLE_RATE.key) ? Integer.parseInt(""+sampleProperties.get(PropertiesKey.SAMPLE_RATE.key)) : null; + Boolean sampling = sampleProperties.containsKey(PropertiesKey.SAMPLE_ENABLE.key) ? Boolean.parseBoolean(""+sampleProperties.get(PropertiesKey.SAMPLE_ENABLE.key)) : null; + + Field samplingRateField = sampler.getClass().getDeclaredField("samplingRate"); + if(samplingRate != null){ + if(samplingRateField != null){ + samplingRateField.setAccessible(true); + Integer samplingRateOld = Integer.parseInt(samplingRateField.get(sampler)+""); + if(!samplingRate.equals(samplingRateOld) ){ + samplingRateResult = samplingRate; + samplingRateField.set(sampler, samplingRate); + } + }else{ + logger.warn("SamplingRateSampler class samplingRate field is null, return!"); + } + } + if(sampling != null){ + Field samplingField = sampler.getClass().getDeclaredField("sampling"); + if(samplingField != null){ + samplingField.setAccessible(true); + Boolean samplingOld = Boolean.parseBoolean(samplingField.get(sampler)+""); + if(!sampling.equals(samplingOld) ){ + samplingResult = sampling; + samplingField.set(sampler, sampling); + } + }else{ + logger.warn("SamplingRateSampler class sampling field is null, return!"); + } + } + } catch (Exception e) { + logger.error("resetConfig {}-{} error, configStr=[{}], e=[{}]!", PropertiesKey.SAMPLE_RATE.key, PropertiesKey.SAMPLE_ENABLE.key, configStr, e); + } + } + + private static Integer samplingRateResult; + private static Boolean samplingResult; + @Override + public void resetProperties(Properties properties){ + if(samplingRateResult != null){ + properties.put(PropertiesKey.SAMPLE_RATE.key, samplingRateResult); + } + if(samplingResult != null) { + properties.put(PropertiesKey.SAMPLE_ENABLE.key, samplingResult); + } + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactory.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactory.java index 7ce580920434..024836e044a5 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactory.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplerFactory.java @@ -16,19 +16,14 @@ package com.navercorp.pinpoint.profiler.sampler; +import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; import com.navercorp.pinpoint.bootstrap.sampler.Sampler; /** * @author emeroad */ public class SamplerFactory { - public Sampler createSampler(boolean sampling, int samplingRate) { - if (!sampling || samplingRate <= 0) { - return new FalseSampler(); - } - if (samplingRate == 1) { - return new TrueSampler(); - } - return new SamplingRateSampler(samplingRate); + public Sampler createSampler(boolean sampling, int samplingRate, ProfilerConfig profilerConfig) { + return new SamplingRateSampler(sampling, samplingRate, profilerConfig); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplingRateSampler.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplingRateSampler.java index 204665b08142..7b4603f845bd 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplingRateSampler.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/sampler/SamplingRateSampler.java @@ -16,8 +16,10 @@ package com.navercorp.pinpoint.profiler.sampler; +import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; import com.navercorp.pinpoint.bootstrap.sampler.Sampler; import com.navercorp.pinpoint.common.util.MathUtils; +import com.navercorp.pinpoint.profiler.monitor.processor.ReSetConfigProcessorFactory; import java.util.concurrent.atomic.AtomicInteger; @@ -28,27 +30,40 @@ public class SamplingRateSampler implements Sampler { private final AtomicInteger counter = new AtomicInteger(0); private final int samplingRate; + private final boolean sampling; + private final ProfilerConfig profilerConfig; - public SamplingRateSampler(int samplingRate) { - if (samplingRate <= 0) { - throw new IllegalArgumentException("Invalid samplingRate " + samplingRate); - } + public SamplingRateSampler(boolean sampling, int samplingRate, ProfilerConfig profilerConfig) { this.samplingRate = samplingRate; + this.sampling = sampling; + this.profilerConfig = profilerConfig; } - - @Override public boolean isSampling() { - int samplingCount = MathUtils.fastAbs(counter.getAndIncrement()); - int isSampling = samplingCount % samplingRate; - return isSampling == 0; + if(ReSetConfigProcessorFactory.isEnableCollect(profilerConfig)){ + if (!sampling || samplingRate <= 0) { + return false; + } + int samplingCount = MathUtils.fastAbs(counter.getAndIncrement()); + int isSampling = samplingCount % samplingRate; + return isSampling == 0; + }else{ + return false; + } + } + public int getSamplingRate(){ + return this.samplingRate; + } + public boolean getSampling(){ + return this.sampling; } @Override public String toString() { return "SamplingRateSampler{" + "counter=" + counter + + "sampling=" + sampling + "samplingRate=" + samplingRate + '}'; } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockApplicationContextFactory.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockApplicationContextFactory.java index 43922d0dac01..a944a07a3082 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockApplicationContextFactory.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/MockApplicationContextFactory.java @@ -39,7 +39,7 @@ public DefaultApplicationContext build(ProfilerConfig config, ModuleFactory modu Instrumentation instrumentation = Mockito.mock(Instrumentation.class); String mockAgent = "mockAgent"; String mockApplicationName = "mockApplicationName"; - AgentOption agentOption = new DefaultAgentOption(instrumentation, mockAgent, mockApplicationName, false, config, Collections.emptyList(), null); + AgentOption agentOption = new DefaultAgentOption(instrumentation, "mockLicence", mockAgent, mockApplicationName, false, config, Collections.emptyList(), null); return new DefaultApplicationContext(agentOption, moduleFactory); } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/graph/DependencyGraph.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/graph/DependencyGraph.java index 7e10ed894b65..05192f8cb000 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/graph/DependencyGraph.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/graph/DependencyGraph.java @@ -84,7 +84,7 @@ private DefaultApplicationContext newApplicationContext() { Instrumentation instrumentation = mock(Instrumentation.class); AgentOption agentOption = new DefaultAgentOption(instrumentation, - "mockAgent", "mockApplicationName", false, profilerConfig, Collections.emptyList(), + "mockLicence", "mockAgent", "mockApplicationName", false, profilerConfig, Collections.emptyList(), null); InterceptorRegistryBinder interceptorRegistryBinder = new TestInterceptorRegistryBinder(); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContextTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContextTest.java index 33b1bd42bcfc..f3b22aadcbea 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContextTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/context/module/DefaultApplicationContextTest.java @@ -89,7 +89,7 @@ private DefaultApplicationContext newApplicationContext() { // when(profilerConfig.getTransportModule()).thenReturn("GRPC"); Instrumentation instrumentation = mock(Instrumentation.class); - AgentOption agentOption = new DefaultAgentOption(instrumentation, "mockAgent", "mockApplicationName", false, + AgentOption agentOption = new DefaultAgentOption(instrumentation, "mockLicence", "mockAgent", "mockApplicationName", false, profilerConfig, Collections.emptyList(), null); InterceptorRegistryBinder interceptorRegistryBinder = new TestInterceptorRegistryBinder(); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SimpleSamplerTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SimpleSamplerTest.java index fee7ac99893a..f15a369370d5 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SimpleSamplerTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/sampler/SimpleSamplerTest.java @@ -33,13 +33,13 @@ public class SimpleSamplerTest { @Test public void test() { - SamplingRateSampler simpleSampler = new SamplingRateSampler(1); + SamplingRateSampler simpleSampler = new SamplingRateSampler(true,1,null); assertChoice(simpleSampler); assertChoice(simpleSampler); assertChoice(simpleSampler); assertChoice(simpleSampler); - SamplingRateSampler simpleSampler2 = new SamplingRateSampler(2); + SamplingRateSampler simpleSampler2 = new SamplingRateSampler(true,2,null); assertChoice(simpleSampler2); assertDrop(simpleSampler2); assertChoice(simpleSampler2); diff --git a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ClientFactoryUtils.java b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ClientFactoryUtils.java index 915e1ba3ad15..eafcc3d37f7c 100644 --- a/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ClientFactoryUtils.java +++ b/rpc/src/main/java/com/navercorp/pinpoint/rpc/util/ClientFactoryUtils.java @@ -36,7 +36,7 @@ public final class ClientFactoryUtils { public interface PinpointClientProvider { PinpointClient get(); - + PinpointClient get(String host, int port); String getAddressAsString(); } @@ -64,6 +64,16 @@ public String getAddressAsString() { public PinpointClient get() { return createPinpointClient(host, port, clientFactory); } + @Override + public PinpointClient get(String host, int port) { + PinpointClient pinpointClient = null; + try { + pinpointClient = clientFactory.connect(host, port); + } catch (Exception e) { + LOGGER.warn("tcp connect fail. remote:{}/{} try reconnect, retryCount:{}", host, port, "remoteConfig"); + } + return pinpointClient; + } } public static PinpointClient createPinpointClient(String host, int port, PinpointClientFactory clientFactory) {