Compare commits

...

2 Commits

Author SHA1 Message Date
zzz
8c4fd32450 Add group name to all PromStats
Some checks failed
Java CI / build (push) Has been cancelled
Java CI / javadoc-latest (push) Has been cancelled
Java CI / build-java7 (push) Has been cancelled
Java with IzPack Snapshot Setup / setup (push) Has been cancelled
2025-05-03 12:15:23 -04:00
zzz
d1b24274c7 label support in subclasses 2025-04-21 14:49:28 -04:00
13 changed files with 359 additions and 66 deletions

View File

@@ -7,8 +7,12 @@ package net.i2p.stat.prometheus;
*/
public abstract class Counter extends PromStat {
public Counter(String name, String desc, Unit unit) {
super(name, desc, Type.COUNTER, unit);
public Counter(String name, String desc, String group, Unit unit) {
super(name, desc, group, Type.COUNTER, unit);
}
public Counter(String name, String desc, String group, Unit unit, String label, String... values) {
super(name, desc, group, Type.COUNTER, unit, label, values);
}
public abstract void increment();
@@ -16,4 +20,30 @@ public abstract class Counter extends PromStat {
public abstract void add(long value);
public abstract void add(float value);
public abstract void add(double value);
public abstract void increment(int labelIndex);
public abstract void add(int labelIndex, int value);
public abstract void add(int labelIndex, long value);
public abstract void add(int labelIndex, float value);
public abstract void add(int labelIndex, double value);
static void throwIfNegative(int value) {
if (value < 0)
throw new IllegalArgumentException("value cannot be negative");
}
static void throwIfNegative(long value) {
if (value < 0)
throw new IllegalArgumentException("value cannot be negative");
}
static void throwIfNegative(float value) {
if (value < 0)
throw new IllegalArgumentException("value cannot be negative");
}
static void throwIfNegative(double value) {
if (value < 0)
throw new IllegalArgumentException("value cannot be negative");
}
}

View File

@@ -8,56 +8,91 @@ package net.i2p.stat.prometheus;
*/
public class FCounter extends Counter implements FloatConsumer, FloatSupplier {
private final AtomicFloat c = new AtomicFloat();
private final AtomicFloat[] a;
public FCounter(String name, String desc, Unit unit) {
super(name, desc, unit);
public FCounter(String name, String desc, String group, Unit unit) {
this(name, desc, group, unit, null);
}
public FCounter(String name, String desc, String group, Unit unit, String label, String... values) {
super(name, desc, group, unit, label, values);
a = new AtomicFloat[label != null ? values.length : 1];
for (int i = 0; i < a.length; i++) {
a[i] = new AtomicFloat();
}
}
public void increment() {
c.incrementAndGet();
// assume won't overflow
increment(0);
}
public void add(int value) {
c.addAndGet(value);
// assume won't overflow
add(0, value);
}
public void add(long value) {
c.addAndGet((float) value);
// assume won't overflow
add(0, value);
}
public void add(float value) {
c.addAndGet(value);
// assume won't overflow
add(0, value);
}
public void add(double value) {
c.addAndGet((float) value);
// assume won't overflow
add(0, value);
}
public float getValue() {
return c.get();
return getValue(0);
}
public double getDoubleValue() {
return c.get();
return getDoubleValue(0);
}
public void increment(int idx) {
a[idx].incrementAndGet();
}
public void add(int idx, int value) {
throwIfNegative(value);
a[idx].addAndGet(value);
}
public void add(int idx, long value) {
throwIfNegative(value);
a[idx].addAndGet((float) value);
}
public void add(int idx, float value) {
throwIfNegative(value);
a[idx].addAndGet(value);
}
public void add(int idx, double value) {
throwIfNegative(value);
a[idx].addAndGet((float) value);
}
public float getValue(int idx) {
return a[idx].get();
}
public double getDoubleValue(int idx) {
return a[idx].get();
}
/**
* Supplier interface
*/
public float getAsFloat() {
return c.get();
return a[0].get();
}
/**
* Consumer interface
*/
public void accept(float value) {
c.addAndGet(value);
a[0].addAndGet(value);
}
}

View File

@@ -8,40 +8,72 @@ package net.i2p.stat.prometheus;
*/
public class FGauge extends Gauge implements FloatConsumer, FloatSupplier {
private final AtomicFloat c = new AtomicFloat();
private final AtomicFloat[] a;
private final FloatSupplier s;
public FGauge(String name, String desc, Unit unit) {
this(name, desc, unit, null);
public FGauge(String name, String desc, String group, Unit unit) {
this(name, desc, group, unit, null);
}
public FGauge(String name, String desc, Unit unit, FloatSupplier supplier) {
super(name, desc, unit);
public FGauge(String name, String desc, String group, Unit unit, FloatSupplier supplier) {
this(name, desc, group, unit, supplier, (String) null);
}
public FGauge(String name, String desc, String group, Unit unit, FloatSupplier supplier, String label, String... values) {
super(name, desc, group, unit);
a = new AtomicFloat[label != null ? values.length : 1];
for (int i = 0; i < a.length; i++) {
a[i] = new AtomicFloat();
}
s = supplier;
}
public void setValue(int value) {
c.set(value);
setValue(0, value);
}
public void setValue(long value) {
c.set((float) value);
setValue(0, value);
}
public void setValue(float value) {
c.set(value);
setValue(0, value);
}
public void setValue(double value) {
c.set((float) value);
setValue(0, value);
}
public float getValue() {
return c.get();
return getValue(0);
}
public double getDoubleValue() {
return c.get();
return getDoubleValue(0);
}
public void setValue(int idx, int value) {
a[idx].set(value);
}
public void setValue(int idx, long value) {
a[idx].set((float) value);
}
public void setValue(int idx, float value) {
a[idx].set(value);
}
public void setValue(int idx, double value) {
a[idx].set((float) value);
}
public float getValue(int idx) {
return a[idx].get();
}
public double getDoubleValue(int idx) {
return a[idx].get();
}
/**
@@ -50,14 +82,14 @@ public class FGauge extends Gauge implements FloatConsumer, FloatSupplier {
@Override
public void coalesceStats() {
if (s != null)
c.set(s.getAsFloat());
a[0].set(s.getAsFloat());
}
/**
* Supplier interface
*/
public float getAsFloat() {
return c.get();
return a[0].get();
}
/**
@@ -66,6 +98,6 @@ public class FGauge extends Gauge implements FloatConsumer, FloatSupplier {
* Adds the value
*/
public void accept(float value) {
c.set(value);
a[0].set(value);
}
}

View File

@@ -7,12 +7,21 @@ package net.i2p.stat.prometheus;
*/
public abstract class Gauge extends PromStat {
public Gauge(String name, String desc, Unit unit) {
super(name, desc, Type.GAUGE, unit);
public Gauge(String name, String desc, String group, Unit unit) {
super(name, desc, group, Type.GAUGE, unit);
}
public Gauge(String name, String desc, String group, Unit unit, String label, String... values) {
super(name, desc, group, Type.GAUGE, unit, label, values);
}
public abstract void setValue(int value);
public abstract void setValue(long value);
public abstract void setValue(float value);
public abstract void setValue(double value);
public abstract void setValue(int labelIndex, int value);
public abstract void setValue(int labelIndex, long value);
public abstract void setValue(int labelIndex, float value);
public abstract void setValue(int labelIndex, double value);
}

View File

@@ -1,6 +1,7 @@
package net.i2p.stat.prometheus;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* A simple Prometheus-style counter, with overflow protection.
@@ -9,10 +10,22 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class ICounter extends Counter implements IntConsumer, IntSupplier {
private final AtomicInteger c = new AtomicInteger();
private final AtomicIntegerArray a;
private final AtomicInteger c;
public ICounter(String name, String desc, Unit unit) {
super(name, desc, unit);
public ICounter(String name, String desc, String group, Unit unit) {
this(name, desc, group, unit, null);
}
public ICounter(String name, String desc, String group, Unit unit, String label, String... values) {
super(name, desc, group, unit, label, values);
if (label != null) {
a = new AtomicIntegerArray(values.length);
c = null;
} else {
a = null;
c = new AtomicInteger();
}
}
/**
@@ -28,6 +41,7 @@ public class ICounter extends Counter implements IntConsumer, IntSupplier {
* Resets to 0 on overflow.
*/
public void add(int value) {
throwIfNegative(value);
int v = c.addAndGet(value);
if (v < 0)
c.set(0);
@@ -53,6 +67,45 @@ public class ICounter extends Counter implements IntConsumer, IntSupplier {
return c.get();
}
/**
* Resets to 0 on overflow.
*/
public void increment(int idx) {
int v = a.incrementAndGet(idx);
if (v < 0)
a.set(idx, 0);
}
/**
* Resets to 0 on overflow.
*/
public void add(int idx, int value) {
throwIfNegative(value);
int v = a.addAndGet(idx, value);
if (v < 0)
a.set(idx, 0);
}
public void add(int idx, long value) {
add(idx, (int) value);
}
public void add(int idx, float value) {
add(idx, (int) value);
}
public void add(int idx, double value) {
add(idx, (int) value);
}
public int getValue(int idx) {
return a.get(idx);
}
public double getDoubleValue(int idx) {
return a.get(idx);
}
/**
* Supplier interface
*/

View File

@@ -1,6 +1,7 @@
package net.i2p.stat.prometheus;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* A simple Prometheus-style gauge
@@ -9,15 +10,27 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class IGauge extends Gauge implements IntConsumer, IntSupplier {
private final AtomicInteger c = new AtomicInteger();
private final AtomicIntegerArray a;
private final AtomicInteger c;
private final IntSupplier s;
public IGauge(String name, String desc, Unit unit) {
this(name, desc, unit, null);
public IGauge(String name, String desc, String group, Unit unit) {
this(name, desc, group, unit, null);
}
public IGauge(String name, String desc, Unit unit, IntSupplier supplier) {
super(name, desc, unit);
public IGauge(String name, String desc, String group, Unit unit, IntSupplier supplier) {
this(name, desc, group, unit, supplier, null);
}
public IGauge(String name, String desc, String group, Unit unit, IntSupplier supplier, String label, String... values) {
super(name, desc, group, unit, label, values);
if (label != null) {
a = new AtomicIntegerArray(values.length);
c = null;
} else {
a = null;
c = new AtomicInteger();
}
s = supplier;
}
@@ -45,6 +58,31 @@ public class IGauge extends Gauge implements IntConsumer, IntSupplier {
return c.get();
}
public void setValue(int idx, int value) {
a.set(idx, value);
}
public void setValue(int idx, long value) {
a.set(idx, (int) value);
}
public void setValue(int idx, float value) {
a.set(idx, (int) value);
}
public void setValue(int idx, double value) {
a.set(idx, (int) value);
}
public long getValue(int idx) {
return a.get(idx);
}
public double getDoubleValue(int idx) {
return a.get(idx);
}
/**
* For StatManager
*/

View File

@@ -10,23 +10,23 @@ import java.util.concurrent.atomic.AtomicInteger;
*
* @since 0.9.67
*/
public class Info extends PromStat implements IntSupplier, PropsSupplier, PropsConsumer {
public class Info extends PromStat implements IntSupplier, MapSupplier, MapConsumer {
private final Map<String, String> labels;
/**
* Map returned by getValues() will be a ConcurrentHashMap
*/
public Info(String name, String desc) {
this(name, desc, null);
public Info(String name, String desc, String group) {
this(name, desc, group, null);
}
/**
* @param labels use caution, use a ConcurrentHashMap if setValue() or accept()
* will be called later to add label names or change the label values
*/
public Info(String name, String desc, Map<String, String> labels) {
super(name, desc, Type.GAUGE, Unit.NONE);
public Info(String name, String desc, String group, Map<String, String> labels) {
super(name, desc, group, Type.GAUGE, Unit.NONE);
this.labels = (labels != null) ? labels : new ConcurrentHashMap<String, String>(4);
}

View File

@@ -1,6 +1,7 @@
package net.i2p.stat.prometheus;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongArray;
/**
* A simple Prometheus-style counter.
@@ -10,35 +11,46 @@ import java.util.concurrent.atomic.AtomicLong;
*/
public class LCounter extends Counter implements LongConsumer, LongSupplier {
private final AtomicLong c = new AtomicLong();
private final AtomicLongArray a;
private final AtomicLong c;
public LCounter(String name, String desc, Unit unit) {
super(name, desc, unit);
public LCounter(String name, String desc, String group, Unit unit) {
this(name, desc, group, unit, null);
}
public LCounter(String name, String desc, String group, Unit unit, String label, String... values) {
super(name, desc, group, unit, label, values);
if (label != null) {
a = new AtomicLongArray(values.length);
c = null;
} else {
a = null;
c = new AtomicLong();
}
}
public void increment() {
c.incrementAndGet();
// assume won't overflow
}
public void add(int value) {
throwIfNegative(value);
c.addAndGet(value);
// assume won't overflow
}
public void add(long value) {
throwIfNegative(value);
c.addAndGet(value);
// assume won't overflow
}
public void add(float value) {
throwIfNegative(value);
c.addAndGet((long) value);
// assume won't overflow
}
public void add(double value) {
throwIfNegative(value);
c.addAndGet((long) value);
// assume won't overflow
}
public long getValue() {
@@ -49,6 +61,38 @@ public class LCounter extends Counter implements LongConsumer, LongSupplier {
return c.get();
}
public void increment(int idx) {
a.incrementAndGet(idx);
}
public void add(int idx, int value) {
throwIfNegative(value);
a.addAndGet(idx, value);
}
public void add(int idx, long value) {
throwIfNegative(value);
a.addAndGet(idx, value);
}
public void add(int idx, float value) {
throwIfNegative(value);
a.addAndGet(idx, (long) value);
}
public void add(int idx, double value) {
throwIfNegative(value);
a.addAndGet(idx, (long) value);
}
public long getValue(int idx) {
return a.get(idx);
}
public double getDoubleValue(int idx) {
return a.get(idx);
}
/**
* Supplier interface
*/

View File

@@ -1,6 +1,7 @@
package net.i2p.stat.prometheus;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicLongArray;
/**
* A simple Prometheus-style gauge
@@ -9,15 +10,27 @@ import java.util.concurrent.atomic.AtomicLong;
*/
public class LGauge extends Gauge implements LongConsumer, LongSupplier {
private final AtomicLong c = new AtomicLong();
private final AtomicLongArray a;
private final AtomicLong c;
private final LongSupplier s;
public LGauge(String name, String desc, Unit unit) {
this(name, desc, unit, null);
public LGauge(String name, String desc, String group, Unit unit) {
this(name, desc, group, unit, null);
}
public LGauge(String name, String desc, Unit unit, LongSupplier supplier) {
super(name, desc, unit);
public LGauge(String name, String desc, String group, Unit unit, LongSupplier supplier) {
this(name, desc, group, unit, supplier, null);
}
public LGauge(String name, String desc, String group, Unit unit, LongSupplier supplier, String label, String... values) {
super(name, desc, group, unit, label, values);
if (label != null) {
a = new AtomicLongArray(values.length);
c = null;
} else {
a = null;
c = new AtomicLong();
}
s = supplier;
}
@@ -45,6 +58,30 @@ public class LGauge extends Gauge implements LongConsumer, LongSupplier {
return c.get();
}
public void setValue(int idx, int value) {
a.set(idx, value);
}
public void setValue(int idx, long value) {
a.set(idx, value);
}
public void setValue(int idx, float value) {
a.set(idx, (long) value);
}
public void setValue(int idx, double value) {
a.set(idx, (long) value);
}
public long getValue(int idx) {
return a.get(idx);
}
public double getDoubleValue(int idx) {
return a.get(idx);
}
/**
* For StatManager
*/

View File

@@ -7,6 +7,6 @@ import java.util.Map;
*
* @since 0.9.67
*/
public interface PropsConsumer {
public interface MapConsumer {
public void accept(Map<String, String> values);
}

View File

@@ -7,6 +7,6 @@ import java.util.Map;
*
* @since 0.9.67
*/
public interface PropsSupplier {
public interface MapSupplier {
public Map<String, String> getAsMap();
}

View File

@@ -15,6 +15,7 @@ public abstract class PromStat {
private final String desc;
private final String name;
private final String promName;
private final String groupName;
private final String labelName;
private final String[] labelValues;
private final Type type;
@@ -24,22 +25,25 @@ public abstract class PromStat {
* No label
*
* @param name [a-zA-Z0-9_.] only. '.' will be replaced with '_' for getPromName()
* @param group use same group names as RateStat and FrequencyStat
*/
public PromStat(String name, String description, Type type, Unit unit) {
this(name, description, type, unit, null);
public PromStat(String name, String description, String group, Type type, Unit unit) {
this(name, description, group, type, unit, null);
}
/*
* With one label and one or more values
*
* @param name [a-zA-Z0-9_.] only. '.' will be replaced with '_' for getPromName()
* @param group use same group names as RateStat and FrequencyStat
* @param label [a-zA-Z0-9_.] only. '.' will be replaced with '_' for getLabelName()
* for example "dir"
* @param values for example "in", "out"
*/
public PromStat(String name, String description, Type type, Unit unit, String label, String... values) {
public PromStat(String name, String description, String group, Type type, Unit unit, String label, String... values) {
this.name = name;
desc = description;
groupName = group;
this.type = type;
this.unit = unit;
String p = fixup(name);
@@ -74,6 +78,13 @@ public abstract class PromStat {
return promName;
}
/*
* @return same group names as RateStat and FrequencyStat
*/
public String getGroupName() {
return groupName;
}
/**
* @return may be null
*/
@@ -140,6 +151,7 @@ public abstract class PromStat {
double rv = getDoubleValue();
switch (unit) {
case KBYTES:
case KBPS:
rv *= 1000f;
break;
@@ -159,6 +171,7 @@ public abstract class PromStat {
double rv = getDoubleValue(labelValueIndex);
switch (unit) {
case KBYTES:
case KBPS:
rv *= 1000f;
break;

View File

@@ -9,6 +9,8 @@ public enum Unit {
BYTES("bytes"),
KBYTES("bytes"),
BPS("bytes"),
KBPS("bytes"),
SECONDS("seconds"),
MS("seconds"),
EVENTS("count"),