From bf5be73d2e8b72760f1d9170e8f97463fce28b09 Mon Sep 17 00:00:00 2001 From: jzw Date: Mon, 10 Jan 2022 15:26:44 +0800 Subject: [PATCH] fix metric log bug (#181) * fix metric-log bug --- .gitignore | 1 + .../log4j2/api/AgentLoggerFactory.java | 16 ++++-- .../metrics/AgentScheduledReporter.java | 2 +- .../plugin/api/config/IPluginConfig.java | 1 - .../easeagent/report/OutputChange.java | 22 ++++++++ .../easeagent/report/OutputProperties.java | 19 +++++++ .../easeagent/report/metric/KeySender.java | 20 +++++-- .../easeagent/report/metric/MetricProps.java | 39 +++++++------- .../report/metric/MetricReporterImpl.java | 52 ++++++++++++++++--- .../megaease/easeagent/report/util/Utils.java | 19 +++++++ 10 files changed, 155 insertions(+), 36 deletions(-) create mode 100644 report/src/main/java/com/megaease/easeagent/report/OutputChange.java diff --git a/.gitignore b/.gitignore index 3563f8295..106e735c7 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ dependency-reduced-pom.xml *.swp **/*.versionsBackup +.patch .classpath .factorypath .project diff --git a/log4j2/log4j2-api/src/main/java/com/megaease/easeagent/log4j2/api/AgentLoggerFactory.java b/log4j2/log4j2-api/src/main/java/com/megaease/easeagent/log4j2/api/AgentLoggerFactory.java index d3e306340..47cdeab17 100644 --- a/log4j2/log4j2-api/src/main/java/com/megaease/easeagent/log4j2/api/AgentLoggerFactory.java +++ b/log4j2/log4j2-api/src/main/java/com/megaease/easeagent/log4j2/api/AgentLoggerFactory.java @@ -38,7 +38,9 @@ public class AgentLoggerFactory { private final Function loggerSupplier; private final Mdc mdc; - private AgentLoggerFactory(@Nonnull ClassLoader classLoader, @Nonnull Object factory, @Nonnull Method method, @Nonnull Function loggerSupplier, @Nonnull Mdc mdc) { + private AgentLoggerFactory(@Nonnull ClassLoader classLoader, + @Nonnull Object factory, @Nonnull Method method, + @Nonnull Function loggerSupplier, @Nonnull Mdc mdc) { this.classLoader = classLoader; this.factory = factory; this.method = method; @@ -47,7 +49,9 @@ private AgentLoggerFactory(@Nonnull ClassLoader classLoader, @Nonnull Object fac this.agentLogger = this.getLogger(AgentLoggerFactory.class.getName()); } - public static Builder builder(ClassloaderSupplier classLoaderSupplier, Function loggerSupplier, Class tClass) { + public static Builder builder(ClassloaderSupplier classLoaderSupplier, + Function loggerSupplier, + Class tClass) { ClassLoader classLoader = Objects.requireNonNull(classLoaderSupplier.get(), "classLoader must not be null."); return new Builder<>(classLoader, loggerSupplier, tClass); } @@ -55,7 +59,8 @@ public static Builder builder(ClassloaderSupplier cla public AgentLoggerFactory newFactory(Function loggerSupplier, Class tClass) { try { return new Builder(classLoader, loggerSupplier, tClass).build(); - } catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException | InstantiationException | InvocationTargetException | IllegalAccessException e) { + } catch (ClassNotFoundException | NoSuchMethodException + | NoSuchFieldException | InstantiationException | InvocationTargetException | IllegalAccessException e) { agentLogger.error("new factory fail: {}", e); } return null; @@ -92,7 +97,9 @@ public Builder(@Nonnull ClassLoader classLoader, @Nonnull Function lo this.tClass = tClass; } - public AgentLoggerFactory build() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { + public AgentLoggerFactory build() throws ClassNotFoundException, NoSuchMethodException, + IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { + ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(classLoader); @@ -123,5 +130,4 @@ private Mdc buildMdc() throws ClassNotFoundException, NoSuchFieldException, Ille return new Mdc(put, remove, get); } } - } diff --git a/metrics/src/main/java/com/megaease/easeagent/metrics/AgentScheduledReporter.java b/metrics/src/main/java/com/megaease/easeagent/metrics/AgentScheduledReporter.java index 771b24177..1428f0bf6 100644 --- a/metrics/src/main/java/com/megaease/easeagent/metrics/AgentScheduledReporter.java +++ b/metrics/src/main/java/com/megaease/easeagent/metrics/AgentScheduledReporter.java @@ -68,7 +68,7 @@ public static Builder forRegistry(MetricRegistry registry) { @SuppressWarnings("rawtypes") public void report(SortedMap gauges, SortedMap counters, SortedMap histograms, SortedMap meters, SortedMap timers) { Boolean e = this.enabled.get(); - if (e != null && e.booleanValue()) { + if (e != null && !e.booleanValue()) { return; } diff --git a/plugin-api/src/main/java/com/megaease/easeagent/plugin/api/config/IPluginConfig.java b/plugin-api/src/main/java/com/megaease/easeagent/plugin/api/config/IPluginConfig.java index 1a27493bb..cc020863b 100644 --- a/plugin-api/src/main/java/com/megaease/easeagent/plugin/api/config/IPluginConfig.java +++ b/plugin-api/src/main/java/com/megaease/easeagent/plugin/api/config/IPluginConfig.java @@ -66,5 +66,4 @@ default Boolean getBoolean(String property, Boolean defaultValue) { Set keySet(); void addChangeListener(PluginConfigChangeListener listener); - } diff --git a/report/src/main/java/com/megaease/easeagent/report/OutputChange.java b/report/src/main/java/com/megaease/easeagent/report/OutputChange.java new file mode 100644 index 000000000..27236f9c8 --- /dev/null +++ b/report/src/main/java/com/megaease/easeagent/report/OutputChange.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021, MegaEase + * All rights reserved. + * + * 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.megaease.easeagent.report; + +public interface OutputChange { + void onOutPutChange(OutputProperties outputProperties); +} diff --git a/report/src/main/java/com/megaease/easeagent/report/OutputProperties.java b/report/src/main/java/com/megaease/easeagent/report/OutputProperties.java index caee62540..30b749766 100644 --- a/report/src/main/java/com/megaease/easeagent/report/OutputProperties.java +++ b/report/src/main/java/com/megaease/easeagent/report/OutputProperties.java @@ -21,6 +21,8 @@ import com.megaease.easeagent.config.ConfigUtils; import com.megaease.easeagent.config.Configs; +import java.util.Map; + import static com.megaease.easeagent.plugin.api.config.ConfigConst.Observability.*; public interface OutputProperties { @@ -44,6 +46,7 @@ public interface OutputProperties { String getEndpointAlgorithm(); + void updateConfig(Map changed); static OutputProperties newDefault(Configs configs) { return new Default(configs); @@ -75,6 +78,22 @@ public Default(Configs configs) { ConfigUtils.bindProp(OUTPUT_ENDPOINT_IDENTIFICATION_ALGORITHM, configs, Config::getString, v -> this.endpointAlgorithm = v); } + @Override + public void updateConfig(Map changed) { + Configs configs = new Configs(changed); + + ConfigUtils.bindProp(OUTPUT_SERVERS, configs, Config::getString, v -> { if (v != null) this.servers = v; }); + ConfigUtils.bindProp(OUTPUT_TIMEOUT, configs, Config::getString, v -> { if (v != null) this.timeout = v; }); + ConfigUtils.bindProp(OUTPUT_ENABLED, configs, Config::getBoolean, v -> { if (v != null) this.enabled = v; }); + ConfigUtils.bindProp(OUTPUT_SECURITY_PROTOCOL, configs, Config::getString, v -> { if (v != null) this.protocol = v; }); + ConfigUtils.bindProp(OUTPUT_SSL_KEYSTORE_TYPE, configs, Config::getString, v -> { if (v != null) this.sslKeyStoreType = v; }); + ConfigUtils.bindProp(OUTPUT_KEY, configs, Config::getString, v -> { if (v != null) this.sslKey = v; }); + ConfigUtils.bindProp(OUTPUT_CERT, configs, Config::getString, v -> { if (v != null) this.certificate = v; }); + ConfigUtils.bindProp(OUTPUT_TRUST_CERT, configs, Config::getString, v -> { if (v != null) this.trustCertificate = v; }); + ConfigUtils.bindProp(OUTPUT_TRUST_CERT_TYPE, configs, Config::getString, v -> { if (v != null) this.trustCertificateType = v; }); + ConfigUtils.bindProp(OUTPUT_ENDPOINT_IDENTIFICATION_ALGORITHM, configs, Config::getString, v -> { if (v != null) this.endpointAlgorithm = v; }); + } + @Override public String getServers() { return this.servers; diff --git a/report/src/main/java/com/megaease/easeagent/report/metric/KeySender.java b/report/src/main/java/com/megaease/easeagent/report/metric/KeySender.java index 36914abd1..940f834a1 100644 --- a/report/src/main/java/com/megaease/easeagent/report/metric/KeySender.java +++ b/report/src/main/java/com/megaease/easeagent/report/metric/KeySender.java @@ -23,10 +23,13 @@ import org.apache.logging.log4j.core.Logger; public class KeySender { + private static final String CONSOLE_APPEND = "console"; private final String key; private final AppenderManager appenderManager; private final MetricProps metricProps; private Logger logger; + private org.slf4j.Logger consoleLogger; + private boolean isConsole = false; public KeySender(String key, AppenderManager appenderManager, MetricProps metricProps) { this.key = key; @@ -36,12 +39,23 @@ public KeySender(String key, AppenderManager appenderManager, MetricProps metric public void send(String content) { this.lazyInitLogger(); - this.logger.info(content); + if (this.isConsole) { + this.consoleLogger.info(content); + } else { + this.logger.info(content); + } } private void lazyInitLogger() { - if (logger == null) { - String loggerName = prepareAppenderAndLogger(); + if (logger != null) { + return; + } + + String loggerName = prepareAppenderAndLogger(); + if (metricProps.getAppendType().equals(CONSOLE_APPEND)) { + this.isConsole = true; + this.consoleLogger = org.slf4j.LoggerFactory.getLogger(loggerName); + } else { logger = LoggerFactory.getLoggerContext().getLogger(loggerName); } } diff --git a/report/src/main/java/com/megaease/easeagent/report/metric/MetricProps.java b/report/src/main/java/com/megaease/easeagent/report/metric/MetricProps.java index 706df968a..61d2f98bd 100644 --- a/report/src/main/java/com/megaease/easeagent/report/metric/MetricProps.java +++ b/report/src/main/java/com/megaease/easeagent/report/metric/MetricProps.java @@ -17,30 +17,27 @@ package com.megaease.easeagent.report.metric; -import com.megaease.easeagent.config.Config; -import com.megaease.easeagent.config.ConfigUtils; -import com.megaease.easeagent.config.Configs; import com.megaease.easeagent.plugin.Const; import com.megaease.easeagent.plugin.api.config.IPluginConfig; import com.megaease.easeagent.plugin.utils.NoNull; -import static com.megaease.easeagent.plugin.api.config.ConfigConst.Observability.*; -import static com.megaease.easeagent.plugin.api.config.ConfigConst.SERVICE_ID_ENABLED_KEY; -import static com.megaease.easeagent.plugin.api.config.ConfigConst.join; +import static com.megaease.easeagent.plugin.api.config.ConfigConst.Observability.KEY_COMM_APPEND_TYPE; +import static com.megaease.easeagent.plugin.api.config.ConfigConst.Observability.KEY_COMM_TOPIC; public interface MetricProps { + String getName(); + String getAppendType(); String getTopic(); boolean isEnabled(); - static MetricProps newDefault(Configs configs, String key) { - return new Default(configs, key); - } + void changeAppendType(String type); static MetricProps newDefault(IPluginConfig config) { return new Default( + config.namespace(), config.enabled(), NoNull.of(config.getString(KEY_COMM_APPEND_TYPE), Const.METRIC_DEFAULT_APPEND_TYPE), NoNull.of(config.getString(KEY_COMM_TOPIC), Const.METRIC_DEFAULT_TOPIC) @@ -48,22 +45,23 @@ static MetricProps newDefault(IPluginConfig config) { } class Default implements MetricProps { - private volatile boolean enabled = false; private volatile String appendType; - private volatile String topic; + private final boolean enabled; + private final String topic; + private final String name; - public Default(Configs configs, String key) { - ConfigUtils.bindProp(join(METRICS, key, SERVICE_ID_ENABLED_KEY), configs, Config::getBoolean, v -> this.enabled = v); - ConfigUtils.bindProp(join(METRICS, key, KEY_COMM_APPEND_TYPE), configs, Config::getString, v -> this.appendType = v); - ConfigUtils.bindProp(join(METRICS, key, KEY_COMM_TOPIC), configs, Config::getString, v -> this.topic = v); - } - - public Default(boolean enabled, String appendType, String topic) { + public Default(String name, boolean enabled, String appendType, String topic) { + this.name = name; this.enabled = enabled; this.appendType = appendType; this.topic = topic; } + @Override + public String getName() { + return this.name; + } + @Override public String getAppendType() { return this.appendType; @@ -78,5 +76,10 @@ public String getTopic() { public boolean isEnabled() { return this.enabled; } + + @Override + public void changeAppendType(String type) { + this.appendType = type; + } } } diff --git a/report/src/main/java/com/megaease/easeagent/report/metric/MetricReporterImpl.java b/report/src/main/java/com/megaease/easeagent/report/metric/MetricReporterImpl.java index e3820b602..4bd8c8936 100644 --- a/report/src/main/java/com/megaease/easeagent/report/metric/MetricReporterImpl.java +++ b/report/src/main/java/com/megaease/easeagent/report/metric/MetricReporterImpl.java @@ -18,9 +18,11 @@ package com.megaease.easeagent.report.metric; import com.megaease.easeagent.config.Configs; +import com.megaease.easeagent.plugin.api.Reporter; import com.megaease.easeagent.plugin.api.config.ChangeItem; import com.megaease.easeagent.plugin.api.config.IPluginConfig; import com.megaease.easeagent.plugin.api.config.PluginConfigChangeListener; +import com.megaease.easeagent.report.OutputChange; import com.megaease.easeagent.report.OutputProperties; import com.megaease.easeagent.report.metric.log4j.AppenderManager; import com.megaease.easeagent.report.util.Utils; @@ -29,12 +31,14 @@ import java.util.concurrent.ConcurrentHashMap; public class MetricReporterImpl implements MetricReporter { - private final ConcurrentHashMap reporters; + private final ConcurrentHashMap reporters; private final AppenderManager appenderManager; + private final OutputProperties outputProperties; + private static final String CONSOLE_APPEND = "console"; public MetricReporterImpl(Configs configs) { this.reporters = new ConcurrentHashMap<>(); - OutputProperties outputProperties = Utils.extractOutputProperties(configs); + outputProperties = Utils.extractOutputProperties(configs); this.appenderManager = AppenderManager.create(outputProperties); configs.addChangeListener(this); } @@ -44,8 +48,8 @@ public static MetricReporter create(Configs config) { } @Override - public com.megaease.easeagent.plugin.api.Reporter reporter(IPluginConfig config) { - Reporter reporter = reporters.get(config.namespace()); + public Reporter reporter(IPluginConfig config) { + DefaultMetricReporter reporter = reporters.get(config.namespace()); if (reporter != null) { return reporter; } @@ -54,7 +58,7 @@ public com.megaease.easeagent.plugin.api.Reporter reporter(IPluginConfig config) if (reporter != null) { return reporter; } - reporter = new Reporter(config); + reporter = new DefaultMetricReporter(config); reporters.put(config.namespace(), reporter); return reporter; } @@ -64,17 +68,24 @@ public com.megaease.easeagent.plugin.api.Reporter reporter(IPluginConfig config) public void onChange(List list) { if (Utils.isOutputPropertiesChange(list)) { appenderManager.refresh(); + Utils.updateOutputPropertiesChange(this.outputProperties, list); + reporters.forEachValue(1, reporter -> reporter.onOutPutChange(this.outputProperties)); } } - public class Reporter implements com.megaease.easeagent.plugin.api.Reporter, PluginConfigChangeListener { + public class DefaultMetricReporter implements Reporter, OutputChange, PluginConfigChangeListener { private final String namespace; private MetricProps metricProps; private KeySender sender; + private String originalAppendType; - public Reporter(IPluginConfig config) { + public DefaultMetricReporter(IPluginConfig config) { this.namespace = config.namespace(); this.metricProps = Utils.extractMetricProps(config); + this.originalAppendType = metricProps.getAppendType(); + + updateAppendType(metricProps, MetricReporterImpl.this.outputProperties, originalAppendType); + this.sender = newKeyLogger(); config.addChangeListener(this); } @@ -90,11 +101,36 @@ private KeySender newKeyLogger() { @Override public void onChange(IPluginConfig oldConfig, IPluginConfig newConfig) { MetricProps newProps = Utils.extractMetricProps(newConfig); - if (metricProps.getTopic().equals(newProps.getTopic()) && metricProps.getAppendType().equals(newProps.getAppendType())) { + + this.originalAppendType = updateAppendType(newProps, + MetricReporterImpl.this.outputProperties, newProps.getAppendType()); + + if (metricProps.getTopic().equals(newProps.getTopic()) + && metricProps.getAppendType().equals(newProps.getAppendType())) { return; } this.metricProps = newProps; this.sender = newKeyLogger(); } + + @Override + public void onOutPutChange(OutputProperties outputProperties) { + String oldAppendType = updateAppendType(this.metricProps, outputProperties, this.originalAppendType); + if (oldAppendType.equals(this.metricProps.getAppendType())) { + return; + } + this.sender = newKeyLogger(); + } + + private String updateAppendType(MetricProps props, OutputProperties output, String originalAppendType) { + String currentAppendType = props.getAppendType(); + if (output.getServers() == null || output.getServers().isEmpty()) { + // override the configuration + props.changeAppendType(CONSOLE_APPEND); + } else { + props.changeAppendType(originalAppendType); + } + return currentAppendType; + } } } diff --git a/report/src/main/java/com/megaease/easeagent/report/util/Utils.java b/report/src/main/java/com/megaease/easeagent/report/util/Utils.java index fc40ee01a..0a6e437f7 100644 --- a/report/src/main/java/com/megaease/easeagent/report/util/Utils.java +++ b/report/src/main/java/com/megaease/easeagent/report/util/Utils.java @@ -26,6 +26,7 @@ import com.megaease.easeagent.report.trace.TraceProps; import java.util.Arrays; +import java.util.HashMap; import java.util.List; public class Utils { @@ -46,6 +47,24 @@ public static boolean isOutputPropertiesChange(List list) { .anyMatch(relatedNames::contains); } + public static void updateOutputPropertiesChange(OutputProperties properties, List list) { + List relatedNames = Arrays.asList(ConfigConst.Observability.OUTPUT_ENABLED + , ConfigConst.Observability.OUTPUT_SERVERS + , ConfigConst.Observability.OUTPUT_TIMEOUT + , ConfigConst.Observability.OUTPUT_CERT + , ConfigConst.Observability.OUTPUT_KEY + , ConfigConst.Observability.OUTPUT_SECURITY_PROTOCOL + , ConfigConst.Observability.OUTPUT_SSL_KEYSTORE_TYPE + , ConfigConst.Observability.OUTPUT_TRUST_CERT + , ConfigConst.Observability.OUTPUT_TRUST_CERT_TYPE + , ConfigConst.Observability.OUTPUT_ENDPOINT_IDENTIFICATION_ALGORITHM + ); + HashMap changes = new HashMap<>(); + list.stream().filter(item -> relatedNames.contains(item.getFullName())) + .forEach(item -> changes.put(item.getFullName(), item.getNewValue())); + properties.updateConfig(changes); + } + public static boolean isTraceOutputPropertiesChange(List list) { return list.stream().map(ChangeItem::getFullName) .anyMatch(name -> name.startsWith(ConfigConst.Observability.TRACE_OUTPUT + ConfigConst.DELIMITER));