Skip to content

Commit

Permalink
feat(client): Add more observability in apollo config client
Browse files Browse the repository at this point in the history
  • Loading branch information
Rawven committed Aug 1, 2024
1 parent 6b0d4c7 commit df5e94d
Show file tree
Hide file tree
Showing 65 changed files with 3,832 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@
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.monitor.internal.NullConfigMonitor;
import com.ctrip.framework.apollo.spi.ConfigFactory;
import com.ctrip.framework.apollo.spi.ConfigRegistry;
import com.ctrip.framework.apollo.util.ConfigUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Entry point for client config use
Expand All @@ -30,10 +36,30 @@
*/
public class ConfigService {
private static final ConfigService s_instance = new ConfigService();

private static final Logger log = LoggerFactory.getLogger(ConfigService.class);
private volatile ConfigMonitor m_configMonitor;
private volatile ConfigManager m_configManager;
private volatile ConfigRegistry m_configRegistry;

private static final ConfigUtil m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);

private ConfigMonitor getMonitor() {
getManager();
if (m_configMonitor == null) {
synchronized (this) {
if (m_configMonitor == null) {
if (m_configUtil.isClientMonitorEnabled()) {
m_configMonitor = ApolloInjector.getInstance(
ConfigMonitor.class);
}else {
log.warn("ConfigService.getMonitor is called but apollo.client.monitor.enabled is set to false, so return NullConfigMonitor");
m_configMonitor = new NullConfigMonitor();
}
}
}
}
return m_configMonitor;
}

private ConfigManager getManager() {
if (m_configManager == null) {
synchronized (this) {
Expand All @@ -42,7 +68,7 @@ private ConfigManager getManager() {
}
}
}

ConfigMonitorInitializer.initializeMonitorSystem();
return m_configManager;
}

Expand Down Expand Up @@ -81,6 +107,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,9 @@
*/
package com.ctrip.framework.apollo.internals;


import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CLIENT_CONFIGCHANGES;

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 +46,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 +115,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,8 @@
*/
package com.ctrip.framework.apollo.internals;

import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CONFIG_EXCEPTION;

