* provides a optional-plugin for tracking ignores enhancement(#1203) * trace ignore plugin config support override by system.env * optimize the trace ignore plugin and make normalization of pom * add AntPathMatcher and an junit test for it * No longer rely on the spring framework * add license at file header * rebuild pom and rewrite README * rebuild optional-plugins pom * clean up useless code * modify junit * rewrite the ant path match logic * rename the matcher class
This commit is contained in:
parent
2502ea2961
commit
29f6f6e50e
|
|
@ -27,12 +27,13 @@
|
|||
<packaging>pom</packaging>
|
||||
|
||||
<artifactId>optional-spring-plugins</artifactId>
|
||||
<properties>
|
||||
<plugin.dest.dir>${project.build.directory}/../../../../../skywalking-agent/optional-plugins</plugin.dest.dir>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>spring-annotation-plugin</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<sdk.plugin.related.dir>/..</sdk.plugin.related.dir>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
@ -30,12 +30,16 @@
|
|||
<properties>
|
||||
<shade.net.bytebuddy.source>net.bytebuddy</shade.net.bytebuddy.source>
|
||||
<shade.net.bytebuddy.target>${shade.package}.${shade.net.bytebuddy.source}</shade.net.bytebuddy.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<plugin.dest.dir>${project.build.directory}/../../../../skywalking-agent/optional-plugins</plugin.dest.dir>
|
||||
<sdk.plugin.related.dir />
|
||||
<agent.package.dest.dir>${project.build.directory}${sdk.plugin.related.dir}/../../../../skywalking-agent</agent.package.dest.dir>
|
||||
<optional.plugin.dest.dir>${agent.package.dest.dir}/optional-plugins</optional.plugin.dest.dir>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>optional-spring-plugins</module>
|
||||
<module>trace-ignore-plugin</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
|
@ -101,11 +105,10 @@
|
|||
<if>
|
||||
<equals arg1="${project.packaging}" arg2="jar" />
|
||||
<then>
|
||||
<mkdir dir="${plugin.dest.dir}" />
|
||||
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar" tofile="${plugin.dest.dir}/${project.artifactId}-${project.version}.jar" overwrite="true" />
|
||||
<mkdir dir="${optional.plugin.dest.dir}" />
|
||||
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar" tofile="${optional.plugin.dest.dir}/${project.artifactId}-${project.version}.jar" overwrite="true" />
|
||||
</then>
|
||||
</if>
|
||||
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
#How to use trace ignore plugin
|
||||
Please copy the apm-trace-ignore-plugin-x.jar to `agent/plugins`
|
||||
|
||||
## How to set config
|
||||
1. This plugin support reading config from environment variables(The env key must start with `skywalking.`, the reuslt should be as same as in `apm-trace-ignore-plugin.config`)
|
||||
2. Or you can copy the `apm-trace-ignore-plugin.config` to `agent/config` then you'll set you need ignore paths in `apm-trace-ignore-plugin.config`
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# 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.
|
||||
|
||||
# If the operation name of the first span is matching, this segment should be ignored
|
||||
# ant path match style
|
||||
# /path/? Match any single character
|
||||
# /path/* Match any number of characters
|
||||
# /path/** Match any number of characters and support multilevel directories
|
||||
# Multiple path comma separation, like trace.ignore_path=/eureka/**,/consul/**
|
||||
#trace.ignore_path=/eureka/**
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>optional-plugins</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>5.0.0-beta2-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>apm-trace-ignore-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>apm-trace-ignore-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration combine.self="override">
|
||||
<tasks>
|
||||
<taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="maven.runtime.classpath" />
|
||||
<mkdir dir="${optional.plugin.dest.dir}/${project.artifactId}" />
|
||||
<!-- copy jar -->
|
||||
<copy file="${project.build.directory}/${project.artifactId}-${project.version}.jar" tofile="${optional.plugin.dest.dir}/${project.artifactId}/${project.artifactId}-${project.version}.jar" overwrite="true" />
|
||||
<!-- copy config file -->
|
||||
<copy file="${project.basedir}/${project.name}.config" tofile="${optional.plugin.dest.dir}/${project.name}/${project.name}.config" overwrite="true" />
|
||||
<!-- copy introduction -->
|
||||
<copy file="${project.basedir}/README.md" tofile="${optional.plugin.dest.dir}/${project.name}/README.md" overwrite="true" />
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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.plugin.trace.ignore;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
|
||||
import org.apache.skywalking.apm.agent.core.boot.OverrideImplementor;
|
||||
import org.apache.skywalking.apm.agent.core.conf.ConfigNotFoundException;
|
||||
import org.apache.skywalking.apm.agent.core.context.AbstractTracerContext;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService;
|
||||
import org.apache.skywalking.apm.agent.core.context.IgnoredTracerContext;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
|
||||
import org.apache.skywalking.apm.plugin.trace.ignore.conf.IgnoreConfig;
|
||||
import org.apache.skywalking.apm.plugin.trace.ignore.conf.IgnoreConfigInitializer;
|
||||
import org.apache.skywalking.apm.plugin.trace.ignore.matcher.AntPathMatcher;
|
||||
import org.apache.skywalking.apm.plugin.trace.ignore.matcher.TracePathMatcher;
|
||||
import org.apache.skywalking.apm.util.StringUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author liujc [liujunc1993@163.com]
|
||||
*
|
||||
*/
|
||||
@OverrideImplementor(ContextManagerExtendService.class)
|
||||
public class TraceIgnoreExtendService extends ContextManagerExtendService {
|
||||
|
||||
private static final ILog LOGGER = LogManager.getLogger(TraceIgnoreExtendService.class);
|
||||
|
||||
private static final String DEFAULT_PATH_SEPARATOR = "/";
|
||||
|
||||
private static final String PATTERN_SEPARATOR = ",";
|
||||
|
||||
private TracePathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
@Override
|
||||
public void boot() {
|
||||
try {
|
||||
IgnoreConfigInitializer.initialize();
|
||||
} catch (ConfigNotFoundException e) {
|
||||
LOGGER.error("trace ignore config init error", e);
|
||||
} catch (AgentPackageNotFoundException e) {
|
||||
LOGGER.error("trace ignore config init error", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractTracerContext createTraceContext(String operationName, boolean forceSampling) {
|
||||
String pattens = IgnoreConfig.Trace.IGNORE_PATH;
|
||||
if (!StringUtil.isEmpty(pattens) && !forceSampling) {
|
||||
String path = operationName;
|
||||
if (!StringUtil.isEmpty(path) && path.length() > 1 && path.endsWith(DEFAULT_PATH_SEPARATOR)) {
|
||||
path = path.substring(0, path.length() - 1);
|
||||
}
|
||||
|
||||
for (String pattern : pattens.split(PATTERN_SEPARATOR)) {
|
||||
if (pathMatcher.match(pattern, path)) {
|
||||
LOGGER.debug("operationName : " + operationName + " Ignore tracking");
|
||||
return new IgnoredTracerContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.createTraceContext(operationName, forceSampling);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.plugin.trace.ignore.conf;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author liujc [liujunc1993@163.com]
|
||||
*
|
||||
*/
|
||||
public class IgnoreConfig {
|
||||
|
||||
public static class Trace {
|
||||
/**
|
||||
* If the operation name of the first span is matching, this segment should be ignored
|
||||
* /path/? Match any single character
|
||||
* /path/* Match any number of characters
|
||||
* /path/** Match any number of characters and support multilevel directories
|
||||
*/
|
||||
public static String IGNORE_PATH = "";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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.plugin.trace.ignore.conf;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
|
||||
import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath;
|
||||
import org.apache.skywalking.apm.agent.core.conf.ConfigNotFoundException;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
|
||||
import org.apache.skywalking.apm.util.ConfigInitializer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author liujc [liujunc1993@163.com]
|
||||
*
|
||||
*/
|
||||
public class IgnoreConfigInitializer {
|
||||
private static final ILog LOGGER = LogManager.getLogger(IgnoreConfigInitializer.class);
|
||||
private static String CONFIG_FILE_NAME = "/config/apm-trace-ignore-plugin.config";
|
||||
private static String ENV_KEY_PREFIX = "skywalking.";
|
||||
|
||||
/**
|
||||
* Try to locate `apm-trace-ignore-plugin.config`, which should be in the /optional-plugins/apm-trace-ignore-plugin/ dictionary of agent package.
|
||||
* <p>
|
||||
* Also try to override the config by system.env and system.properties. All the keys in these two places should
|
||||
* start with {@link #ENV_KEY_PREFIX}. e.g. in env `skywalking.trace.ignore_path=your_path` to override
|
||||
* `trace.ignore_path` in apm-trace-ignore-plugin.config file.
|
||||
* <p>
|
||||
*/
|
||||
public static void initialize() throws ConfigNotFoundException, AgentPackageNotFoundException {
|
||||
InputStream configFileStream;
|
||||
try {
|
||||
configFileStream = loadConfigFromAgentFolder();
|
||||
Properties properties = new Properties();
|
||||
properties.load(configFileStream);
|
||||
ConfigInitializer.initialize(properties, IgnoreConfig.class);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e, "Failed to read the config file, skywalking is going to run in default config.");
|
||||
}
|
||||
|
||||
try {
|
||||
overrideConfigBySystemEnv();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(e, "Failed to read the system env.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void overrideConfigBySystemEnv() throws IllegalAccessException {
|
||||
Properties properties = new Properties();
|
||||
Properties systemProperties = System.getProperties();
|
||||
Iterator<Map.Entry<Object, Object>> entryIterator = systemProperties.entrySet().iterator();
|
||||
while (entryIterator.hasNext()) {
|
||||
Map.Entry<Object, Object> prop = entryIterator.next();
|
||||
if (prop.getKey().toString().startsWith(ENV_KEY_PREFIX)) {
|
||||
String realKey = prop.getKey().toString().substring(ENV_KEY_PREFIX.length());
|
||||
properties.put(realKey, prop.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (!properties.isEmpty()) {
|
||||
ConfigInitializer.initialize(properties, IgnoreConfig.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load the config file, where the agent jar is.
|
||||
*
|
||||
* @return the config file {@link InputStream}, or null if not needEnhance.
|
||||
*/
|
||||
private static InputStream loadConfigFromAgentFolder() throws AgentPackageNotFoundException, ConfigNotFoundException {
|
||||
File configFile = new File(AgentPackagePath.getPath(), CONFIG_FILE_NAME);
|
||||
if (configFile.exists() && configFile.isFile()) {
|
||||
try {
|
||||
LOGGER.info("Ignore config file found in {}.", configFile);
|
||||
return new FileInputStream(configFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new ConfigNotFoundException("Fail to load apm-trace-ignore-plugin.config", e);
|
||||
}
|
||||
}
|
||||
throw new ConfigNotFoundException("Fail to load ignore config file.");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* 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.plugin.trace.ignore.matcher;
|
||||
|
||||
import org.apache.skywalking.apm.util.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author liujc [liujunc1993@163.com]
|
||||
*
|
||||
*/
|
||||
public class AntPathMatcher implements TracePathMatcher {
|
||||
|
||||
private static final String DEFAULT_PATH_SEPARATOR = "/";
|
||||
|
||||
private static final String ANY_ONE_MATCHING_CHAR = "?";
|
||||
|
||||
private static final String ANY_MATCHING_CHAR = "*";
|
||||
|
||||
private static final String MULTILEVEL_DIRECTORIES_ANY_MATCHING_CHAR = ANY_MATCHING_CHAR.concat(ANY_MATCHING_CHAR);
|
||||
|
||||
@Override
|
||||
public boolean match(String pattern, String path) {
|
||||
if (!MatchAssist.checkPatternAndPath(pattern, path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// resolve pattern and path by default path separator
|
||||
String[] resolvedPatterns = MatchAssist.resolvePath(pattern);
|
||||
String[] resolvedPaths = MatchAssist.resolvePath(path);
|
||||
|
||||
int patternIdxStart = 0;
|
||||
int patternIdxEnd = resolvedPatterns.length - 1;
|
||||
int pathIdxStart = 0;
|
||||
int pathIdxEnd = resolvedPaths.length - 1;
|
||||
|
||||
|
||||
// try to match first '**'
|
||||
while (true) {
|
||||
if (patternIdxStart > patternIdxEnd || pathIdxStart > pathIdxEnd) {
|
||||
break;
|
||||
}
|
||||
String resolvedPattern = resolvedPatterns[patternIdxStart];
|
||||
if (MULTILEVEL_DIRECTORIES_ANY_MATCHING_CHAR.equals(resolvedPattern)) {
|
||||
break;
|
||||
}
|
||||
if (!MatchAssist.matchStrings(resolvedPattern, resolvedPaths[pathIdxStart])) {
|
||||
return false;
|
||||
}
|
||||
patternIdxStart++;
|
||||
pathIdxStart++;
|
||||
}
|
||||
|
||||
if (pathIdxStart > pathIdxEnd) {
|
||||
if (patternIdxStart > patternIdxEnd) {
|
||||
return pattern.endsWith(DEFAULT_PATH_SEPARATOR) == path.endsWith(DEFAULT_PATH_SEPARATOR);
|
||||
}
|
||||
return patternIdxStart == patternIdxEnd && resolvedPatterns[patternIdxStart].equals(ANY_MATCHING_CHAR) && path.endsWith(DEFAULT_PATH_SEPARATOR)
|
||||
|| MatchAssist.checkPatternIdx(patternIdxStart, patternIdxEnd, resolvedPatterns);
|
||||
}
|
||||
else if (patternIdxStart > patternIdxEnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to match last '**'
|
||||
while (true) {
|
||||
if (patternIdxStart > patternIdxEnd || pathIdxStart > pathIdxEnd) {
|
||||
break;
|
||||
}
|
||||
String resolvedPattern = resolvedPatterns[patternIdxEnd];
|
||||
if (resolvedPattern.equals(MULTILEVEL_DIRECTORIES_ANY_MATCHING_CHAR)) {
|
||||
break;
|
||||
}
|
||||
if (!MatchAssist.matchStrings(resolvedPattern, resolvedPaths[pathIdxEnd])) {
|
||||
return false;
|
||||
}
|
||||
patternIdxEnd--;
|
||||
pathIdxEnd--;
|
||||
}
|
||||
if (pathIdxStart > pathIdxEnd) {
|
||||
return MatchAssist.checkPatternIdx(patternIdxStart, patternIdxEnd, resolvedPatterns);
|
||||
}
|
||||
|
||||
while (patternIdxStart != patternIdxEnd && pathIdxStart <= pathIdxEnd) {
|
||||
int patIdxTmp = -1;
|
||||
for (int i = patternIdxStart + 1; i <= patternIdxEnd; i++) {
|
||||
if (resolvedPatterns[i].equals(MULTILEVEL_DIRECTORIES_ANY_MATCHING_CHAR)) {
|
||||
patIdxTmp = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (patIdxTmp == patternIdxStart + 1) {
|
||||
// '**/**' situation, so skip one
|
||||
patternIdxStart++;
|
||||
continue;
|
||||
}
|
||||
// Find the pattern between patternIdxStart & padIdxTmp in str between
|
||||
// strIdxStart & strIdxEnd
|
||||
int patLength = patIdxTmp - patternIdxStart - 1;
|
||||
int strLength = pathIdxEnd - pathIdxStart + 1;
|
||||
int foundIdx = -1;
|
||||
|
||||
strLoop:
|
||||
for (int i = 0; i <= strLength - patLength; i++) {
|
||||
for (int j = 0; j < patLength; j++) {
|
||||
String subPat = resolvedPatterns[patternIdxStart + j + 1];
|
||||
String subStr = resolvedPatterns[pathIdxStart + i + j];
|
||||
if (!MatchAssist.matchStrings(subPat, subStr)) {
|
||||
continue strLoop;
|
||||
}
|
||||
}
|
||||
foundIdx = pathIdxStart + i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (foundIdx == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
patternIdxStart = patIdxTmp;
|
||||
pathIdxStart = foundIdx + patLength;
|
||||
}
|
||||
|
||||
return MatchAssist.checkPatternIdx(patternIdxStart, patternIdxEnd, resolvedPatterns);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static class MatchAssist {
|
||||
|
||||
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{((?:\\{[^/]+?\\}|[^/{}]|\\\\[{}])+?)\\}");
|
||||
|
||||
private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
|
||||
|
||||
private static final ConcurrentMap<String, Pattern> GLOBAL_COMPILED_PATTERN_CACHE = new ConcurrentHashMap<String, Pattern>();
|
||||
|
||||
|
||||
private static boolean checkPatternIdx(int patternIdxStart, int patternIdxEnd, String[] resolvedPatterns) {
|
||||
for (int i = patternIdxStart; i <= patternIdxEnd; i++) {
|
||||
if (!resolvedPatterns[i].equals(MULTILEVEL_DIRECTORIES_ANY_MATCHING_CHAR)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* make sure of the pattern and path is validate
|
||||
*/
|
||||
private static boolean checkPatternAndPath(String pattern, String path) {
|
||||
return !StringUtil.isEmpty(pattern) && !StringUtil.isEmpty(path) &&
|
||||
path.startsWith(DEFAULT_PATH_SEPARATOR) == pattern.startsWith(DEFAULT_PATH_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* resolve path by default path separator
|
||||
*/
|
||||
private static String[] resolvePath(String path) {
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
StringTokenizer st = new StringTokenizer(path, DEFAULT_PATH_SEPARATOR);
|
||||
List<String> tokens = new ArrayList<String>();
|
||||
while (st.hasMoreTokens()) {
|
||||
String token = st.nextToken();
|
||||
token = token.trim();
|
||||
if (token.length() > 0) {
|
||||
tokens.add(token);
|
||||
}
|
||||
}
|
||||
return tokens.toArray(new String[tokens.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* use pattern match path
|
||||
*/
|
||||
private static boolean matchStrings(String pattern, String path) {
|
||||
if (StringUtil.isEmpty(pattern) || StringUtil.isEmpty(pattern)) {
|
||||
return false;
|
||||
}
|
||||
// if this pattern has been compiled
|
||||
Pattern compliedPattern = GLOBAL_COMPILED_PATTERN_CACHE.get(pattern);
|
||||
if (compliedPattern == null) {
|
||||
// build new pattern
|
||||
StringBuilder patternBuilder = new StringBuilder();
|
||||
Matcher matcher = GLOB_PATTERN.matcher(pattern);
|
||||
int end = 0;
|
||||
while (matcher.find()) {
|
||||
patternBuilder.append(quote(pattern, end, matcher.start()));
|
||||
String match = matcher.group();
|
||||
if (ANY_ONE_MATCHING_CHAR.equals(match)) {
|
||||
patternBuilder.append('.');
|
||||
}
|
||||
else if (ANY_MATCHING_CHAR.equals(match)) {
|
||||
patternBuilder.append(".".concat(ANY_MATCHING_CHAR));
|
||||
}
|
||||
else if (match.startsWith("{") && match.endsWith("}")) {
|
||||
int colonIdx = match.indexOf(':');
|
||||
if (colonIdx == -1) {
|
||||
patternBuilder.append(DEFAULT_VARIABLE_PATTERN);
|
||||
}
|
||||
else {
|
||||
String variablePattern = match.substring(colonIdx + 1, match.length() - 1);
|
||||
patternBuilder.append('(');
|
||||
patternBuilder.append(variablePattern);
|
||||
patternBuilder.append(')');
|
||||
}
|
||||
}
|
||||
end = matcher.end();
|
||||
}
|
||||
patternBuilder.append(quote(pattern, end, pattern.length()));
|
||||
compliedPattern = Pattern.compile(patternBuilder.toString());
|
||||
GLOBAL_COMPILED_PATTERN_CACHE.putIfAbsent(pattern, compliedPattern);
|
||||
}
|
||||
|
||||
return compliedPattern.matcher(path).matches();
|
||||
}
|
||||
|
||||
private static String quote(String s, int start, int end) {
|
||||
if (start == end) {
|
||||
return "";
|
||||
}
|
||||
return Pattern.quote(s.substring(start, end));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.plugin.trace.ignore.matcher;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author liujc [liujunc1993@163.com]
|
||||
*
|
||||
*/
|
||||
public interface TracePathMatcher {
|
||||
|
||||
boolean match(String pattern, String path);
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
|
||||
org.apache.skywalking.apm.plugin.trace.ignore.TraceIgnoreExtendService
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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.plugin.trace.ignore;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.AbstractTracerContext;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService;
|
||||
import org.apache.skywalking.apm.agent.core.context.IgnoredTracerContext;
|
||||
import org.apache.skywalking.apm.agent.core.context.TracingContext;
|
||||
import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
|
||||
import org.apache.skywalking.apm.plugin.trace.ignore.conf.IgnoreConfig;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author liujc [liujunc1993@163.com]
|
||||
*/
|
||||
public class TraceIgnoreTest {
|
||||
|
||||
@Rule
|
||||
public AgentServiceRule serviceRule = new AgentServiceRule();
|
||||
|
||||
@Test
|
||||
public void testServiceOverrideFromPlugin() {
|
||||
ContextManagerExtendService service = ServiceManager.INSTANCE.findService(ContextManagerExtendService.class);
|
||||
Assert.assertEquals(TraceIgnoreExtendService.class, service.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTraceIgnore() {
|
||||
ContextManagerExtendService service = ServiceManager.INSTANCE.findService(ContextManagerExtendService.class);
|
||||
IgnoreConfig.Trace.IGNORE_PATH = "/eureka/**";
|
||||
AbstractTracerContext ignoredTracerContext = service.createTraceContext("/eureka/apps", false);
|
||||
Assert.assertEquals(IgnoredTracerContext.class, ignoredTracerContext.getClass());
|
||||
|
||||
AbstractTracerContext traceContext = service.createTraceContext("/consul/apps", false);
|
||||
Assert.assertEquals(TracingContext.class, traceContext.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.plugin.trace.ignore;
|
||||
|
||||
import org.apache.skywalking.apm.plugin.trace.ignore.matcher.AntPathMatcher;
|
||||
import org.apache.skywalking.apm.plugin.trace.ignore.matcher.TracePathMatcher;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TracePathMatcherTest {
|
||||
|
||||
@Test
|
||||
public void testAntPathMatcher() {
|
||||
TracePathMatcher pathMatcher = new AntPathMatcher();
|
||||
String patten = "/eureka/*";
|
||||
String path = "/eureka/app";
|
||||
|
||||
boolean match = pathMatcher.match(patten, path);
|
||||
Assert.assertTrue(match);
|
||||
|
||||
path = "/eureka/apps/list";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertFalse(match);
|
||||
|
||||
patten = "/eureka/**";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertTrue(match);
|
||||
|
||||
patten = "/eureka/apps/lis?";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertTrue(match);
|
||||
|
||||
path = "eureka/apps/lists";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertFalse(match);
|
||||
|
||||
patten = "eureka/**/lists";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertTrue(match);
|
||||
|
||||
path = "eureka/apps/a/b/c/lists";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertTrue(match);
|
||||
|
||||
path = "eureka/apps/a/b/c/";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertFalse(match);
|
||||
|
||||
patten = "eureka/**/b/**";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertTrue(match);
|
||||
|
||||
patten = "/eureka/**/b/**/*.txt";
|
||||
path = "/eureka/a/aa/aaa/b/bb/bbb/xxxxxx.txt";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertTrue(match);
|
||||
|
||||
path = "/eureka/a/aa/aaa/b/bb/bbb/xxxxxx";
|
||||
match = pathMatcher.match(patten, path);
|
||||
Assert.assertFalse(match);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
|
||||
org.apache.skywalking.apm.plugin.trace.ignore.TraceIgnoreExtendService
|
||||
Loading…
Reference in New Issue