diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml new file mode 100644 index 0000000..9728d94 --- /dev/null +++ b/docker-compose-dev.yaml @@ -0,0 +1,30 @@ +services: + db: + image: postgres + restart: always + shm_size: 128mb + environment: + POSTGRES_PASSWORD: postgres + ports: + - "6666:5432" + db-big-bucket: + image: postgres + restart: always + shm_size: 128mb + environment: + POSTGRES_PASSWORD: postgres + ports: + - "6667:5432" + big-bucket: + image: harbor.dinauer.dev/big-bucket/core:13 + ports: + - "8090:8080" + environment: + BIG_BUCKET_CLIENT_KUBOOBOO_RW: password + BIG_BUCKET_UNITS: RAW,HOURLY,DAILY + DB_USER: postgres + DB_PASSWORD: postgres + DB_HOST: db-big-bucket + DB_PORT: 5432 + DB_DATABASE: postgres + DB_SCHEMA: public \ No newline at end of file diff --git a/pg-docker-compose.yaml b/pg-docker-compose.yaml deleted file mode 100644 index 83997da..0000000 --- a/pg-docker-compose.yaml +++ /dev/null @@ -1,9 +0,0 @@ -services: - db: - image: postgres - restart: always - shm_size: 128mb - environment: - POSTGRES_PASSWORD: postgres - ports: - - "6666:5432" \ No newline at end of file diff --git a/src/main/java/dev/dinauer/monitoring/MonitoredNode.java b/src/main/java/dev/dinauer/monitoring/MonitoredNode.java deleted file mode 100644 index 80cffee..0000000 --- a/src/main/java/dev/dinauer/monitoring/MonitoredNode.java +++ /dev/null @@ -1,10 +0,0 @@ -package dev.dinauer.monitoring; - -import dev.dinauer.monitoring.indexing.IndexCollection; -import io.fabric8.kubernetes.api.model.Node; - -import java.util.List; - -public record MonitoredNode(Node node, List jobs) -{ -} diff --git a/src/main/java/dev/dinauer/monitoring/MonitoredResource.java b/src/main/java/dev/dinauer/monitoring/MonitoredResource.java index 4462f7a..074afcd 100644 --- a/src/main/java/dev/dinauer/monitoring/MonitoredResource.java +++ b/src/main/java/dev/dinauer/monitoring/MonitoredResource.java @@ -1,9 +1,10 @@ package dev.dinauer.monitoring; +import dev.dinauer.monitoring.indexing.Bucket; import io.fabric8.kubernetes.api.model.Pod; import java.util.List; -public record MonitoredResource(E resource, List jobs) +public record MonitoredResource(E resource, List jobs) { } diff --git a/src/main/java/dev/dinauer/monitoring/MonitoringJobResource.java b/src/main/java/dev/dinauer/monitoring/MonitoringJobResource.java index 94a18a9..02b661f 100644 --- a/src/main/java/dev/dinauer/monitoring/MonitoringJobResource.java +++ b/src/main/java/dev/dinauer/monitoring/MonitoringJobResource.java @@ -2,14 +2,10 @@ package dev.dinauer.monitoring; import dev.dinauer.monitoring.entity.MonitoringConfig; import dev.dinauer.monitoring.entity.repo.MonitoringRepo; -import dev.dinauer.monitoring.indexing.IndexCollection; -import dev.dinauer.monitoring.indexing.IndexMetricsRepo; -import dev.dinauer.monitoring.indexing.TimeUnit; +import dev.dinauer.monitoring.indexing.Bucket; import io.fabric8.kubernetes.api.model.Pod; -import io.smallrye.common.constraint.NotNull; import jakarta.inject.Inject; import jakarta.ws.rs.*; -import jakarta.ws.rs.core.Response; import java.io.IOException; import java.util.ArrayList; @@ -24,22 +20,19 @@ public class MonitoringJobResource @Inject MonitoringService monitoringService; - @Inject - IndexMetricsRepo indexMetricsRepo; - @GET - public List> get(@PathParam("monitoring-id") String monitoringId, @QueryParam("from") Long from, @QueryParam("to") Long to) throws IOException + public List> get(@PathParam("monitoring-id") String monitoringId, @QueryParam("from") Long from, @QueryParam("to") Long to) throws IOException { if (from == null || to == null) { throw new BadRequestException(); } - List> result = new ArrayList<>(); + List> result = new ArrayList<>(); MonitoringConfig config = monitoringRepo.findById(monitoringId); List pods = monitoringService.findRunningPodsByMonitoringConfig(config); for (Pod pod : pods) { - result.add(new MonitoredResource<>(pod, indexMetricsRepo.findByResourceAndMetricAndTimeUnitAndPeriod(String.format("POD-%s", pod.getMetadata().getUid()), config.getType().toString(), TimeUnit.RAW, from, to))); + result.add(new MonitoredResource<>(pod, null)); } return result; } diff --git a/src/main/java/dev/dinauer/monitoring/MonitoringJobRunner.java b/src/main/java/dev/dinauer/monitoring/MonitoringJobRunner.java index 58d30c6..6604b98 100644 --- a/src/main/java/dev/dinauer/monitoring/MonitoringJobRunner.java +++ b/src/main/java/dev/dinauer/monitoring/MonitoringJobRunner.java @@ -56,6 +56,7 @@ public class MonitoringJobRunner Runnable task = () -> { try { + System.out.println("x"); nodeMonitoringService.run(); } catch (Exception e) diff --git a/src/main/java/dev/dinauer/monitoring/NodeMonitoringJobResource.java b/src/main/java/dev/dinauer/monitoring/NodeMonitoringJobResource.java index 240a9ae..3644e09 100644 --- a/src/main/java/dev/dinauer/monitoring/NodeMonitoringJobResource.java +++ b/src/main/java/dev/dinauer/monitoring/NodeMonitoringJobResource.java @@ -1,16 +1,16 @@ package dev.dinauer.monitoring; -import dev.dinauer.monitoring.indexing.IndexCollection; -import dev.dinauer.monitoring.indexing.IndexMetric; -import dev.dinauer.monitoring.indexing.IndexMetricsRepo; -import dev.dinauer.monitoring.indexing.TimeUnit; +import dev.dinauer.monitoring.indexing.BigBucketService; +import dev.dinauer.monitoring.indexing.Bucket; +import dev.dinauer.monitoring.indexing.BucketUnit; +import dev.dinauer.service.NodeService; import dev.dinauer.utils.ClientProvider; import io.fabric8.kubernetes.api.model.Node; import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; import jakarta.ws.rs.QueryParam; +import org.jboss.resteasy.reactive.common.NotImplementedYet; import java.io.IOException; import java.time.ZonedDateTime; @@ -21,25 +21,23 @@ import java.util.List; public class NodeMonitoringJobResource { @Inject - IndexMetricsRepo indexMetricsRepo; + NodeService nodeService; @Inject - ClientProvider clientProvider; + BigBucketService bigBucketService; @GET - public List> get(@QueryParam("from") ZonedDateTime from, @QueryParam("to") ZonedDateTime to) throws IOException + public List> get(@QueryParam("from") ZonedDateTime from, @QueryParam("to") ZonedDateTime to) throws IOException { - List> result = new ArrayList<>(); - List nodes = clientProvider.getClient().nodes().list().getItems(); - for (Node node : nodes) + List> result = new ArrayList<>(); + for (Node node : nodeService.findAll()) { - String resource = String.format("NODE-%s", node.getMetadata().getUid()); - result.add(new MonitoredResource<>(node, indexMetricsRepo.findByResourceAndMetricAndTimeUnit(resource, "NODE_METRICS", determineTimeUnit(from, to)))); + result.add(new MonitoredResource<>(node, bigBucketService.get(String.format("NODE-%s", node.getMetadata().getUid()), "NODE_METRICS", determineTimeUnit(from, to)))); } return result; } - private TimeUnit determineTimeUnit(ZonedDateTime from, ZonedDateTime to) + private BucketUnit determineTimeUnit(ZonedDateTime from, ZonedDateTime to) { long day = 60 * 60 * 24; long twoDays = day * 2; @@ -48,12 +46,12 @@ public class NodeMonitoringJobResource long dif = to.toEpochSecond() - from.toEpochSecond(); if (dif < twoDays) { - return TimeUnit.RAW; + return BucketUnit.RAW; } if (dif < fifteenDays) { - return TimeUnit.HOUR; + return BucketUnit.HOURLY; } - return TimeUnit.DAY; + return BucketUnit.DAILY; } } diff --git a/src/main/java/dev/dinauer/monitoring/indexing/BigBucketClient.java b/src/main/java/dev/dinauer/monitoring/indexing/BigBucketClient.java new file mode 100644 index 0000000..73c8cf0 --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/indexing/BigBucketClient.java @@ -0,0 +1,19 @@ +package dev.dinauer.monitoring.indexing; + +import io.quarkus.rest.client.reactive.ClientBasicAuth; +import jakarta.ws.rs.*; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; + +import java.util.List; + +@Path("/api/metrics/{resource}/{metric}") +@RegisterRestClient(configKey = "big-bucket") +@ClientBasicAuth(username = "${big.bucket.username}", password = "${big.bucket.password}") +public interface BigBucketClient +{ + @POST + void index(@PathParam("resource") String resource, @PathParam("metric") String metric, Insert body); + + @GET + List get(@PathParam("resource") String resource, @PathParam("metric") String metric, @QueryParam("bucket-unit") BucketUnit bucketUnit); +} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/BigBucketService.java b/src/main/java/dev/dinauer/monitoring/indexing/BigBucketService.java new file mode 100644 index 0000000..714f54b --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/indexing/BigBucketService.java @@ -0,0 +1,47 @@ +package dev.dinauer.monitoring.indexing; + +import io.quarkus.runtime.Startup; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.ws.rs.InternalServerErrorException; +import org.eclipse.microprofile.rest.client.inject.RestClient; +import org.jboss.logging.Logger; + +import java.util.List; +import java.util.Map; + +@Startup +@ApplicationScoped +public class BigBucketService +{ + @Inject + Logger LOG; + + @RestClient + BigBucketClient client; + + public void index(String resource, String metric, Map values) + { + try + { + client.index(resource, metric, new Insert(values)); + } + catch (Exception e) + { + LOG.errorf("Failed to index to BigBucket: %s", e.getMessage()); + } + } + + public List get(String resource, String metric, BucketUnit bucketUnit) + { + try + { + return client.get(resource, metric, bucketUnit); + } + catch (Exception e) + { + LOG.errorf("Failed to retrieve from BigBucket: %s", e.getMessage()); + throw new InternalServerErrorException(); + } + } +} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/Bucket.java b/src/main/java/dev/dinauer/monitoring/indexing/Bucket.java new file mode 100644 index 0000000..f22818e --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/indexing/Bucket.java @@ -0,0 +1,7 @@ +package dev.dinauer.monitoring.indexing; + +import java.util.Map; + +public record Bucket(String resource, String timestamp, long unixTimestamp, BucketUnit bucketUnit, Map metrics, String owner) +{ +} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/BucketUnit.java b/src/main/java/dev/dinauer/monitoring/indexing/BucketUnit.java new file mode 100644 index 0000000..7e251d7 --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/indexing/BucketUnit.java @@ -0,0 +1,6 @@ +package dev.dinauer.monitoring.indexing; + +public enum BucketUnit +{ + RAW, HOURLY, DAILY, WEEKLY, MONTHLY, YEARLY, TOTAL +} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/IndexCollection.java b/src/main/java/dev/dinauer/monitoring/indexing/IndexCollection.java deleted file mode 100644 index 00141cb..0000000 --- a/src/main/java/dev/dinauer/monitoring/indexing/IndexCollection.java +++ /dev/null @@ -1,124 +0,0 @@ -package dev.dinauer.monitoring.indexing; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.persistence.*; - -import java.lang.reflect.Type; -import java.util.Map; -import java.util.UUID; - -@Entity -@Table(name = "metrics_index") -public class IndexCollection -{ - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - - @Id - private String id; - - private String resource; - - private String metric; - - private String timestamp; - - private long unix; - - @Enumerated(EnumType.STRING) - private TimeUnit unit; - - @Column(columnDefinition = "text") - private String metrics; - - public IndexCollection() - { - } - - public IndexCollection(String resource, String metric, String timestamp, long unix, TimeUnit unit) - { - this.id = UUID.randomUUID().toString(); - this.resource = resource; - this.timestamp = timestamp; - this.unix = unix; - this.unit = unit; - this.metric = metric; - this.metrics = "{}"; - } - - public String getId() - { - return id; - } - - public void add(String key, long value) - { - Map metrics = getMetrics(); - IndexMetric metric = metrics.get(key); - if (metric != null) - { - metric.add(value); - } - else - { - IndexMetric newMetric = new IndexMetric(); - newMetric.add(value); - metrics.put(key, newMetric); - } - try - { - this.metrics = OBJECT_MAPPER.writeValueAsString(metrics); - } - catch (JsonProcessingException e) - { - throw new RuntimeException(e); - } - } - - private double calculateAverage(long sum, int count) - { - if (count == 0) - { - return 0; - } - return sum * 1.0 / count; - } - - public String getTimestamp() - { - return timestamp; - } - - public String getMetric() - { - return metric; - } - - public TimeUnit getUnit() - { - return unit; - } - - public String getResource() - { - return resource; - } - - public Map getMetrics() - { - try - { - return OBJECT_MAPPER.readValue(metrics, new TypeReference>() {}); - } - catch (JsonProcessingException e) - { - throw new RuntimeException(e); - } - } - - public long getUnix() - { - return unix; - } -} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/IndexMetric.java b/src/main/java/dev/dinauer/monitoring/indexing/IndexMetric.java deleted file mode 100644 index 7ac6c53..0000000 --- a/src/main/java/dev/dinauer/monitoring/indexing/IndexMetric.java +++ /dev/null @@ -1,46 +0,0 @@ -package dev.dinauer.monitoring.indexing; - -public class IndexMetric -{ - private int count; - private long sum; - private double average; - - public IndexMetric() - { - this.count = 0; - this.sum = 0; - this.average = 0.0F; - } - - public void add(long value) - { - count = count + 1; - sum = sum + value; - average = calculateAverage(sum, count); - } - - private double calculateAverage(long sum, int count) - { - if (count == 0) - { - return 0; - } - return sum * 1.0 / count; - } - - public int getCount() - { - return count; - } - - public long getSum() - { - return sum; - } - - public double getAverage() - { - return average; - } -} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/IndexMetricsRepo.java b/src/main/java/dev/dinauer/monitoring/indexing/IndexMetricsRepo.java deleted file mode 100644 index 5e30c3d..0000000 --- a/src/main/java/dev/dinauer/monitoring/indexing/IndexMetricsRepo.java +++ /dev/null @@ -1,27 +0,0 @@ -package dev.dinauer.monitoring.indexing; - -import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase; -import io.quarkus.panache.common.Parameters; -import jakarta.enterprise.context.ApplicationScoped; - -import java.util.List; -import java.util.Optional; - -@ApplicationScoped -public class IndexMetricsRepo implements PanacheRepositoryBase -{ - public Optional findByProperties(String resource, String metric, String timestamp, TimeUnit unit) - { - return find("resource = :resource AND metric = :metric AND timestamp = :timestamp AND unit = :unit", Parameters.with("resource", resource).and("metric", metric).and("timestamp", timestamp).and("unit", unit)).firstResultOptional(); - } - - public List findByResourceAndMetricAndTimeUnit(String resource, String metric, TimeUnit unit) - { - return list("resource = :resource AND metric = :metric AND unit = :unit ORDER BY timestamp ASC", Parameters.with("resource", resource).and("metric", metric).and("unit", unit)); - } - - public List findByResourceAndMetricAndTimeUnitAndPeriod(String resource, String metric, TimeUnit unit, long from, long to) - { - return list("resource = :resource AND metric = :metric AND unit = :unit AND (unix >= :from AND unix <= :to) ORDER BY timestamp ASC", Parameters.with("resource", resource).and("metric", metric).and("unit", unit).and("from", from).and("to", to)); - } -} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/IndexingService.java b/src/main/java/dev/dinauer/monitoring/indexing/IndexingService.java deleted file mode 100644 index 2a733a4..0000000 --- a/src/main/java/dev/dinauer/monitoring/indexing/IndexingService.java +++ /dev/null @@ -1,35 +0,0 @@ -package dev.dinauer.monitoring.indexing; - -import io.quarkus.logging.Log; -import io.quarkus.runtime.Startup; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import jakarta.transaction.Transactional; - -import java.time.Clock; -import java.time.ZonedDateTime; -import java.util.Map; - -@Startup -@ApplicationScoped -public class IndexingService -{ - @Inject - IndexMetricsRepo indexMetricsRepo; - - @Transactional - public void index(String resource, String metric, Map values) - { - for (TimeUnit unit : TimeUnit.values()) - { - ZonedDateTime now = ZonedDateTime.now(Clock.systemUTC()); - String timestamp = TimestampGenerator.generateTimestamp(now, unit); - IndexCollection metrics = indexMetricsRepo.findByProperties(resource, metric, timestamp, unit).orElse(new IndexCollection(resource, metric, timestamp, now.toEpochSecond(), unit)); - for (Map.Entry entry : values.entrySet()) - { - metrics.add(entry.getKey().toUpperCase(), entry.getValue()); - } - indexMetricsRepo.persist(metrics); - } - } -} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/Insert.java b/src/main/java/dev/dinauer/monitoring/indexing/Insert.java new file mode 100644 index 0000000..709c985 --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/indexing/Insert.java @@ -0,0 +1,7 @@ +package dev.dinauer.monitoring.indexing; + +import java.util.Map; + +public record Insert(Map values) +{ +} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/Metric.java b/src/main/java/dev/dinauer/monitoring/indexing/Metric.java new file mode 100644 index 0000000..fca0bce --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/indexing/Metric.java @@ -0,0 +1,5 @@ +package dev.dinauer.monitoring.indexing; + +public record Metric(int count, int sum, double average, Double min, Double max) +{ +} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/TimeUnit.java b/src/main/java/dev/dinauer/monitoring/indexing/TimeUnit.java deleted file mode 100644 index 0e81a6b..0000000 --- a/src/main/java/dev/dinauer/monitoring/indexing/TimeUnit.java +++ /dev/null @@ -1,6 +0,0 @@ -package dev.dinauer.monitoring.indexing; - -public enum TimeUnit -{ - RAW, HOUR, DAY -} diff --git a/src/main/java/dev/dinauer/monitoring/indexing/TimestampGenerator.java b/src/main/java/dev/dinauer/monitoring/indexing/TimestampGenerator.java deleted file mode 100644 index 74f50d7..0000000 --- a/src/main/java/dev/dinauer/monitoring/indexing/TimestampGenerator.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.dinauer.monitoring.indexing; - -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; - -public class TimestampGenerator -{ - public static String generateTimestamp(ZonedDateTime timestamp, TimeUnit unit) - { - switch (unit) - { - case TimeUnit.RAW -> - { - return timestamp.format(DateTimeFormatter.ISO_DATE_TIME).substring(0, 19); - } - case TimeUnit.HOUR -> - { - return timestamp.format(DateTimeFormatter.ISO_DATE_TIME).substring(0, 13); - } - case TimeUnit.DAY -> - { - return timestamp.format(DateTimeFormatter.ISO_DATE_TIME).substring(0, 10); - } - } - throw new RuntimeException("Cannot index by chono unit " + unit); - } -} diff --git a/src/main/java/dev/dinauer/monitoring/memory/MemoryMonitoringJobRunner.java b/src/main/java/dev/dinauer/monitoring/memory/MemoryMonitoringJobRunner.java index a0cf23b..a4229dd 100644 --- a/src/main/java/dev/dinauer/monitoring/memory/MemoryMonitoringJobRunner.java +++ b/src/main/java/dev/dinauer/monitoring/memory/MemoryMonitoringJobRunner.java @@ -4,7 +4,7 @@ import dev.dinauer.ProcessRunner; import dev.dinauer.monitoring.MonitoringService; import dev.dinauer.monitoring.entity.MonitoringConfig; import dev.dinauer.monitoring.entity.MonitoringType; -import dev.dinauer.monitoring.indexing.IndexingService; +import dev.dinauer.monitoring.indexing.BigBucketService; import io.fabric8.kubernetes.api.model.Pod; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -23,7 +23,7 @@ public class MemoryMonitoringJobRunner MonitoringService monitoringService; @Inject - IndexingService indexingService; + BigBucketService bigBucketService; public void run(MonitoringConfig config) throws IOException, InterruptedException { @@ -34,7 +34,7 @@ public class MemoryMonitoringJobRunner String podId = pod.getMetadata().getUid(); String podName = pod.getMetadata().getName(); String result = processRunner.runToText(String.format("kubectl top pod %s -n %s", podName, config.getTargetConfig().getNamespace())); - indexingService.index(String.format("POD-%s", podId), MonitoringType.WORKLOAD.toString(), Map.ofEntries(Map.entry("MEMORY", ByteExtractor.extractBytes(result)), Map.entry("CPU", ByteExtractor.extractCpu(result)))); + bigBucketService.index(String.format("POD-%s", podId), MonitoringType.WORKLOAD.toString(), Map.ofEntries(Map.entry("MEMORY", ByteExtractor.extractBytes(result)), Map.entry("CPU", ByteExtractor.extractCpu(result)))); } } } diff --git a/src/main/java/dev/dinauer/monitoring/nodes/NodeMonitoringService.java b/src/main/java/dev/dinauer/monitoring/nodes/NodeMonitoringService.java index 459f66c..0d700ba 100644 --- a/src/main/java/dev/dinauer/monitoring/nodes/NodeMonitoringService.java +++ b/src/main/java/dev/dinauer/monitoring/nodes/NodeMonitoringService.java @@ -1,12 +1,15 @@ package dev.dinauer.monitoring.nodes; import dev.dinauer.monitoring.TopNodesService; -import dev.dinauer.monitoring.indexing.IndexingService; +import dev.dinauer.monitoring.indexing.BigBucketService; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import java.io.IOException; +import java.util.AbstractMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; @ApplicationScoped public class NodeMonitoringService @@ -15,7 +18,7 @@ public class NodeMonitoringService TopNodesService topNodesService; @Inject - IndexingService indexingService; + BigBucketService bigBucketService; public void run() throws IOException, InterruptedException { @@ -23,23 +26,17 @@ public class NodeMonitoringService for (MonitoredNode node : nodes) { NodeMetrics nodeMetrics = node.getMetrics(); - Map metrics = Map.ofEntries( - Map.entry("RELATIVE_CPU", toLong(nodeMetrics.relativeCpuUsage())), - Map.entry("RELATIVE_MEMORY", toLong(nodeMetrics.relativeMemory())), - Map.entry("ABSOLUTE_MEMORY", toLong(nodeMetrics.absoluteMemory())), - Map.entry("ABSOLUTE_CPU", toLong(nodeMetrics.absoluteCpuUsage())), - Map.entry("RELATIVE_DISK_SPACE", toLong(nodeMetrics.relativeDiskUsage())), - Map.entry("TOTAL_DISK_SPACE", nodeMetrics.totalDiskSpace())); - indexingService.index(String.format("NODE-%s", node.getMetadata().getUid()), "NODE_METRICS", metrics); - } - } + Map metrics = Stream.of( + new AbstractMap.SimpleEntry<>("RELATIVE_CPU", nodeMetrics.relativeCpuUsage()), + new AbstractMap.SimpleEntry<>("RELATIVE_MEMORY", nodeMetrics.relativeMemory()), + new AbstractMap.SimpleEntry<>("ABSOLUTE_MEMORY", nodeMetrics.absoluteMemory()), + new AbstractMap.SimpleEntry<>("ABSOLUTE_CPU", nodeMetrics.absoluteCpuUsage()), + new AbstractMap.SimpleEntry<>("RELATIVE_DISK_SPACE", nodeMetrics.relativeDiskUsage()), + new AbstractMap.SimpleEntry<>("TOTAL_DISK_SPACE", nodeMetrics.totalDiskSpace())) + .filter(entry -> entry.getValue() != null) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - private Long toLong(Integer input) - { - if (input != null) - { - return Long.valueOf(input); + bigBucketService.index(String.format("NODE-%s", node.getMetadata().getUid()), "NODE_METRICS", metrics); } - return null; } } diff --git a/src/main/java/dev/dinauer/monitoring/nodes/client/NodeDiskService.java b/src/main/java/dev/dinauer/monitoring/nodes/client/NodeDiskService.java index a074801..3fe1a88 100644 --- a/src/main/java/dev/dinauer/monitoring/nodes/client/NodeDiskService.java +++ b/src/main/java/dev/dinauer/monitoring/nodes/client/NodeDiskService.java @@ -52,7 +52,6 @@ public class NodeDiskService String port = "8080"; try (HttpClient client = HttpClient.newBuilder().build()) { - LOG.infof("Collect disk monitoring for node %s", nodeName); HttpRequest request = HttpRequest.newBuilder().uri(getURI(ip, port)).GET().build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); NodeDiskMetrics metrics = parse(response.body()); diff --git a/src/main/java/dev/dinauer/monitoring/pods/MonitoredPod.java b/src/main/java/dev/dinauer/monitoring/pods/MonitoredPod.java new file mode 100644 index 0000000..7efa0ec --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/pods/MonitoredPod.java @@ -0,0 +1,19 @@ +package dev.dinauer.monitoring.pods; + +import io.fabric8.kubernetes.api.model.Pod; + +public class MonitoredPod extends Pod +{ + private final PodMetrics metrics; + + public MonitoredPod(Pod pod, PodMetrics metrics) + { + super(pod.getApiVersion(), pod.getKind(), pod.getMetadata(), pod.getSpec(), pod.getStatus()); + this.metrics = metrics; + } + + public PodMetrics getMetrics() + { + return metrics; + } +} diff --git a/src/main/java/dev/dinauer/monitoring/pods/PodMetrics.java b/src/main/java/dev/dinauer/monitoring/pods/PodMetrics.java new file mode 100644 index 0000000..6c726b8 --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/pods/PodMetrics.java @@ -0,0 +1,5 @@ +package dev.dinauer.monitoring.pods; + +public record PodMetrics(String cpu, String memory) +{ +} diff --git a/src/main/java/dev/dinauer/monitoring/pods/PodMetricsService.java b/src/main/java/dev/dinauer/monitoring/pods/PodMetricsService.java new file mode 100644 index 0000000..3f4af11 --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/pods/PodMetricsService.java @@ -0,0 +1,45 @@ +package dev.dinauer.monitoring.pods; + +import dev.dinauer.ProcessRunner; +import io.fabric8.kubernetes.api.model.Pod; +import io.quarkus.scheduler.Scheduled; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ApplicationScoped +public class PodMetricsService +{ + @Inject + ProcessRunner processRunner; + + Map metrics; + + @Scheduled(every = "1m") + public void find() + { + Map result = new HashMap<>(); + List podMetrics = processRunner.runToLines("kubectl top pods --all-namespaces --no-headers"); + for (String line : podMetrics) + { + String[] sections = line.split("\\s+"); + if (sections.length == 4) + { + String namespace = sections[0].trim(); + String name = sections[1].trim(); + String cpu = sections[2].trim(); + String memory = sections[3].trim(); + result.put(String.format("%s/%s", namespace, name), new PodMetrics(cpu, memory)); + } + } + this.metrics = result; + } + + public PodMetrics getForPod(Pod pod) + { + return this.metrics.get(String.format("%s/%s", pod.getMetadata().getNamespace(), pod.getMetadata().getName())); + } +} diff --git a/src/main/java/dev/dinauer/monitoring/volume/VolumeMonitoringJobRunner.java b/src/main/java/dev/dinauer/monitoring/volume/VolumeMonitoringJobRunner.java index 327d591..1bd2f55 100644 --- a/src/main/java/dev/dinauer/monitoring/volume/VolumeMonitoringJobRunner.java +++ b/src/main/java/dev/dinauer/monitoring/volume/VolumeMonitoringJobRunner.java @@ -4,7 +4,7 @@ import dev.dinauer.ProcessRunner; import dev.dinauer.monitoring.MonitoringService; import dev.dinauer.monitoring.entity.MonitoringConfig; import dev.dinauer.monitoring.entity.MonitoringType; -import dev.dinauer.monitoring.indexing.IndexingService; +import dev.dinauer.monitoring.indexing.BigBucketService; import io.fabric8.kubernetes.api.model.Pod; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -34,7 +34,7 @@ public class VolumeMonitoringJobRunner VolumeUsageRepo volumeUsageRepo; @Inject - IndexingService indexingService; + BigBucketService bigBucketService; public void run(MonitoringConfig monitoring) throws IOException, InterruptedException { @@ -49,7 +49,7 @@ public class VolumeMonitoringJobRunner String result = processRunner.runToText(String.format("kubectl exec -i %s -c %s -n %s -- df -B1 --output=size,used,avail,pcent -h %s -B1", podName, monitoring.getVolumeConfig().getContainerName(), monitoring.getTargetConfig().getNamespace(), monitoring.getVolumeConfig().getMountPath())); UsageMetrics usage = extractUsage(result); volumeUsageRepo.persist(new VolumeUsage(UUID.randomUUID().toString(), monitoring.getId(), podId, podName, monitoring.getTargetConfig().getNamespace(), ZonedDateTime.now().truncatedTo(ChronoUnit.MILLIS), usage)); - indexingService.index(String.format("POD-%s", podId), MonitoringType.VOLUME.toString(), Map.ofEntries(Map.entry("VOLUME", (long) usage.percentage()))); + bigBucketService.index(String.format("POD-%s", podId), MonitoringType.VOLUME.toString(), Map.ofEntries(Map.entry("VOLUME", (long) usage.percentage()))); } } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 6677d57..8b71a10 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -27,4 +27,11 @@ quarkus.datasource.db-kind = postgresql %prod.quarkus.hibernate-orm.schema-management.strategy=drop-and-create # Banner -quarkus.banner.path=banner.txt \ No newline at end of file +quarkus.banner.path=banner.txt + +# Big Bucket +%dev.quarkus.rest-client.big-bucket.url=http://localhost:8090 +%dev.big.bucket.username=kubooboo +%dev.big.bucket.password=password + +%prod.quarkus.rest-client.big-bucket.url=${BIG_BUCKET_URL} \ No newline at end of file