VictoriaMetrics/lib/promrelabel/debug.qtpl
Aliaksandr Valialkin 1af6e0b233
lib/promrelabel: pass query args via query string at /metric-relabel-debug and /target-relabel-debug pages if their length doesnt exceed 1000
This allows copy-n-pasting the url to another browser window and seeing the same result.

The limit in 1000 chars is selected in order to prevent from potential issues with systems
which limit the url length such as Internet Explorer - see https://stackoverflow.com/questions/812925/what-is-the-maximum-possible-length-of-a-query-string

If the limit is exceeded, then query args are sent via POST method and aren't visible in the url.

Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3580
2023-01-05 16:45:42 -08:00

159 lines
5.6 KiB
Text

{% import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/htmlcomponents"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promutils"
) %}
{% stripspace %}
{% func RelabelDebugSteps(isTargetRelabel bool, targetID string, dss []DebugStep, metric, relabelConfigs string, err error) %}
<!DOCTYPE html>
<html lang="en">
<head>
{%= htmlcomponents.CommonHeader() %}
<title>Metric relabel debug</title>
<script>
function submitRelabelDebugForm(e) {
var form = e.target;
var method = "GET";
if (form.elements["relabel_configs"].value.length + form.elements["metric"].value.length > 1000) {
method = "POST";
}
form.method = method;
}
</script>
</head>
<body>
{%= htmlcomponents.Navbar() %}
<div class="container-fluid">
<a href="https://docs.victoriametrics.com/relabeling.html" target="_blank">Relabeling docs</a>{% space %}
{% if isTargetRelabel %}
<a href="metric-relabel-debug{% if targetID != "" %}?id={%s targetID %}{% endif %}">Metric relabel debug</a>
{% else %}
<a href="target-relabel-debug{% if targetID != "" %}?id={%s targetID %}{% endif %}">Target relabel debug</a>
{% endif %}
<br>
{% if err != nil %}
{%= htmlcomponents.ErrorNotification(err) %}
{% endif %}
<div class="m-3">
<form method="POST" onsubmit="submitRelabelDebugForm(event)">
{%= relabelDebugFormInputs(metric, relabelConfigs) %}
{% if targetID != "" %}
<input type="hidden" name="id" value="{%s targetID %}" />
{% endif %}
<input type="submit" value="Submit" class="btn btn-primary m-1" />
{% if targetID != "" %}
<button type="button" onclick="location.href='?id={%s targetID %}'" class="btn btn-secondary m-1">Reset</button>
{% endif %}
</form>
</div>
<div class="row">
<main class="col-12">
{%= relabelDebugSteps(dss) %}
</main>
</div>
</div>
</body>
</html>
{% endfunc %}
{% func relabelDebugFormInputs(metric, relabelConfigs string) %}
<div>
Relabel configs:<br/>
<textarea name="relabel_configs" style="width: 100%; height: 15em" class="m-1">{%s relabelConfigs %}</textarea>
</div>
<div>
Labels:<br/>
<textarea name="metric" style="width: 100%; height: 5em" class="m-1">{%s metric %}</textarea>
</div>
{% endfunc %}
{% func relabelDebugSteps(dss []DebugStep) %}
{% if len(dss) > 0 %}
<div class="m-3">
<b>Original labels:</b> <samp>{%= mustFormatLabels(dss[0].In) %}</samp>
</div>
{% endif %}
<table class="table table-striped table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col" style="width: 5%">Step</th>
<th scope="col" style="width: 25%">Relabeling Rule</th>
<th scope="col" style="width: 35%">Input Labels</th>
<th scope="col" stile="width: 35%">Output labels</a>
</tr>
</thead>
<tbody>
{% for i, ds := range dss %}
{% code
inLabels := promutils.MustNewLabelsFromString(ds.In)
outLabels := promutils.MustNewLabelsFromString(ds.Out)
changedLabels := getChangedLabelNames(inLabels, outLabels)
%}
<tr>
<td>{%d i %}</td>
<td><b><pre class="m-2">{%s ds.Rule %}</pre></b></td>
<td>
<div class="m-2" style="font-size: 0.9em" title="deleted and updated labels highlighted in red">
{%= labelsWithHighlight(inLabels, changedLabels, "red") %}
</div>
</td>
<td>
<div class="m-2" style="font-size: 0.9em" title="added and updated labels highlighted in blue">
{%= labelsWithHighlight(outLabels, changedLabels, "blue") %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if len(dss) > 0 %}
<div class="m-3">
<b>Resulting labels:</b> <samp>{%= mustFormatLabels(dss[len(dss)-1].Out) %}</samp>
</div>
{% endif %}
{% endfunc %}
{% func labelsWithHighlight(labels *promutils.Labels, highlight map[string]struct{}, color string) %}
{% code
labelsList := labels.GetLabels()
metricName := ""
for i, label := range labelsList {
if label.Name == "__name__" {
metricName = label.Value
labelsList = append(labelsList[:i], labelsList[i+1:]...)
break
}
}
%}
{% if metricName != "" %}
{% if _, ok := highlight["__name__"]; ok %}
<span style="font-weight:bold;color:{%s color %}">{%s metricName %}</span>
{% else %}
{%s metricName %}
{% endif %}
{% if len(labelsList) == 0 %}{% return %}{% endif %}
{% endif %}
{
{% for i, label := range labelsList %}
{% if _, ok := highlight[label.Name]; ok %}
<span style="font-weight:bold;color:{%s color %}">{%s label.Name %}={%q label.Value %}</span>
{% else %}
{%s label.Name %}={%q label.Value %}
{% endif %}
{% if i < len(labelsList)-1 %},{% space %}{% endif %}
{% endfor %}
}
{% endfunc %}
{% func mustFormatLabels(s string) %}
{% code labels := promutils.MustNewLabelsFromString(s) %}
{%= labelsWithHighlight(labels, nil, "") %}
{% endfunc %}
{% endstripspace %}