This repository has been archived by the owner on Sep 21, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 575
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix prometheus bug where running/starting containers could be wrong (#…
…728) * Fix prometheus bug where running/starting containers could be wrong * Add test case
- Loading branch information
Showing
5 changed files
with
140 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
src/main/java/de/zalando/ep/zalenium/prometheus/ContainerStatusCollectorExports.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package de.zalando.ep.zalenium.prometheus; | ||
|
||
import static java.util.Collections.singletonList; | ||
import static java.util.stream.Collectors.counting; | ||
import static java.util.stream.Collectors.groupingBy; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
import de.zalando.ep.zalenium.container.ContainerCreationStatus; | ||
import de.zalando.ep.zalenium.proxy.AutoStartProxySet.ContainerStatus; | ||
import io.prometheus.client.Collector; | ||
import io.prometheus.client.GaugeMetricFamily; | ||
|
||
public class ContainerStatusCollectorExports extends Collector { | ||
|
||
private enum States { | ||
RUNNING, | ||
STARTING; | ||
} | ||
|
||
private Map<ContainerCreationStatus, ContainerStatus> startedContainers; | ||
private static List<States> STATES = Arrays.asList(States.values()); | ||
|
||
public ContainerStatusCollectorExports(Map<ContainerCreationStatus, ContainerStatus> startedContainers) { | ||
super(); | ||
this.startedContainers = startedContainers; | ||
} | ||
|
||
@Override | ||
public List<MetricFamilySamples> collect() { | ||
|
||
GaugeMetricFamily seleniumContainersStateMetric = new GaugeMetricFamily("selenium_containers", | ||
"The number of Selenium Containers broken down by state", | ||
singletonList("state")); | ||
|
||
Map<States, Long> containerStates = startedContainers.values().stream() | ||
.collect(groupingBy(s -> { | ||
return s.isStarted() ? States.RUNNING : States.STARTING; | ||
}, counting())); | ||
|
||
// Ensure that if a state is empty it is 0 instead of missing. | ||
STATES.stream().forEach(s -> | ||
seleniumContainersStateMetric.addMetric(singletonList(s.name().toLowerCase()), | ||
Optional.ofNullable(containerStates.get(s)).orElse(0L))); | ||
|
||
List<MetricFamilySamples> mfs = new ArrayList<MetricFamilySamples>(); | ||
mfs.add(seleniumContainersStateMetric); | ||
return mfs; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
src/test/java/de/zalando/ep/zalenium/prometheus/ContainerStatusCollectorExportsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package de.zalando.ep.zalenium.prometheus; | ||
|
||
|
||
import static org.hamcrest.CoreMatchers.equalTo; | ||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.mockito.Mockito.mock; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
import org.junit.After; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
|
||
import de.zalando.ep.zalenium.container.ContainerCreationStatus; | ||
import de.zalando.ep.zalenium.proxy.AutoStartProxySet.ContainerStatus; | ||
import io.prometheus.client.CollectorRegistry; | ||
|
||
public class ContainerStatusCollectorExportsTest { | ||
|
||
@Before | ||
@After | ||
public void resetPrometheus() { | ||
CollectorRegistry.defaultRegistry.clear(); | ||
} | ||
|
||
@Test | ||
public void testEmptyMapBothValuesZero() { | ||
Map<ContainerCreationStatus,ContainerStatus> map = new HashMap<ContainerCreationStatus, ContainerStatus>(); | ||
new ContainerStatusCollectorExports(map).register(CollectorRegistry.defaultRegistry); | ||
|
||
Double startingValue = CollectorRegistry.defaultRegistry.getSampleValue("selenium_containers", new String[] {"state"}, new String[] {"starting"}); | ||
Double runningValue = CollectorRegistry.defaultRegistry.getSampleValue("selenium_containers", new String[] {"state"}, new String[] {"running"}); | ||
assertThat(startingValue, equalTo(0.0)); | ||
assertThat(runningValue, equalTo(0.0)); | ||
} | ||
|
||
@Test | ||
public void testIncrementChanges() { | ||
// Given an empty map | ||
Map<ContainerCreationStatus,ContainerStatus> map = new HashMap<ContainerCreationStatus, ContainerStatus>(); | ||
new ContainerStatusCollectorExports(map).register(CollectorRegistry.defaultRegistry); | ||
|
||
// We get an empty values for both states | ||
Double startingValue = CollectorRegistry.defaultRegistry.getSampleValue("selenium_containers", new String[] {"state"}, new String[] {"starting"}); | ||
Double runningValue = CollectorRegistry.defaultRegistry.getSampleValue("selenium_containers", new String[] {"state"}, new String[] {"running"}); | ||
assertThat(startingValue, equalTo(0.0)); | ||
assertThat(runningValue, equalTo(0.0)); | ||
|
||
// After we add 2 starting containers | ||
ContainerStatus container1 = new ContainerStatus("123", 0l); | ||
ContainerStatus container2 = new ContainerStatus("1234", 0l); | ||
|
||
map.put(mock(ContainerCreationStatus.class), container1); | ||
map.put(mock(ContainerCreationStatus.class), container2); | ||
|
||
// We expect 2 starting and 0 running | ||
startingValue = CollectorRegistry.defaultRegistry.getSampleValue("selenium_containers", new String[] {"state"}, new String[] {"starting"}); | ||
runningValue = CollectorRegistry.defaultRegistry.getSampleValue("selenium_containers", new String[] {"state"}, new String[] {"running"}); | ||
assertThat(startingValue, equalTo(2.0)); | ||
assertThat(runningValue, equalTo(0.0)); | ||
|
||
// Once we add a started time | ||
container1.setTimeStarted(Optional.of(0l)); | ||
container2.setTimeStarted(Optional.of(0l)); | ||
|
||
// We expect 0 starting and 2 running | ||
startingValue = CollectorRegistry.defaultRegistry.getSampleValue("selenium_containers", new String[] {"state"}, new String[] {"starting"}); | ||
runningValue = CollectorRegistry.defaultRegistry.getSampleValue("selenium_containers", new String[] {"state"}, new String[] {"running"}); | ||
assertThat(startingValue, equalTo(0.0)); | ||
assertThat(runningValue, equalTo(2.0)); | ||
} | ||
} |