diff --git a/CHANGES.md b/CHANGES.md index 45b20f1aa8..b27ad9805b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -22,6 +22,7 @@ Release Notes. * Fix Gateway 2.0.x plugin not activated for spring-cloud-starter-gateway 2.0.0.RELEASE. * Support kafka-clients-3.9.x intercept. * Upgrade kafka-clients version in optional-reporter-plugins to 3.9.1. +* Fix AbstractLogger replaceParam when the replaced string contains a replacement marker. All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/242?closed=1) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/logging/core/AbstractLogger.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/logging/core/AbstractLogger.java index 20b55589f9..4020359d0a 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/logging/core/AbstractLogger.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/logging/core/AbstractLogger.java @@ -32,7 +32,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; /** * An abstract class to simplify the real implementation of the loggers. @@ -189,18 +188,17 @@ protected String replaceParam(String message, Object... parameters) { int startSize = 0; int parametersIndex = 0; int index; - String tmpMessage = message; - while ((index = message.indexOf("{}", startSize)) != -1) { + StringBuilder sb = new StringBuilder(message); + while ((index = sb.indexOf("{}", startSize)) != -1) { if (parametersIndex >= parameters.length) { break; } - /** - * @Fix the Illegal group reference issue - */ - tmpMessage = tmpMessage.replaceFirst("\\{\\}", Matcher.quoteReplacement(String.valueOf(parameters[parametersIndex++]))); - startSize = index + 2; + + String replaced = String.valueOf(parameters[parametersIndex++]); + sb.replace(index, index + 2, replaced); + startSize = index + replaced.length(); } - return tmpMessage; + return sb.toString(); } protected void logger(LogLevel level, String message, Throwable e) { diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/logging/core/AbstractLoggerTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/logging/core/AbstractLoggerTest.java new file mode 100644 index 0000000000..1d56d7700b --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/logging/core/AbstractLoggerTest.java @@ -0,0 +1,56 @@ +/* + * 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.logging.core; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class AbstractLoggerTest { + + @Test + public void replaceParamNormal() { + TestLogger logger = new TestLogger("AbstractLoggerTest"); + String result = logger.testReplaceParam("from {} to {}", "a", "b"); + assertEquals("from a to b", result); + } + + @Test + public void replaceParamWithReplaceMark() { + TestLogger logger = new TestLogger("AbstractLoggerTest"); + String result = logger.testReplaceParam("from {} to {}", "a={}", "b={}"); + assertEquals("from a={} to b={}", result); + } + + private static class TestLogger extends AbstractLogger { + + public TestLogger(String targetClass) { + super(targetClass); + } + + @Override + protected String format(LogLevel level, String message, Throwable e) { + return message; + } + + String testReplaceParam(String message, Object... parameters) { + return replaceParam(message, parameters); + } + } +} \ No newline at end of file