Skip to content

Commit bd7fe56

Browse files
committed
feat(client): Add more observability in apollo config client
1 parent 6b0d4c7 commit bd7fe56

File tree

64 files changed

+3824
-95
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+3824
-95
lines changed

apollo-client/src/main/java/com/ctrip/framework/apollo/ConfigService.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import com.ctrip.framework.apollo.core.ConfigConsts;
2121
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
2222
import com.ctrip.framework.apollo.internals.ConfigManager;
23+
import com.ctrip.framework.apollo.internals.ConfigMonitorInitializer;
24+
import com.ctrip.framework.apollo.monitor.api.ConfigMonitor;
2325
import com.ctrip.framework.apollo.spi.ConfigFactory;
2426
import com.ctrip.framework.apollo.spi.ConfigRegistry;
2527

@@ -30,19 +32,31 @@
3032
*/
3133
public class ConfigService {
3234
private static final ConfigService s_instance = new ConfigService();
33-
35+
private volatile ConfigMonitor m_configMonitor;
3436
private volatile ConfigManager m_configManager;
3537
private volatile ConfigRegistry m_configRegistry;
36-
38+
39+
private ConfigMonitor getMonitor() {
40+
getManager();
41+
if (m_configMonitor == null) {
42+
synchronized (this) {
43+
if (m_configMonitor == null) {
44+
m_configMonitor = ApolloInjector.getInstance(ConfigMonitor.class);
45+
}
46+
}
47+
}
48+
return m_configMonitor;
49+
}
50+
3751
private ConfigManager getManager() {
3852
if (m_configManager == null) {
3953
synchronized (this) {
4054
if (m_configManager == null) {
4155
m_configManager = ApolloInjector.getInstance(ConfigManager.class);
56+
ConfigMonitorInitializer.initialize();
4257
}
4358
}
4459
}
45-
4660
return m_configManager;
4761
}
4862

@@ -81,6 +95,10 @@ public static ConfigFile getConfigFile(String namespace, ConfigFileFormat config
8195
return s_instance.getManager().getConfigFile(namespace, configFileFormat);
8296
}
8397

98+
public static ConfigMonitor getConfigMonitor(){
99+
return s_instance.getMonitor();
100+
}
101+
84102
static void setConfig(Config config) {
85103
setConfig(ConfigConsts.NAMESPACE_APPLICATION, config);
86104
}

apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
public abstract class AbstractConfig implements Config {
5454
private static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class);
5555

56-
private static final ExecutorService m_executorService;
56+
protected static final ExecutorService m_executorService;
5757

5858
private final List<ConfigChangeListener> m_listeners = Lists.newCopyOnWriteArrayList();
5959
private final Map<ConfigChangeListener, Set<String>> m_interestedKeys = Maps.newConcurrentMap();

apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigFile.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
*/
1717
package com.ctrip.framework.apollo.internals;
1818

19+
20+
import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CLIENT_CONFIGCHANGES;
21+
1922
import com.ctrip.framework.apollo.build.ApolloInjector;
2023
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
2124
import com.ctrip.framework.apollo.enums.ConfigSourceType;
@@ -43,7 +46,7 @@
4346
*/
4447
public abstract class AbstractConfigFile implements ConfigFile, RepositoryChangeListener {
4548
private static final Logger logger = DeferredLoggerFactory.getLogger(AbstractConfigFile.class);
46-
private static ExecutorService m_executorService;
49+
protected static ExecutorService m_executorService;
4750
protected final ConfigRepository m_configRepository;
4851
protected final String m_namespace;
4952
protected final AtomicReference<Properties> m_configProperties;
@@ -112,7 +115,7 @@ public synchronized void onRepositoryChange(String namespace, Properties newProp
112115

113116
this.fireConfigChange(new ConfigFileChangeEvent(m_namespace, oldValue, newValue, changeType));
114117

115-
Tracer.logEvent("Apollo.Client.ConfigChanges", m_namespace);
118+
Tracer.logEvent(APOLLO_CLIENT_CONFIGCHANGES, m_namespace);
116119
}
117120

118121
@Override

apollo-client/src/main/java/com/ctrip/framework/apollo/internals/AbstractConfigRepository.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
*/
1717
package com.ctrip.framework.apollo.internals;
1818

19+
import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CONFIG_EXCEPTION;
20+
1921
import com.ctrip.framework.apollo.build.ApolloInjector;
2022
import com.ctrip.framework.apollo.util.factory.PropertiesFactory;
2123
import java.util.List;
@@ -41,7 +43,7 @@ protected boolean trySync() {
4143
sync();
4244
return true;
4345
} catch (Throwable ex) {
44-
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
46+
Tracer.logEvent(APOLLO_CONFIG_EXCEPTION, ExceptionUtil.getDetailMessage(ex));
4547
logger
4648
.warn("Sync config failed, will retry. Repository {}, reason: {}", this.getClass(), ExceptionUtil
4749
.getDetailMessage(ex));
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright 2022 Apollo Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*/
17+
package com.ctrip.framework.apollo.internals;
18+
19+
import com.ctrip.framework.apollo.build.ApolloInjector;
20+
import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil;
21+
import com.ctrip.framework.apollo.monitor.api.ConfigMonitor;
22+
import com.ctrip.framework.apollo.monitor.internal.DefaultConfigMonitor;
23+
import com.ctrip.framework.apollo.monitor.internal.collector.MetricsCollector;
24+
import com.ctrip.framework.apollo.monitor.internal.collector.MetricsCollectorManager;
25+
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultApolloExceptionCollector;
26+
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultApolloNamespaceCollector;
27+
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultApolloRunningParamsCollector;
28+
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultApolloThreadPoolCollector;
29+
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultMetricsCollectorManager;
30+
import com.ctrip.framework.apollo.monitor.internal.exporter.MetricsExporter;
31+
import com.ctrip.framework.apollo.monitor.internal.exporter.MetricsExporterFactory;
32+
import com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite;
33+
import com.ctrip.framework.apollo.monitor.internal.tracer.MonitorMessageProducer;
34+
import com.ctrip.framework.apollo.tracer.internals.NullMessageProducer;
35+
import com.ctrip.framework.apollo.tracer.internals.cat.CatMessageProducer;
36+
import com.ctrip.framework.apollo.tracer.internals.cat.CatNames;
37+
import com.ctrip.framework.apollo.tracer.spi.MessageProducer;
38+
import com.ctrip.framework.apollo.util.ConfigUtil;
39+
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
40+
import com.google.common.collect.Lists;
41+
import java.util.List;
42+
import org.slf4j.Logger;
43+
import org.slf4j.LoggerFactory;
44+
45+
/**
46+
* @author Rawven
47+
*/
48+
public class ConfigMonitorInitializer {
49+
50+
private static final Logger logger = LoggerFactory.getLogger(ConfigMonitorInitializer.class);
51+
52+
private static ConfigUtil m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);
53+
private static Boolean hasInitialized = false;
54+
55+
public static void initialize() {
56+
if (m_configUtil.isClientMonitorEnabled() && !hasInitialized) {
57+
logger.info("Initializing ConfigMonitor...");
58+
DefaultMetricsCollectorManager manager = initializeMetricsCollectorManager();
59+
List<MetricsCollector> collectors = initializeCollectors(manager);
60+
MetricsExporter metricsExporter = initializeMetricsExporter(collectors);
61+
initializeConfigMonitor(collectors, metricsExporter);
62+
hasInitialized = true;
63+
logger.info("ConfigMonitor initialized successfully.");
64+
}
65+
}
66+
67+
private static DefaultMetricsCollectorManager initializeMetricsCollectorManager() {
68+
return (DefaultMetricsCollectorManager) ApolloInjector.getInstance(
69+
MetricsCollectorManager.class);
70+
}
71+
72+
private static List<MetricsCollector> initializeCollectors(
73+
DefaultMetricsCollectorManager manager) {
74+
DefaultConfigManager configManager = (DefaultConfigManager) ApolloInjector.getInstance(
75+
ConfigManager.class);
76+
DefaultApolloExceptionCollector exceptionCollector = new DefaultApolloExceptionCollector();
77+
DefaultApolloThreadPoolCollector threadPoolCollector = new DefaultApolloThreadPoolCollector(
78+
RemoteConfigRepository.m_executorService, AbstractConfig.m_executorService,
79+
AbstractConfigFile.m_executorService);
80+
DefaultApolloNamespaceCollector namespaceCollector = new DefaultApolloNamespaceCollector(
81+
configManager.m_configs, configManager.m_configLocks, configManager.m_configFiles,
82+
configManager.m_configFileLocks);
83+
DefaultApolloRunningParamsCollector startupCollector = new DefaultApolloRunningParamsCollector(
84+
m_configUtil);
85+
86+
List<MetricsCollector> collectors = Lists.newArrayList(exceptionCollector, namespaceCollector,
87+
threadPoolCollector, startupCollector);
88+
manager.setCollectors(collectors);
89+
return collectors;
90+
}
91+
92+
private static MetricsExporter initializeMetricsExporter(List<MetricsCollector> collectors) {
93+
MetricsExporterFactory reporterFactory = ApolloInjector.getInstance(
94+
MetricsExporterFactory.class);
95+
return reporterFactory.getMetricsReporter(collectors);
96+
}
97+
98+
private static void initializeConfigMonitor(List<MetricsCollector> collectors,
99+
MetricsExporter metricsExporter) {
100+
DefaultConfigMonitor defaultConfigMonitor = (DefaultConfigMonitor) ApolloInjector.getInstance(
101+
ConfigMonitor.class);
102+
DefaultApolloExceptionCollector exceptionCollector = (DefaultApolloExceptionCollector) collectors.get(
103+
0);
104+
DefaultApolloNamespaceCollector namespaceCollector = (DefaultApolloNamespaceCollector) collectors.get(
105+
1);
106+
DefaultApolloThreadPoolCollector threadPoolCollector = (DefaultApolloThreadPoolCollector) collectors.get(
107+
2);
108+
DefaultApolloRunningParamsCollector startupCollector = (DefaultApolloRunningParamsCollector) collectors.get(
109+
3);
110+
defaultConfigMonitor.init(namespaceCollector, threadPoolCollector, exceptionCollector,
111+
startupCollector, metricsExporter);
112+
}
113+
114+
public static MessageProducerComposite initializeMessageProducerComposite() {
115+
116+
// Prioritize loading user-defined producers from SPI
117+
List<MessageProducer> producers = ServiceBootstrap.loadAllOrdered(MessageProducer.class);
118+
119+
// The producer that comes with the client
120+
if (m_configUtil.isClientMonitorEnabled()) {
121+
producers.add(new MonitorMessageProducer());
122+
}
123+
124+
if (ClassLoaderUtil.isClassPresent(CatNames.CAT_CLASS)) {
125+
producers.add(new CatMessageProducer());
126+
}
127+
128+
// default logic
129+
if (producers.isEmpty()) {
130+
producers.add(new NullMessageProducer());
131+
}
132+
return new MessageProducerComposite(producers);
133+
}
134+
}

apollo-client/src/main/java/com/ctrip/framework/apollo/internals/ConfigServiceLocator.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,40 +16,42 @@
1616
*/
1717
package com.ctrip.framework.apollo.internals;
1818

19-
import com.ctrip.framework.apollo.core.ApolloClientSystemConsts;
20-
import com.ctrip.framework.apollo.core.ServiceNameConsts;
21-
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
22-
import com.ctrip.framework.apollo.core.utils.DeprecatedPropertyNotifyUtil;
23-
import com.ctrip.framework.foundation.Foundation;
24-
import com.google.common.util.concurrent.RateLimiter;
25-
import java.lang.reflect.Type;
26-
import java.util.List;
27-
import java.util.Map;
28-
import java.util.concurrent.Executors;
29-
import java.util.concurrent.ScheduledExecutorService;
30-
import java.util.concurrent.atomic.AtomicBoolean;
31-
import java.util.concurrent.atomic.AtomicReference;
32-
33-
import org.slf4j.Logger;
19+
import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CONFIG_EXCEPTION;
20+
import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CONFIG_SERVICES;
21+
import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_META_SERVICE;
3422

3523
import com.ctrip.framework.apollo.build.ApolloInjector;
24+
import com.ctrip.framework.apollo.core.ApolloClientSystemConsts;
25+
import com.ctrip.framework.apollo.core.ServiceNameConsts;
3626
import com.ctrip.framework.apollo.core.dto.ServiceDTO;
3727
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
28+
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
29+
import com.ctrip.framework.apollo.core.utils.DeprecatedPropertyNotifyUtil;
3830
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
3931
import com.ctrip.framework.apollo.tracer.Tracer;
4032
import com.ctrip.framework.apollo.tracer.spi.Transaction;
4133
import com.ctrip.framework.apollo.util.ConfigUtil;
4234
import com.ctrip.framework.apollo.util.ExceptionUtil;
35+
import com.ctrip.framework.apollo.util.http.HttpClient;
4336
import com.ctrip.framework.apollo.util.http.HttpRequest;
4437
import com.ctrip.framework.apollo.util.http.HttpResponse;
45-
import com.ctrip.framework.apollo.util.http.HttpClient;
38+
import com.ctrip.framework.foundation.Foundation;
4639
import com.google.common.base.Joiner;
4740
import com.google.common.base.Strings;
4841
import com.google.common.collect.Lists;
4942
import com.google.common.collect.Maps;
5043
import com.google.common.escape.Escaper;
5144
import com.google.common.net.UrlEscapers;
45+
import com.google.common.util.concurrent.RateLimiter;
5246
import com.google.gson.reflect.TypeToken;
47+
import java.lang.reflect.Type;
48+
import java.util.List;
49+
import java.util.Map;
50+
import java.util.concurrent.Executors;
51+
import java.util.concurrent.ScheduledExecutorService;
52+
import java.util.concurrent.atomic.AtomicBoolean;
53+
import java.util.concurrent.atomic.AtomicReference;
54+
import org.slf4j.Logger;
5355

5456
public class ConfigServiceLocator {
5557
private static final Logger logger = DeferredLoggerFactory.getLogger(ConfigServiceLocator.class);
@@ -218,7 +220,7 @@ private void schedulePeriodicRefresh() {
218220
@Override
219221
public void run() {
220222
logger.debug("refresh config services");
221-
Tracer.logEvent("Apollo.MetaService", "periodicRefresh");
223+
Tracer.logEvent(APOLLO_META_SERVICE, "periodicRefresh");
222224
tryUpdateConfigServices();
223225
}
224226
}, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(),
@@ -258,7 +260,7 @@ private synchronized void updateConfigServices() {
258260
setConfigServices(services);
259261
return;
260262
} catch (Throwable ex) {
261-
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
263+
Tracer.logEvent(APOLLO_CONFIG_EXCEPTION, ExceptionUtil.getDetailMessage(ex));
262264
transaction.setStatus(ex);
263265
exception = ex;
264266
} finally {
@@ -302,6 +304,6 @@ private void logConfigServices(List<ServiceDTO> serviceDtos) {
302304
}
303305

304306
private void logConfigService(String serviceUrl) {
305-
Tracer.logEvent("Apollo.Config.Services", serviceUrl);
307+
Tracer.logEvent(APOLLO_CONFIG_SERVICES, serviceUrl);
306308
}
307309
}

apollo-client/src/main/java/com/ctrip/framework/apollo/internals/DefaultConfig.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
*/
1717
package com.ctrip.framework.apollo.internals;
1818

19+
import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CLIENT_CONFIGCHANGES;
20+
1921
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
2022
import com.ctrip.framework.apollo.enums.ConfigSourceType;
2123
import com.google.common.collect.Maps;
@@ -236,7 +238,7 @@ public synchronized void onRepositoryChange(String namespace, Properties newProp
236238

237239
this.fireConfigChange(m_namespace, actualChanges);
238240

239-
Tracer.logEvent("Apollo.Client.ConfigChanges", m_namespace);
241+
Tracer.logEvent(APOLLO_CLIENT_CONFIGCHANGES, m_namespace);
240242
}
241243

242244
private void updateConfig(Properties newConfigProperties, ConfigSourceType sourceType) {

0 commit comments

Comments
 (0)