Skip to content

Commit

Permalink
Add rule based error classification
Browse files Browse the repository at this point in the history
  • Loading branch information
itsankit-google committed Feb 7, 2025
1 parent f3955ad commit 6135feb
Show file tree
Hide file tree
Showing 7 changed files with 526 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,7 @@ public static final class Logging {
public static final String USER_LOG_TAG_VALUE = "userLog";
public static final String TAG_FAILED_STAGE = "failedStage";
public static final String TAG_ERROR_CATEGORY = "errorCategory";
public static final String TAG_PARENT_ERROR_CATEGORY = "parentErrorCategory";
public static final String TAG_ERROR_REASON = "errorReason";
public static final String TAG_ERROR_TYPE = "errorType";
public static final String TAG_DEPENDENCY = "dependency";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@ public final class ErrorClassificationResponse {
private final String errorCodeType;
private final String errorCode;
private final String supportedDocumentationUrl;
private transient final String throwableClassName;

private ErrorClassificationResponse(String stageName, String errorCategory, String errorReason,
String errorMessage, String errorType, String dependency, String errorCodeType,
String errorCode, String supportedDocumentationUrl, String throwableClassName) {
String errorCode, String supportedDocumentationUrl) {
this.stageName = stageName;
this.errorCategory = errorCategory;
this.errorReason = errorReason;
Expand All @@ -45,7 +44,6 @@ private ErrorClassificationResponse(String stageName, String errorCategory, Stri
this.errorCodeType = errorCodeType;
this.errorCode = errorCode;
this.supportedDocumentationUrl = supportedDocumentationUrl;
this.throwableClassName = throwableClassName;
}

/**
Expand Down Expand Up @@ -111,13 +109,6 @@ public String getSupportedDocumentationUrl() {
return supportedDocumentationUrl;
}

/**
* Gets the throwable class name for ErrorClassificationResponse.
*/
public String getThrowableClassName() {
return throwableClassName;
}

@Override
public boolean equals(Object o) {
if (!(o instanceof ErrorClassificationResponse)) {
Expand Down Expand Up @@ -154,7 +145,6 @@ public static class Builder {
private String errorCodeType;
private String errorCode;
private String supportedDocumentationUrl;
private String throwableClassName;

/**
* Sets the stage name for ErrorClassificationResponse.
Expand Down Expand Up @@ -228,21 +218,12 @@ public Builder setSupportedDocumentationUrl(String supportedDocumentationUrl) {
return this;
}

/**
* Sets the throwable class name for ErrorClassificationResponse.
*/
public Builder setThrowableClassName(String throwableClassName) {
this.throwableClassName = throwableClassName;
return this;
}

/**
* Builds and returns a new instance of ErrorClassificationResponse.
*/
public ErrorClassificationResponse build() {
return new ErrorClassificationResponse(stageName, errorCategory, errorReason, errorMessage,
errorType, dependency, errorCodeType, errorCode, supportedDocumentationUrl,
throwableClassName);
errorType, dependency, errorCodeType, errorCode, supportedDocumentationUrl);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright © 2025 Cask Data, Inc.
*
* 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 io.cdap.cdap.logging;

import io.cdap.cdap.proto.ErrorClassificationResponse;
import java.util.Objects;
import javax.annotation.Nullable;

/**
* Wrapper class for {@link ErrorClassificationResponse}.
*/
public final class ErrorClassificationResponseWrapper {
private final ErrorClassificationResponse errorClassificationResponse;
private final String parentErrorCategory;
private final String throwableClassName;
private final Integer rulePriority;
private final String ruleId;

/**
* Constructor for {@link ErrorClassificationResponseWrapper}.
*/
public ErrorClassificationResponseWrapper(ErrorClassificationResponse response,
String parentErrorCategory, String throwableClassName, @Nullable Integer rulePriority,
@Nullable String ruleId) {
this.errorClassificationResponse = response;
this.parentErrorCategory = parentErrorCategory;
this.throwableClassName = throwableClassName;
this.ruleId = ruleId;
this.rulePriority = rulePriority;
}

/**
* Gets the error classification response for ErrorClassificationResponse.
*/
public ErrorClassificationResponse getErrorClassificationResponse() {
return errorClassificationResponse;
}

/**
* Gets the parent error category for ErrorClassificationResponse.
*/
public String getParentErrorCategory() {
return parentErrorCategory;
}

/**
* Gets the throwable class name for ErrorClassificationResponse.
*/
public String getThrowableClassName() {
return throwableClassName;
}

/**
* Gets the rule priority for ErrorClassificationResponse.
*/
public Integer getRulePriority() {
return rulePriority == null ? Integer.MAX_VALUE : rulePriority;
}

/**
* Gets the rule id for ErrorClassificationResponse.
*/
public String getRuleId() {
return ruleId;
}

@Override
public boolean equals(Object o) {
if (!(o instanceof ErrorClassificationResponseWrapper)) {
return false;
}
ErrorClassificationResponseWrapper that = (ErrorClassificationResponseWrapper) o;

return Objects.equals(this.errorClassificationResponse, that.errorClassificationResponse)
&& Objects.equals(this.throwableClassName, that.throwableClassName)
&& Objects.equals(this.rulePriority, that.rulePriority)
&& Objects.equals(this.ruleId, that.ruleId);
}

@Override
public int hashCode() {
return Objects.hash(errorClassificationResponse, throwableClassName, rulePriority, ruleId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
* Copyright © 2025 Cask Data, Inc.
*
* 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 io.cdap.cdap.logging;

import com.google.common.base.Strings;
import io.cdap.cdap.api.exception.ErrorType;
import java.util.regex.Pattern;
import javax.annotation.Nullable;

/**
* Represents the rule for classifying error logs.
*/
public final class ErrorClassificationRule implements Comparable<ErrorClassificationRule> {
public static final Pattern DEFAULT_PATTERN = Pattern.compile(".*");
private final String id;
private final String description;
private final int priority;
private final String exceptionClassRegex;
private final String codeMethodRegex;
private final ErrorType errorType;
private final boolean dependency;
private Pattern exceptionClassRegexPattern;
private Pattern codeMethodRegexPattern;


private ErrorClassificationRule(String id, String description, int priority,
@Nullable String exceptionClassRegex, @Nullable String codeMethodRegex,
ErrorType errorType, boolean dependency) {
this.id = id;
this.description = description;
this.priority = priority;
this.exceptionClassRegex = exceptionClassRegex;
this.codeMethodRegex = codeMethodRegex;
this.errorType = errorType;
this.dependency = dependency;
}

/**
* Returns the id for ErrorClassificationRule.
*/
public String getId() {
return id;
}

/**
* Returns the description for ErrorClassificationRule.
*/
public String getDescription() {
return description;
}

/**
* Returns the priority for ErrorClassificationRule.
*/
public int getPriority() {
return priority;
}

/**
* Returns the exception class regex pattern for ErrorClassificationRule.
*/
public Pattern getExceptionClassRegex() {
if (this.exceptionClassRegexPattern == null) {
this.exceptionClassRegexPattern =
Strings.isNullOrEmpty(this.exceptionClassRegex) ? DEFAULT_PATTERN
: Pattern.compile(this.exceptionClassRegex);
}
return this.exceptionClassRegexPattern;
}

/**
* Returns the code method regex pattern for ErrorClassificationRule.
*/
public Pattern getCodeMethodRegex() {
if (this.codeMethodRegexPattern == null) {
this.codeMethodRegexPattern = Strings.isNullOrEmpty(this.codeMethodRegex) ? DEFAULT_PATTERN
: Pattern.compile(this.codeMethodRegex);
}
return this.codeMethodRegexPattern;
}

/**
* Returns the {@link ErrorType} for ErrorClassificationRule.
*/
public ErrorType getErrorType() {
return errorType == null ? ErrorType.UNKNOWN : errorType;
}

/**
* Returns the dependency flag for ErrorClassificationRule.
*/
public boolean isDependency() {
return dependency;
}

@Override
public int compareTo(ErrorClassificationRule that) {
return Integer.compare(this.priority, that.priority);
}

@Override
public String toString() {
return String.format("Rule Id: '%s', Description: '%s', Exception Class Name: '%s',"
+ "Code Method Regex: '%s', Error Type: '%s', Dependency: '%s'", id, description,
getExceptionClassRegex().pattern(), getCodeMethodRegex().pattern(), errorType, dependency);
}

/**
* Builder class for {@link ErrorClassificationRule}.
*/
public static class Builder {
private String id;
private String description;
private int priority;
private String exceptionClassRegex;
private String codeMethodRegex;
private ErrorType errorType;
private boolean dependency;

/**
* Sets the id for ErrorClassificationRule.
*/
public Builder setId(String id) {
this.id = id;
return this;
}

/**
* Sets the description for ErrorClassificationRule.
*/
public Builder setDescription(String description) {
this.description = description;
return this;
}

/**
* Sets the priority for ErrorClassificationRule.
*/
public Builder setPriority(int priority) {
this.priority = priority;
return this;
}

/**
* Sets the exception class name regex for ErrorClassificationRule.
*/
public Builder setExceptionClassName(String exceptionClassRegex) {
this.exceptionClassRegex = exceptionClassRegex;
return this;
}

/**
* Sets the code method regex for ErrorClassificationRule.
*/
public Builder setCodeMethodRegex(String codeMethodRegex) {
this.codeMethodRegex = codeMethodRegex;
return this;
}

/**
* Sets the {@link ErrorType} for ErrorClassificationRule.
*/
public Builder setErrorType(ErrorType errorType) {
this.errorType = errorType;
return this;
}

/**
* Sets the dependency flag for ErrorClassificationRule.
*/
public Builder setDependency(boolean dependency) {
this.dependency = dependency;
return this;
}

public ErrorClassificationRule build() {
return new ErrorClassificationRule(id, description, priority, exceptionClassRegex,
codeMethodRegex, errorType, dependency);
}
}
}
Loading

0 comments on commit 6135feb

Please sign in to comment.