First draft of implementation (#1)

* First draft of implementation

Readme will follow

* Rename id.

* Exclude `commons-io` to disable build warnings

* Simplify metrics and add documentation
This commit is contained in:
Stephan Schnabel 2023-03-03 12:32:46 +01:00
parent dc38b3715e
commit c8977d7175
Signed by: stephan.schnabel
GPG key ID: E07AF5BA239FE543
23 changed files with 1345 additions and 1 deletions

View file

@ -0,0 +1,61 @@
package io.kokuwa.keycloak.metrics.prometheus;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.keycloak.events.EventType;
/**
* Client to access Prometheus metric values:
*
* @author Stephan Schnabel
*/
public class Prometheus {
private final Set<PrometheusMetric> state = new HashSet<>();
private final PrometheusClient client;
public Prometheus(PrometheusClient client) {
this.client = client;
}
public int userEvent(EventType type) {
return state.stream()
.filter(metric -> Objects.equals(metric.name(), "keycloak_event_user_total"))
.filter(metric -> Objects.equals(metric.tags().get("type"), type.toString()))
.mapToInt(metric -> metric.value().intValue())
.sum();
}
public int userEvent(EventType type, String realmName) {
return state.stream()
.filter(metric -> Objects.equals(metric.name(), "keycloak_event_user_total"))
.filter(metric -> Objects.equals(metric.tags().get("type"), type.toString()))
.filter(metric -> Objects.equals(metric.tags().get("realm"), realmName))
.mapToInt(metric -> metric.value().intValue())
.sum();
}
public void scrap() {
state.clear();
Stream.of(client.scrap().split("[\\r\\n]+"))
.filter(line -> !line.startsWith("#"))
.filter(line -> line.startsWith("keycloak"))
.map(line -> {
var name = line.substring(0, line.contains("{") ? line.indexOf("{") : line.lastIndexOf(" "));
var tags = line.contains("{")
? Stream.of(line.substring(line.indexOf("{") + 1, line.indexOf("}")).split(","))
.map(tag -> tag.split("="))
.filter(tag -> tag.length >= 2)
.collect(Collectors.toMap(tag -> tag[0], tag -> tag[1].replace("\"", "")))
: Map.<String, String>of();
var value = Double.parseDouble(line.substring(line.lastIndexOf(" ")));
return new PrometheusMetric(name, tags, value);
})
.forEach(state::add);
}
}