Create shards metrics supplier (#24035)

* Implement shards metrics supplier

* Add changelog

* Update test class name

* Refactor tests
This commit is contained in:
Ismail Belkacim
2025-11-07 17:38:09 +01:00
committed by GitHub
parent ba51222ad1
commit 2f80015380
4 changed files with 132 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
type = "a"
message = "Create metrics supplier for shards."
pulls = ["24035"]
issues = ["Graylog2/graylog-plugin-enterprise#12221", "Graylog2/graylog-plugin-enterprise#12223"]

View File

@@ -21,6 +21,7 @@ import org.graylog2.plugin.PluginModule;
import org.graylog2.telemetry.scheduler.TelemetrySubmissionPeriodical;
import org.graylog2.telemetry.suppliers.InputsMetricsSupplier;
import org.graylog2.telemetry.suppliers.OutputsMetricsSupplier;
import org.graylog2.telemetry.suppliers.ShardsMetricsSupplier;
public class TelemetryModule extends PluginModule {
@Override
@@ -33,5 +34,6 @@ public class TelemetryModule extends PluginModule {
addTelemetryMetricProvider("Inputs Metrics", InputsMetricsSupplier.class);
addTelemetryMetricProvider("Outputs Metrics", OutputsMetricsSupplier.class);
addTelemetryMetricProvider("Shards Metrics", ShardsMetricsSupplier.class);
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
package org.graylog2.telemetry.suppliers;
import jakarta.inject.Inject;
import org.graylog2.configuration.ElasticsearchConfiguration;
import org.graylog2.indexer.cluster.Cluster;
import org.graylog2.rest.models.system.indexer.responses.ClusterHealth;
import org.graylog2.telemetry.scheduler.TelemetryEvent;
import org.graylog2.telemetry.scheduler.TelemetryMetricSupplier;
import java.util.Map;
import java.util.Optional;
public class ShardsMetricsSupplier implements TelemetryMetricSupplier {
private final ElasticsearchConfiguration elasticsearchConfiguration;
private final Cluster cluster;
@Inject
public ShardsMetricsSupplier(ElasticsearchConfiguration elasticsearchConfiguration, Cluster cluster) {
this.elasticsearchConfiguration = elasticsearchConfiguration;
this.cluster = cluster;
}
@Override
public Optional<TelemetryEvent> get() {
Optional<ClusterHealth.ShardStatus> shardStatus = cluster.clusterHealthStats().map(ClusterHealth::shards);
Map<String, Object> metrics = Map.of(
"shard_min_size", elasticsearchConfiguration.getTimeSizeOptimizingRotationMinShardSize().getQuantity(),
"shard_max_size", elasticsearchConfiguration.getTimeSizeOptimizingRotationMaxShardSize().getQuantity(),
"shards_active", shardStatus.map(ClusterHealth.ShardStatus::active).orElse(0),
"shards_initializing", shardStatus.map(ClusterHealth.ShardStatus::initializing).orElse(0),
"shards_relocating", shardStatus.map(ClusterHealth.ShardStatus::relocating).orElse(0),
"shards_unassigned", shardStatus.map(ClusterHealth.ShardStatus::unassigned).orElse(0)
);
return Optional.of(TelemetryEvent.of(metrics));
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
package org.graylog2.telemetry.suppliers;
import com.github.joschi.jadconfig.util.Size;
import org.graylog2.configuration.ElasticsearchConfiguration;
import org.graylog2.indexer.cluster.Cluster;
import org.graylog2.rest.models.system.indexer.responses.ClusterHealth;
import org.graylog2.telemetry.scheduler.TelemetryEvent;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Map;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
public class ShardsMetricsSupplierTest {
@Mock
private ElasticsearchConfiguration elasticsearchConfiguration;
@Mock
private Cluster cluster;
@InjectMocks
private ShardsMetricsSupplier shardsMetricsSupplier;
@Test
public void shouldReturnShardMetrics() {
Size minSize = Size.gigabytes(29L);
Size maxSize = Size.gigabytes(34L);
ClusterHealth.ShardStatus shardStatus = ClusterHealth.ShardStatus.create(5, 4, 2, 1);
when(elasticsearchConfiguration.getTimeSizeOptimizingRotationMinShardSize()).thenReturn(minSize);
when(elasticsearchConfiguration.getTimeSizeOptimizingRotationMaxShardSize()).thenReturn(maxSize);
when(cluster.clusterHealthStats()).thenReturn(Optional.of(
ClusterHealth.create("yellow", shardStatus)
));
Optional<TelemetryEvent> event = shardsMetricsSupplier.get();
assertThat(event).isPresent();
assertThat(event.get().metrics()).isEqualTo(Map.<String, Object>of(
"shard_min_size", minSize.getQuantity(),
"shard_max_size", maxSize.getQuantity(),
"shards_active", shardStatus.active(),
"shards_initializing", shardStatus.initializing(),
"shards_relocating", shardStatus.relocating(),
"shards_unassigned", shardStatus.unassigned()
));
}
}