Skip to content
Permalink
Browse files
use MP config for database config as well
  • Loading branch information
rmannibucau committed Jan 8, 2019
1 parent a758c87 commit 4b6539f502baf2d8596d58f67acf95401830517a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 11 deletions.
@@ -29,10 +29,6 @@

// copy of metrics Histogram impl
public class InMemoryDatabase<T> {
private static final double ALPHA = Double.parseDouble(System.getProperty("geronimo.reporter.storage.alpha", "0.015"));

private static final int BUCKET_SIZE = Integer.getInteger("geronimo.reporter.storage.size", 12 /* one point/5s */ * 60 * 60);

private static final long REFRESH_INTERVAL = TimeUnit.HOURS.toNanos(1);

private final String unit;
@@ -43,12 +39,17 @@

private final AtomicLong nextRefreshTime = new AtomicLong(System.nanoTime() + REFRESH_INTERVAL);

private final double alpha;
private final int bucketSize;

private volatile long startTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());

private final ConcurrentSkipListMap<Double, Value<T>> bucket = new ConcurrentSkipListMap<>();

public InMemoryDatabase(final String unit) {
public InMemoryDatabase(final double alpha, final int bucketSize, final String unit) {
this.unit = unit;
this.alpha = alpha;
this.bucketSize = bucketSize;
}

public String getUnit() {
@@ -73,11 +74,11 @@ public void add(final T value) {
final Lock lock = this.lock.readLock();
lock.lock();
try {
final Value<T> sample = new Value<>(value, now, Math.exp(ALPHA * (TimeUnit.MILLISECONDS.toSeconds(now) - startTime)));
final Value<T> sample = new Value<>(value, now, Math.exp(alpha * (TimeUnit.MILLISECONDS.toSeconds(now) - startTime)));
final double priority = sample.weight / Math.random();

final long size = count.incrementAndGet();
if (size <= BUCKET_SIZE) {
if (size <= bucketSize) {
bucket.put(priority, sample);
} else { // iterate through the bucket until we need removing low priority entries to get a new space
double first = bucket.firstKey();
@@ -105,7 +106,7 @@ private void ensureUpToDate() {
if (nextRefreshTime.compareAndSet(next, now + REFRESH_INTERVAL)) {
final long oldStartTime = startTime;
startTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
final double updateFactor = Math.exp(-ALPHA * (startTime - oldStartTime));
final double updateFactor = Math.exp(-alpha * (startTime - oldStartTime));
if (updateFactor != 0.) {
bucket.putAll(new ArrayList<>(bucket.keySet()).stream().collect(toMap(k -> k * updateFactor, k -> {
final Value<T> previous = bucket.remove(k);
@@ -20,26 +20,50 @@
import java.util.Map;
import java.util.stream.Stream;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Destroyed;
import javax.enterprise.event.Observes;
import javax.inject.Inject;

import org.apache.geronimo.microprofile.reporter.storage.plugins.health.CheckSnapshot;
import org.apache.geronimo.microprofile.reporter.storage.plugins.metrics.MeterSnapshot;
import org.apache.geronimo.microprofile.reporter.storage.plugins.metrics.SnapshotStat;
import org.apache.geronimo.microprofile.reporter.storage.plugins.metrics.TimerSnapshot;
import org.apache.geronimo.microprofile.reporter.storage.plugins.tracing.SpanEntry;
import org.eclipse.microprofile.config.inject.ConfigProperty;

@ApplicationScoped
public class MicroprofileDatabase {
private final InMemoryDatabase<SpanEntry> spanDatabase = new InMemoryDatabase<>("none");
@Inject
@ConfigProperty(name = "geronimo.reporter.storage.alpha", defaultValue = "0.015")
private Double alpha;

@Inject
@ConfigProperty(name = "geronimo.reporter.storage.size", defaultValue = "43200" /*each 5s*/)
private Integer bucketSize;

private InMemoryDatabase<SpanEntry> spanDatabase;
private final Map<String, InMemoryDatabase<Long>> counters = new HashMap<>();
private final Map<String, InMemoryDatabase<Double>> gauges = new HashMap<>();
private final Map<String, InMemoryDatabase<SnapshotStat>> histograms = new HashMap<>();
private final Map<String, InMemoryDatabase<MeterSnapshot>> meters = new HashMap<>();
private final Map<String, InMemoryDatabase<TimerSnapshot>> timers = new HashMap<>();
private final Map<String, InMemoryDatabase<CheckSnapshot>> checks = new HashMap<>();

@PostConstruct
private void init() {
spanDatabase = new InMemoryDatabase<>(alpha, bucketSize,"none");
}

public Double getAlpha() {
return alpha;
}

public Integer getBucketSize() {
return bucketSize;
}

public InMemoryDatabase<SpanEntry> getSpans() {
return spanDatabase;
}
@@ -59,7 +59,7 @@ private void updateHealthCheck(final CheckSnapshot healthCheckResponse) {
final String name = healthCheckResponse.getName();
InMemoryDatabase<CheckSnapshot> db = database.getChecks().get(name);
if (db == null) {
db = new InMemoryDatabase<>("check");
db = new InMemoryDatabase<>(database.getAlpha(), database.getBucketSize(), "check");
final InMemoryDatabase<CheckSnapshot> existing = database.getChecks().putIfAbsent(name, db);
if (existing != null) {
db = existing;
@@ -105,7 +105,8 @@ private <T> InMemoryDatabase<T> getDb(final Map<String, InMemoryDatabase<T>> reg
final String key) {
InMemoryDatabase<T> db = registry.get(virtualName);
if (db == null) {
db = new InMemoryDatabase<>(ofNullable(source.getMetadata().get(key).getUnit()).orElse(""));
db = new InMemoryDatabase<>(database.getAlpha(), database.getBucketSize(),
ofNullable(source.getMetadata().get(key).getUnit()).orElse(""));
final InMemoryDatabase<T> existing = registry.putIfAbsent(virtualName, db);
if (existing != null) {
db = existing;

0 comments on commit 4b6539f

Please sign in to comment.