From d1d2fd226ac782ad356b8bf94f3464730768ab56 Mon Sep 17 00:00:00 2001 From: Seoyoung Park Date: Fri, 23 Aug 2024 16:45:03 +0900 Subject: [PATCH] [#9631] Add API to retrieve CLP replaced tokens with count and ordering --- .../common/pinot/PinotFunctions.java | 34 +++++ exceptiontrace/exceptiontrace-web/pom.xml | 9 ++ .../config/ExceptionTraceRegistryHandler.java | 6 +- .../controller/ExceptionTraceController.java | 35 +++++- .../web/dao/ExceptionTraceDao.java | 5 +- .../web/dao/PinotExceptionTraceDao.java | 15 ++- .../web/entity/ClpConvertedEntity.java | 44 +++++++ .../exceptiontrace/web/mapper/CLPMapper.java | 81 ++++++++++-- .../web/mapper/ExceptionEntityMapper.java | 32 +++-- .../web/model/ClpConverted.java | 47 +++++++ .../web/query/ClpQueryParameter.java | 117 ++++++++++++++++++ .../ExceptionTraceQueryParameter.java | 8 +- .../web/service/ExceptionTraceService.java | 5 +- .../service/ExceptionTraceServiceImpl.java | 9 +- .../web/util/ClpReplacedColumns.java | 57 +++++++++ .../mapper/ExceptionMetadataMapper.xml | 37 ++++-- .../web/mapper/CLPMapperTest.java | 12 +- 17 files changed, 513 insertions(+), 40 deletions(-) create mode 100644 exceptiontrace/exceptiontrace-common/src/main/java/com/navercorp/pinpoint/exceptiontrace/common/pinot/PinotFunctions.java create mode 100644 exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/entity/ClpConvertedEntity.java create mode 100644 exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/model/ClpConverted.java create mode 100644 exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/query/ClpQueryParameter.java rename exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/{util => query}/ExceptionTraceQueryParameter.java (96%) create mode 100644 exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/util/ClpReplacedColumns.java 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 000000000000..d2d35af12f17 --- /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 7b279ecd67c2..095155f79ab2 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 b2c62a8dfdad..9ab9f43d30bd 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 @@ -18,9 +18,11 @@ import com.navercorp.pinpoint.exceptiontrace.web.entity.ErrorSummaryEntity; import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionChartValueViewEntity; import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionGroupSummaryEntity; +import com.navercorp.pinpoint.exceptiontrace.web.entity.ClpConvertedEntity; import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionMetaDataEntity; 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; @@ -36,7 +38,9 @@ public void registerTypeAlias(TypeAliasRegistry typeAliasRegistry) { typeAliasRegistry.registerAlias(ErrorSummaryEntity.class); typeAliasRegistry.registerAlias(ExceptionGroupSummaryEntity.class); typeAliasRegistry.registerAlias(ExceptionChartValueViewEntity.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 6ed3de1074c0..048839a69b27 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 @@ -20,9 +20,11 @@ import com.navercorp.pinpoint.common.server.util.time.RangeValidator; import com.navercorp.pinpoint.exceptiontrace.web.model.ErrorSummary; import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionGroupSummary; +import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionChartValueView; +import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted; +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.util.GroupByAttributes; import com.navercorp.pinpoint.exceptiontrace.web.view.ErrorSummaryView; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionDetailView; @@ -197,6 +199,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 ExceptionChartView 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 c23e274403b3..077c433de5f1 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 @@ -20,9 +20,11 @@ import com.navercorp.pinpoint.exceptiontrace.common.model.ExceptionMetaData; import com.navercorp.pinpoint.exceptiontrace.web.model.ErrorSummary; import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionGroupSummary; +import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionChartValueView; -import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionDetailView; +import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted; +import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter; import java.util.List; @@ -36,4 +38,5 @@ public interface ExceptionTraceDao { List getGroupSummaries(ExceptionTraceQueryParameter exceptionTraceQueryParameter); List getChartValueViews(ExceptionTraceQueryParameter exceptionTraceQueryParameter); List getErrorSummaries(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 d4f97267c8b6..59d75423226d 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 @@ -19,14 +19,17 @@ import com.navercorp.pinpoint.exceptiontrace.common.model.ExceptionMetaData; import com.navercorp.pinpoint.exceptiontrace.web.entity.ErrorSummaryEntity; import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionGroupSummaryEntity; +import com.navercorp.pinpoint.exceptiontrace.web.entity.ClpConvertedEntity; import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionMetaDataEntity; import com.navercorp.pinpoint.exceptiontrace.web.model.ErrorSummary; import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionChartValueViewEntity; import com.navercorp.pinpoint.exceptiontrace.web.mapper.ExceptionEntityMapper; import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionGroupSummary; -import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter; +import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionChartValueView; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionDetailView; +import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted; +import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.mybatis.spring.SqlSessionTemplate; @@ -52,6 +55,7 @@ public class PinotExceptionTraceDao implements ExceptionTraceDao { private static final String SELECT_GROUP_SUMMARIES_QUERY = "selectGroupSummaries"; private static final String SELECT_CHART_QUERY = "selectChartValueViews"; private static final String SELECT_ERROR_SUMMARIES_QUERY = "selectErrorSummaries"; + private static final String SELECT_CLP_VARIABLES_QUERY = "selectClpVariables"; private final SqlSessionTemplate sqlPinotSessionTemplate; @@ -124,4 +128,13 @@ public List getErrorSummaries(ExceptionTraceQueryParameter excepti ) ).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 000000000000..a7917d4bda26 --- /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 54ab0da7578c..21f9e22f34d8 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/ExceptionEntityMapper.java b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/ExceptionEntityMapper.java index 61c023053437..051fc772e199 100644 --- a/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/ExceptionEntityMapper.java +++ b/exceptiontrace/exceptiontrace-web/src/main/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/ExceptionEntityMapper.java @@ -21,10 +21,12 @@ import com.navercorp.pinpoint.exceptiontrace.web.entity.ErrorSummaryEntity; import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionChartValueViewEntity; import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionGroupSummaryEntity; +import com.navercorp.pinpoint.exceptiontrace.web.entity.ClpConvertedEntity; import com.navercorp.pinpoint.exceptiontrace.web.entity.ExceptionMetaDataEntity; import com.navercorp.pinpoint.exceptiontrace.web.entity.GroupedFieldNameEntity; import com.navercorp.pinpoint.exceptiontrace.web.model.ErrorSummary; import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionGroupSummary; +import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted; import com.navercorp.pinpoint.exceptiontrace.web.model.Grouped; import com.navercorp.pinpoint.exceptiontrace.web.model.GroupedFieldName; import com.navercorp.pinpoint.exceptiontrace.web.model.params.GroupFilterParams; @@ -40,10 +42,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 @@ -60,7 +64,8 @@ public interface ExceptionEntityMapper { @Mappings({ - @Mapping(source = ".", target = "stackTrace", qualifiedBy = StackTraceMapper.StringsToStackTrace.class), + @Mapping(source = ".", target = "stackTrac" + + "e", qualifiedBy = StackTraceMapper.StringsToStackTrace.class), }) ExceptionMetaData toModel(ExceptionMetaDataEntity entity); @@ -98,6 +103,11 @@ ErrorSummary toErrorSummary( List attributesList ); + @Mappings({ + }) + ClpConverted toClpConverted(ClpConvertedEntity entity); + + @AfterMapping default void addGroupFilterParams( GroupedFieldNameEntity entity, @@ -117,7 +127,12 @@ default void addGroupFilterParams( grouped.setGroupFilterParams(params); } - @AfterMapping + @Named("encode") + default String encode(String string) { + return URLEncoder.encode(string, StandardCharsets.UTF_8); + } + + @Named("addGroupedFieldName") default void addGroupedFieldName( GroupedFieldNameEntity entity, List attributesList, @@ -129,8 +144,9 @@ default void addGroupedFieldName( 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(checkIfNull(selectErrorMessage(entity))); + case ERROR_MESSAGE_LOG_TYPE -> groupedFieldName.setErrorMessage(checkIfNull( + entity.getErrorMessage_logtype() + )); } } grouped.setGroupedFieldName(groupedFieldName); @@ -139,9 +155,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 000000000000..478f6e5e9544 --- /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 000000000000..d33aecf7f3c2 --- /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 045612810201..f3e649a21624 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 d662fe8fc442..8460c77848a1 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 @@ -18,9 +18,11 @@ import com.navercorp.pinpoint.exceptiontrace.web.model.ErrorSummary; import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionGroupSummary; -import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter; +import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionChartValueView; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionDetailView; +import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted; +import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter; import java.util.List; @@ -37,4 +39,5 @@ public interface ExceptionTraceService { List getChartViews(ExceptionTraceQueryParameter queryParameter); List getErrorSummaries(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 b1435c61b0ec..b5291572df50 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 @@ -19,9 +19,11 @@ import com.navercorp.pinpoint.exceptiontrace.web.dao.ExceptionTraceDao; import com.navercorp.pinpoint.exceptiontrace.web.model.ErrorSummary; import com.navercorp.pinpoint.exceptiontrace.web.model.ExceptionGroupSummary; -import com.navercorp.pinpoint.exceptiontrace.web.util.ExceptionTraceQueryParameter; +import com.navercorp.pinpoint.exceptiontrace.web.query.ExceptionTraceQueryParameter; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionDetailView; import com.navercorp.pinpoint.exceptiontrace.web.view.ExceptionChartValueView; +import com.navercorp.pinpoint.exceptiontrace.web.model.ClpConverted; +import com.navercorp.pinpoint.exceptiontrace.web.query.ClpQueryParameter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.stereotype.Service; @@ -67,4 +69,9 @@ public List getChartViews(ExceptionTraceQueryParameter public List getErrorSummaries(ExceptionTraceQueryParameter queryParameter) { return exceptionTraceDao.getErrorSummaries(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 000000000000..e6781887cfa0 --- /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/ExceptionMetadataMapper.xml b/exceptiontrace/exceptiontrace-web/src/main/resources/exceptiontrace/mapper/ExceptionMetadataMapper.xml index cd773d120dfd..e0fc5deebe54 100644 --- a/exceptiontrace/exceptiontrace-web/src/main/resources/exceptiontrace/mapper/ExceptionMetadataMapper.xml +++ b/exceptiontrace/exceptiontrace-web/src/main/resources/exceptiontrace/mapper/ExceptionMetadataMapper.xml @@ -53,9 +53,9 @@ SELECT - + FROM - + WHERE tenantId = #{tenantId} AND applicationName = #{applicationName} @@ -89,7 +89,7 @@ AND agentId = #{agentId} - + ORDER BY ${orderBy.getAttributeName} ${isDesc} LIMIT ${limit} @@ -97,9 +97,9 @@ + + + \ No newline at end of file diff --git a/exceptiontrace/exceptiontrace-web/src/test/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/CLPMapperTest.java b/exceptiontrace/exceptiontrace-web/src/test/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/CLPMapperTest.java index e8088dc99bd9..f214c47777e9 100644 --- a/exceptiontrace/exceptiontrace-web/src/test/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/CLPMapperTest.java +++ b/exceptiontrace/exceptiontrace-web/src/test/java/com/navercorp/pinpoint/exceptiontrace/web/mapper/CLPMapperTest.java @@ -6,8 +6,8 @@ import java.io.IOException; -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.correctEncoding; +import static com.navercorp.pinpoint.exceptiontrace.web.mapper.CLPMapper.replaceSimple; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -23,7 +23,7 @@ public void testEncodedLogtype() { String example = "INFO Task \u0011\u0000 assigned to container: [NodeAddress:\u0011\u0001, ...\n" + "ContainerID:\u0011\u0002], operation took \u0012\u0013 seconds"; - String replaced = replacePlaceHolders(example); + String replaced = replaceSimple(example); logger.info(example); logger.info(replaced); assertNotEquals(example, replaced); @@ -36,7 +36,7 @@ public void testMakeReadable1() throws IOException { String rawExample = "getAgentsList.from: \u0011 ì\u009D´ì\u0083\u0081ì\u009D´ì\u0096´ì\u0095¼ í\u0095©ë\u008B\u0088ë\u008B¤"; String example = "getAgentsList.from: \u0011 이상이어야 합니다"; - assertEquals(example, makeReadableString(rawExample)); + assertEquals(example, correctEncoding(rawExample)); } @Test @@ -44,7 +44,7 @@ public void testMakeReadable2() { String rawExample = "\\n not found: limit=\u0011 content=â\u0080¦"; String example = "\\n not found: limit=\u0011 content=…"; - assertEquals(example, makeReadableString(rawExample)); + assertEquals(example, correctEncoding(rawExample)); } @Test @@ -52,6 +52,6 @@ public void testMakeReadable3() { String rawExample = "Request processing failed: jakarta.validation.ConstraintViolationException"; String example = "Request processing failed: jakarta.validation.ConstraintViolationException"; - assertEquals(example, makeReadableString(rawExample)); + assertEquals(example, correctEncoding(rawExample)); } } \ No newline at end of file