diff --git a/exceptiontrace/exceptiontrace-common/src/main/java/com/navercorp/pinpoint/exceptiontrace/common/pinot/PinotFunctions.java b/exceptiontrace/exceptiontrace-common/src/main/java/com/navercorp/pinpoint/exceptiontrace/common/pinot/PinotFunctions.java
new file mode 100644
index 0000000000000..d2d35af12f17b
--- /dev/null
+++ b/exceptiontrace/exceptiontrace-common/src/main/java/com/navercorp/pinpoint/exceptiontrace/common/pinot/PinotFunctions.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2024 NAVER Corp.
+ *
+ * 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.navercorp.pinpoint.exceptiontrace.common.pinot;
+
+/**
+ * @author intr3p1d
+ */
+public enum PinotFunctions {
+ ARRAY_SLICE_INT("arraySliceInt"),
+ ARRAY_SLICE_STRING("arraySliceString");
+
+ private final String name;
+
+ PinotFunctions(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
diff --git a/exceptiontrace/exceptiontrace-web/pom.xml b/exceptiontrace/exceptiontrace-web/pom.xml
index 7b279ecd67c29..095155f79ab28 100644
--- a/exceptiontrace/exceptiontrace-web/pom.xml
+++ b/exceptiontrace/exceptiontrace-web/pom.xml
@@ -29,6 +29,15 @@
com.navercorp.pinpoint
pinpoint-exceptiontrace-common
+
+ org.apache.commons
+ commons-text
+ 1.10.0
+
+
+ org.apache.commons
+ commons-lang3
+
org.mapstruct
mapstruct
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/config/ExceptionTraceRegistryHandler.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/config/ExceptionTraceRegistryHandler.java
index 480543c5e0d47..a50cb83519abd 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/config/ExceptionTraceRegistryHandler.java
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/config/ExceptionTraceRegistryHandler.java
@@ -15,11 +15,13 @@
*/
package com.navercorp.pinpoint.exceptiontrace.web.config;
+import com.navercorp.pinpoint.exceptiontrace.web.entity.ClpConvertedEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionMetaDataEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionTraceSummaryEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionTraceValueViewEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.GroupedFieldNameEntity;
-import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter;
import com.navercorp.pinpoint.mybatis.MyBatisRegistryHandler;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.apache.ibatis.type.TypeHandlerRegistry;
@@ -34,7 +36,9 @@ public void registerTypeAlias(TypeAliasRegistry typeAliasRegistry) {
typeAliasRegistry.registerAlias(GroupedFieldNameEntity.class);
typeAliasRegistry.registerAlias(ExceptionTraceSummaryEntity.class);
typeAliasRegistry.registerAlias(ExceptionTraceValueViewEntity.class);
+ typeAliasRegistry.registerAlias(ClpConvertedEntity.class);
typeAliasRegistry.registerAlias(ExceptionTraceQueryParameter.class);
+ typeAliasRegistry.registerAlias(ClpQueryParameter.class);
}
@Override
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/controller/ExceptionTraceController.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/controller/ExceptionTraceController.java
index 667820af3a038..95c1a891f97cc 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/controller/ExceptionTraceController.java
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/controller/ExceptionTraceController.java
@@ -18,10 +18,12 @@
import com.navercorp.pinpoint.common.server.util.time.Range;
import com.navercorp.pinpoint.common.server.util.time.RangeValidator;
+import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceSummary;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceValueView;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter;
import com.navercorp.pinpoint.exceptiontrace.web.service.ExceptionTraceService;
-import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter;
import com.navercorp.pinpoint.exceptiontrace.web.util.GroupByAttributes;
import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionMetaDataView;
import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionTraceView;
@@ -159,6 +161,37 @@ public List getListOfExceptionMetaDataWithDynamicGroupBy(
);
}
+ @GetMapping("/replacedTokens")
+ public List getReplacedVariables(
+ @RequestParam("applicationName") @NotBlank String applicationName,
+ @RequestParam(value = "agentId", required = false) String agentId,
+ @RequestParam("from") @PositiveOrZero long from,
+ @RequestParam("to") @PositiveOrZero long to,
+
+ @RequestParam("logType") String logType,
+ @RequestParam("targetColumn") String targetColumn,
+ @RequestParam("targetIndex") int targetIndex
+ ) {
+ Range range = Range.between(from, to);
+ rangeValidator.validate(range);
+
+ ClpQueryParameter queryParameter = new ClpQueryParameter.Builder()
+ .setTableName(tableName)
+ .setTenantId(tenantProvider.getTenantId())
+ .setApplicationName(applicationName)
+ .setAgentId(agentId)
+ .setRange(Range.between(from, to))
+ .setTimePrecision(DETAILED_TIME_PRECISION)
+ .setLogType(logType)
+ .setTargetColumn(targetColumn)
+ .setTargetIndex(targetIndex)
+ .build();
+
+ return exceptionTraceService.getReplacedVariables(
+ queryParameter
+ );
+ }
+
@GetMapping("/chart")
public ExceptionTraceView getCollectedExceptionMetaDataByGivenRange(
@RequestParam("applicationName") @NotBlank String applicationName,
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/dao/ExceptionTraceDao.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/dao/ExceptionTraceDao.java
index 0ad00a05645dc..04b3d04103a62 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/dao/ExceptionTraceDao.java
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/dao/ExceptionTraceDao.java
@@ -18,9 +18,11 @@
import com.navercorp.pinpoint.exceptiontrace.common.model.ExceptionMetaData;
+import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceSummary;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceValueView;
-import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter;
import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionMetaDataView;
import java.util.List;
@@ -34,4 +36,5 @@ public interface ExceptionTraceDao {
ExceptionMetaData getException(ExceptionTraceQueryParameter exceptionTraceQueryParameter);
List getSummaries(ExceptionTraceQueryParameter exceptionTraceQueryParameter);
List getValueViews(ExceptionTraceQueryParameter exceptionTraceQueryParameter);
+ List getReplacedVariables(ClpQueryParameter queryParameter);
}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/dao/PinotExceptionTraceDao.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/dao/PinotExceptionTraceDao.java
index e8ecc8ec642bc..2d89dc04ad1cf 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/dao/PinotExceptionTraceDao.java
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/dao/PinotExceptionTraceDao.java
@@ -17,13 +17,16 @@
package com.navercorp.pinpoint.exceptiontrace.web.dao;
import com.navercorp.pinpoint.exceptiontrace.common.model.ExceptionMetaData;
+import com.navercorp.pinpoint.exceptiontrace.web.entity.ClpConvertedEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionMetaDataEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionTraceSummaryEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionTraceValueViewEntity;
import com.navercorp.pinpoint.exceptiontrace.web.mapper.ExceptionMetaDataEntityMapper;
+import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceSummary;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceValueView;
-import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter;
import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionMetaDataView;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -49,6 +52,7 @@ public class PinotExceptionTraceDao implements ExceptionTraceDao {
private static final String SELECT_EXACT_QUERY = "selectExactException";
private static final String SELECT_SUMMARIES_QUERY = "selectSummaries";
private static final String SELECT_VALUEVIEWS_QUERY = "selectValueViews";
+ private static final String SELECT_CLP_VARIABLES_QUERY = "selectClpVariables";
private final SqlSessionTemplate sqlPinotSessionTemplate;
@@ -105,4 +109,13 @@ public List getValueViews(ExceptionTraceQueryParameter
)
).collect(Collectors.toList());
}
+
+ @Override
+ public List getReplacedVariables(ClpQueryParameter queryParameter) {
+ List clpConvertedEntities = this.sqlPinotSessionTemplate.selectList(NAMESPACE + SELECT_CLP_VARIABLES_QUERY, queryParameter);
+
+ return clpConvertedEntities.stream()
+ .map(mapper::toClpConverted)
+ .collect(Collectors.toList());
+ }
}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/entity/ClpConvertedEntity.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/entity/ClpConvertedEntity.java
new file mode 100644
index 0000000000000..a7917d4bda26e
--- /dev/null
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/entity/ClpConvertedEntity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2024 NAVER Corp.
+ *
+ * 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.navercorp.pinpoint.exceptiontrace.web.entity;
+
+/**
+ * @author intr3p1d
+ */
+public class ClpConvertedEntity {
+
+ private String replacedToken;
+ private int count;
+
+ public ClpConvertedEntity() {
+ }
+
+ public String getReplacedToken() {
+ return replacedToken;
+ }
+
+ public void setReplacedToken(String replacedToken) {
+ this.replacedToken = replacedToken;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/CLPMapper.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/CLPMapper.java
index 54ab0da7578ca..21f9e22f34d89 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/CLPMapper.java
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/CLPMapper.java
@@ -15,7 +15,13 @@
*/
package com.navercorp.pinpoint.exceptiontrace.web.mapper;
+
+import org.apache.commons.text.StringEscapeUtils;
+
import java.nio.charset.StandardCharsets;
+import java.util.function.Function;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* @author intr3p1d
@@ -26,17 +32,76 @@ public class CLPMapper {
public final static char DICTIONARY_VARIABLE_VALUE = '\u0011';
public final static char NON_DICTIONARY_VALUE = '\u0012';
- public final static String DICTIONARY_REPLACEMENT = "▨▨▨";
- public final static String NON_DICTIONARY_REPLACEMENT = "▧▧▧";
+ public final static String DICTIONARY_REPLACEMENT = "";
+ public final static String NON_DICTIONARY_REPLACEMENT = "";
+
+ public final static String SIMPLE_REPLACEMENT = "▨▨▨";
+
+ static String fixAndEscapeLogType(String encodedLogType) {
+ return replaceDictPlaceHolder(replaceNonDictPlaceHolder(
+ escapeXml(correctEncoding(
+ encodedLogType
+ ))
+ ));
+ }
+
+ static String processEncodedLogType(String encodedLogType) {
+ return replaceSimple(correctEncoding(
+ encodedLogType
+ ));
+ }
- static String makeReadableString(String encodedLogType) {
- byte[] encodedLogTypeBytes = encodedLogType.getBytes(StandardCharsets.ISO_8859_1);
+ static String correctEncoding(String isoString) {
+ byte[] encodedLogTypeBytes = isoString.getBytes(StandardCharsets.ISO_8859_1);
return new String(encodedLogTypeBytes, StandardCharsets.UTF_8);
}
- static String replacePlaceHolders(String encodedLogType) {
- return encodedLogType
- .replaceAll(String.valueOf(DICTIONARY_VARIABLE_VALUE), DICTIONARY_REPLACEMENT)
- .replaceAll(String.valueOf(NON_DICTIONARY_VALUE), NON_DICTIONARY_REPLACEMENT);
+ static String escapeXml(String rawString) {
+ return StringEscapeUtils.escapeHtml4(rawString);
+ }
+
+ static String replaceNonDictPlaceHolder(String encodedLogType) {
+ return replaceHolder(
+ encodedLogType,
+ String.valueOf(NON_DICTIONARY_VALUE),
+ x -> stringFunction(NON_DICTIONARY_REPLACEMENT, x)
+ );
+ }
+
+ static String replaceDictPlaceHolder(String encodedLogType) {
+ return replaceHolder(
+ encodedLogType,
+ String.valueOf(DICTIONARY_VARIABLE_VALUE),
+ x -> stringFunction(DICTIONARY_REPLACEMENT, x)
+ );
+ }
+
+ static String replaceSimple(String encodedLogType) {
+ return replaceHolder(replaceHolder(
+ encodedLogType,
+ String.valueOf((DICTIONARY_VARIABLE_VALUE)),
+ x -> stringFunction(SIMPLE_REPLACEMENT, x)
+ ),
+ String.valueOf(NON_DICTIONARY_VALUE),
+ x -> stringFunction(SIMPLE_REPLACEMENT, x)
+ );
+ }
+
+ static String stringFunction(String format, int index) {
+ return String.format(format, index);
+ }
+
+ static String replaceHolder(String encodedLogType, String replacedCharacter, Function replacement) {
+ Pattern pattern = Pattern.compile(replacedCharacter);
+ Matcher matcher = pattern.matcher(encodedLogType);
+ StringBuilder result = new StringBuilder();
+ int wordCount = 0;
+
+ while (matcher.find()) {
+ matcher.appendReplacement(result, replacement.apply(wordCount++));
+ }
+ matcher.appendTail(result);
+
+ return result.toString();
}
}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/ExceptionMetaDataEntityMapper.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/ExceptionMetaDataEntityMapper.java
index 37180f934a953..826d410757cce 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/ExceptionMetaDataEntityMapper.java
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/ExceptionMetaDataEntityMapper.java
@@ -18,10 +18,12 @@
import com.navercorp.pinpoint.common.server.mapper.MapStructUtils;
import com.navercorp.pinpoint.common.util.StringUtils;
import com.navercorp.pinpoint.exceptiontrace.common.model.ExceptionMetaData;
+import com.navercorp.pinpoint.exceptiontrace.web.entity.ClpConvertedEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionMetaDataEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionTraceSummaryEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionTraceValueViewEntity;
import com.navercorp.pinpoint.exceptiontrace.web.entity.GroupedFieldNameEntity;
+import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceSummary;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceValueView;
import com.navercorp.pinpoint.exceptiontrace.web.model.Grouped;
@@ -38,10 +40,12 @@
import org.mapstruct.Mappings;
import org.mapstruct.Named;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
import java.util.List;
+import java.util.function.Function;
-import static com.navercorp.pinpoint.exceptiontrace.web.mapper.CLPMapper.makeReadableString;
-import static com.navercorp.pinpoint.exceptiontrace.web.mapper.CLPMapper.replacePlaceHolders;
+import static com.navercorp.pinpoint.exceptiontrace.web.mapper.CLPMapper.fixAndEscapeLogType;
/**
* @author intr3p1d
@@ -58,7 +62,8 @@
public interface ExceptionMetaDataEntityMapper {
@Mappings({
- @Mapping(source = ".", target = "stackTrace", qualifiedBy = StackTraceMapper.StringsToStackTrace.class),
+ @Mapping(source = ".", target = "stackTrac" +
+ "e", qualifiedBy = StackTraceMapper.StringsToStackTrace.class),
})
ExceptionMetaData toModel(ExceptionMetaDataEntity entity);
@@ -86,6 +91,11 @@ ExceptionTraceSummary toSummary(
List attributesList
);
+ @Mappings({
+ })
+ ClpConverted toClpConverted(ClpConvertedEntity entity);
+
+
@AfterMapping
default void addRawGroupedFieldName(
ExceptionTraceSummaryEntity entity,
@@ -98,18 +108,42 @@ default void addRawGroupedFieldName(
case STACK_TRACE -> groupedFieldName.setStackTraceHash(checkIfNull(entity.getStackTraceHash()));
case URI_TEMPLATE -> groupedFieldName.setUriTemplate(checkIfNull(entity.getUriTemplate()));
case ERROR_CLASS_NAME -> groupedFieldName.setErrorClassName(checkIfNull(entity.getErrorClassName()));
- case ERROR_MESSAGE_LOG_TYPE ->
- groupedFieldName.setErrorMessage_logtype(checkIfNull(entity.getErrorMessage_logtype()));
+ case ERROR_MESSAGE_LOG_TYPE -> groupedFieldName.setErrorMessage_logtype(checkIfNull(
+ encode(entity.getErrorMessage_logtype())));
}
}
summary.setRawFieldName(groupedFieldName);
}
+ @Named("encode")
+ default String encode(String string) {
+ return URLEncoder.encode(string, StandardCharsets.UTF_8);
+ }
+
@AfterMapping
+ default void addGroupedFieldNameToSummary(
+ GroupedFieldNameEntity entity,
+ List attributesList,
+ @MappingTarget ExceptionTraceSummary exceptionTraceSummary
+ ) {
+ addGroupedFieldName(entity, attributesList, exceptionTraceSummary, CLPMapper::fixAndEscapeLogType);
+ }
+
+ @AfterMapping
+ default void addGroupedFieldNameToValueView(
+ GroupedFieldNameEntity entity,
+ List attributesList,
+ @MappingTarget ExceptionTraceValueView exceptionTraceValueView
+ ) {
+ addGroupedFieldName(entity, attributesList, exceptionTraceValueView, CLPMapper::processEncodedLogType);
+ }
+
+ @Named("addGroupedFieldName")
default void addGroupedFieldName(
GroupedFieldNameEntity entity,
List attributesList,
- @MappingTarget Grouped grouped
+ @MappingTarget Grouped grouped,
+ Function function
) {
GroupedFieldName groupedFieldName = new GroupedFieldName();
for (GroupByAttributes attributes : attributesList) {
@@ -118,7 +152,9 @@ default void addGroupedFieldName(
case URI_TEMPLATE -> groupedFieldName.setUriTemplate(checkIfNull(entity.getUriTemplate()));
case ERROR_CLASS_NAME -> groupedFieldName.setErrorClassName(checkIfNull(entity.getErrorClassName()));
case ERROR_MESSAGE_LOG_TYPE ->
- groupedFieldName.setErrorMessage(checkIfNull(selectErrorMessage(entity)));
+ groupedFieldName.setErrorMessage(checkIfNull(
+ function.apply(entity.getErrorMessage_logtype())
+ ));
}
}
grouped.setGroupedFieldName(groupedFieldName);
@@ -127,9 +163,7 @@ default void addGroupedFieldName(
@Named("selectErrorMessage")
default String selectErrorMessage(GroupedFieldNameEntity entity) {
if (entity.getErrorMessage_logtype() != null) {
- return replacePlaceHolders(
- makeReadableString(entity.getErrorMessage_logtype())
- );
+ return fixAndEscapeLogType(entity.getErrorMessage_logtype());
}
return entity.getErrorMessage();
}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/model/ClpConverted.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/model/ClpConverted.java
new file mode 100644
index 0000000000000..478f6e5e95444
--- /dev/null
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/model/ClpConverted.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2024 NAVER Corp.
+ *
+ * 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.navercorp.pinpoint.exceptiontrace.web.model;
+
+import java.util.List;
+
+/**
+ * @author intr3p1d
+ */
+public class ClpConverted {
+
+ private String replacedToken;
+ private int count;
+
+
+ public ClpConverted() {
+ }
+
+ public String getReplacedToken() {
+ return replacedToken;
+ }
+
+ public void setReplacedToken(String replacedToken) {
+ this.replacedToken = replacedToken;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/query/ClpQueryParameter.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/query/ClpQueryParameter.java
new file mode 100644
index 0000000000000..d33aecf7f3c26
--- /dev/null
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/query/ClpQueryParameter.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2024 NAVER Corp.
+ *
+ * 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.navercorp.pinpoint.exceptiontrace.web.query;
+
+import com.navercorp.pinpoint.exceptiontrace.web.util.ClpReplacedColumns;
+import com.navercorp.pinpoint.metric.web.util.QueryParameter;
+
+/**
+ * @author intr3p1d
+ */
+public class ClpQueryParameter extends QueryParameter {
+
+ private final String tableName;
+ private final String tenantId;
+ private final String applicationName;
+ private final String agentId;
+
+ private final ClpReplacedColumns targetColumn;
+ private final int targetIndex;
+ private final String logType;
+
+ protected ClpQueryParameter(Builder builder) {
+ super(builder.getRange(), builder.getTimePrecision(), builder.getLimit());
+ this.tableName = builder.tableName;
+ this.tenantId = builder.tenantId;
+ this.applicationName = builder.applicationName;
+ this.agentId = builder.agentId;
+ this.targetColumn = builder.targetColumn;
+ this.targetIndex = builder.targetIndex;
+ this.logType = builder.logType;
+ }
+
+ public static class Builder extends QueryParameter.Builder {
+
+ private String tableName;
+ private String tenantId;
+ private String applicationName;
+ private String agentId;
+
+ private ClpReplacedColumns targetColumn;
+ private int targetIndex;
+ private String logType;
+
+ @Override
+ protected Builder self() {
+ return this;
+ }
+
+
+ public Builder setTableName(String tableName) {
+ this.tableName = tableName;
+ return self();
+ }
+
+ public Builder setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ return self();
+ }
+
+ public Builder setApplicationName(String applicationName) {
+ this.applicationName = applicationName;
+ return self();
+ }
+
+ public Builder setAgentId(String agentId) {
+ this.agentId = agentId;
+ return self();
+ }
+
+ public Builder setTargetColumn(String targetColumn) {
+ this.targetColumn = ClpReplacedColumns.fromValue(targetColumn);
+ return self();
+ }
+
+ public Builder setTargetIndex(int targetIndex) {
+ this.targetIndex = targetIndex;
+ return self();
+ }
+
+ public Builder setLogType(String logType) {
+ this.logType = logType;
+ return self();
+ }
+
+ @Override
+ public ClpQueryParameter build() {
+ return new ClpQueryParameter(this);
+ }
+ }
+
+
+ @Override
+ public String toString() {
+ return "ClpQueryParameter{" +
+ "tableName='" + tableName + '\'' +
+ ", tenantId='" + tenantId + '\'' +
+ ", applicationName='" + applicationName + '\'' +
+ ", agentId='" + agentId + '\'' +
+ ", targetColumn=" + targetColumn +
+ ", targetIndex=" + targetIndex +
+ ", logType='" + logType + '\'' +
+ '}';
+ }
+}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/util/ExceptionTraceQueryParameter.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/query/ExceptionTraceQueryParameter.java
similarity index 96%
rename from exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/util/ExceptionTraceQueryParameter.java
rename to exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/query/ExceptionTraceQueryParameter.java
index 24bcb2406ae7c..ebee58631e941 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/util/ExceptionTraceQueryParameter.java
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/query/ExceptionTraceQueryParameter.java
@@ -14,13 +14,14 @@
* limitations under the License.
*/
-package com.navercorp.pinpoint.exceptiontrace.web.util;
+package com.navercorp.pinpoint.exceptiontrace.web.query;
import com.navercorp.pinpoint.common.util.StringUtils;
-import com.navercorp.pinpoint.exceptiontrace.web.ExceptionTraceWebConfig;
+import com.navercorp.pinpoint.exceptiontrace.web.util.FilterByAttributes;
+import com.navercorp.pinpoint.exceptiontrace.web.util.GroupByAttributes;
+import com.navercorp.pinpoint.exceptiontrace.web.util.OrderByAttributes;
import com.navercorp.pinpoint.metric.web.util.QueryParameter;
import com.navercorp.pinpoint.metric.web.util.TimePrecision;
-import org.springframework.beans.factory.annotation.Value;
import java.security.InvalidParameterException;
import java.util.ArrayList;
@@ -28,7 +29,6 @@
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
/**
* @author intr3p1d
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/service/ExceptionTraceService.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/service/ExceptionTraceService.java
index c25217898bc4e..ecc7fce80ac25 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/service/ExceptionTraceService.java
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/service/ExceptionTraceService.java
@@ -16,9 +16,11 @@
package com.navercorp.pinpoint.exceptiontrace.web.service;
+import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceSummary;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceValueView;
-import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter;
import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionMetaDataView;
import java.util.List;
@@ -35,4 +37,6 @@ public interface ExceptionTraceService {
List getSummaries(ExceptionTraceQueryParameter queryParameter);
List getValueViews(ExceptionTraceQueryParameter queryParameter);
+
+ List getReplacedVariables(ClpQueryParameter queryParameter);
}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/service/ExceptionTraceServiceImpl.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/service/ExceptionTraceServiceImpl.java
index 05710625d9f5e..0d160e072127d 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/service/ExceptionTraceServiceImpl.java
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/service/ExceptionTraceServiceImpl.java
@@ -17,9 +17,11 @@
package com.navercorp.pinpoint.exceptiontrace.web.service;
import com.navercorp.pinpoint.exceptiontrace.web.dao.ExceptionTraceDao;
+import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceSummary;
import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionTraceValueView;
-import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter;
+import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter;
import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionMetaDataView;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -99,4 +101,13 @@ private List getExceptionTraceSummaries(ExceptionTraceQue
private List getExceptionTraceValueViews(ExceptionTraceQueryParameter queryParameter) {
return exceptionTraceDao.getValueViews(queryParameter);
}
+
+
+ @Override
+ public List getReplacedVariables(ClpQueryParameter queryParameter) {
+ return exceptionTraceDao.getReplacedVariables(queryParameter);
+ }
+
+
+
}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/util/ClpReplacedColumns.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/util/ClpReplacedColumns.java
new file mode 100644
index 0000000000000..e6781887cfa0b
--- /dev/null
+++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/util/ClpReplacedColumns.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2024 NAVER Corp.
+ *
+ * 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.navercorp.pinpoint.exceptiontrace.web.util;
+
+import com.navercorp.pinpoint.common.server.util.EnumGetter;
+import com.navercorp.pinpoint.exceptiontrace.common.pinot.PinotColumns;
+import com.navercorp.pinpoint.exceptiontrace.common.pinot.PinotFunctions;
+
+/**
+ * @author intr3p1d
+ */
+public enum ClpReplacedColumns {
+
+ ERROR_MESSAGE_ENCODED_VARS("non-dict", PinotColumns.ERROR_MESSAGE_ENCODED_VARS, PinotFunctions.ARRAY_SLICE_INT),
+ ERROR_MESSAGE_DICTIONARY_VARS("dict", PinotColumns.ERROR_MESSAGE_DICTIONARY_VARS, PinotFunctions.ARRAY_SLICE_STRING);
+
+ private static final EnumGetter GETTER = new EnumGetter<>(ClpReplacedColumns.class);
+
+ private final String name;
+ private final PinotColumns columns;
+ private final PinotFunctions sliceFunction;
+
+ ClpReplacedColumns(String name, PinotColumns columns, PinotFunctions sliceFunction) {
+ this.name = name;
+ this.columns = columns;
+ this.sliceFunction = sliceFunction;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public PinotColumns getColumns() {
+ return columns;
+ }
+
+ public PinotFunctions getSliceFunction() {
+ return sliceFunction;
+ }
+
+ public static ClpReplacedColumns fromValue(String name) {
+ return GETTER.fromValue(ClpReplacedColumns::getName, name);
+ }
+}
diff --git a/exceptiontrace/exceptiontrace-web/src/main/resources/exceptiontrace/mapper/ExceptionTraceMapper.xml b/exceptiontrace/exceptiontrace-web/src/main/resources/exceptiontrace/mapper/ExceptionTraceMapper.xml
index a9826c4e0b5b6..0f451269d3cdd 100644
--- a/exceptiontrace/exceptiontrace-web/src/main/resources/exceptiontrace/mapper/ExceptionTraceMapper.xml
+++ b/exceptiontrace/exceptiontrace-web/src/main/resources/exceptiontrace/mapper/ExceptionTraceMapper.xml
@@ -10,6 +10,9 @@
+
+
+
${tableName}
@@ -21,7 +24,7 @@
-
+
AND ${key.column.name}=#{value}
@@ -42,7 +45,8 @@
- ,
+ ,
+
@@ -66,7 +70,8 @@
agentId,
uriTemplate,
errorClassName,
- as "errorMessage",
+
+ as "errorMessage",
exceptionDepth,
stackTraceClassName,
stackTraceFileName,
@@ -87,7 +92,8 @@
agentId,
uriTemplate,
errorClassName,
- as "errorMessage",
+
+ as "errorMessage",
exceptionDepth,
stackTraceHash
@@ -95,9 +101,9 @@