|
@@ -4,35 +4,52 @@ import static io.prometheus.client.Collector.MetricFamilySamples;
|
|
import static org.springframework.util.StringUtils.hasText;
|
|
import static org.springframework.util.StringUtils.hasText;
|
|
|
|
|
|
import com.provectus.kafka.ui.config.ClustersProperties;
|
|
import com.provectus.kafka.ui.config.ClustersProperties;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
import java.util.Optional;
|
|
import java.util.Optional;
|
|
import java.util.stream.Stream;
|
|
import java.util.stream.Stream;
|
|
|
|
+import reactor.core.publisher.Flux;
|
|
import reactor.core.publisher.Mono;
|
|
import reactor.core.publisher.Mono;
|
|
|
|
|
|
public interface MetricsSink {
|
|
public interface MetricsSink {
|
|
|
|
|
|
static MetricsSink create(ClustersProperties.Cluster cluster) {
|
|
static MetricsSink create(ClustersProperties.Cluster cluster) {
|
|
- return Optional.ofNullable(cluster.getMetrics())
|
|
|
|
|
|
+ List<MetricsSink> sinks = new ArrayList<>();
|
|
|
|
+ Optional.ofNullable(cluster.getMetrics())
|
|
.flatMap(metrics -> Optional.ofNullable(metrics.getStore()))
|
|
.flatMap(metrics -> Optional.ofNullable(metrics.getStore()))
|
|
.flatMap(store -> Optional.ofNullable(store.getPrometheus()))
|
|
.flatMap(store -> Optional.ofNullable(store.getPrometheus()))
|
|
- .map(prometheusConf -> {
|
|
|
|
|
|
+ .ifPresent(prometheusConf -> {
|
|
if (hasText(prometheusConf.getUrl()) && Boolean.TRUE.equals(prometheusConf.getRemoteWrite())) {
|
|
if (hasText(prometheusConf.getUrl()) && Boolean.TRUE.equals(prometheusConf.getRemoteWrite())) {
|
|
- return new PrometheusRemoteWriteSink(prometheusConf.getUrl());
|
|
|
|
|
|
+ sinks.add(new PrometheusRemoteWriteSink(prometheusConf.getUrl()));
|
|
}
|
|
}
|
|
if (hasText(prometheusConf.getPushGatewayUrl())) {
|
|
if (hasText(prometheusConf.getPushGatewayUrl())) {
|
|
- return PrometheusPushGatewaySink.create(
|
|
|
|
- prometheusConf.getPushGatewayUrl(),
|
|
|
|
- prometheusConf.getPushGatewayJobName(),
|
|
|
|
- prometheusConf.getPushGatewayUsername(),
|
|
|
|
- prometheusConf.getPushGatewayPassword()
|
|
|
|
- );
|
|
|
|
|
|
+ sinks.add(
|
|
|
|
+ PrometheusPushGatewaySink.create(
|
|
|
|
+ prometheusConf.getPushGatewayUrl(),
|
|
|
|
+ prometheusConf.getPushGatewayJobName(),
|
|
|
|
+ prometheusConf.getPushGatewayUsername(),
|
|
|
|
+ prometheusConf.getPushGatewayPassword()
|
|
|
|
+ ));
|
|
}
|
|
}
|
|
- return noop();
|
|
|
|
}
|
|
}
|
|
- ).orElse(noop());
|
|
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ Optional.ofNullable(cluster.getMetrics())
|
|
|
|
+ .flatMap(metrics -> Optional.ofNullable(metrics.getStore()))
|
|
|
|
+ .flatMap(store -> Optional.ofNullable(store.getKafka()))
|
|
|
|
+ .flatMap(kafka -> Optional.ofNullable(kafka.getTopic()))
|
|
|
|
+ .ifPresent(topic -> sinks.add(KafkaSink.create(cluster, topic)));
|
|
|
|
+
|
|
|
|
+ return compoundSink(sinks);
|
|
}
|
|
}
|
|
|
|
|
|
- static MetricsSink noop() {
|
|
|
|
- return m -> Mono.empty();
|
|
|
|
|
|
+ static MetricsSink compoundSink(List<MetricsSink> sinks) {
|
|
|
|
+ return metricsStream -> {
|
|
|
|
+ var materialized = metricsStream.toList();
|
|
|
|
+ return Flux.fromIterable(sinks)
|
|
|
|
+ .flatMap(sink -> sink.send(materialized.stream()))
|
|
|
|
+ .then();
|
|
|
|
+ };
|
|
}
|
|
}
|
|
|
|
|
|
Mono<Void> send(Stream<MetricFamilySamples> metrics);
|
|
Mono<Void> send(Stream<MetricFamilySamples> metrics);
|