Fix the bug that error occurs in JMX metrics exporter when resource name contains '*' (#2992)
This commit is contained in:
parent
9f3712eed7
commit
59a32994cd
|
|
@ -20,12 +20,13 @@ package com.alibaba.csp.sentinel.metric.exporter.jmx;
|
|||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
import com.alibaba.csp.sentinel.node.metric.MetricNode;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import javax.management.ObjectName;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* the metric bean writer, it provides {@link MetricBeanWriter#write} method for register the
|
||||
|
|
@ -40,6 +41,8 @@ public class MetricBeanWriter {
|
|||
private final MBeanRegistry mBeanRegistry = MBeanRegistry.getInstance();
|
||||
|
||||
private static final String DEFAULT_APP_NAME = "sentinel-application";
|
||||
|
||||
private static final Pattern SPECIAL_CHARACTER_PATTERN = Pattern.compile("[*?=:\"\n]");
|
||||
|
||||
/**
|
||||
* write the MetricNode value to MetricBean
|
||||
|
|
@ -68,7 +71,10 @@ public class MetricBeanWriter {
|
|||
long version = System.currentTimeMillis();
|
||||
// set or update the new metric value
|
||||
for (MetricNode metricNode : map.values()) {
|
||||
final String mBeanName = "Sentinel:type=Metric,resource=" + metricNode.getResource()
|
||||
// Fix JMX Metrics export error: https://github.com/alibaba/Sentinel/issues/2989
|
||||
// Without escape, it will throw "cannot add mbean for pattern name" or "invalid character in value part of property" exception
|
||||
String resourceName = escapeSpecialCharacter(metricNode.getResource());
|
||||
final String mBeanName = "Sentinel:type=Metric,resource=" + resourceName
|
||||
+",classification=" + metricNode.getClassification()
|
||||
+",appName=" + appName;
|
||||
MetricBean metricBean = mBeanRegistry.findMBean(mBeanName);
|
||||
|
|
@ -95,4 +101,17 @@ public class MetricBeanWriter {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* escape only when arg has special character eg.(*,?,\n,\")
|
||||
*
|
||||
* @param resourceName need escape resource name
|
||||
* @return escaped characters
|
||||
*/
|
||||
public static String escapeSpecialCharacter(String resourceName) {
|
||||
if (StringUtil.isBlank(resourceName) || !SPECIAL_CHARACTER_PATTERN.matcher(resourceName).find()) {
|
||||
return resourceName;
|
||||
}
|
||||
return ObjectName.quote(resourceName);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright 1999-2022 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* 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.alibaba.cps.sentinel.metric.exporter;
|
||||
|
||||
import com.alibaba.csp.sentinel.metric.exporter.jmx.MetricBeanWriter;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* {@link com.alibaba.csp.sentinel.metric.exporter.jmx.MetricBeanWriter} unit test
|
||||
*
|
||||
* @author quguai
|
||||
* @date 2022/12/7 21:33
|
||||
*/
|
||||
public class MetricBeanWriterTest {
|
||||
|
||||
@Test
|
||||
public void testEscapeSpecialCharacter() {
|
||||
String character = MetricBeanWriter.escapeSpecialCharacter(null);
|
||||
Assert.assertNull(character);
|
||||
|
||||
character = MetricBeanWriter.escapeSpecialCharacter("");
|
||||
Assert.assertEquals("", character);
|
||||
|
||||
character = MetricBeanWriter.escapeSpecialCharacter("sentinel");
|
||||
Assert.assertEquals("sentinel", character);
|
||||
|
||||
character = MetricBeanWriter.escapeSpecialCharacter("*sentinel");
|
||||
Assert.assertEquals("\"\\*sentinel\"", character);
|
||||
|
||||
character = MetricBeanWriter.escapeSpecialCharacter("?sentinel");
|
||||
Assert.assertEquals("\"\\?sentinel\"", character);
|
||||
|
||||
character = MetricBeanWriter.escapeSpecialCharacter("\nsentinel");
|
||||
Assert.assertEquals("\"\\nsentinel\"", character);
|
||||
|
||||
character = MetricBeanWriter.escapeSpecialCharacter("\"sentinel");
|
||||
Assert.assertEquals("\"\\\"sentinel\"", character);
|
||||
|
||||
character = MetricBeanWriter.escapeSpecialCharacter("=sentinel");
|
||||
Assert.assertEquals("\"=sentinel\"", character);
|
||||
|
||||
character = MetricBeanWriter.escapeSpecialCharacter(":sentinel");
|
||||
Assert.assertEquals("\":sentinel\"", character);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue