diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ObservationConfig.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ObservationConfig.java new file mode 100644 index 000000000000..6d54c2ab3498 --- /dev/null +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/configurations/ObservationConfig.java @@ -0,0 +1,36 @@ +package com.appsmith.server.configurations; + +import com.appsmith.server.constants.FieldName; +import com.appsmith.server.exceptions.AppsmithException; +import io.micrometer.common.KeyValue; +import io.micrometer.common.KeyValues; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.server.reactive.observation.DefaultServerRequestObservationConvention; +import org.springframework.http.server.reactive.observation.ServerRequestObservationContext; +import org.springframework.http.server.reactive.observation.ServerRequestObservationConvention; + +@Configuration +public class ObservationConfig { + + @Bean + public ServerRequestObservationConvention customObservationConvention() { + return new DefaultServerRequestObservationConvention() { + @Override + public KeyValues getLowCardinalityKeyValues(ServerRequestObservationContext context) { + KeyValues keyValues = super.getLowCardinalityKeyValues(context); + + // Extract error code safely + String errorCode = context.getError() != null && context.getError() instanceof AppsmithException + ? (((AppsmithException) context.getError()).getAppErrorCode()) + : FieldName.NONE; + + String errorTitle = context.getError() != null && context.getError() instanceof AppsmithException + ? (((AppsmithException) context.getError()).getTitle()) + : FieldName.NONE; + + return keyValues.and(KeyValue.of("errorCode", errorCode)).and(KeyValue.of("exception", errorTitle)); + } + }; + } +} diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java index 4a2aa044ce01..ab487f3e12e5 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/constants/ce/FieldNameCE.java @@ -203,4 +203,5 @@ public class FieldNameCE { public static final String ARTIFACT_CONTEXT = "artifactContext"; public static final String ARTIFACT_ID = "artifactId"; public static final String BODY = "body"; + public static final String NONE = "none"; } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java index f9ef6a4dfb41..9c73bd563940 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/GlobalExceptionHandler.java @@ -10,6 +10,7 @@ import com.appsmith.server.helpers.RedisUtils; import com.appsmith.server.services.AnalyticsService; import com.appsmith.server.services.SessionUserService; +import io.micrometer.common.KeyValue; import io.micrometer.core.instrument.util.StringUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -17,6 +18,7 @@ import org.eclipse.jgit.errors.LockFailedException; import org.springframework.core.io.buffer.DataBufferLimitException; import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.observation.ServerRequestObservationContext; import org.springframework.security.access.AccessDeniedException; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.ControllerAdvice; @@ -84,6 +86,12 @@ public Mono> catchAppsmithException(AppsmithException e, S e.getAppErrorCode(), e.getErrorType(), e.getMessage(), e.getTitle(), e.getReferenceDoc())); } + ServerRequestObservationContext.findCurrent(exchange.getAttributes()).ifPresent(context -> { + context.setError(e); + context.addLowCardinalityKeyValue(KeyValue.of("errorCode", e.getAppErrorCode())); + context.addLowCardinalityKeyValue(KeyValue.of("exception", e.getTitle())); + }); + return getResponseDTOMono(urlPath, response); }