Gitlab Community Edition Instance

Commit 3a8e39ee authored by mhellka's avatar mhellka
Browse files

Added lots of metrics for pools and sessions.

parent 587a6bc4
Pipeline #115014 passed with stages
in 10 minutes and 5 seconds
......@@ -6,6 +6,7 @@ import java.io.OutputStream;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileStore;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
......@@ -27,6 +28,7 @@ import org.slf4j.LoggerFactory;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import de.gwdg.cdstar.MultiDigest;
import de.gwdg.cdstar.Utils;
......@@ -70,6 +72,7 @@ public class NioPool implements StoragePool {
NioRecoveryHandler recoveryHandler;
LoadingCache<Path, JsonIndex> indexCache;
private PoolStats stats;
public NioPool(Config cfg) throws IOException, ConfigException {
// TODO: Make more than just the path configurable
......@@ -89,6 +92,8 @@ public class NioPool implements StoragePool {
// Allow GC to shrink the heap during idle hours.
.expireAfterAccess(60, TimeUnit.SECONDS)
.build(this::loadFromDisk);
stats = new PoolStats();
}
@Override
......@@ -337,4 +342,46 @@ public class NioPool implements StoragePool {
return false;
}
public PoolStats getStats() {
return stats;
}
public class PoolStats {
public CacheStats getCacheStats() {
return indexCache.stats();
}
public long getDiskTotal() {
long total = 0;
for (FileStore store : basePath.getFileSystem().getFileStores()) {
try {
total = store.getTotalSpace();
} catch (IOException e) {
continue;
}
}
return total;
}
public long getDiskFree() {
long usable = 0;
for (FileStore store : basePath.getFileSystem().getFileStores()) {
try {
usable = store.getUsableSpace();
} catch (IOException e) {
continue;
}
}
return usable;
}
public long cacheHitCount() {
return indexCache.stats().hitCount();
}
public long cacheMissCount() {
return indexCache.stats().missCount();
}
}
}
......@@ -5,10 +5,14 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Predicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.codahale.metrics.MetricRegistry;
import de.gwdg.cdstar.runtime.RuntimeContext;
import de.gwdg.cdstar.runtime.client.CDStarSession;
import de.gwdg.cdstar.runtime.listener.RuntimeListener;
......@@ -19,12 +23,21 @@ public class SessionRegistry implements SessionStartListener, SessionListener, R
private final ConcurrentHashMap<String, CDStarSession> allSessions = new ConcurrentHashMap<>();
private ScheduledFuture<?> sessionReaper;
private final AtomicLong totalCounter = new AtomicLong();
private static final Logger log = LoggerFactory.getLogger(SessionRegistry.class);
@Override
public void onStartup(RuntimeContext ctx) throws Exception {
sessionReaper = ctx.lookupRequired(CronService.class).schedule(this::reapExpiredSessions, 10, TimeUnit.SECONDS);
ctx.lookup(MetricRegistry.class).ifPresent(mr -> {
mr.gauge("sess.open", () -> () -> allSessions.size());
mr.gauge("sess.open.ro", () -> () -> allSessions.values().stream()
.filter(CDStarSession::isReadOnly).count());
mr.gauge("sess.open.rw", () -> () -> allSessions.values().stream()
.filter(((Predicate<CDStarSession>)CDStarSession::isReadOnly).negate()).count());
mr.gauge("sess.total", () -> () -> totalCounter.get());
});
}
private void reapExpiredSessions() {
......@@ -56,6 +69,7 @@ public class SessionRegistry implements SessionStartListener, SessionListener, R
@Override
public void onSessionStarted(CDStarSession session) {
allSessions.put(session.getSessionId(), session);
totalCounter.incrementAndGet();
session.addListener(this);
}
......
......@@ -19,12 +19,15 @@ import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.codahale.metrics.MetricRegistry;
import de.gwdg.cdstar.Utils;
import de.gwdg.cdstar.config.ConfigLoader;
import de.gwdg.cdstar.config.MapConfig;
import de.gwdg.cdstar.pool.PoolError;
import de.gwdg.cdstar.pool.StoragePool;
import de.gwdg.cdstar.pool.nio.NioPool;
import de.gwdg.cdstar.pool.nio.NioPool.PoolStats;
import de.gwdg.cdstar.runtime.Config;
import de.gwdg.cdstar.runtime.ConfigException;
import de.gwdg.cdstar.runtime.RuntimeContext;
......@@ -200,6 +203,9 @@ public class VaultRegistry implements RuntimeListener {
if (!StoragePool.class.isAssignableFrom(poolClass))
throw new ConfigException("Pool does not implement " + StoragePool.class.getName());
vci.pool = (StoragePool) poolClass.getConstructor(Config.class).newInstance(scoped);
addMetrics(vci);
return vci.pool;
} catch (final Exception e) {
if (e instanceof PoolError)
......@@ -209,6 +215,24 @@ public class VaultRegistry implements RuntimeListener {
}
}
private void addMetrics(VaultConfigImpl vci) {
if(vci.pool instanceof NioPool) {
runtime.lookup(MetricRegistry.class).ifPresent(mr -> {
String name = "pool."+vci.getName();
NioPool pool = (NioPool) vci.pool;
PoolStats poolStats = pool.getStats();
mr.gauge(name+".cache.hit", () -> () -> poolStats.cacheHitCount());
mr.gauge(name+".cache.miss", () -> () -> poolStats.cacheMissCount());
mr.gauge(name+".disk.total", () -> () -> poolStats.getDiskTotal());
mr.gauge(name+".disk.free", () -> () -> poolStats.getDiskFree());
});
}
}
private boolean isValidVaultName(String name) {
return vaultNamePattern.matcher(name).matches();
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment