Skip to content

Commit 5d03377

Browse files
committed
Implement shinyproxy_absolute_apps_running metric
1 parent 6a8bba8 commit 5d03377

2 files changed

Lines changed: 52 additions & 13 deletions

File tree

src/main/java/eu/openanalytics/containerproxy/backend/docker/AbstractDockerBackend.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,6 @@
2020
*/
2121
package eu.openanalytics.containerproxy.backend.docker;
2222

23-
import java.io.IOException;
24-
import java.io.OutputStream;
25-
import java.net.URI;
26-
import java.nio.file.Paths;
27-
import java.util.HashMap;
28-
import java.util.ArrayList;
29-
import java.util.List;
30-
import java.util.Map;
31-
import java.util.function.BiConsumer;
32-
3323
import com.google.common.collect.ImmutableMap;
3424
import com.spotify.docker.client.DefaultDockerClient;
3525
import com.spotify.docker.client.DockerCertificates;
@@ -53,9 +43,9 @@
5343
import java.net.URI;
5444
import java.nio.file.Paths;
5545
import java.util.ArrayList;
46+
import java.util.HashMap;
5647
import java.util.List;
5748
import java.util.Map;
58-
import java.util.Optional;
5949
import java.util.function.BiConsumer;
6050

6151

src/main/java/eu/openanalytics/containerproxy/stat/impl/Micrometer.java

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,17 @@
3535

3636
import javax.annotation.PostConstruct;
3737
import javax.inject.Inject;
38+
import java.util.ArrayList;
39+
import java.util.List;
40+
import java.util.Timer;
41+
import java.util.TimerTask;
42+
import java.util.concurrent.ConcurrentHashMap;
3843
import java.util.function.DoubleFunction;
3944

4045
public class Micrometer implements IStatCollector {
4146

47+
private static final int CACHE_UPDATE_INTERVAL = 20 * 1000; // update cache every 20 seconds
48+
4249
@Inject
4350
private MeterRegistry registry;
4451

@@ -50,6 +57,12 @@ public class Micrometer implements IStatCollector {
5057

5158
private final Logger logger = LogManager.getLogger(getClass());
5259

60+
// keeps track of the number of proxies per spec id
61+
private final ConcurrentHashMap<String, Integer> proxyCountCache = new ConcurrentHashMap<>();
62+
63+
// need to store a reference to the proxyCounters as the Micrometer library only stores weak references
64+
private final List<ProxyCounter> proxyCounters = new ArrayList<>();
65+
5366
private Counter appStartFailedCounter;
5467

5568
private Counter authFailedCounter;
@@ -58,8 +71,6 @@ public class Micrometer implements IStatCollector {
5871

5972
private Counter userLogouts;
6073

61-
private Number usersLoggedIn;
62-
6374
@PostConstruct
6475
public void init() {
6576

@@ -72,9 +83,19 @@ public void init() {
7283
for (ProxySpec spec : proxyService.getProxySpecs(null, true)) {
7384
registry.counter("appStarts", "spec.id", spec.getId());
7485
registry.counter("appStops", "spec.id", spec.getId());
86+
ProxyCounter proxyCounter = new ProxyCounter(spec.getId());
87+
proxyCounters.add(proxyCounter);
88+
registry.gauge("shinyproxy_absolute_apps_running", Tags.of("spec.id", spec.getId()), proxyCounter, ProxyCounter::getProxyCount);
7589
registry.timer("startupTime", "spec.id", spec.getId());
7690
registry.timer("usageTime", "spec.id", spec.getId());
7791
}
92+
93+
new Timer().schedule(new TimerTask() {
94+
@Override
95+
public void run() {
96+
updateCachedProxyCount();
97+
}
98+
}, 0, CACHE_UPDATE_INTERVAL);
7899
}
79100

80101
@EventListener
@@ -115,4 +136,32 @@ public void onAuthFailedEvent(AuthFailedEvent event) {
115136
authFailedCounter.increment();
116137
}
117138

139+
/**
140+
* Updates the cache containing the number of proxies running for each spec id.
141+
* We only update this value every CACHE_UPDATE_INTERVAL because this is a relative heavy computation to do.
142+
* Therefore we don't want that this calculation is performed every time the guage is updated.
143+
* Especially since could be called using an HTTP request.
144+
*/
145+
private void updateCachedProxyCount() {
146+
for (ProxySpec spec : proxyService.getProxySpecs(null, true)) {
147+
Integer count = proxyService.getProxies(p -> p.getSpec().getId().equals(spec.getId()), true).size();
148+
proxyCountCache.put(spec.getId(), count);
149+
logger.debug(String.format("Running proxies count for spec %s: %s ", spec.getId(), count));
150+
}
151+
}
152+
153+
private class ProxyCounter {
154+
155+
private final String specId;
156+
157+
public ProxyCounter(String specId) {
158+
this.specId = specId;
159+
}
160+
161+
public int getProxyCount() {
162+
return proxyCountCache.getOrDefault(specId, null);
163+
}
164+
165+
}
166+
118167
}

0 commit comments

Comments
 (0)