Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OSPP]Add more observability in apollo config client #74

Merged
merged 15 commits into from
Oct 19, 2024
Merged
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,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,134 @@
/*
* 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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

private static final Logger logger = LoggerFactory.getLogger(ConfigMonitorInitializer.class);

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

public static void initialize() {
if (m_configUtil.isClientMonitorEnabled() && !hasInitialized) {
logger.info("Initializing ConfigMonitor...");
DefaultMetricsCollectorManager manager = initializeMetricsCollectorManager();
List<MetricsCollector> collectors = initializeCollectors(manager);
MetricsExporter metricsExporter = initializeMetricsExporter(collectors);
initializeConfigMonitor(collectors, metricsExporter);
hasInitialized = true;
logger.info("ConfigMonitor initialized successfully.");
}
Rawven marked this conversation as resolved.
Show resolved Hide resolved
}

private static DefaultMetricsCollectorManager initializeMetricsCollectorManager() {
return (DefaultMetricsCollectorManager) ApolloInjector.getInstance(
MetricsCollectorManager.class);
}
Rawven marked this conversation as resolved.
Show resolved Hide resolved

private static List<MetricsCollector> initializeCollectors(
DefaultMetricsCollectorManager manager) {
DefaultConfigManager configManager = (DefaultConfigManager) ApolloInjector.getInstance(
Rawven marked this conversation as resolved.
Show resolved Hide resolved
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);
}
Rawven marked this conversation as resolved.
Show resolved Hide resolved

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
Loading