Skip to content

Commit

Permalink
[OSPP]Add more observability in apollo config client (#74)
Browse files Browse the repository at this point in the history
* feat(client): Add more observability in apollo config client

* feat(client): add unit test

* refactor: rollback meaningless change

* docs: add CHANGES.md
  • Loading branch information
Rawven authored Oct 19, 2024
1 parent 5fbfd0c commit e43ddf5
Show file tree
Hide file tree
Showing 94 changed files with 5,295 additions and 34 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Apollo Java 2.4.0
------------------
* [Fix the Cannot enhance @Configuration bean definition issue](https://github.com/apolloconfig/apollo-java/pull/82)
* [Feature openapi query namespace support not fill item](https://github.com/apolloconfig/apollo-java/pull/83)
* [Add more observability in apollo config client](https://github.com/apolloconfig/apollo-java/pull/74)

------------------
All issues and pull requests are [here](https://github.com/apolloconfig/apollo-java/milestone/4?closed=1)
11 changes: 11 additions & 0 deletions apollo-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@
<artifactId>mockserver-netty</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.noconnor</groupId>
<artifactId>junitperf</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- end of test -->
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.internals.ConfigManager;
import com.ctrip.framework.apollo.internals.ConfigMonitorInitializer;
import com.ctrip.framework.apollo.monitor.api.ConfigMonitor;
import com.ctrip.framework.apollo.spi.ConfigFactory;
import com.ctrip.framework.apollo.spi.ConfigRegistry;

Expand All @@ -30,19 +32,31 @@
*/
public class ConfigService {
private static final ConfigService s_instance = new ConfigService();

private volatile ConfigMonitor m_configMonitor;
private volatile ConfigManager m_configManager;
private volatile ConfigRegistry m_configRegistry;


private ConfigMonitor getMonitor() {
getManager();
if (m_configMonitor == null) {
synchronized (this) {
if (m_configMonitor == null) {
m_configMonitor = ApolloInjector.getInstance(ConfigMonitor.class);
}
}
}
return m_configMonitor;
}

private ConfigManager getManager() {
if (m_configManager == null) {
synchronized (this) {
if (m_configManager == null) {
m_configManager = ApolloInjector.getInstance(ConfigManager.class);
ConfigMonitorInitializer.initialize();
}
}
}

return m_configManager;
}

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

public static ConfigMonitor getConfigMonitor(){
return s_instance.getMonitor();
}

static void setConfig(Config config) {
setConfig(ConfigConsts.NAMESPACE_APPLICATION, config);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
public abstract class AbstractConfig implements Config {
private static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class);

private static final ExecutorService m_executorService;
protected static final ExecutorService m_executorService;

private final List<ConfigChangeListener> m_listeners = Lists.newCopyOnWriteArrayList();
private final Map<ConfigChangeListener, Set<String>> m_interestedKeys = Maps.newConcurrentMap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package com.ctrip.framework.apollo.internals;


import static com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorConstant.*;
import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
Expand Down Expand Up @@ -43,7 +45,7 @@
*/
public abstract class AbstractConfigFile implements ConfigFile, RepositoryChangeListener {
private static final Logger logger = DeferredLoggerFactory.getLogger(AbstractConfigFile.class);
private static ExecutorService m_executorService;
protected static ExecutorService m_executorService;
protected final ConfigRepository m_configRepository;
protected final String m_namespace;
protected final AtomicReference<Properties> m_configProperties;
Expand Down Expand Up @@ -112,7 +114,7 @@ public synchronized void onRepositoryChange(String namespace, Properties newProp

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

Tracer.logEvent("Apollo.Client.ConfigChanges", m_namespace);
Tracer.logEvent(APOLLO_CLIENT_CONFIGCHANGES, m_namespace);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.ctrip.framework.apollo.internals;

import static com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorConstant.*;
import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.util.factory.PropertiesFactory;
import java.util.List;
Expand All @@ -41,7 +42,7 @@ protected boolean trySync() {
sync();
return true;
} catch (Throwable ex) {
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
Tracer.logEvent(APOLLO_CONFIG_EXCEPTION, ExceptionUtil.getDetailMessage(ex));
logger
.warn("Sync config failed, will retry. Repository {}, reason: {}", this.getClass(), ExceptionUtil
.getDetailMessage(ex));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Copyright 2022 Apollo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.ctrip.framework.apollo.internals;

import static com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorConstant.MBEAN_NAME;

import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil;
import com.ctrip.framework.apollo.monitor.internal.exporter.AbstractApolloClientMetricsExporter;
import com.ctrip.framework.apollo.monitor.internal.exporter.ApolloClientMetricsExporter;
import com.ctrip.framework.apollo.monitor.internal.jmx.ApolloClientJmxMBeanRegister;
import com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorContext;
import com.ctrip.framework.apollo.monitor.internal.listener.impl.DefaultApolloClientBootstrapArgsApi;
import com.ctrip.framework.apollo.monitor.internal.listener.impl.DefaultApolloClientExceptionApi;
import com.ctrip.framework.apollo.monitor.internal.listener.impl.DefaultApolloClientNamespaceApi;
import com.ctrip.framework.apollo.monitor.internal.listener.impl.DefaultApolloClientThreadPoolApi;
import com.ctrip.framework.apollo.monitor.internal.exporter.ApolloClientMetricsExporterFactory;
import com.ctrip.framework.apollo.monitor.internal.tracer.ApolloClientMonitorMessageProducer;
import com.ctrip.framework.apollo.monitor.internal.tracer.ApolloClientMessageProducerComposite;
import com.ctrip.framework.apollo.tracer.internals.NullMessageProducer;
import com.ctrip.framework.apollo.tracer.internals.cat.CatMessageProducer;
import com.ctrip.framework.apollo.tracer.internals.cat.CatNames;
import com.ctrip.framework.apollo.tracer.spi.MessageProducer;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
import com.google.common.collect.Lists;
import java.util.List;

/**
* ConfigMonitorInitializer initializes the Apollo Config Monitor.
*/
public class ConfigMonitorInitializer {

private static final ApolloClientMonitorContext MONITOR_CONTEXT = ApolloInjector.getInstance(
ApolloClientMonitorContext.class);
protected static volatile boolean hasInitialized = false;
private static ConfigUtil m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);

public static void initialize() {
if (m_configUtil.isClientMonitorEnabled() && !hasInitialized) {
synchronized (ConfigMonitorInitializer.class) {
if (!hasInitialized) {
doInit();
hasInitialized = true;
}
}
}
}

private static void doInit() {
initializeMetricsEventListener();
initializeMetricsExporter();
initializeJmxMonitoring();
}


private static void initializeJmxMonitoring() {
if (m_configUtil.isClientMonitorJmxEnabled()) {
MONITOR_CONTEXT.getApolloClientMonitorEventListeners().forEach(metricsListener ->
ApolloClientJmxMBeanRegister.register(
MBEAN_NAME + metricsListener.getName(), metricsListener)
);
}
}

private static void initializeMetricsEventListener() {
ConfigManager configManager = ApolloInjector.getInstance(
ConfigManager.class);
DefaultApolloClientBootstrapArgsApi defaultApolloClientBootstrapArgsApi = new DefaultApolloClientBootstrapArgsApi(
m_configUtil);
DefaultApolloClientExceptionApi defaultApolloClientExceptionApi = new DefaultApolloClientExceptionApi(m_configUtil);
DefaultApolloClientNamespaceApi defaultApolloClientNamespaceApi = new DefaultApolloClientNamespaceApi(
configManager);
DefaultApolloClientThreadPoolApi defaultApolloClientThreadPoolApi = new DefaultApolloClientThreadPoolApi(
RemoteConfigRepository.m_executorService,
AbstractConfig.m_executorService, AbstractConfigFile.m_executorService,
AbstractApolloClientMetricsExporter.m_executorService);

MONITOR_CONTEXT.setApolloClientBootstrapArgsMonitorApi(defaultApolloClientBootstrapArgsApi);
MONITOR_CONTEXT.setApolloClientExceptionMonitorApi(defaultApolloClientExceptionApi);
MONITOR_CONTEXT.setApolloClientNamespaceMonitorApi(defaultApolloClientNamespaceApi);
MONITOR_CONTEXT.setApolloClientThreadPoolMonitorApi(defaultApolloClientThreadPoolApi);
MONITOR_CONTEXT.setApolloClientMonitorEventListeners(
Lists.newArrayList(defaultApolloClientBootstrapArgsApi,
defaultApolloClientNamespaceApi, defaultApolloClientThreadPoolApi,
defaultApolloClientExceptionApi));
}

private static void initializeMetricsExporter(
) {
ApolloClientMetricsExporterFactory exporterFactory = ApolloInjector.getInstance(
ApolloClientMetricsExporterFactory.class);
ApolloClientMetricsExporter metricsReporter = exporterFactory.getMetricsReporter(
MONITOR_CONTEXT.getApolloClientMonitorEventListeners());
if (metricsReporter != null) {
MONITOR_CONTEXT.setApolloClientMetricsExporter(metricsReporter);
}
}

public static ApolloClientMessageProducerComposite initializeMessageProducerComposite() {
List<MessageProducer> producers = ServiceBootstrap.loadAllOrdered(MessageProducer.class);

if (m_configUtil.isClientMonitorEnabled()) {
producers.add(new ApolloClientMonitorMessageProducer());
}

if (ClassLoaderUtil.isClassPresent(CatNames.CAT_CLASS)) {
producers.add(new CatMessageProducer());
}

if (producers.isEmpty()) {
producers.add(new NullMessageProducer());
}

return new ApolloClientMessageProducerComposite(producers);
}

// for test only
protected static void reset() {
hasInitialized = false;
m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package com.ctrip.framework.apollo.internals;

import static com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorConstant.*;

import com.ctrip.framework.apollo.core.ApolloClientSystemConsts;
import com.ctrip.framework.apollo.core.ServiceNameConsts;
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
Expand Down Expand Up @@ -218,7 +220,7 @@ private void schedulePeriodicRefresh() {
@Override
public void run() {
logger.debug("refresh config services");
Tracer.logEvent("Apollo.MetaService", "periodicRefresh");
Tracer.logEvent(APOLLO_META_SERVICE, "periodicRefresh");
tryUpdateConfigServices();
}
}, m_configUtil.getRefreshInterval(), m_configUtil.getRefreshInterval(),
Expand Down Expand Up @@ -258,7 +260,7 @@ private synchronized void updateConfigServices() {
setConfigServices(services);
return;
} catch (Throwable ex) {
Tracer.logEvent("ApolloConfigException", ExceptionUtil.getDetailMessage(ex));
Tracer.logEvent(APOLLO_CONFIG_EXCEPTION, ExceptionUtil.getDetailMessage(ex));
transaction.setStatus(ex);
exception = ex;
} finally {
Expand Down Expand Up @@ -302,6 +304,6 @@ private void logConfigServices(List<ServiceDTO> serviceDtos) {
}

private void logConfigService(String serviceUrl) {
Tracer.logEvent("Apollo.Config.Services", serviceUrl);
Tracer.logEvent(APOLLO_CONFIG_SERVICES, serviceUrl);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.ctrip.framework.apollo.internals;

import static com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorConstant.*;
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import com.google.common.collect.Maps;
Expand Down Expand Up @@ -236,7 +237,7 @@ public synchronized void onRepositoryChange(String namespace, Properties newProp

this.fireConfigChange(m_namespace, actualChanges);

Tracer.logEvent("Apollo.Client.ConfigChanges", m_namespace);
Tracer.logEvent(APOLLO_CLIENT_CONFIGCHANGES, m_namespace);
}

private void updateConfig(Properties newConfigProperties, ConfigSourceType sourceType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,18 @@
*/
package com.ctrip.framework.apollo.internals;

import java.util.Map;
import static com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorConstant.APOLLO_CLIENT_NAMESPACE_USAGE;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigFile;
import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.enums.ConfigSourceType;
import com.ctrip.framework.apollo.spi.ConfigFactory;
import com.ctrip.framework.apollo.spi.ConfigFactoryManager;
import com.ctrip.framework.apollo.tracer.Tracer;
import com.google.common.collect.Maps;
import java.util.Map;

/**
* @author Jason Song(song_s@ctrip.com)
Expand All @@ -44,7 +47,7 @@ public DefaultConfigManager() {
@Override
public Config getConfig(String namespace) {
Config config = m_configs.get(namespace);

if (config == null) {
Object lock = m_configLocks.computeIfAbsent(namespace, key -> new Object());
synchronized (lock) {
Expand All @@ -58,6 +61,9 @@ public Config getConfig(String namespace) {
}
}
}
if (!ConfigSourceType.NONE.equals(config.getSourceType())) {
Tracer.logMetricsForCount(APOLLO_CLIENT_NAMESPACE_USAGE + ":" + namespace);
}

return config;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
package com.ctrip.framework.apollo.internals;

import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.monitor.api.ConfigMonitor;
import com.ctrip.framework.apollo.monitor.internal.DefaultConfigMonitor;
import com.ctrip.framework.apollo.monitor.internal.exporter.impl.DefaultApolloClientMetricsExporterFactory;
import com.ctrip.framework.apollo.monitor.internal.ApolloClientMonitorContext;
import com.ctrip.framework.apollo.monitor.internal.exporter.ApolloClientMetricsExporterFactory;
import com.ctrip.framework.apollo.spi.ApolloInjectorCustomizer;
import com.ctrip.framework.apollo.spi.ConfigFactory;
import com.ctrip.framework.apollo.spi.ConfigFactoryManager;
Expand All @@ -30,7 +35,6 @@
import com.ctrip.framework.apollo.util.factory.PropertiesFactory;
import com.ctrip.framework.apollo.util.http.DefaultHttpClient;
import com.ctrip.framework.apollo.util.http.HttpClient;

import com.ctrip.framework.apollo.util.yaml.YamlParser;
import com.ctrip.framework.foundation.internals.ServiceBootstrap;
import com.google.inject.AbstractModule;
Expand Down Expand Up @@ -105,6 +109,9 @@ protected void configure() {
bind(RemoteConfigLongPollService.class).in(Singleton.class);
bind(YamlParser.class).in(Singleton.class);
bind(PropertiesFactory.class).to(DefaultPropertiesFactory.class).in(Singleton.class);
bind(ConfigMonitor.class).to(DefaultConfigMonitor.class).in(Singleton.class);
bind(ApolloClientMonitorContext.class).in(Singleton.class);
bind(ApolloClientMetricsExporterFactory.class).to(DefaultApolloClientMetricsExporterFactory.class).in(Singleton.class);
}
}
}
Loading

0 comments on commit e43ddf5

Please sign in to comment.