add partial label support (WIP)

This commit is contained in:
zzz
2025-04-21 08:33:37 -04:00
parent b9eda05ac4
commit d28556e35c
2 changed files with 111 additions and 17 deletions

View File

@@ -12,7 +12,7 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
public class Info extends PromStat implements IntSupplier, PropsSupplier, PropsConsumer {
private final Map<String, String> props;
private final Map<String, String> labels;
/**
* Map returned by getValues() will be a ConcurrentHashMap
@@ -22,12 +22,12 @@ public class Info extends PromStat implements IntSupplier, PropsSupplier, PropsC
}
/**
* @param props use caution, use a ConcurrentHashMap if setValue() or accept()
* will be called later to change the properties
* @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> props) {
public Info(String name, String desc, Map<String, String> labels) {
super(name, desc, Type.GAUGE, Unit.NONE);
this.props = (props != null) ? props : new ConcurrentHashMap<String, String>(4);
this.labels = (labels != null) ? labels : new ConcurrentHashMap<String, String>(4);
}
public int getValue() {
@@ -41,16 +41,16 @@ public class Info extends PromStat implements IntSupplier, PropsSupplier, PropsC
/**
* @return not a copy
*/
public Map<String, String> getValues() {
return props;
public Map<String, String> getLabels() {
return labels;
}
public void setValue(String key, String val) {
props.put(key, val);
public void setLabel(String labelName, String labelValue) {
labels.put(labelName, labelValue);
}
public void removeValue(String key) {
props.remove(key);
public void removeLabel(String labelName) {
labels.remove(labelName);
}
/**
@@ -64,13 +64,13 @@ public class Info extends PromStat implements IntSupplier, PropsSupplier, PropsC
* Supplier interface
*/
public Map<String, String> getAsMap() {
return props;
return labels;
}
/**
* Consumer interface
*/
public void accept(Map<String, String> values) {
props.putAll(values);
public void accept(Map<String, String> labels) {
this.labels.putAll(labels);
}
}

View File

@@ -15,25 +15,55 @@ public abstract class PromStat {
private final String desc;
private final String name;
private final String promName;
private final String labelName;
private final String[] labelValues;
private final Type type;
private final Unit unit;
/*
* No label
*
* @param name [a-zA-Z0-9_.] only. '.' will be replaced with '_' for getPromName()
*/
public PromStat(String name, String description, Type type, Unit unit) {
this(name, description, 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 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) {
this.name = name;
desc = description;
this.type = type;
this.unit = unit;
String p = name.replace(".", "_");
if (p.replaceAll("[a-zA-Z0-9_]", "").length() != 0)
throw new IllegalArgumentException("invalid chars in name " + name);
String p = fixup(name);
if (type != Type.INFO)
p += '_' + unit.getName();
if (type == Type.COUNTER)
p += "_total";
promName = p;
if (label != null) {
labelName = fixup(label);
if (values == null || values.length == 0)
throw new IllegalArgumentException("must have at least one label value");
labelValues = values;
} else {
labelName = null;
labelValues = null;
}
}
static String fixup(String name) {
String p = name.replace(".", "_");
if (p.replaceAll("[a-zA-Z0-9_]", "").length() != 0)
throw new IllegalArgumentException("invalid chars in name or label " + name);
return p;
}
public String getName() {
@@ -44,6 +74,36 @@ public abstract class PromStat {
return promName;
}
/**
* @return may be null
*/
public String getLabelName() {
return labelName;
}
/**
* @return may be null
*/
public String[] getLabelValues() {
return labelValues;
}
/**
* @return may be null
*/
public String getLabelValue(int labelValueIndex) {
if (labelValues == null || labelValueIndex < 0 || labelValueIndex >= labelValues.length)
return null;
return labelValues[labelValueIndex];
}
/**
* @return number of label values
*/
public int getLabelValueCount() {
return labelValues != null ? labelValues.length : 0;
}
public String getDescription() {
return desc;
}
@@ -53,11 +113,26 @@ public abstract class PromStat {
public Unit getUnit() { return unit; }
/**
* No label.
* In units specified
*/
public abstract double getDoubleValue();
/**
* This implementation requires labelValueIndex to be 0,
* and returns getDoubleValue().
* Classes supporting labels must override.
*
* @return getDoubleValue()
*/
public double getDoubleValue(int labelValueIndex) {
if (labelValueIndex != 0)
throw new IllegalArgumentException("Index must be 0");
return getDoubleValue();
}
/**
* No label.
* Scaled to what Prometheus expects,
* seconds, bytes, or count.
*/
@@ -75,6 +150,25 @@ public abstract class PromStat {
return rv;
}
/**
* With label.
* Scaled to what Prometheus expects,
* seconds, bytes, or count.
*/
public double getScaledValue(int labelValueIndex) {
double rv = getDoubleValue(labelValueIndex);
switch (unit) {
case KBYTES:
rv *= 1000f;
break;
case MS:
rv /= 1000f;
break;
}
return rv;
}
/**
* For StatManager.
* Does nothing (for counters), extend for guages if necessary.