import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.util.factory.PropertiesFactory;
import java.util.List;
Expand All @@ -41,7 +43,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,113 @@
/*
* 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 com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.core.utils.ClassLoaderUtil;
import com.ctrip.framework.apollo.monitor.api.ConfigMonitor;
import com.ctrip.framework.apollo.monitor.internal.DefaultConfigMonitor;
import com.ctrip.framework.apollo.monitor.internal.collector.MetricsCollector;
import com.ctrip.framework.apollo.monitor.internal.collector.MetricsCollectorManager;
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultApolloExceptionCollector;
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultApolloNamespaceCollector;
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultApolloRunningParamsCollector;
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultApolloThreadPoolCollector;
import com.ctrip.framework.apollo.monitor.internal.collector.internal.DefaultMetricsCollectorManager;
import com.ctrip.framework.apollo.monitor.internal.exporter.MetricsExporter;
import com.ctrip.framework.apollo.monitor.internal.exporter.MetricsExporterFactory;
import com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite;
import com.ctrip.framework.apollo.monitor.internal.tracer.MonitorMessageProducer;
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;

/**
* @author Rawven
*/
public class ConfigMonitorInitializer {

private static ConfigUtil m_configUtil = ApolloInjector.getInstance(ConfigUtil.class);
private static Boolean hasInitialized = false;

public static void initializeMonitorSystem() {
if (m_configUtil.isClientMonitorEnabled() && !hasInitialized) {
DefaultMetricsCollectorManager manager = initializeMetricsCollectorManager();
List<MetricsCollector> collectors = initializeCollectors(manager);
MetricsExporter metricsExporter = initializeMetricsExporter(collectors);
initializeConfigMonitor(collectors, metricsExporter);
hasInitialized = true;
}
}

private static DefaultMetricsCollectorManager initializeMetricsCollectorManager() {
return (DefaultMetricsCollectorManager) ApolloInjector.getInstance(MetricsCollectorManager.class);
}

private static List<MetricsCollector> initializeCollectors(DefaultMetricsCollectorManager manager) {
DefaultConfigManager configManager = (DefaultConfigManager) ApolloInjector.getInstance(ConfigManager.class);
DefaultApolloExceptionCollector exceptionCollector = new DefaultApolloExceptionCollector();
DefaultApolloThreadPoolCollector threadPoolCollector = new DefaultApolloThreadPoolCollector(
RemoteConfigRepository.m_executorService, AbstractConfig.m_executorService, AbstractConfigFile.m_executorService);
DefaultApolloNamespaceCollector namespaceCollector = new DefaultApolloNamespaceCollector(
configManager.m_configs, configManager.m_configLocks, configManager.m_configFiles, configManager.m_configFileLocks);
DefaultApolloRunningParamsCollector startupCollector = new DefaultApolloRunningParamsCollector(m_configUtil);

List<MetricsCollector> collectors = Lists.newArrayList(exceptionCollector, namespaceCollector, threadPoolCollector, startupCollector);
manager.setCollectors(collectors);
return collectors;
}

private static MetricsExporter initializeMetricsExporter(List<MetricsCollector> collectors) {
MetricsExporterFactory reporterFactory = ApolloInjector.getInstance(MetricsExporterFactory.class);
return reporterFactory.getMetricsReporter(collectors);
}

private static void initializeConfigMonitor(List<MetricsCollector> collectors, MetricsExporter metricsExporter) {
DefaultConfigMonitor defaultConfigMonitor = (DefaultConfigMonitor) ApolloInjector.getInstance(ConfigMonitor.class);
DefaultApolloExceptionCollector exceptionCollector = (DefaultApolloExceptionCollector) collectors.get(0);
DefaultApolloNamespaceCollector namespaceCollector = (DefaultApolloNamespaceCollector) collectors.get(1);
DefaultApolloThreadPoolCollector threadPoolCollector = (DefaultApolloThreadPoolCollector) collectors.get(2);
DefaultApolloRunningParamsCollector startupCollector = (DefaultApolloRunningParamsCollector) collectors.get(3);
defaultConfigMonitor.init(namespaceCollector, threadPoolCollector, exceptionCollector, startupCollector, metricsExporter);
}

public static MessageProducerComposite initializeMessageProducerComposite() {

// Prioritize loading user-defined producers from SPI
List<MessageProducer> producers = ServiceBootstrap.loadAllOrdered(MessageProducer.class);

// The producer that comes with the client
if (m_configUtil.isClientMonitorEnabled()) {
producers.add(new MonitorMessageProducer());
}

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

// default logic
if (producers.isEmpty()) {
producers.add(new NullMessageProducer());
}
return new MessageProducerComposite(producers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,42 @@
*/
package com.ctrip.framework.apollo.internals;

import com.ctrip.framework.apollo.core.ApolloClientSystemConsts;
import com.ctrip.framework.apollo.core.ServiceNameConsts;
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
import com.ctrip.framework.apollo.core.utils.DeprecatedPropertyNotifyUtil;
import com.ctrip.framework.foundation.Foundation;
import com.google.common.util.concurrent.RateLimiter;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

import org.slf4j.Logger;
import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CONFIG_EXCEPTION;
import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CONFIG_SERVICES;
import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_META_SERVICE;

import com.ctrip.framework.apollo.build.ApolloInjector;
import com.ctrip.framework.apollo.core.ApolloClientSystemConsts;
import com.ctrip.framework.apollo.core.ServiceNameConsts;
import com.ctrip.framework.apollo.core.dto.ServiceDTO;
import com.ctrip.framework.apollo.core.utils.ApolloThreadFactory;
import com.ctrip.framework.apollo.core.utils.DeferredLoggerFactory;
import com.ctrip.framework.apollo.core.utils.DeprecatedPropertyNotifyUtil;
import com.ctrip.framework.apollo.exceptions.ApolloConfigException;
import com.ctrip.framework.apollo.tracer.Tracer;
import com.ctrip.framework.apollo.tracer.spi.Transaction;
import com.ctrip.framework.apollo.util.ConfigUtil;
import com.ctrip.framework.apollo.util.ExceptionUtil;
import com.ctrip.framework.apollo.util.http.HttpClient;
import com.ctrip.framework.apollo.util.http.HttpRequest;
import com.ctrip.framework.apollo.util.http.HttpResponse;
import com.ctrip.framework.apollo.util.http.HttpClient;
import com.ctrip.framework.foundation.Foundation;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.escape.Escaper;
import com.google.common.net.UrlEscapers;
import com.google.common.util.concurrent.RateLimiter;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.slf4j.Logger;

public class ConfigServiceLocator {
private static final Logger logger = DeferredLoggerFactory.getLogger(ConfigServiceLocator.class);
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,8 @@
*/
package com.ctrip.framework.apollo.internals;

import static com.ctrip.framework.apollo.monitor.internal.tracer.MessageProducerComposite.APOLLO_CLIENT_CONFIGCHANGES;

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 +238,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
Loading

0 comments on commit df5e94d

Please sign in to comment.