Browse Source

1. stacktrace field added to error responses (#1145)

1. stacktrace field added to error responses (#1145)
2. lastError added to Cluster responce
3. blocking metrics initialization on startup changed to async init (returned to prev behavior)
Ilya Kuramshin 3 years ago
parent
commit
062367efcc

+ 9 - 4
kafka-ui-api/src/main/java/com/provectus/kafka/ui/exception/GlobalErrorWebExceptionHandler.java

@@ -1,5 +1,6 @@
 package com.provectus.kafka.ui.exception;
 
+import com.google.common.base.Throwables;
 import com.google.common.collect.Sets;
 import com.provectus.kafka.ui.model.ErrorResponseDTO;
 import java.math.BigDecimal;
@@ -73,7 +74,8 @@ public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHan
         .code(ErrorCode.UNEXPECTED.code())
         .message(coalesce(throwable.getMessage(), "Unexpected internal error"))
         .requestId(requestId(request))
-        .timestamp(currentTimestamp());
+        .timestamp(currentTimestamp())
+        .stackTrace(Throwables.getStackTraceAsString(throwable));
     return ServerResponse
         .status(ErrorCode.UNEXPECTED.httpStatus())
         .contentType(MediaType.APPLICATION_JSON)
@@ -86,7 +88,8 @@ public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHan
         .code(errorCode.code())
         .message(coalesce(baseException.getMessage(), "Internal error"))
         .requestId(requestId(request))
-        .timestamp(currentTimestamp());
+        .timestamp(currentTimestamp())
+        .stackTrace(Throwables.getStackTraceAsString(baseException));
     return ServerResponse
         .status(errorCode.httpStatus())
         .contentType(MediaType.APPLICATION_JSON)
@@ -115,7 +118,8 @@ public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHan
         .message(message)
         .requestId(requestId(request))
         .timestamp(currentTimestamp())
-        .fieldsErrors(fieldsErrors);
+        .fieldsErrors(fieldsErrors)
+        .stackTrace(Throwables.getStackTraceAsString(exception));
     return ServerResponse
         .status(HttpStatus.BAD_REQUEST)
         .contentType(MediaType.APPLICATION_JSON)
@@ -128,7 +132,8 @@ public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHan
         .code(ErrorCode.UNEXPECTED.code())
         .message(msg)
         .requestId(requestId(request))
-        .timestamp(currentTimestamp());
+        .timestamp(currentTimestamp())
+        .stackTrace(Throwables.getStackTraceAsString(exception));
     return ServerResponse
         .status(exception.getStatus())
         .contentType(MediaType.APPLICATION_JSON)

+ 8 - 0
kafka-ui-api/src/main/java/com/provectus/kafka/ui/model/InternalClusterState.java

@@ -1,9 +1,11 @@
 package com.provectus.kafka.ui.model;
 
+import com.google.common.base.Throwables;
 import com.provectus.kafka.ui.service.MetricsCache;
 import com.provectus.kafka.ui.util.ClusterUtil;
 import java.math.BigDecimal;
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import lombok.Data;
 
@@ -11,6 +13,7 @@ import lombok.Data;
 public class InternalClusterState {
   private String name;
   private ServerStatusDTO status;
+  private MetricsCollectionErrorDTO lastError;
   private Integer topicCount;
   private Integer brokerCount;
   private Integer zooKeeperStatus;
@@ -29,6 +32,11 @@ public class InternalClusterState {
   public InternalClusterState(KafkaCluster cluster, MetricsCache.Metrics metrics) {
     name = cluster.getName();
     status = metrics.getStatus();
+    lastError = Optional.ofNullable(metrics.getLastKafkaException())
+        .map(e -> new MetricsCollectionErrorDTO()
+            .message(e.getMessage())
+            .stackTrace(Throwables.getStackTraceAsString(e)))
+        .orElse(null);
     topicCount = metrics.getTopicDescriptions().size();
     brokerCount = metrics.getClusterDescription().getNodes().size();
     zooKeeperStatus = ClusterUtil.convertToIntServerStatus(metrics.getZkStatus().getStatus());

+ 1 - 6
kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/ClustersMetricsScheduler.java

@@ -1,6 +1,5 @@
 package com.provectus.kafka.ui.service;
 
-import javax.annotation.PostConstruct;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.log4j.Log4j2;
 import org.springframework.scheduling.annotation.Scheduled;
@@ -17,11 +16,7 @@ public class ClustersMetricsScheduler {
 
   private final MetricsService metricsService;
 
-  @PostConstruct //need to fill metrics before application startup to prevent invalid state render
-  @Scheduled(
-      fixedRateString = "${kafka.update-metrics-rate-millis:30000}",
-      initialDelayString = "${kafka.update-metrics-rate-millis:30000}"
-  )
+  @Scheduled(fixedRateString = "${kafka.update-metrics-rate-millis:30000}")
   public void updateMetrics() {
     Flux.fromIterable(clustersStorage.getKafkaClusters())
         .parallel()

+ 2 - 1
kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/MetricsCache.java

@@ -8,6 +8,7 @@ import com.provectus.kafka.ui.util.JmxClusterUtil;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import lombok.Builder;
@@ -88,7 +89,7 @@ public class MetricsCache {
   }
 
   public Metrics get(KafkaCluster c) {
-    return cache.get(c.getName());
+    return Optional.ofNullable(cache.get(c.getName())).orElseGet(MetricsCache::empty);
   }
 
 }

+ 12 - 0
kafka-ui-contract/src/main/resources/swagger/kafka-ui-api.yaml

@@ -1478,6 +1478,8 @@ components:
           type: array
           items:
             $ref: '#/components/schemas/FieldError'
+        stackTrace:
+          type: string
 
     FieldError:
       type: object
@@ -1491,6 +1493,14 @@ components:
           items:
             type: string
 
+    MetricsCollectionError:
+      type: object
+      properties:
+        message:
+          type: string
+        stackTrace:
+          type: string
+
     Cluster:
       type: object
       properties:
@@ -1500,6 +1510,8 @@ components:
           type: boolean
         status:
           $ref: '#/components/schemas/ServerStatus'
+        lastError:
+          $ref: '#/components/schemas/MetricsCollectionError'
         brokerCount:
           type: integer
         onlinePartitionCount: