mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2024-11-30 20:43:55 -06:00
partial work on dashboard capture
This commit is contained in:
parent
4a8c4cf390
commit
e561b4b847
@ -0,0 +1,4 @@
|
||||
package io.nosqlbench.engine.clients.grafana;
|
||||
|
||||
public class GRangeResult {
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package io.nosqlbench.engine.clients.grafana;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class GStitcher {
|
||||
|
||||
private final Map<String, Set<String>> values;
|
||||
private final static Pattern pattern = Pattern.compile("\\$(\\w+)");
|
||||
|
||||
public GStitcher(Map<String, Set<String>> values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public String stitchRegex(String spec) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Matcher matcher = pattern.matcher(spec);
|
||||
while (matcher.find()) {
|
||||
String word = matcher.group(1);
|
||||
if (values.containsKey(word)) {
|
||||
Set<String> elems = values.get(word);
|
||||
String replacement = "(" + String.join("|", elems) + ")";
|
||||
matcher.appendReplacement(sb, replacement);
|
||||
} else {
|
||||
matcher.appendReplacement(sb, "NOTFOUND[" + word + "]");
|
||||
}
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package io.nosqlbench.engine.clients.grafana;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class GTimeUnit {
|
||||
|
||||
private enum Durations {
|
||||
s("second", 1000L),
|
||||
m("minute", 60000L),
|
||||
h("hour", 3600000L),
|
||||
d("day", 86400000L),
|
||||
w("week", 86400000L * 7L),
|
||||
M("month", 86400000L * 30L),
|
||||
y("year", 86400000L * 365L);
|
||||
|
||||
|
||||
private final String unitName;
|
||||
private final long millisPerUnit;
|
||||
|
||||
Durations(String unitName, long millisPerUnit) {
|
||||
this.unitName = unitName;
|
||||
this.millisPerUnit = millisPerUnit;
|
||||
}
|
||||
|
||||
public long durationInMillis(long count) {
|
||||
return count * millisPerUnit;
|
||||
}
|
||||
|
||||
public long durationInSeconds(long count) {
|
||||
return (count * millisPerUnit) / 1000L;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final Pattern absolute = Pattern.compile("\\d+");
|
||||
private static final Pattern ISO_INSTANT = Pattern.compile(
|
||||
"(?<year>\\d+)-(?<month>\\d+)-(?<day>\\d+) " +
|
||||
"(?<hour>\\d+):(?<minute>\\d+):(?<second>\\d+)(\\.(?<millis>\\d+))?Z?"
|
||||
);
|
||||
private static final Pattern relUnit = Pattern.compile(
|
||||
"now((?<value>[-+]\\d+)(?<unit>[smhdwMy]))?(\\/(?<interval>[smhdwMy]))?"
|
||||
);
|
||||
|
||||
public static long epochSecondsFor(String spec) {
|
||||
if (spec.startsWith("now")) {
|
||||
Matcher relative = relUnit.matcher(spec);
|
||||
if (relative.matches()) {
|
||||
if (relative.group("interval") != null) {
|
||||
throw new RuntimeException("date field boundaries like '"
|
||||
+ spec +
|
||||
"' are not supported yet.");
|
||||
}
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
long delta = 0L;
|
||||
String v = relative.group("value");
|
||||
String u = relative.group("unit");
|
||||
if (v != null && u != null) {
|
||||
long value = Long.parseLong(v);
|
||||
Durations duration = Durations.valueOf(u);
|
||||
delta = duration.durationInSeconds(value);
|
||||
}
|
||||
|
||||
long timevalue = now + delta;
|
||||
return timevalue;
|
||||
} else {
|
||||
throw new RuntimeException("unable to match input '" + spec + "'");
|
||||
}
|
||||
|
||||
} else if (spec.matches("\\\\d+")) {
|
||||
return Long.parseLong(spec);
|
||||
} else {
|
||||
Matcher matcher = ISO_INSTANT.matcher(spec);
|
||||
if (matcher.matches()) {
|
||||
ZonedDateTime parsed = ZonedDateTime.parse(spec);
|
||||
return parsed.toEpochSecond();
|
||||
} else {
|
||||
throw new RuntimeException("Unrecognized format for grafana time unit '" + spec + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -5,18 +5,22 @@ import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import io.nosqlbench.engine.clients.grafana.annotator.GrafanaMetricsAnnotator;
|
||||
import io.nosqlbench.engine.clients.grafana.transfer.*;
|
||||
import io.nosqlbench.engine.clients.prometheus.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @see <a href="https://grafana.com/docs/grafana/latest/http_api/annotations/">Grafana Annotations API Docs</a>
|
||||
@ -25,6 +29,7 @@ public class GrafanaClient {
|
||||
|
||||
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
private final GrafanaClientConfig config;
|
||||
private List<GDataSource> datasources;
|
||||
|
||||
public GrafanaClient(GrafanaClientConfig config) {
|
||||
this.config = config;
|
||||
@ -273,7 +278,7 @@ public class GrafanaClient {
|
||||
}
|
||||
|
||||
|
||||
public GDashboardMeta getDashboardByUid(String uid) {
|
||||
public GDashboardResponse getDashboardByUid(String uid) {
|
||||
HttpClient client = config.newClient();
|
||||
HttpRequest.Builder rqb = config.newRequest("api/dashboards/uid/" + uid);
|
||||
rqb = rqb.GET();
|
||||
@ -290,7 +295,7 @@ public class GrafanaClient {
|
||||
}
|
||||
String body = response.body();
|
||||
|
||||
GDashboardMeta dashboardMeta = gson.fromJson(body, GDashboardMeta.class);
|
||||
GDashboardResponse dashboardMeta = gson.fromJson(body, GDashboardResponse.class);
|
||||
return dashboardMeta;
|
||||
}
|
||||
|
||||
@ -511,4 +516,174 @@ public class GrafanaClient {
|
||||
return result;
|
||||
}
|
||||
|
||||
public <T> T doProxyQuery(String dsname, String path, String query, TypeToken<? extends T> asType) {
|
||||
GDataSource datasource = getCachedDatasource(dsname);
|
||||
long dsid = datasource.getId();
|
||||
String composedQuery = path;
|
||||
if (query != null && !query.isBlank()) {
|
||||
composedQuery = composedQuery + "?" + query;
|
||||
}
|
||||
|
||||
HttpClient client = config.newClient();
|
||||
HttpRequest.Builder rqb =
|
||||
config.newRequest("api/datasources/proxy/" + dsid + "/" + composedQuery);
|
||||
rqb.setHeader("Accept", "application/json");
|
||||
rqb = rqb.GET();
|
||||
|
||||
HttpResponse<String> response = null;
|
||||
try {
|
||||
response = client.send(rqb.build(), HttpResponse.BodyHandlers.ofString());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (response.statusCode() < 200 || response.statusCode() >= 300) {
|
||||
throw new RuntimeException("Executing proxy query failed with status code " + response.statusCode() +
|
||||
" at baseuri " + config.getBaseUri() + ": " + response.body() + " for datasource '" + dsid + "' and query '" + query + "'");
|
||||
}
|
||||
String body = response.body();
|
||||
T result = gson.fromJson(body, asType.getType());
|
||||
return result;
|
||||
}
|
||||
|
||||
private GDataSource getCachedDatasource(String dsname) {
|
||||
return getCachedDatasources().stream()
|
||||
.filter(gd -> gd.getName().equals(dsname))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
}
|
||||
|
||||
public Map<String, Set<String>> resolveAllTplValues(List<GTemplate> tpls, String timeStart, String timeEnd) {
|
||||
Map<String, Set<String>> allTplValues = new HashMap<>();
|
||||
for (GTemplate gTemplate : tpls) {
|
||||
Set<String> strings = resolveTplValues(gTemplate, timeStart, timeEnd, getCachedDatasources());
|
||||
allTplValues.put(gTemplate.getName(), strings);
|
||||
}
|
||||
return allTplValues;
|
||||
}
|
||||
|
||||
|
||||
public Set<String> resolveTplValues(GTemplate tpl, String timeStart, String timeEnd, List<GDataSource> dss) {
|
||||
Set<String> resolved = new HashSet<>();
|
||||
|
||||
List<String> values = tpl.getCurrent().getValues();
|
||||
|
||||
if (values.size() == 1 && values.get(0).equals("$__all")) {
|
||||
if (tpl.getAllValue() != null && !tpl.getAllValue().isBlank()) {
|
||||
resolved.add(tpl.getAllValue());
|
||||
} else {
|
||||
|
||||
|
||||
String dsname = tpl.getDatasource();
|
||||
Optional<GDataSource> dso = dss.stream().filter(n -> n.getName().equals(dsname)).findFirst();
|
||||
GDataSource ds = dso.orElseThrow();
|
||||
|
||||
String query = tpl.getQuery();
|
||||
String formatted = formatSeriesQuery(ds.getType(), query, timeStart, timeEnd);
|
||||
|
||||
if (ds.getType().equals("prometheus")) {
|
||||
long startSpec = GTimeUnit.epochSecondsFor(timeStart);
|
||||
long endSpec = GTimeUnit.epochSecondsFor(timeEnd);
|
||||
String q = "api/v1/series?match[]=" + URLEncoder.encode(tpl.getQuery()) +
|
||||
"&start=" + startSpec +
|
||||
"&end=" + endSpec;
|
||||
PromSeriesLookupResult psr = doProxyQuery("prometheus", "api/v1/series", q, new TypeToken<PromSeriesLookupResult>() {
|
||||
});
|
||||
for (PromSeriesLookupResult.Element elem : psr.getData()) {
|
||||
String elementSpec = elem.toString();
|
||||
String regex = tpl.getRegex();
|
||||
if (regex != null && !regex.isBlank()) {
|
||||
if (regex.startsWith("/")) {
|
||||
regex = regex.substring(1, regex.length() - 2);
|
||||
}
|
||||
Pattern p = Pattern.compile(regex);
|
||||
Matcher m = p.matcher(elementSpec);
|
||||
if (m.find()) {
|
||||
String group = m.group(1);
|
||||
resolved.add(group);
|
||||
}
|
||||
} else {
|
||||
resolved.add(elem.toString());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("datasource type not supported yet for template values: '" + ds.getType() + "'");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (String value : tpl.getCurrent().getValues()) {
|
||||
resolved.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
private String formatSeriesQuery(String type, String query, String startTime, String endTime) {
|
||||
if (type.equals("prometheus")) {
|
||||
long startSpec = GTimeUnit.epochSecondsFor(startTime);
|
||||
long endSpec = GTimeUnit.epochSecondsFor(endTime);
|
||||
return "api/v1/series?match[]=" + URLEncoder.encode(query, StandardCharsets.UTF_8) + "&start=" + startSpec +
|
||||
"&end=" + endSpec;
|
||||
} else {
|
||||
throw new RuntimeException("Unknown query target type '" + type + "'");
|
||||
}
|
||||
}
|
||||
|
||||
public List<GDataSource> getDatasources() {
|
||||
HttpClient client = config.newClient();
|
||||
HttpRequest.Builder rqb = config.newRequest("api/datasources");
|
||||
rqb = rqb.GET();
|
||||
|
||||
HttpResponse<String> response = null;
|
||||
try {
|
||||
response = client.send(rqb.build(), HttpResponse.BodyHandlers.ofString());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (response.statusCode() < 200 || response.statusCode() >= 300) {
|
||||
throw new RuntimeException("Getting datasources failed with status code " + response.statusCode() +
|
||||
" at baseuri " + config.getBaseUri() + ": " + response.body());
|
||||
}
|
||||
String body = response.body();
|
||||
|
||||
Type dsListType = new TypeToken<List<GDataSource>>() {
|
||||
}.getType();
|
||||
List<GDataSource> dataSourcesList = gson.fromJson(body, dsListType);
|
||||
return dataSourcesList;
|
||||
}
|
||||
|
||||
private List<GDataSource> getCachedDatasources() {
|
||||
if (datasources == null) {
|
||||
datasources = getDatasources();
|
||||
}
|
||||
return datasources;
|
||||
}
|
||||
|
||||
public GRangeResult doRangeQuery(String datasource, String expr, String startSpec, String endSpec) {
|
||||
GDataSource ds = getCachedDatasource(datasource);
|
||||
if (ds.getType().equals("prometheus")) {
|
||||
long start = GTimeUnit.epochSecondsFor(startSpec);
|
||||
long end = GTimeUnit.epochSecondsFor(endSpec);
|
||||
// http://44.242.139.57:3000/api/datasources/proxy/1/api/v1/query_range?query=result%7Btype%3D%22avg_rate%22%2Cavg_of%3D%221m%22%2Calias%3D~%22keyvalue_main_001%22%7D&start=1608534000&end=1608620400&step=300
|
||||
// http://44.242.139.57:3000/api/datasources/proxy/1/api/v1/query_range?query=result%7Btype%3D%22avg_rate%22%2Cavg_of%3D%221m%22%2Calias%3D%7E%22%28.*%29%22%7D&start=1608611971&end=1608622771&step=300
|
||||
String path = "api/v1/query_range?query=" +
|
||||
URLEncoder.encode(expr) + "&start=" + start + "&end=" + end + "&step=300";
|
||||
|
||||
PromQueryResult<PMatrixData> vectorData = doProxyQuery(
|
||||
datasource,
|
||||
"api/v1/query_range",
|
||||
"query=" + URLEncoder.encode(expr) + "&start=" + start + "&end=" + end + "&step=300",
|
||||
new TypeToken<PromQueryResult<PMatrixData>>() {
|
||||
});
|
||||
System.out.println(vectorData);
|
||||
return null;
|
||||
} else {
|
||||
throw new RuntimeException("data source " + datasource + " is not yet supported.");
|
||||
}
|
||||
|
||||
|
||||
// TODO: Distinguish between datasources named "prometheus" and data source types "prometheus"
|
||||
// TODO: Figure out how to set step equivalently
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
package io.nosqlbench.engine.clients.grafana.analyzer;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class GQueryResult extends LinkedHashMap<String, Object> {
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
package io.nosqlbench.engine.clients.grafana.analyzer;
|
||||
|
||||
import io.nosqlbench.engine.clients.grafana.GRangeResult;
|
||||
import io.nosqlbench.engine.clients.grafana.GStitcher;
|
||||
import io.nosqlbench.engine.clients.grafana.GrafanaClient;
|
||||
import io.nosqlbench.engine.clients.grafana.GrafanaClientConfig;
|
||||
import io.nosqlbench.engine.clients.grafana.transfer.GAnnotation;
|
||||
import io.nosqlbench.engine.clients.grafana.transfer.GDashboard;
|
||||
import io.nosqlbench.engine.clients.grafana.transfer.GPanelDef;
|
||||
import io.nosqlbench.engine.clients.grafana.transfer.GSnapshotInfo;
|
||||
import io.nosqlbench.engine.clients.grafana.transfer.*;
|
||||
import io.nosqlbench.nb.api.SystemId;
|
||||
|
||||
import java.nio.file.Path;
|
||||
@ -14,6 +13,8 @@ import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -87,13 +88,56 @@ public class GrafanaRegionAnalyzer implements Runnable {
|
||||
}
|
||||
|
||||
public void getQueries(GDashboard db) {
|
||||
List<GPanelDef> graphs = db.getPanels().stream()
|
||||
|
||||
List<GDataSource> datasources = getClient().getDatasources();
|
||||
|
||||
List<GPanelDef> mainpanels = db.getPanels().stream()
|
||||
.filter(p -> p.getType().equals("graph"))
|
||||
.collect(Collectors.toList());
|
||||
System.out.println(graphs.size() + " graphs...");
|
||||
|
||||
Map<String, Set<String>> tplValues = getClient().resolveAllTplValues(
|
||||
db.getTemplating().getList(),
|
||||
db.getTime().getFrom(),
|
||||
db.getTime().getTo());
|
||||
GStitcher stitcher = new GStitcher(tplValues);
|
||||
|
||||
|
||||
for (GPanelDef mainpanel : mainpanels) {
|
||||
long id = mainpanel.getId();
|
||||
String title = mainpanel.getTitle();
|
||||
String description = mainpanel.getDescription();
|
||||
|
||||
List<GPanelDef> panels = mainpanel.getPanels();
|
||||
String datasource = mainpanel.getDatasource();
|
||||
Map<String, Object> fieldConfig = mainpanel.getFieldConfig();
|
||||
Map<String, String> options = mainpanel.getOptions();
|
||||
List<GPanelDef.GTarget> targets = mainpanel.getTargets();
|
||||
System.out.println("targets:\n" + targets);
|
||||
|
||||
for (GPanelDef.GTarget target : targets) {
|
||||
String expr = target.getExpr();
|
||||
expr = stitcher.stitchRegex(expr);
|
||||
// expr = GStitcher.resolve(expr,tplValues,GStitcher.Regex);
|
||||
System.out.println("expr now:" + expr);
|
||||
GRangeResult result = getClient().doRangeQuery(mainpanel.getDatasource(), expr, db.getTime().getFrom(), db.getTime().getTo());
|
||||
// GQueryResult gqr = getClient().doProxyQuery(mainpanel.getDatasource(), expr, new TypeToken<GQueryResult>() {});
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
//System.out.println(mainpanel);
|
||||
}
|
||||
System.out.println(mainpanels.size() + " graphs...");
|
||||
|
||||
//http://44.242.139.57:3000/api/datasources/proxy/1/
|
||||
// api/v1/query_range?query= result{
|
||||
// type="avg_rate",
|
||||
// avg_of="1m",
|
||||
// alias=~"(keyvalue_default_main|keyvalue_default_rampup|keyvalue_default_schema|keyvalue_main_001
|
||||
// |keyvalue_rampup_001|keyvalue_schema_001)"}&start=1607996100&end=1608600900&step=300
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
@ -127,4 +171,7 @@ public class GrafanaRegionAnalyzer implements Runnable {
|
||||
System.out.println("end");
|
||||
}
|
||||
|
||||
public GDashboard getDashboard(String dbUid) {
|
||||
return getClient().getDashboardByUid(dbUid).getDashboard();
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class GDashboard {
|
||||
long schemaVersion;
|
||||
String style;
|
||||
List<Object> tags;
|
||||
Map<String, Object> templating;
|
||||
GTemplating templating;
|
||||
Time time;
|
||||
Map<String, List<String>> timepicker;
|
||||
String timezone;
|
||||
@ -129,11 +129,11 @@ public class GDashboard {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public Map<String, Object> getTemplating() {
|
||||
public GTemplating getTemplating() {
|
||||
return templating;
|
||||
}
|
||||
|
||||
public void setTemplating(Map<String, Object> templating) {
|
||||
public void setTemplating(GTemplating templating) {
|
||||
this.templating = templating;
|
||||
}
|
||||
|
||||
@ -185,6 +185,8 @@ public class GDashboard {
|
||||
// URL resource = GDashboard.class.getClassLoader().getResource(path);
|
||||
|
||||
|
||||
String json = null;
|
||||
|
||||
try {
|
||||
URL url = GDashboard.class.getClassLoader().getResource(path);
|
||||
if (url == null) {
|
||||
@ -192,7 +194,7 @@ public class GDashboard {
|
||||
}
|
||||
Path found = Paths.get(url.toURI());
|
||||
byte[] bytes = Files.readAllBytes(found);
|
||||
String json = new String(bytes, StandardCharsets.UTF_8);
|
||||
json = new String(bytes, StandardCharsets.UTF_8);
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
GDashboard db = gson.fromJson(json, GDashboard.class);
|
||||
return db;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.nosqlbench.engine.clients.grafana.transfer;
|
||||
|
||||
public class GDashboardMeta {
|
||||
public class GDashboardResponse {
|
||||
|
||||
GMeta meta;
|
||||
GDashboard dashboard;
|
@ -0,0 +1,133 @@
|
||||
package io.nosqlbench.engine.clients.grafana.transfer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class GDataSource {
|
||||
long id;
|
||||
long orgId;
|
||||
|
||||
String name;
|
||||
String type;
|
||||
String typeLogoUrl;
|
||||
String access;
|
||||
String url;
|
||||
String password;
|
||||
String user;
|
||||
String database;
|
||||
boolean basicAuth;
|
||||
boolean isDefault;
|
||||
Map<String, Object> jsonData;
|
||||
boolean readOnly;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public long getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(long orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getTypeLogoUrl() {
|
||||
return typeLogoUrl;
|
||||
}
|
||||
|
||||
public void setTypeLogoUrl(String typeLogoUrl) {
|
||||
this.typeLogoUrl = typeLogoUrl;
|
||||
}
|
||||
|
||||
public String getAccess() {
|
||||
return access;
|
||||
}
|
||||
|
||||
public void setAccess(String access) {
|
||||
this.access = access;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public void setDatabase(String database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public boolean isBasicAuth() {
|
||||
return basicAuth;
|
||||
}
|
||||
|
||||
public void setBasicAuth(boolean basicAuth) {
|
||||
this.basicAuth = basicAuth;
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return isDefault;
|
||||
}
|
||||
|
||||
public void setDefault(boolean aDefault) {
|
||||
isDefault = aDefault;
|
||||
}
|
||||
|
||||
public Map<String, Object> getJsonData() {
|
||||
return jsonData;
|
||||
}
|
||||
|
||||
public void setJsonData(Map<String, Object> jsonData) {
|
||||
this.jsonData = jsonData;
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
public void setReadOnly(boolean readOnly) {
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ public class GPanelDef {
|
||||
Map<String, Object> fieldConfig;
|
||||
Map<String, String> options;
|
||||
String pluginVersion;
|
||||
List<Map<String, String>> targets;
|
||||
List<GTarget> targets;
|
||||
String title;
|
||||
String type;
|
||||
String datasource;
|
||||
@ -82,11 +82,11 @@ public class GPanelDef {
|
||||
this.pluginVersion = pluginVersion;
|
||||
}
|
||||
|
||||
public List<Map<String, String>> getTargets() {
|
||||
public List<GTarget> getTargets() {
|
||||
return targets;
|
||||
}
|
||||
|
||||
public void setTargets(List<Map<String, String>> targets) {
|
||||
public void setTargets(List<GTarget> targets) {
|
||||
this.targets = targets;
|
||||
}
|
||||
|
||||
@ -117,4 +117,73 @@ public class GPanelDef {
|
||||
public String toString() {
|
||||
return id + ":'" + title + "'";
|
||||
}
|
||||
|
||||
public static class GTarget {
|
||||
String queryType;
|
||||
String refId;
|
||||
String expr;
|
||||
String interval;
|
||||
String legendFormat;
|
||||
boolean hide;
|
||||
|
||||
public String getQueryType() {
|
||||
return queryType;
|
||||
}
|
||||
|
||||
public void setQueryType(String queryType) {
|
||||
this.queryType = queryType;
|
||||
}
|
||||
|
||||
public String getRefId() {
|
||||
return refId;
|
||||
}
|
||||
|
||||
public void setRefId(String refId) {
|
||||
this.refId = refId;
|
||||
}
|
||||
|
||||
public String getExpr() {
|
||||
return expr;
|
||||
}
|
||||
|
||||
public void setExpr(String expr) {
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
public String getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
public void setInterval(String interval) {
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
public String getLegendFormat() {
|
||||
return legendFormat;
|
||||
}
|
||||
|
||||
public void setLegendFormat(String legendFormat) {
|
||||
this.legendFormat = legendFormat;
|
||||
}
|
||||
|
||||
public boolean isHide() {
|
||||
return hide;
|
||||
}
|
||||
|
||||
public void setHide(boolean hide) {
|
||||
this.hide = hide;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GTarget{" +
|
||||
"queryType='" + queryType + '\'' +
|
||||
", refId='" + refId + '\'' +
|
||||
", expr='" + expr + '\'' +
|
||||
", interval='" + interval + '\'' +
|
||||
", legendFormat='" + legendFormat + '\'' +
|
||||
", hide=" + hide +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,246 @@
|
||||
package io.nosqlbench.engine.clients.grafana.transfer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GTemplate {
|
||||
String allValue;
|
||||
String name;
|
||||
GCurrentValue current;
|
||||
String datasource;
|
||||
String definition;
|
||||
Object error;
|
||||
long hide;
|
||||
boolean includeAll;
|
||||
String label;
|
||||
boolean multi;
|
||||
List<Object> options;
|
||||
String query;
|
||||
long refresh;
|
||||
String regex;
|
||||
boolean skipUrlSync;
|
||||
long sort;
|
||||
String tagValuesQuery;
|
||||
List<String> tags;
|
||||
String tagsQuery;
|
||||
String type;
|
||||
boolean useTags;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAllValue() {
|
||||
return allValue;
|
||||
}
|
||||
|
||||
public void setAllValue(String allValue) {
|
||||
this.allValue = allValue;
|
||||
}
|
||||
|
||||
public GCurrentValue getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public void setCurrent(GCurrentValue current) {
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
public String getDatasource() {
|
||||
return datasource;
|
||||
}
|
||||
|
||||
public void setDatasource(String datasource) {
|
||||
this.datasource = datasource;
|
||||
}
|
||||
|
||||
public String getDefinition() {
|
||||
return definition;
|
||||
}
|
||||
|
||||
public void setDefinition(String definition) {
|
||||
this.definition = definition;
|
||||
}
|
||||
|
||||
public Object getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(Object error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public long getHide() {
|
||||
return hide;
|
||||
}
|
||||
|
||||
public void setHide(long hide) {
|
||||
this.hide = hide;
|
||||
}
|
||||
|
||||
public boolean isIncludeAll() {
|
||||
return includeAll;
|
||||
}
|
||||
|
||||
public void setIncludeAll(boolean includeAll) {
|
||||
this.includeAll = includeAll;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public boolean isMulti() {
|
||||
return multi;
|
||||
}
|
||||
|
||||
public void setMulti(boolean multi) {
|
||||
this.multi = multi;
|
||||
}
|
||||
|
||||
public List<Object> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setOptions(List<Object> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public String getQuery() {
|
||||
return query;
|
||||
}
|
||||
|
||||
public void setQuery(String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public long getRefresh() {
|
||||
return refresh;
|
||||
}
|
||||
|
||||
public void setRefresh(long refresh) {
|
||||
this.refresh = refresh;
|
||||
}
|
||||
|
||||
public String getRegex() {
|
||||
return regex;
|
||||
}
|
||||
|
||||
public void setRegex(String regex) {
|
||||
this.regex = regex;
|
||||
}
|
||||
|
||||
public boolean isSkipUrlSync() {
|
||||
return skipUrlSync;
|
||||
}
|
||||
|
||||
public void setSkipUrlSync(boolean skipUrlSync) {
|
||||
this.skipUrlSync = skipUrlSync;
|
||||
}
|
||||
|
||||
public long getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public void setSort(long sort) {
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
public String getTagValuesQuery() {
|
||||
return tagValuesQuery;
|
||||
}
|
||||
|
||||
public void setTagValuesQuery(String tagValuesQuery) {
|
||||
this.tagValuesQuery = tagValuesQuery;
|
||||
}
|
||||
|
||||
public List<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<String> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public String getTagsQuery() {
|
||||
return tagsQuery;
|
||||
}
|
||||
|
||||
public void setTagsQuery(String tagsQuery) {
|
||||
this.tagsQuery = tagsQuery;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean isUseTags() {
|
||||
return useTags;
|
||||
}
|
||||
|
||||
public void setUseTags(boolean useTags) {
|
||||
this.useTags = useTags;
|
||||
}
|
||||
|
||||
public static class GCurrentValue {
|
||||
boolean selected;
|
||||
Object text;
|
||||
Object value;
|
||||
|
||||
public boolean isSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
this.selected = selected;
|
||||
}
|
||||
|
||||
public Object getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(Object text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public List<String> getValues() {
|
||||
if (value instanceof String) {
|
||||
return List.of((String) value);
|
||||
} else if (value instanceof List) {
|
||||
return (List<String>) value;
|
||||
} else {
|
||||
throw new RuntimeException("Unrecognized form of value:" + value.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<String> getTexts() {
|
||||
if (text instanceof String) {
|
||||
return List.of((String) text);
|
||||
} else if (text instanceof List) {
|
||||
return (List<String>) text;
|
||||
} else {
|
||||
throw new RuntimeException("Unrecognized form of text:" + text.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package io.nosqlbench.engine.clients.grafana.transfer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GTemplating {
|
||||
List<GTemplate> list;
|
||||
|
||||
public List<GTemplate> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setList(List<GTemplate> list) {
|
||||
this.list = list;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package io.nosqlbench.engine.clients.prometheus;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PMatrixData {
|
||||
String resultType;
|
||||
List<PMatrixElem> result;
|
||||
|
||||
public String getResultType() {
|
||||
return resultType;
|
||||
}
|
||||
|
||||
public void setResultType(String resultType) {
|
||||
this.resultType = resultType;
|
||||
}
|
||||
|
||||
public List<PMatrixElem> getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(List<PMatrixElem> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PMatrixData{" +
|
||||
"resultType='" + resultType + '\'' +
|
||||
", result=" + result +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package io.nosqlbench.engine.clients.prometheus;
|
||||
|
||||
public class PMatrixElem {
|
||||
PMetric metric;
|
||||
PValues values;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PMatrixElem{" +
|
||||
"metric=" + metric +
|
||||
", values=" + values +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package io.nosqlbench.engine.clients.prometheus;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class PMetric extends LinkedHashMap<String, String> {
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{");
|
||||
forEach((k, v) -> {
|
||||
sb.append(k).append("=");
|
||||
sb.append("\"").append(v).append("\",");
|
||||
});
|
||||
sb.setLength(sb.length() - 1);
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.nosqlbench.engine.clients.prometheus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PValue extends ArrayList<Object> {
|
||||
public double getInstant() {
|
||||
return (double) get(0);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return (String) get(1);
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package io.nosqlbench.engine.clients.prometheus;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PValues extends ArrayList<PValue> {
|
||||
private final static Gson gson = new GsonBuilder().create();
|
||||
|
||||
public String toString() {
|
||||
return gson.toJson(this);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package io.nosqlbench.engine.clients.prometheus;
|
||||
|
||||
public class PromQueryResult<T> {
|
||||
String status;
|
||||
T data;
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PromQueryResult{" +
|
||||
"status='" + status + '\'' +
|
||||
", data=" + data +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package io.nosqlbench.engine.clients.prometheus;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PromSeriesDataResult {
|
||||
String status;
|
||||
Data data;
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static class Data {
|
||||
String resultType;
|
||||
List<Result> result;
|
||||
|
||||
public String getResultType() {
|
||||
return resultType;
|
||||
}
|
||||
|
||||
public void setResultType(String resultType) {
|
||||
this.resultType = resultType;
|
||||
}
|
||||
|
||||
public List<Result> getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(List<Result> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
private static class Result {
|
||||
Map<String, String> metric;
|
||||
Value[] values;
|
||||
|
||||
public Map<String, String> getMetric() {
|
||||
return metric;
|
||||
}
|
||||
|
||||
public void setMetric(Map<String, String> metric) {
|
||||
this.metric = metric;
|
||||
}
|
||||
|
||||
public Value[] getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
public void setValues(Value[] values) {
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public static class Value {
|
||||
long instant;
|
||||
String value;
|
||||
|
||||
public long getInstant() {
|
||||
return instant;
|
||||
}
|
||||
|
||||
public void setInstant(long instant) {
|
||||
this.instant = instant;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package io.nosqlbench.engine.clients.prometheus;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class PromSeriesLookupResult {
|
||||
String status;
|
||||
List<Element> data;
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public List<Element> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(List<Element> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static class Element extends LinkedHashMap<String, String> {
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{");
|
||||
forEach((k, v) -> {
|
||||
sb.append(k).append("=");
|
||||
sb.append("\"").append(v).append("\",");
|
||||
});
|
||||
sb.setLength(sb.length() - 1);
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package io.nosqlbench.engine.clients.grafana;
|
||||
|
||||
import org.assertj.core.data.Offset;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class GTimeUnitTest {
|
||||
|
||||
@Test
|
||||
public void testParseBasic() {
|
||||
long result = GTimeUnit.epochSecondsFor("now");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseRelative() {
|
||||
long result = GTimeUnit.epochSecondsFor("now-1w");
|
||||
assertThat(result).isCloseTo((System.currentTimeMillis() / 1000) - (86400L * 7L), Offset.offset(60L));
|
||||
}
|
||||
|
||||
}
|
@ -9,9 +9,10 @@ public class GrafanaRegionAnalyzerTest {
|
||||
public void testGetQueries() {
|
||||
GrafanaRegionAnalyzer gra = new GrafanaRegionAnalyzer();
|
||||
gra.setBaseUrl("http://44.242.139.57:3000/");
|
||||
GDashboard db = GDashboard.fromFile("examples/db.json");
|
||||
|
||||
gra.getQueries(db);
|
||||
GDashboard db = gra.getDashboard("aIIX1f6Wz");
|
||||
//GDashboard db = GDashboard.fromFile("examples/db.json");
|
||||
// gra.getQueries(db);
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,56 @@
|
||||
package io.nosqlbench.engine.clients.prometheus;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class PMatrixElemTest {
|
||||
|
||||
@Test
|
||||
public void testMatrixElem() {
|
||||
Gson gson = new GsonBuilder().create();
|
||||
String json = """
|
||||
{
|
||||
"status" : "success",
|
||||
"data" : {
|
||||
"resultType" : "matrix",
|
||||
"result" : [
|
||||
{
|
||||
"metric" : {
|
||||
"__name__" : "up",
|
||||
"job" : "prometheus",
|
||||
"instance" : "localhost:9090"
|
||||
},
|
||||
"values" : [
|
||||
[ 1435781430.781, "1" ],
|
||||
[ 1435781445.781, "1" ],
|
||||
[ 1435781460.781, "1" ]
|
||||
]
|
||||
},
|
||||
{
|
||||
"metric" : {
|
||||
"__name__" : "up",
|
||||
"job" : "node",
|
||||
"instance" : "localhost:9091"
|
||||
},
|
||||
"values" : [
|
||||
[ 1435781430.781, "0" ],
|
||||
[ 1435781445.781, "0" ],
|
||||
[ 1435781460.781, "1" ]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}""";
|
||||
Type type = new TypeToken<PromQueryResult<PMatrixData>>() {
|
||||
}.getType();
|
||||
Object result = gson.fromJson(json, type);
|
||||
assertThat(result).isOfAnyClassIn(PromQueryResult.class);
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user