From fd02bcd6f6099f3c8ef074233a8cab0a25fd924a Mon Sep 17 00:00:00 2001 From: Ax1an Date: Thu, 28 Jan 2021 21:40:34 +0800 Subject: [PATCH] Support dynamic change agent.ignore_suffix on java agent. (#6272) --- CHANGES.md | 1 + .../apm/agent/core/conf/Config.java | 1 + .../context/ContextManagerExtendService.java | 16 ++++- .../context/IgnoreSuffixPatternsWatcher.java | 72 +++++++++++++++++++ .../IgnoreSuffixPatternsWatcherTest.java | 63 ++++++++++++++++ apm-sniffer/config/agent.config | 2 +- .../ignore/TraceIgnoreExtendService.java | 2 +- .../java-agent/configuration-discovery.md | 3 +- 8 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoreSuffixPatternsWatcher.java create mode 100644 apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/IgnoreSuffixPatternsWatcherTest.java diff --git a/CHANGES.md b/CHANGES.md index 770f742f3..26ddb6166 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -36,6 +36,7 @@ Release Notes. * Fix RestTemplate plugin recording url tag with wrong port * Support collecting logs and forwarding through gRPC. * Support config `agent.sample_n_per_3_secs` can be changed in the runtime. +* Support config `agent.ignore_suffix` can be changed in the runtime. * Support DNS periodic resolving mechanism to update backend service. * Support config `agent.trace.ignore_path` can be changed in the runtime. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java index 4f4a9816f..e8df48b51 100755 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java @@ -62,6 +62,7 @@ public class Config { /** * If the operation name of the first span is included in this set, this segment should be ignored. + * Multiple values should be separated by `,`. */ public static String IGNORE_SUFFIX = ".jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg"; diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManagerExtendService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManagerExtendService.java index 8f0bef058..9d718f4b5 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManagerExtendService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ContextManagerExtendService.java @@ -22,28 +22,36 @@ import org.apache.skywalking.apm.agent.core.boot.BootService; import org.apache.skywalking.apm.agent.core.boot.DefaultImplementor; import org.apache.skywalking.apm.agent.core.boot.ServiceManager; import org.apache.skywalking.apm.agent.core.conf.Config; +import org.apache.skywalking.apm.agent.core.conf.dynamic.ConfigurationDiscoveryService; import org.apache.skywalking.apm.agent.core.remote.GRPCChannelListener; import org.apache.skywalking.apm.agent.core.remote.GRPCChannelManager; import org.apache.skywalking.apm.agent.core.remote.GRPCChannelStatus; import org.apache.skywalking.apm.agent.core.sampling.SamplingService; +import org.apache.skywalking.apm.util.StringUtil; import java.util.Arrays; @DefaultImplementor public class ContextManagerExtendService implements BootService, GRPCChannelListener { - private String[] ignoreSuffixArray = new String[0]; + private volatile String[] ignoreSuffixArray = new String[0]; private volatile GRPCChannelStatus status = GRPCChannelStatus.DISCONNECT; + private IgnoreSuffixPatternsWatcher ignoreSuffixPatternsWatcher; + @Override public void prepare() { ServiceManager.INSTANCE.findService(GRPCChannelManager.class).addChannelListener(this); + ignoreSuffixPatternsWatcher = new IgnoreSuffixPatternsWatcher("agent.ignore_suffix", this); } @Override public void boot() { ignoreSuffixArray = Config.Agent.IGNORE_SUFFIX.split(","); + ServiceManager.INSTANCE.findService(ConfigurationDiscoveryService.class) + .registerAgentConfigChangeWatcher(ignoreSuffixPatternsWatcher); + handleIgnoreSuffixPatternsChanged(); } @Override @@ -84,4 +92,10 @@ public class ContextManagerExtendService implements BootService, GRPCChannelList public void statusChanged(final GRPCChannelStatus status) { this.status = status; } + + void handleIgnoreSuffixPatternsChanged() { + if (StringUtil.isNotBlank(ignoreSuffixPatternsWatcher.getIgnoreSuffixPatterns())) { + ignoreSuffixArray = ignoreSuffixPatternsWatcher.getIgnoreSuffixPatterns().split(","); + } + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoreSuffixPatternsWatcher.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoreSuffixPatternsWatcher.java new file mode 100644 index 000000000..cb488f52f --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/IgnoreSuffixPatternsWatcher.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.context; + +import org.apache.skywalking.apm.agent.core.conf.Config; +import org.apache.skywalking.apm.agent.core.conf.dynamic.AgentConfigChangeWatcher; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; + +import java.util.concurrent.atomic.AtomicReference; + +public class IgnoreSuffixPatternsWatcher extends AgentConfigChangeWatcher { + + private static final ILog LOGGER = LogManager.getLogger(IgnoreSuffixPatternsWatcher.class); + + private final AtomicReference ignoreSuffixPatterns; + private final ContextManagerExtendService contextManagerExtendService; + + public IgnoreSuffixPatternsWatcher(final String propertyKey, ContextManagerExtendService contextManagerExtendService) { + super(propertyKey); + this.ignoreSuffixPatterns = new AtomicReference(getDefaultValue()); + this.contextManagerExtendService = contextManagerExtendService; + } + + private void activeSetting(String config) { + if (LOGGER.isDebugEnable()) { + LOGGER.debug("Updating using new static config: {}", config); + } + + this.ignoreSuffixPatterns.set(config); + contextManagerExtendService.handleIgnoreSuffixPatternsChanged(); + } + + @Override + public void notify(final ConfigChangeEvent value) { + if (EventType.DELETE.equals(value.getEventType())) { + activeSetting(getDefaultValue()); + } else { + activeSetting(value.getNewValue()); + } + } + + @Override + public String value() { + return ignoreSuffixPatterns.get(); + } + + private String getDefaultValue() { + return Config.Agent.IGNORE_SUFFIX; + } + + public String getIgnoreSuffixPatterns() { + return ignoreSuffixPatterns.get(); + } + +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/IgnoreSuffixPatternsWatcherTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/IgnoreSuffixPatternsWatcherTest.java new file mode 100644 index 000000000..4e6cbc74f --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/context/IgnoreSuffixPatternsWatcherTest.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.skywalking.apm.agent.core.context; + +import org.apache.skywalking.apm.agent.core.conf.dynamic.AgentConfigChangeWatcher; +import org.apache.skywalking.apm.agent.core.test.tools.AgentServiceRule; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.powermock.reflect.Whitebox; + +public class IgnoreSuffixPatternsWatcherTest { + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + private ContextManagerExtendService contextManagerExtendService = new ContextManagerExtendService(); + + @Before + public void setUp() { + contextManagerExtendService.prepare(); + } + + @Test + public void testConfigModifyEvent() { + IgnoreSuffixPatternsWatcher ignoreSuffixPatternsWatcher = Whitebox.getInternalState(contextManagerExtendService + , "ignoreSuffixPatternsWatcher"); + ignoreSuffixPatternsWatcher.notify(new AgentConfigChangeWatcher.ConfigChangeEvent( + ".txt,.log", + AgentConfigChangeWatcher.EventType.MODIFY + )); + Assert.assertEquals(".txt,.log", ignoreSuffixPatternsWatcher.getIgnoreSuffixPatterns()); + Assert.assertEquals("agent.ignore_suffix", ignoreSuffixPatternsWatcher.getPropertyKey()); + } + + @Test + public void testConfigDeleteEvent() { + IgnoreSuffixPatternsWatcher ignoreSuffixPatternsWatcher = Whitebox.getInternalState(contextManagerExtendService + , "ignoreSuffixPatternsWatcher"); + ignoreSuffixPatternsWatcher.notify(new AgentConfigChangeWatcher.ConfigChangeEvent( + null, + AgentConfigChangeWatcher.EventType.DELETE + )); + Assert.assertEquals("agent.ignore_suffix", ignoreSuffixPatternsWatcher.getPropertyKey()); + } +} diff --git a/apm-sniffer/config/agent.config b/apm-sniffer/config/agent.config index b85ac3d4c..5475eb557 100644 --- a/apm-sniffer/config/agent.config +++ b/apm-sniffer/config/agent.config @@ -31,7 +31,7 @@ agent.service_name=${SW_AGENT_NAME:Your_ApplicationName} # Through this config item, SkyWalking keep your application memory cost estimated. # agent.span_limit_per_segment=${SW_AGENT_SPAN_LIMIT:150} -# Ignore the segments if their operation names end with these suffix. +# If the operation name of the first span is included in this set, this segment should be ignored. Multiple values should be separated by `,`. # agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg} # If true, SkyWalking agent will save all instrumented classes files in `/debugging` folder. diff --git a/apm-sniffer/optional-plugins/trace-ignore-plugin/src/main/java/org/apache/skywalking/apm/plugin/trace/ignore/TraceIgnoreExtendService.java b/apm-sniffer/optional-plugins/trace-ignore-plugin/src/main/java/org/apache/skywalking/apm/plugin/trace/ignore/TraceIgnoreExtendService.java index 22e74c850..eb872827c 100644 --- a/apm-sniffer/optional-plugins/trace-ignore-plugin/src/main/java/org/apache/skywalking/apm/plugin/trace/ignore/TraceIgnoreExtendService.java +++ b/apm-sniffer/optional-plugins/trace-ignore-plugin/src/main/java/org/apache/skywalking/apm/plugin/trace/ignore/TraceIgnoreExtendService.java @@ -35,7 +35,7 @@ public class TraceIgnoreExtendService extends SamplingService { private static final ILog LOGGER = LogManager.getLogger(TraceIgnoreExtendService.class); private static final String PATTERN_SEPARATOR = ","; private TracePathMatcher pathMatcher = new FastPathMatcher(); - private String[] patterns = new String[] {}; + private volatile String[] patterns = new String[] {}; private TraceIgnorePatternWatcher traceIgnorePatternWatcher; @Override diff --git a/docs/en/setup/service-agent/java-agent/configuration-discovery.md b/docs/en/setup/service-agent/java-agent/configuration-discovery.md index cc61ecc1e..65423f66e 100644 --- a/docs/en/setup/service-agent/java-agent/configuration-discovery.md +++ b/docs/en/setup/service-agent/java-agent/configuration-discovery.md @@ -25,6 +25,7 @@ Java agent supports the following dynamic configurations. | Config Key | Value Description | Value Format Example | Required Plugin(s) | | :-----------------------: | :----------------------------------------------------------: | :-------------------: | :----------------: | | agent.sample_n_per_3_secs | The number of sampled traces per 3 seconds | -1 | - | -| agent.trace.ignore_path | The value is the path that you need to ignore, multiple paths should be separated by `,` [more details](./agent-optional-plugins/trace-ignore-plugin.md) | `/your/path/1/**,/your/path/2/**` | `apm-trace-ignore-plugin` | +| agent.ignore_suffix | If the operation name of the first span is included in this set, this segment should be ignored. Multiple values should be separated by `,` | `.txt,.log` | - | +| agent.trace.ignore_path | The value is the path that you need to ignore, multiple paths should be separated by `,` [more details](./agent-optional-plugins/trace-ignore-plugin.md) | `/your/path/1/**,/your/path/2/**` | `apm-trace-ignore-plugin` | * `Required plugin(s)`, the configuration affects only when the required plugins activated.