lib/promscrape: adds service discovery visualization for /targets page(#2675)

* lib/promscrape: updated template

* lib/promscrape: fixed click on unhealthy and all btns

* app/vmselect: jquery scripts into static folder

Co-authored-by: f41gh7 <nik@victoriametrics.com>
This commit is contained in:
Dmytro Kozlov 2022-06-03 16:38:45 +03:00 committed by GitHub
parent a18914abee
commit 8edb390e21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 1287 additions and 569 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -15,6 +15,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
## tip
* FEATURE: adds service discovery visualisation tab for `/targets` page. It simplifies service discovery debugging. See [this PR](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/2675).
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): Allows using kubeconfig file within `kubernetes_sd_configs`. It may be useful for kubernetes cluster monitoring by `vmagent` outside kubernetes cluster. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1464).
* FEATURE: allow overriding default limits for in-memory cache `indexdb/tagFilters` via flag `-storage.cacheSizeIndexDBTagFilters`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2663).
* FEATURE: add support of `lowercase` and `uppercase` relabeling actions in the same way as [Prometheus 2.36.0 does](https://github.com/prometheus/prometheus/releases/tag/v2.36.0). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2664).

View file

@ -0,0 +1,82 @@
{% import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
) %}
{% func ServiceDiscovery(jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, droppedKeyStatuses []droppedKeyStatus) %}
<div class="row mt-4">
<div class="col-12">
{% for i, js := range jts %}
{% if showOnlyUnhealthy && js.upCount == js.targetsTotal %}{% continue %}{% endif %}
<h4>
<span class="me-2">{%s js.job %}{% space %}({%d js.upCount %}/{%d js.targetsTotal %}{% space %}up)</span>
<button type="button" class="btn btn-primary btn-sm me-1"
onclick="document.querySelector('.table-discovery-{%d i %}').style.display='none'">collapse
</button>
<button type="button" class="btn btn-secondary btn-sm me-1"
onclick="document.querySelector('.table-discovery-{%d i %}').style.display='block'">expand
</button>
</h4>
<div id="table-discovery-{%d i %}" class="table-responsive table-discovery-{%d i %}">
<table class="table table-striped table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col" style="width: 50%">Discovered Labels</th>
<th scope="col" style="width: 50%">Target Labels</th>
</tr>
</thead>
<tbody class="list-{%d i %}">
{% for _, ts := range js.targetsStatus %}
{% if showOnlyUnhealthy && ts.up %}{% continue %}{% endif %}
<tr {% if !ts.up %}{%space%}class="alert alert-danger" role="alert" {% endif %}>
<td class="labels">
{%= formatLabel(ts.sw.Config.OriginalLabels) %}
</td>
<td class="labels">
{%= formatLabel(promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels)) %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
</div>
</div>
{% for i,jobName := range emptyJobs %}
<div>
<h4>
<a>{%s jobName %} (0/0 up)</a>
<button type="button" class="btn btn-primary btn-sm me-1"
onclick="document.querySelector('.table-empty-{%d i %}').style.display='none'">collapse
</button>
<button type="button" class="btn btn-secondary btn-sm me-1"
onclick="document.querySelector('.table-empty-{%d i %}').style.display='block'">expand
</button>
</h4>
<table id="table-empty-{%d i %}" class="table table-striped table-hover table-bordered table-sm table-empty-{%d i %}">
<thead>
<tr>
<th scope="col" style="width: 50%">Discovered Labels</th>
<th scope="col" style="width: 50%">Target Labels</th>
</tr>
</thead>
<tbody class="list-{%d i %}">
{% for _, status := range droppedKeyStatuses %}
{% for _, label := range status.originalLabels %}
{% if label.Value == jobName %}
<tr>
<td class="labels">
{%= formatLabel(status.originalLabels) %}
</td>
<td class="labels">
<span class="badge bg-danger">DROPPED</span>
</td>
</tr>
{% endif %}
{% endfor %}
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
{% endfunc %}

View file

@ -0,0 +1,279 @@
// Code generated by qtc from "service_discovery.qtpl". DO NOT EDIT.
// See https://github.com/valyala/quicktemplate for details.
//line lib/promscrape/service_discovery.qtpl:1
package promscrape
//line lib/promscrape/service_discovery.qtpl:1
import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
)
//line lib/promscrape/service_discovery.qtpl:5
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
//line lib/promscrape/service_discovery.qtpl:5
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
//line lib/promscrape/service_discovery.qtpl:5
func StreamServiceDiscovery(qw422016 *qt422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, droppedKeyStatuses []droppedKeyStatus) {
//line lib/promscrape/service_discovery.qtpl:5
qw422016.N().S(`
<div class="row mt-4">
<div class="col-12">
`)
//line lib/promscrape/service_discovery.qtpl:8
for i, js := range jts {
//line lib/promscrape/service_discovery.qtpl:8
qw422016.N().S(`
`)
//line lib/promscrape/service_discovery.qtpl:9
if showOnlyUnhealthy && js.upCount == js.targetsTotal {
//line lib/promscrape/service_discovery.qtpl:9
continue
//line lib/promscrape/service_discovery.qtpl:9
}
//line lib/promscrape/service_discovery.qtpl:9
qw422016.N().S(`
<h4>
<span class="me-2">`)
//line lib/promscrape/service_discovery.qtpl:11
qw422016.E().S(js.job)
//line lib/promscrape/service_discovery.qtpl:11
qw422016.N().S(` `)
//line lib/promscrape/service_discovery.qtpl:11
qw422016.N().S(`(`)
//line lib/promscrape/service_discovery.qtpl:11
qw422016.N().D(js.upCount)
//line lib/promscrape/service_discovery.qtpl:11
qw422016.N().S(`/`)
//line lib/promscrape/service_discovery.qtpl:11
qw422016.N().D(js.targetsTotal)
//line lib/promscrape/service_discovery.qtpl:11
qw422016.N().S(` `)
//line lib/promscrape/service_discovery.qtpl:11
qw422016.N().S(`up)</span>
<button type="button" class="btn btn-primary btn-sm me-1"
onclick="document.querySelector('.table-discovery-`)
//line lib/promscrape/service_discovery.qtpl:13
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:13
qw422016.N().S(`').style.display='none'">collapse
</button>
<button type="button" class="btn btn-secondary btn-sm me-1"
onclick="document.querySelector('.table-discovery-`)
//line lib/promscrape/service_discovery.qtpl:16
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:16
qw422016.N().S(`').style.display='block'">expand
</button>
</h4>
<div id="table-discovery-`)
//line lib/promscrape/service_discovery.qtpl:19
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:19
qw422016.N().S(`" class="table-responsive table-discovery-`)
//line lib/promscrape/service_discovery.qtpl:19
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:19
qw422016.N().S(`">
<table class="table table-striped table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col" style="width: 50%">Discovered Labels</th>
<th scope="col" style="width: 50%">Target Labels</th>
</tr>
</thead>
<tbody class="list-`)
//line lib/promscrape/service_discovery.qtpl:27
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:27
qw422016.N().S(`">
`)
//line lib/promscrape/service_discovery.qtpl:28
for _, ts := range js.targetsStatus {
//line lib/promscrape/service_discovery.qtpl:28
qw422016.N().S(`
`)
//line lib/promscrape/service_discovery.qtpl:29
if showOnlyUnhealthy && ts.up {
//line lib/promscrape/service_discovery.qtpl:29
continue
//line lib/promscrape/service_discovery.qtpl:29
}
//line lib/promscrape/service_discovery.qtpl:29
qw422016.N().S(`
<tr `)
//line lib/promscrape/service_discovery.qtpl:30
if !ts.up {
//line lib/promscrape/service_discovery.qtpl:30
qw422016.N().S(` `)
//line lib/promscrape/service_discovery.qtpl:30
qw422016.N().S(`class="alert alert-danger" role="alert" `)
//line lib/promscrape/service_discovery.qtpl:30
}
//line lib/promscrape/service_discovery.qtpl:30
qw422016.N().S(`>
<td class="labels">
`)
//line lib/promscrape/service_discovery.qtpl:32
streamformatLabel(qw422016, ts.sw.Config.OriginalLabels)
//line lib/promscrape/service_discovery.qtpl:32
qw422016.N().S(`
</td>
<td class="labels">
`)
//line lib/promscrape/service_discovery.qtpl:35
streamformatLabel(qw422016, promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels))
//line lib/promscrape/service_discovery.qtpl:35
qw422016.N().S(`
</td>
</tr>
`)
//line lib/promscrape/service_discovery.qtpl:38
}
//line lib/promscrape/service_discovery.qtpl:38
qw422016.N().S(`
</tbody>
</table>
</div>
`)
//line lib/promscrape/service_discovery.qtpl:42
}
//line lib/promscrape/service_discovery.qtpl:42
qw422016.N().S(`
</div>
</div>
`)
//line lib/promscrape/service_discovery.qtpl:45
for i, jobName := range emptyJobs {
//line lib/promscrape/service_discovery.qtpl:45
qw422016.N().S(`
<div>
<h4>
<a>`)
//line lib/promscrape/service_discovery.qtpl:48
qw422016.E().S(jobName)
//line lib/promscrape/service_discovery.qtpl:48
qw422016.N().S(` (0/0 up)</a>
<button type="button" class="btn btn-primary btn-sm me-1"
onclick="document.querySelector('.table-empty-`)
//line lib/promscrape/service_discovery.qtpl:50
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:50
qw422016.N().S(`').style.display='none'">collapse
</button>
<button type="button" class="btn btn-secondary btn-sm me-1"
onclick="document.querySelector('.table-empty-`)
//line lib/promscrape/service_discovery.qtpl:53
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:53
qw422016.N().S(`').style.display='block'">expand
</button>
</h4>
<table id="table-empty-`)
//line lib/promscrape/service_discovery.qtpl:56
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:56
qw422016.N().S(`" class="table table-striped table-hover table-bordered table-sm table-empty-`)
//line lib/promscrape/service_discovery.qtpl:56
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:56
qw422016.N().S(`">
<thead>
<tr>
<th scope="col" style="width: 50%">Discovered Labels</th>
<th scope="col" style="width: 50%">Target Labels</th>
</tr>
</thead>
<tbody class="list-`)
//line lib/promscrape/service_discovery.qtpl:63
qw422016.N().D(i)
//line lib/promscrape/service_discovery.qtpl:63
qw422016.N().S(`">
`)
//line lib/promscrape/service_discovery.qtpl:64
for _, status := range droppedKeyStatuses {
//line lib/promscrape/service_discovery.qtpl:64
qw422016.N().S(`
`)
//line lib/promscrape/service_discovery.qtpl:65
for _, label := range status.originalLabels {
//line lib/promscrape/service_discovery.qtpl:65
qw422016.N().S(`
`)
//line lib/promscrape/service_discovery.qtpl:66
if label.Value == jobName {
//line lib/promscrape/service_discovery.qtpl:66
qw422016.N().S(`
<tr>
<td class="labels">
`)
//line lib/promscrape/service_discovery.qtpl:69
streamformatLabel(qw422016, status.originalLabels)
//line lib/promscrape/service_discovery.qtpl:69
qw422016.N().S(`
</td>
<td class="labels">
<span class="badge bg-danger">DROPPED</span>
</td>
</tr>
`)
//line lib/promscrape/service_discovery.qtpl:75
}
//line lib/promscrape/service_discovery.qtpl:75
qw422016.N().S(`
`)
//line lib/promscrape/service_discovery.qtpl:76
}
//line lib/promscrape/service_discovery.qtpl:76
qw422016.N().S(`
`)
//line lib/promscrape/service_discovery.qtpl:77
}
//line lib/promscrape/service_discovery.qtpl:77
qw422016.N().S(`
</tbody>
</table>
</div>
`)
//line lib/promscrape/service_discovery.qtpl:81
}
//line lib/promscrape/service_discovery.qtpl:81
qw422016.N().S(`
`)
//line lib/promscrape/service_discovery.qtpl:82
}
//line lib/promscrape/service_discovery.qtpl:82
func WriteServiceDiscovery(qq422016 qtio422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, droppedKeyStatuses []droppedKeyStatus) {
//line lib/promscrape/service_discovery.qtpl:82
qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/service_discovery.qtpl:82
StreamServiceDiscovery(qw422016, jts, emptyJobs, showOnlyUnhealthy, droppedKeyStatuses)
//line lib/promscrape/service_discovery.qtpl:82
qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/service_discovery.qtpl:82
}
//line lib/promscrape/service_discovery.qtpl:82
func ServiceDiscovery(jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, droppedKeyStatuses []droppedKeyStatus) string {
//line lib/promscrape/service_discovery.qtpl:82
qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/service_discovery.qtpl:82
WriteServiceDiscovery(qb422016, jts, emptyJobs, showOnlyUnhealthy, droppedKeyStatuses)
//line lib/promscrape/service_discovery.qtpl:82
qs422016 := string(qb422016.B)
//line lib/promscrape/service_discovery.qtpl:82
qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/service_discovery.qtpl:82
return qs422016
//line lib/promscrape/service_discovery.qtpl:82
}

107
lib/promscrape/targets.qtpl Normal file
View file

@ -0,0 +1,107 @@
{% import (
"time"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
) %}
{% func Targets(jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool) %}
<div class="row mt-4">
<div class="col-12">
{% for i, js := range jts %}
{% if showOnlyUnhealthy && js.upCount == js.targetsTotal %}{% continue %}{% endif %}
<div class="row mb-4">
<div class="col-12">
<h4>
<span class="me-2">{%s js.job %}{% space %}({%d js.upCount %}/{%d js.targetsTotal %}{% space %}up)</span>
<button type="button" class="btn btn-primary btn-sm me-1"
onclick="document.getElementById('table-{%d i %}').style.display='none'">collapse
</button>
<button type="button" class="btn btn-secondary btn-sm me-1"
onclick="document.getElementById('table-{%d i %}').style.display='block'">expand
</button>
</h4>
<div id="table-{%d i %}" class="table-responsive">
<table class="table table-striped table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col">Endpoint</th>
<th scope="col">State</th>
<th scope="col" title="scrape target labels">Labels</th>
<th scope="col" title="total scrapes">Scrapes</th>
<th scope="col" title="total scrape errors">Errors</th>
<th scope="col" title="the time of the last scrape">Last Scrape</th>
<th scope="col" title="the duration of the last scrape">Duration</th>
<th scope="col" title="the number of metrics scraped during the last scrape">Samples</th>
<th scope="col" title="error from the last scrape (if any)">Last error</th>
</tr>
</thead>
<tbody class="list-{%d i %}">
{% for _, ts := range js.targetsStatus %}
{% code
endpoint := ts.sw.Config.ScrapeURL
targetID := getTargetID(ts.sw)
lastScrapeTime := ts.getDurationFromLastScrape()
%}
{% if showOnlyUnhealthy && ts.up %}{% continue %}{% endif %}
<tr {% if !ts.up %}{%space%}class="alert alert-danger" role="alert" {% endif %}>
<td class="endpoint"><a href="{%s endpoint %}" target="_blank">{%s endpoint %}</a> (
<a href="target_response?id={%s targetID %}" target="_blank"
title="click to fetch target response on behalf of the scraper">response</a>
)
</td>
<td>
{% if ts.up %}
<span class="badge bg-success">UP</span>
{% else %}
<span class="badge bg-danger">DOWN</span>
{% endif %}
</td>
<td class="labels">
<div title="click to show original labels"
onclick="document.getElementById('original_labels_{%s targetID %}').style.display='block'">
{%= formatLabel(promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels)) %}
</div>
<div style="display:none" id="original_labels_{%s targetID %}">
{%= formatLabel(ts.sw.Config.OriginalLabels) %}
</div>
</td>
<td>{%d ts.scrapesTotal %}</td>
<td>{%d ts.scrapesFailed %}</td>
<td>
{% if lastScrapeTime < 365*24*time.Hour %}
{%f.3 lastScrapeTime.Seconds() %}s ago
{% else %}
none
{% endif %}
<td>{%d int(ts.scrapeDuration) %}ms</td>
<td>{%d ts.samplesScraped %}</td>
<td>{% if ts.err != nil %}{%s ts.err.Error() %}{% endif %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% for _, jobName := range emptyJobs %}
<div>
<h4><a>{%s jobName %} (0/0 up)</a></h4>
<table class="table table-striped table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col">Endpoint</th>
<th scope="col">State</th>
<th scope="col">Labels</th>
<th scope="col">Last Scrape</th>
<th scope="col">Scrape Duration</th>
<th scope="col">Samples Scraped</th>
<th scope="col">Error</th>
</tr>
</thead>
</table>
</div>
{% endfor %}
{% endfunc %}

View file

@ -0,0 +1,327 @@
// Code generated by qtc from "targets.qtpl". DO NOT EDIT.
// See https://github.com/valyala/quicktemplate for details.
//line lib/promscrape/targets.qtpl:1
package promscrape
//line lib/promscrape/targets.qtpl:1
import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
"time"
)
//line lib/promscrape/targets.qtpl:6
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
//line lib/promscrape/targets.qtpl:6
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
//line lib/promscrape/targets.qtpl:6
func StreamTargets(qw422016 *qt422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool) {
//line lib/promscrape/targets.qtpl:6
qw422016.N().S(`
<div class="row mt-4">
<div class="col-12">
`)
//line lib/promscrape/targets.qtpl:9
for i, js := range jts {
//line lib/promscrape/targets.qtpl:9
qw422016.N().S(`
`)
//line lib/promscrape/targets.qtpl:10
if showOnlyUnhealthy && js.upCount == js.targetsTotal {
//line lib/promscrape/targets.qtpl:10
continue
//line lib/promscrape/targets.qtpl:10
}
//line lib/promscrape/targets.qtpl:10
qw422016.N().S(`
<div class="row mb-4">
<div class="col-12">
<h4>
<span class="me-2">`)
//line lib/promscrape/targets.qtpl:14
qw422016.E().S(js.job)
//line lib/promscrape/targets.qtpl:14
qw422016.N().S(` `)
//line lib/promscrape/targets.qtpl:14
qw422016.N().S(`(`)
//line lib/promscrape/targets.qtpl:14
qw422016.N().D(js.upCount)
//line lib/promscrape/targets.qtpl:14
qw422016.N().S(`/`)
//line lib/promscrape/targets.qtpl:14
qw422016.N().D(js.targetsTotal)
//line lib/promscrape/targets.qtpl:14
qw422016.N().S(` `)
//line lib/promscrape/targets.qtpl:14
qw422016.N().S(`up)</span>
<button type="button" class="btn btn-primary btn-sm me-1"
onclick="document.getElementById('table-`)
//line lib/promscrape/targets.qtpl:16
qw422016.N().D(i)
//line lib/promscrape/targets.qtpl:16
qw422016.N().S(`').style.display='none'">collapse
</button>
<button type="button" class="btn btn-secondary btn-sm me-1"
onclick="document.getElementById('table-`)
//line lib/promscrape/targets.qtpl:19
qw422016.N().D(i)
//line lib/promscrape/targets.qtpl:19
qw422016.N().S(`').style.display='block'">expand
</button>
</h4>
<div id="table-`)
//line lib/promscrape/targets.qtpl:22
qw422016.N().D(i)
//line lib/promscrape/targets.qtpl:22
qw422016.N().S(`" class="table-responsive">
<table class="table table-striped table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col">Endpoint</th>
<th scope="col">State</th>
<th scope="col" title="scrape target labels">Labels</th>
<th scope="col" title="total scrapes">Scrapes</th>
<th scope="col" title="total scrape errors">Errors</th>
<th scope="col" title="the time of the last scrape">Last Scrape</th>
<th scope="col" title="the duration of the last scrape">Duration</th>
<th scope="col" title="the number of metrics scraped during the last scrape">Samples</th>
<th scope="col" title="error from the last scrape (if any)">Last error</th>
</tr>
</thead>
<tbody class="list-`)
//line lib/promscrape/targets.qtpl:37
qw422016.N().D(i)
//line lib/promscrape/targets.qtpl:37
qw422016.N().S(`">
`)
//line lib/promscrape/targets.qtpl:38
for _, ts := range js.targetsStatus {
//line lib/promscrape/targets.qtpl:38
qw422016.N().S(`
`)
//line lib/promscrape/targets.qtpl:40
endpoint := ts.sw.Config.ScrapeURL
targetID := getTargetID(ts.sw)
lastScrapeTime := ts.getDurationFromLastScrape()
//line lib/promscrape/targets.qtpl:43
qw422016.N().S(`
`)
//line lib/promscrape/targets.qtpl:44
if showOnlyUnhealthy && ts.up {
//line lib/promscrape/targets.qtpl:44
continue
//line lib/promscrape/targets.qtpl:44
}
//line lib/promscrape/targets.qtpl:44
qw422016.N().S(`
<tr `)
//line lib/promscrape/targets.qtpl:45
if !ts.up {
//line lib/promscrape/targets.qtpl:45
qw422016.N().S(` `)
//line lib/promscrape/targets.qtpl:45
qw422016.N().S(`class="alert alert-danger" role="alert" `)
//line lib/promscrape/targets.qtpl:45
}
//line lib/promscrape/targets.qtpl:45
qw422016.N().S(`>
<td class="endpoint"><a href="`)
//line lib/promscrape/targets.qtpl:46
qw422016.E().S(endpoint)
//line lib/promscrape/targets.qtpl:46
qw422016.N().S(`" target="_blank">`)
//line lib/promscrape/targets.qtpl:46
qw422016.E().S(endpoint)
//line lib/promscrape/targets.qtpl:46
qw422016.N().S(`</a> (
<a href="target_response?id=`)
//line lib/promscrape/targets.qtpl:47
qw422016.E().S(targetID)
//line lib/promscrape/targets.qtpl:47
qw422016.N().S(`" target="_blank"
title="click to fetch target response on behalf of the scraper">response</a>
)
</td>
<td>
`)
//line lib/promscrape/targets.qtpl:52
if ts.up {
//line lib/promscrape/targets.qtpl:52
qw422016.N().S(`
<span class="badge bg-success">UP</span>
`)
//line lib/promscrape/targets.qtpl:54
} else {
//line lib/promscrape/targets.qtpl:54
qw422016.N().S(`
<span class="badge bg-danger">DOWN</span>
`)
//line lib/promscrape/targets.qtpl:56
}
//line lib/promscrape/targets.qtpl:56
qw422016.N().S(`
</td>
<td class="labels">
<div title="click to show original labels"
onclick="document.getElementById('original_labels_`)
//line lib/promscrape/targets.qtpl:60
qw422016.E().S(targetID)
//line lib/promscrape/targets.qtpl:60
qw422016.N().S(`').style.display='block'">
`)
//line lib/promscrape/targets.qtpl:61
streamformatLabel(qw422016, promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels))
//line lib/promscrape/targets.qtpl:61
qw422016.N().S(`
</div>
<div style="display:none" id="original_labels_`)
//line lib/promscrape/targets.qtpl:63
qw422016.E().S(targetID)
//line lib/promscrape/targets.qtpl:63
qw422016.N().S(`">
`)
//line lib/promscrape/targets.qtpl:64
streamformatLabel(qw422016, ts.sw.Config.OriginalLabels)
//line lib/promscrape/targets.qtpl:64
qw422016.N().S(`
</div>
</td>
<td>`)
//line lib/promscrape/targets.qtpl:67
qw422016.N().D(ts.scrapesTotal)
//line lib/promscrape/targets.qtpl:67
qw422016.N().S(`</td>
<td>`)
//line lib/promscrape/targets.qtpl:68
qw422016.N().D(ts.scrapesFailed)
//line lib/promscrape/targets.qtpl:68
qw422016.N().S(`</td>
<td>
`)
//line lib/promscrape/targets.qtpl:70
if lastScrapeTime < 365*24*time.Hour {
//line lib/promscrape/targets.qtpl:70
qw422016.N().S(`
`)
//line lib/promscrape/targets.qtpl:71
qw422016.N().FPrec(lastScrapeTime.Seconds(), 3)
//line lib/promscrape/targets.qtpl:71
qw422016.N().S(`s ago
`)
//line lib/promscrape/targets.qtpl:72
} else {
//line lib/promscrape/targets.qtpl:72
qw422016.N().S(`
none
`)
//line lib/promscrape/targets.qtpl:74
}
//line lib/promscrape/targets.qtpl:74
qw422016.N().S(`
<td>`)
//line lib/promscrape/targets.qtpl:75
qw422016.N().D(int(ts.scrapeDuration))
//line lib/promscrape/targets.qtpl:75
qw422016.N().S(`ms</td>
<td>`)
//line lib/promscrape/targets.qtpl:76
qw422016.N().D(ts.samplesScraped)
//line lib/promscrape/targets.qtpl:76
qw422016.N().S(`</td>
<td>`)
//line lib/promscrape/targets.qtpl:77
if ts.err != nil {
//line lib/promscrape/targets.qtpl:77
qw422016.E().S(ts.err.Error())
//line lib/promscrape/targets.qtpl:77
}
//line lib/promscrape/targets.qtpl:77
qw422016.N().S(`</td>
</tr>
`)
//line lib/promscrape/targets.qtpl:79
}
//line lib/promscrape/targets.qtpl:79
qw422016.N().S(`
</tbody>
</table>
</div>
</div>
</div>
`)
//line lib/promscrape/targets.qtpl:85
}
//line lib/promscrape/targets.qtpl:85
qw422016.N().S(`
</div>
</div>
`)
//line lib/promscrape/targets.qtpl:89
for _, jobName := range emptyJobs {
//line lib/promscrape/targets.qtpl:89
qw422016.N().S(`
<div>
<h4><a>`)
//line lib/promscrape/targets.qtpl:91
qw422016.E().S(jobName)
//line lib/promscrape/targets.qtpl:91
qw422016.N().S(` (0/0 up)</a></h4>
<table class="table table-striped table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col">Endpoint</th>
<th scope="col">State</th>
<th scope="col">Labels</th>
<th scope="col">Last Scrape</th>
<th scope="col">Scrape Duration</th>
<th scope="col">Samples Scraped</th>
<th scope="col">Error</th>
</tr>
</thead>
</table>
</div>
`)
//line lib/promscrape/targets.qtpl:106
}
//line lib/promscrape/targets.qtpl:106
qw422016.N().S(`
`)
//line lib/promscrape/targets.qtpl:107
}
//line lib/promscrape/targets.qtpl:107
func WriteTargets(qq422016 qtio422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool) {
//line lib/promscrape/targets.qtpl:107
qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targets.qtpl:107
StreamTargets(qw422016, jts, emptyJobs, showOnlyUnhealthy)
//line lib/promscrape/targets.qtpl:107
qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targets.qtpl:107
}
//line lib/promscrape/targets.qtpl:107
func Targets(jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool) string {
//line lib/promscrape/targets.qtpl:107
qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targets.qtpl:107
WriteTargets(qb422016, jts, emptyJobs, showOnlyUnhealthy)
//line lib/promscrape/targets.qtpl:107
qs422016 := string(qb422016.B)
//line lib/promscrape/targets.qtpl:107
qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targets.qtpl:107
return qs422016
//line lib/promscrape/targets.qtpl:107
}

View file

@ -16,7 +16,7 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/fasttime"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
xxhash "github.com/cespare/xxhash/v2"
"github.com/cespare/xxhash/v2"
)
var maxDroppedTargets = flag.Int("promscrape.maxDroppedTargets", 1000, "The maximum number of droppedTargets to show at /api/v1/targets page. "+
@ -49,12 +49,20 @@ func WriteHumanReadableTargetsStatus(w http.ResponseWriter, r *http.Request) {
showOnlyUnhealthy, _ := strconv.ParseBool(r.FormValue("show_only_unhealthy"))
endpointSearch := strings.TrimSpace(r.FormValue("endpoint_search"))
labelSearch := strings.TrimSpace(r.FormValue("label_search"))
activeTab := strings.TrimSpace(r.FormValue("active_tab"))
filter := requestFilter{
showOriginalLabels: showOriginalLabels,
showOnlyUnhealthy: showOnlyUnhealthy,
endpointSearch: endpointSearch,
labelSearch: labelSearch,
activeTab: activeTab,
}
if accept := r.Header.Get("Accept"); strings.Contains(accept, "text/html") {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
tsmGlobal.WriteTargetsHTML(w, showOnlyUnhealthy, endpointSearch, labelSearch)
tsmGlobal.WriteTargetsHTML(w, filter)
} else {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
tsmGlobal.WriteTargetsPlain(w, showOriginalLabels, showOnlyUnhealthy, endpointSearch, labelSearch)
tsmGlobal.WriteTargetsPlain(w, filter)
}
}
@ -167,17 +175,17 @@ func (tsm *targetStatusMap) StatusByGroup(group string, up bool) int {
return count
}
// WriteActiveTargetsJSON writes `activeTargets` contents to w according to https://prometheus.io/docs/prometheus/latest/querying/api/#targets
func (tsm *targetStatusMap) WriteActiveTargetsJSON(w io.Writer) {
type activeKeyStatus struct {
key string
st targetStatus
}
func (tsm *targetStatusMap) getActiveKeyStatuses() []activeKeyStatus {
tsm.mu.Lock()
type keyStatus struct {
key string
st targetStatus
}
kss := make([]keyStatus, 0, len(tsm.m))
kss := make([]activeKeyStatus, 0, len(tsm.m))
for sw, st := range tsm.m {
key := promLabelsString(sw.Config.OriginalLabels)
kss = append(kss, keyStatus{
kss = append(kss, activeKeyStatus{
key: key,
st: *st,
})
@ -187,6 +195,12 @@ func (tsm *targetStatusMap) WriteActiveTargetsJSON(w io.Writer) {
sort.Slice(kss, func(i, j int) bool {
return kss[i].key < kss[j].key
})
return kss
}
// WriteActiveTargetsJSON writes `activeTargets` contents to w according to https://prometheus.io/docs/prometheus/latest/querying/api/#targets
func (tsm *targetStatusMap) WriteActiveTargetsJSON(w io.Writer) {
kss := tsm.getActiveKeyStatuses()
fmt.Fprintf(w, `[`)
for i, ks := range kss {
st := ks.st
@ -244,15 +258,38 @@ func (st *targetStatus) getDurationFromLastScrape() time.Duration {
return time.Since(time.Unix(st.scrapeTime/1000, (st.scrapeTime%1000)*1e6))
}
type droppedTargets struct {
mu sync.Mutex
m map[uint64]droppedTarget
lastCleanupTime uint64
}
type (
droppedTargets struct {
mu sync.Mutex
m map[uint64]droppedTarget
lastCleanupTime uint64
}
droppedTarget struct {
originalLabels []prompbmarshal.Label
deadline uint64
}
droppedKeyStatus struct {
key string
originalLabels []prompbmarshal.Label
}
)
type droppedTarget struct {
originalLabels []prompbmarshal.Label
deadline uint64
func (dt *droppedTargets) getDroppedKeyStatuses() []droppedKeyStatus {
dt.mu.Lock()
kss := make([]droppedKeyStatus, 0, len(dt.m))
for _, v := range dt.m {
key := promLabelsString(v.originalLabels)
kss = append(kss, droppedKeyStatus{
key: key,
originalLabels: v.originalLabels,
})
}
dt.mu.Unlock()
sort.Slice(kss, func(i, j int) bool {
return kss[i].key < kss[j].key
})
return kss
}
func (dt *droppedTargets) Register(originalLabels []prompbmarshal.Label) {
@ -300,24 +337,7 @@ var xxhashPool = &sync.Pool{
// WriteDroppedTargetsJSON writes `droppedTargets` contents to w according to https://prometheus.io/docs/prometheus/latest/querying/api/#targets
func (dt *droppedTargets) WriteDroppedTargetsJSON(w io.Writer) {
dt.mu.Lock()
type keyStatus struct {
key string
originalLabels []prompbmarshal.Label
}
kss := make([]keyStatus, 0, len(dt.m))
for _, v := range dt.m {
key := promLabelsString(v.originalLabels)
kss = append(kss, keyStatus{
key: key,
originalLabels: v.originalLabels,
})
}
dt.mu.Unlock()
sort.Slice(kss, func(i, j int) bool {
return kss[i].key < kss[j].key
})
kss := dt.getDroppedKeyStatuses()
fmt.Fprintf(w, `[`)
for i, ks := range kss {
fmt.Fprintf(w, `{"discoveredLabels":`)
@ -465,16 +485,46 @@ func getEmptyJobs(jts []jobTargetsStatuses, jobNames []string) []string {
return emptyJobs
}
type (
requestFilter struct {
showOriginalLabels bool
showOnlyUnhealthy bool
endpointSearch string
labelSearch string
activeTab string
}
targetsStatuses struct {
jobTargetsStatuses []jobTargetsStatuses
droppedKeyStatuses []droppedKeyStatus
emptyJobs []string
err error
}
scrapeTargets struct {
requestFilter
targetsStatuses
}
)
// WriteTargetsHTML writes targets status grouped by job into writer w in html table,
// accepts filter to show only unhealthy targets.
func (tsm *targetStatusMap) WriteTargetsHTML(w io.Writer, showOnlyUnhealthy bool, endpointSearch, labelSearch string) {
jss, emptyJobs, err := tsm.getTargetsStatusByJob(endpointSearch, labelSearch)
WriteTargetsResponseHTML(w, jss, emptyJobs, showOnlyUnhealthy, endpointSearch, labelSearch, err)
func (tsm *targetStatusMap) WriteTargetsHTML(w io.Writer, filter requestFilter) {
droppedKeyStatuses := droppedTargetsMap.getDroppedKeyStatuses()
jss, emptyJobs, err := tsm.getTargetsStatusByJob(filter.endpointSearch, filter.labelSearch)
scrapeTargets := scrapeTargets{
requestFilter: filter,
targetsStatuses: targetsStatuses{
jobTargetsStatuses: jss,
droppedKeyStatuses: droppedKeyStatuses,
emptyJobs: emptyJobs,
err: err,
},
}
WriteTargetsResponseHTML(w, scrapeTargets)
}
// WriteTargetsPlain writes targets grouped by job into writer w in plain text,
// accept filter to show original labels.
func (tsm *targetStatusMap) WriteTargetsPlain(w io.Writer, showOriginalLabels, showOnlyUnhealthy bool, endpointSearch, labelSearch string) {
jss, emptyJobs, err := tsm.getTargetsStatusByJob(endpointSearch, labelSearch)
WriteTargetsResponsePlain(w, jss, emptyJobs, showOriginalLabels, showOnlyUnhealthy, err)
func (tsm *targetStatusMap) WriteTargetsPlain(w io.Writer, filter requestFilter) {
jss, emptyJobs, err := tsm.getTargetsStatusByJob(filter.endpointSearch, filter.labelSearch)
WriteTargetsResponsePlain(w, jss, emptyJobs, filter.showOriginalLabels, filter.showOnlyUnhealthy, err)
}

View file

@ -1,6 +1,5 @@
{% import (
"net/url"
"time"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
) %}
@ -42,7 +41,14 @@ job={%q= jobName %} (0/0 up)
{% endfunc %}
{% func TargetsResponseHTML(jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, endpointSearch, labelSearch string, err error) %}
{% func TargetsResponseHTML(scrapeTargets scrapeTargets) %}
{% code
targetsStatuses := scrapeTargets.targetsStatuses
filter := scrapeTargets.requestFilter
if filter.activeTab == "" {
filter.activeTab="targets-tab"
}
%}
<!DOCTYPE html>
<html lang="en">
<head>
@ -52,21 +58,23 @@ job={%q= jobName %} (0/0 up)
<title>Scrape targets</title>
<script>
function collapse_all() {
for (var i = 0; i < {%d len(jts) %}; i++) {
let el = document.getElementById("table-" + i);
if (!el) {
continue;
}
el.style.display = 'none';
for (var i = 0; i <= {%d len(targetsStatuses.jobTargetsStatuses) %}; i++) {
["table-"+i, "table-discovery-"+i, "table-empty-"+i].forEach((id) => {
let el = document.getElementById(id);
if (el) {
el.style.display = 'none';
}
})
}
}
function expand_all() {
for (var i = 0; i < {%d len(jts) %}; i++) {
let el = document.getElementById("table-" + i);
if (!el) {
continue;
}
el.style.display = 'block';
for (var i = 0; i <= {%d len(targetsStatuses.jobTargetsStatuses) %}; i++) {
["table-"+i, "table-discovery-"+i, "table-empty-"+i].forEach((id) => {
let el = document.getElementById(id);
if (el) {
el.style.display = 'block';
}
});
}
}
</script>
@ -81,8 +89,8 @@ function expand_all() {
</div>
</div>
<div class="container-fluid">
{% if err != nil %}
{%= errorNotification(err) %}
{% if targetsStatuses.err != nil %}
{%= errorNotification(targetsStatuses.err) %}
{% endif %}
<div class="row">
<main class="col-12">
@ -90,19 +98,21 @@ function expand_all() {
<hr />
<div class="row g-3 align-items-center mb-3">
<div class="col-auto">
<button type="button" class="btn{% space %}{% if !showOnlyUnhealthy %}btn-secondary{% else %}btn-success{% endif %}" onclick="location.href='?{%= queryArgs(map[string]string{
<button id="all-btn" type="button" class="btn{% space %}{% if !filter.showOnlyUnhealthy %}btn-secondary{% else %}btn-success{% endif %}" onclick="location.href='?{%= queryArgs(map[string]string{
"show_only_unhealthy": "false",
"endpoint_search": endpointSearch,
"label_search": labelSearch,
"endpoint_search": filter.endpointSearch,
"label_search": filter.labelSearch,
"active_tab": filter.activeTab,
}) %}'">
All
</button>
</div>
<div class="col-auto">
<button type="button" class="btn{% space %}{% if showOnlyUnhealthy %}btn-secondary{% else %}btn-danger{% endif %}" onclick="location.href='?{%= queryArgs(map[string]string{
<button id="unhealthy-btn" type="button" class="btn{% space %}{% if filter.showOnlyUnhealthy %}btn-secondary{% else %}btn-danger{% endif %}" onclick="location.href='?{%= queryArgs(map[string]string{
"show_only_unhealthy": "true",
"endpoint_search": endpointSearch,
"label_search": labelSearch,
"endpoint_search": filter.endpointSearch,
"label_search": filter.labelSearch,
"active_tab": filter.activeTab,
}) %}'">
Unhealthy
</button>
@ -118,7 +128,7 @@ function expand_all() {
</button>
</div>
<div class="col-auto">
{% if endpointSearch == "" && labelSearch == "" %}
{% if filter.endpointSearch == "" && filter.labelSearch == "" %}
<button type="button" class="btn btn-success" onclick="document.getElementById('filters').style.display='block'">
Filter targets
</button>
@ -129,126 +139,77 @@ function expand_all() {
{% endif %}
</div>
</div>
<div id="filters" {% if endpointSearch == "" && labelSearch == "" %}style="display:none"{% endif %}>
<div id="filters" {% if filter.endpointSearch == "" && filter.labelSearch == "" %}style="display:none"{% endif %}>
<form class="form-horizontal">
<div class="form-group mb-3">
<label for="endpoint_search" class="col-sm-10 control-label">Endpoint filter (<a target="_blank" href="https://github.com/google/re2/wiki/Syntax">Regexp</a> is accepted)</label>
<div class="col-sm-10">
<input type="text" id="endpoint_search" name="endpoint_search"
placeholder="For example, 127.0.0.1" class="form-control" value="{%s endpointSearch %}"/>
placeholder="For example, 127.0.0.1" class="form-control" value="{%s filter.endpointSearch %}"/>
</div>
</div>
<div class="form-group mb-3">
<label for="label_search" class="col-sm-10 control-label">Labels filter (<a target="_blank" href="https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors">Arbitrary time series selectors</a> are accepted)</label>
<div class="col-sm-10">
<input type="text" id="label_search" name="label_search"
placeholder="For example, {instance=~'.+:9100'}" class="form-control" value="{%s labelSearch %}"/>
placeholder="For example, {instance=~'.+:9100'}" class="form-control" value="{%s filter.labelSearch %}"/>
</div>
</div>
<input type="hidden" name="show_only_unhealthy" value="{%v showOnlyUnhealthy %}"/>
<input type="hidden" name="show_only_unhealthy" value="{%v filter.showOnlyUnhealthy %}"/>
<input id="tab_input" type="hidden" name="active_tab" value="{%s filter.activeTab %}" />
<button type="submit" class="btn btn-success mb-3">Submit</button>
</form>
</div>
<hr />
<div class="row">
<div class="col-12">
{% for i, js := range jts %}
{% if showOnlyUnhealthy && js.upCount == js.targetsTotal %}{% continue %}{% endif %}
<div class="row mb-4">
<div class="col-12">
<h4>
<span class="me-2">{%s js.job %}{% space %}({%d js.upCount %}/{%d js.targetsTotal %}{% space %}up)</span>
<button type="button" class="btn btn-primary btn-sm me-1"
onclick="document.getElementById('table-{%d i %}').style.display='none'">collapse
</button>
<button type="button" class="btn btn-secondary btn-sm me-1"
onclick="document.getElementById('table-{%d i %}').style.display='block'">expand
</button>
</h4>
<div id="table-{%d i %}" class="table-responsive">
<table class="table table-striped table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col">Endpoint</th>
<th scope="col">State</th>
<th scope="col" title="scrape target labels">Labels</th>
<th scope="col" title="total scrapes">Scrapes</th>
<th scope="col" title="total scrape errors">Errors</th>
<th scope="col" title="the time of the last scrape">Last Scrape</th>
<th scope="col" title="the duration of the last scrape">Duration</th>
<th scope="col" title="the number of metrics scraped during the last scrape">Samples</th>
<th scope="col" title="error from the last scrape (if any)">Last error</th>
</tr>
</thead>
<tbody class="list-{%d i %}">
{% for _, ts := range js.targetsStatus %}
{% code
endpoint := ts.sw.Config.ScrapeURL
targetID := getTargetID(ts.sw)
lastScrapeTime := ts.getDurationFromLastScrape()
%}
{% if showOnlyUnhealthy && ts.up %}{% continue %}{% endif %}
<tr {% if !ts.up %}{%space%}class="alert alert-danger" role="alert" {% endif %}>
<td class="endpoint"><a href="{%s endpoint %}" target="_blank">{%s endpoint %}</a> (
<a href="target_response?id={%s targetID %}" target="_blank"
title="click to fetch target response on behalf of the scraper">response</a>
)
</td>
<td>{% if ts.up %}UP{% else %}DOWN{% endif %}</td>
<td class="labels">
<div title="click to show original labels"
onclick="document.getElementById('original_labels_{%s targetID %}').style.display='block'">
{%= formatLabel(promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels)) %}
</div>
<div style="display:none" id="original_labels_{%s targetID %}">
{%= formatLabel(ts.sw.Config.OriginalLabels) %}
</div>
</td>
<td>{%d ts.scrapesTotal %}</td>
<td>{%d ts.scrapesFailed %}</td>
<td>
{% if lastScrapeTime < 365*24*time.Hour %}
{%f.3 lastScrapeTime.Seconds() %}s ago
{% else %}
none
{% endif %}
<td>{%d int(ts.scrapeDuration) %}ms</td>
<td>{%d ts.samplesScraped %}</td>
<td>{% if ts.err != nil %}{%s ts.err.Error() %}{% endif %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endfor %}
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button id="targets-tab" class="nav-link {%if filter.activeTab=="targets-tab"%} {% space %}active {%endif%}" data-bs-toggle="tab" data-bs-target="#targets" type="button" role="tab" aria-controls="home" aria-selected="true">Targets</button>
</li>
<li class="nav-item" role="presentation">
<button id="discovery-tab" class="nav-link {%if filter.activeTab=="discovery-tab"%} {% space %}active {%endif%}" data-bs-toggle="tab" data-bs-target="#discovery" type="button" role="tab" aria-controls="profile" aria-selected="false">Service Discovery</button>
</li>
</ul>
<div class="tab-content">
<div id="targets" class="tab-pane {%if filter.activeTab=="targets-tab"%} {% space %}active{%endif%}" role="tabpanel" aria-labelledby="targets-tab">
{%= Targets(targetsStatuses.jobTargetsStatuses, targetsStatuses.emptyJobs, filter.showOnlyUnhealthy) %}
</div>
<div id="discovery" class="tab-pane {%if filter.activeTab=="discovery-tab"%} {% space %}active{%endif%}" role="tabpanel" aria-labelledby="profile-tab">
{%= ServiceDiscovery(targetsStatuses.jobTargetsStatuses, targetsStatuses.emptyJobs, filter.showOnlyUnhealthy, targetsStatuses.droppedKeyStatuses) %}
</div>
</div>
{% for _, jobName := range emptyJobs %}
<div>
<h4>
<a>{%s jobName %} (0/0 up)</a>
</h4>
<table class="table table-striped table-hover table-bordered table-sm">
<thead>
<tr>
<th scope="col">Endpoint</th>
<th scope="col">State</th>
<th scope="col">Labels</th>
<th scope="col">Last Scrape</th>
<th scope="col">Scrape Duration</th>
<th scope="col">Samples Scraped</th>
<th scope="col">Error</th>
</tr>
</thead>
</table>
</div>
{% endfor %}
</main>
</div>
</div>
<script src="static/js/jquery-3.6.0.min.js" type="text/javascript"></script>
<script src="static/js/bootstrap.bundle.min.js" type="text/javascript"></script>
<script>
(function(){
const navBtns = document.querySelectorAll(".nav-link");
const tabInput = document.getElementById("tab_input");
const unhealthyBtn = document.getElementById("unhealthy-btn");
const allBtn = document.getElementById("all-btn");
navBtns.forEach((btn) => {
if (btn) {
btn.addEventListener("click", (e) => {
if (window.history.replaceState) {
var url = new URL(window.location.href);
url.searchParams.set("active_tab", e.target.id);
tabInput.value = e.target.id;
unhealthyBtn.onclick = () => {
url.searchParams.set("show_only_unhealthy", "true");
window.location.href=url;
};
allBtn.onclick = () => {
url.searchParams.set("show_only_unhealthy", "false");
window.location.href=url;
};
window.history.replaceState({}, "", url);
}
});
}
})
})()
</script>
</body>
</html>
{% endfunc %}

View file

@ -9,625 +9,520 @@ import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
"net/url"
"time"
)
//line lib/promscrape/targetstatus.qtpl:10
//line lib/promscrape/targetstatus.qtpl:9
import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
)
//line lib/promscrape/targetstatus.qtpl:10
//line lib/promscrape/targetstatus.qtpl:9
var (
_ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer
)
//line lib/promscrape/targetstatus.qtpl:10
//line lib/promscrape/targetstatus.qtpl:9
func StreamTargetsResponsePlain(qw422016 *qt422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels, showOnlyUnhealthy bool, err error) {
//line lib/promscrape/targetstatus.qtpl:12
//line lib/promscrape/targetstatus.qtpl:11
if err != nil {
//line lib/promscrape/targetstatus.qtpl:13
//line lib/promscrape/targetstatus.qtpl:12
qw422016.N().S(err.Error())
//line lib/promscrape/targetstatus.qtpl:14
//line lib/promscrape/targetstatus.qtpl:13
return
//line lib/promscrape/targetstatus.qtpl:15
//line lib/promscrape/targetstatus.qtpl:14
}
//line lib/promscrape/targetstatus.qtpl:17
//line lib/promscrape/targetstatus.qtpl:16
for _, js := range jts {
//line lib/promscrape/targetstatus.qtpl:18
//line lib/promscrape/targetstatus.qtpl:17
if showOnlyUnhealthy && js.upCount == js.targetsTotal {
//line lib/promscrape/targetstatus.qtpl:18
//line lib/promscrape/targetstatus.qtpl:17
continue
//line lib/promscrape/targetstatus.qtpl:18
//line lib/promscrape/targetstatus.qtpl:17
}
//line lib/promscrape/targetstatus.qtpl:18
//line lib/promscrape/targetstatus.qtpl:17
qw422016.N().S(`job=`)
//line lib/promscrape/targetstatus.qtpl:19
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().Q(js.job)
//line lib/promscrape/targetstatus.qtpl:19
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().S(`(`)
//line lib/promscrape/targetstatus.qtpl:19
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().D(js.upCount)
//line lib/promscrape/targetstatus.qtpl:19
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().S(`/`)
//line lib/promscrape/targetstatus.qtpl:19
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().D(js.targetsTotal)
//line lib/promscrape/targetstatus.qtpl:19
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:19
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().S(`up)`)
//line lib/promscrape/targetstatus.qtpl:20
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(`
`)
//line lib/promscrape/targetstatus.qtpl:21
//line lib/promscrape/targetstatus.qtpl:20
for _, ts := range js.targetsStatus {
//line lib/promscrape/targetstatus.qtpl:22
//line lib/promscrape/targetstatus.qtpl:21
if showOnlyUnhealthy && ts.up {
//line lib/promscrape/targetstatus.qtpl:22
//line lib/promscrape/targetstatus.qtpl:21
continue
//line lib/promscrape/targetstatus.qtpl:21
}
//line lib/promscrape/targetstatus.qtpl:22
}
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S("\t")
//line lib/promscrape/targetstatus.qtpl:23
//line lib/promscrape/targetstatus.qtpl:22
qw422016.N().S(`state=`)
//line lib/promscrape/targetstatus.qtpl:24
//line lib/promscrape/targetstatus.qtpl:23
if ts.up {
//line lib/promscrape/targetstatus.qtpl:24
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S(`up`)
//line lib/promscrape/targetstatus.qtpl:24
//line lib/promscrape/targetstatus.qtpl:23
} else {
//line lib/promscrape/targetstatus.qtpl:24
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S(`down`)
//line lib/promscrape/targetstatus.qtpl:24
//line lib/promscrape/targetstatus.qtpl:23
}
//line lib/promscrape/targetstatus.qtpl:24
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:24
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:24
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S(`endpoint=`)
//line lib/promscrape/targetstatus.qtpl:25
//line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(ts.sw.Config.ScrapeURL)
//line lib/promscrape/targetstatus.qtpl:25
//line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:25
//line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:25
//line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(`labels=`)
//line lib/promscrape/targetstatus.qtpl:26
//line lib/promscrape/targetstatus.qtpl:25
qw422016.N().S(promLabelsString(promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels)))
//line lib/promscrape/targetstatus.qtpl:26
//line lib/promscrape/targetstatus.qtpl:25
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:26
//line lib/promscrape/targetstatus.qtpl:25
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:27
//line lib/promscrape/targetstatus.qtpl:26
if showOriginLabels {
//line lib/promscrape/targetstatus.qtpl:27
//line lib/promscrape/targetstatus.qtpl:26
qw422016.N().S(`originalLabels=`)
//line lib/promscrape/targetstatus.qtpl:27
//line lib/promscrape/targetstatus.qtpl:26
qw422016.N().S(promLabelsString(ts.sw.Config.OriginalLabels))
//line lib/promscrape/targetstatus.qtpl:27
//line lib/promscrape/targetstatus.qtpl:26
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:27
//line lib/promscrape/targetstatus.qtpl:26
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:27
//line lib/promscrape/targetstatus.qtpl:26
}
//line lib/promscrape/targetstatus.qtpl:27
//line lib/promscrape/targetstatus.qtpl:26
qw422016.N().S(`scrapes_total=`)
//line lib/promscrape/targetstatus.qtpl:28
//line lib/promscrape/targetstatus.qtpl:27
qw422016.N().D(ts.scrapesTotal)
//line lib/promscrape/targetstatus.qtpl:28
//line lib/promscrape/targetstatus.qtpl:27
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:28
//line lib/promscrape/targetstatus.qtpl:27
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:28
//line lib/promscrape/targetstatus.qtpl:27
qw422016.N().S(`scrapes_failed=`)
//line lib/promscrape/targetstatus.qtpl:29
//line lib/promscrape/targetstatus.qtpl:28
qw422016.N().D(ts.scrapesFailed)
//line lib/promscrape/targetstatus.qtpl:29
//line lib/promscrape/targetstatus.qtpl:28
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:29
//line lib/promscrape/targetstatus.qtpl:28
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:29
//line lib/promscrape/targetstatus.qtpl:28
qw422016.N().S(`last_scrape=`)
//line lib/promscrape/targetstatus.qtpl:30
//line lib/promscrape/targetstatus.qtpl:29
qw422016.N().FPrec(ts.getDurationFromLastScrape().Seconds(), 3)
//line lib/promscrape/targetstatus.qtpl:30
//line lib/promscrape/targetstatus.qtpl:29
qw422016.N().S(`s ago,`)
//line lib/promscrape/targetstatus.qtpl:30
//line lib/promscrape/targetstatus.qtpl:29
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:30
//line lib/promscrape/targetstatus.qtpl:29
qw422016.N().S(`scrape_duration=`)
//line lib/promscrape/targetstatus.qtpl:31
//line lib/promscrape/targetstatus.qtpl:30
qw422016.N().D(int(ts.scrapeDuration))
//line lib/promscrape/targetstatus.qtpl:31
//line lib/promscrape/targetstatus.qtpl:30
qw422016.N().S(`ms,`)
//line lib/promscrape/targetstatus.qtpl:31
//line lib/promscrape/targetstatus.qtpl:30
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:31
//line lib/promscrape/targetstatus.qtpl:30
qw422016.N().S(`samples_scraped=`)
//line lib/promscrape/targetstatus.qtpl:32
//line lib/promscrape/targetstatus.qtpl:31
qw422016.N().D(ts.samplesScraped)
//line lib/promscrape/targetstatus.qtpl:32
//line lib/promscrape/targetstatus.qtpl:31
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:32
//line lib/promscrape/targetstatus.qtpl:31
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:32
//line lib/promscrape/targetstatus.qtpl:31
qw422016.N().S(`error=`)
//line lib/promscrape/targetstatus.qtpl:33
//line lib/promscrape/targetstatus.qtpl:32
if ts.err != nil {
//line lib/promscrape/targetstatus.qtpl:33
//line lib/promscrape/targetstatus.qtpl:32
qw422016.N().S(ts.err.Error())
//line lib/promscrape/targetstatus.qtpl:33
//line lib/promscrape/targetstatus.qtpl:32
}
//line lib/promscrape/targetstatus.qtpl:34
//line lib/promscrape/targetstatus.qtpl:33
qw422016.N().S(`
`)
//line lib/promscrape/targetstatus.qtpl:35
//line lib/promscrape/targetstatus.qtpl:34
}
//line lib/promscrape/targetstatus.qtpl:36
//line lib/promscrape/targetstatus.qtpl:35
}
//line lib/promscrape/targetstatus.qtpl:38
//line lib/promscrape/targetstatus.qtpl:37
for _, jobName := range emptyJobs {
//line lib/promscrape/targetstatus.qtpl:38
//line lib/promscrape/targetstatus.qtpl:37
qw422016.N().S(`job=`)
//line lib/promscrape/targetstatus.qtpl:39
//line lib/promscrape/targetstatus.qtpl:38
qw422016.N().Q(jobName)
//line lib/promscrape/targetstatus.qtpl:39
//line lib/promscrape/targetstatus.qtpl:38
qw422016.N().S(`(0/0 up)`)
//line lib/promscrape/targetstatus.qtpl:40
//line lib/promscrape/targetstatus.qtpl:39
qw422016.N().S(`
`)
//line lib/promscrape/targetstatus.qtpl:41
//line lib/promscrape/targetstatus.qtpl:40
}
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
}
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
func WriteTargetsResponsePlain(qq422016 qtio422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels, showOnlyUnhealthy bool, err error) {
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
StreamTargetsResponsePlain(qw422016, jts, emptyJobs, showOriginLabels, showOnlyUnhealthy, err)
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
}
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
func TargetsResponsePlain(jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels, showOnlyUnhealthy bool, err error) string {
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
WriteTargetsResponsePlain(qb422016, jts, emptyJobs, showOriginLabels, showOnlyUnhealthy, err)
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
return qs422016
//line lib/promscrape/targetstatus.qtpl:43
//line lib/promscrape/targetstatus.qtpl:42
}
//line lib/promscrape/targetstatus.qtpl:45
func StreamTargetsResponseHTML(qw422016 *qt422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, endpointSearch, labelSearch string, err error) {
//line lib/promscrape/targetstatus.qtpl:45
qw422016.N().S(`<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link href="static/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"><title>Scrape targets</title><script>function collapse_all() {for (var i = 0; i <`)
//line lib/promscrape/targetstatus.qtpl:55
qw422016.N().D(len(jts))
//line lib/promscrape/targetstatus.qtpl:55
qw422016.N().S(`; i++) {let el = document.getElementById("table-" + i);if (!el) {continue;}el.style.display = 'none';}}function expand_all() {for (var i = 0; i <`)
//line lib/promscrape/targetstatus.qtpl:64
qw422016.N().D(len(jts))
//line lib/promscrape/targetstatus.qtpl:64
qw422016.N().S(`; i++) {let el = document.getElementById("table-" + i);if (!el) {continue;}el.style.display = 'block';}}</script></head><body><div class="navbar navbar-dark bg-dark box-shadow"><div class="d-flex justify-content-between"><a href="#" class="navbar-brand d-flex align-items-center ms-3" title="The High Performance Open Source Time Series Database &amp; Monitoring Solution "><svg xmlns="http://www.w3.org/2000/svg" id="VM_logo" viewBox="0 0 464.61 533.89" width="20" height="20" class="me-1"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M459.86,467.77c9,7.67,24.12,13.49,39.3,13.69v0h1.68v0c15.18-.2,30.31-6,39.3-13.69,47.43-40.45,184.65-166.24,184.65-166.24,36.84-34.27-65.64-68.28-223.95-68.47h-1.68c-158.31.19-260.79,34.2-224,68.47C275.21,301.53,412.43,427.32,459.86,467.77Z" transform="translate(-267.7 -233.05)"/><path class="cls-1" d="M540.1,535.88c-9,7.67-24.12,13.5-39.3,13.7h-1.6c-15.18-.2-30.31-6-39.3-13.7-32.81-28-148.56-132.93-192.16-172.7v60.74c0,6.67,2.55,15.52,7.09,19.68,29.64,27.18,143.94,131.8,185.07,166.88,9,7.67,24.12,13.49,39.3,13.69v0h1.6v0c15.18-.2,30.31-6,39.3-13.69,41.13-35.08,155.43-139.7,185.07-166.88,4.54-4.16,7.09-13,7.09-19.68V363.18C688.66,403,572.91,507.9,540.1,535.88Z" transform="translate(-267.7 -233.05)"/><path class="cls-1" d="M540.1,678.64c-9,7.67-24.12,13.49-39.3,13.69v0h-1.6v0c-15.18-.2-30.31-6-39.3-13.69-32.81-28-148.56-132.94-192.16-172.7v60.73c0,6.67,2.55,15.53,7.09,19.69,29.64,27.17,143.94,131.8,185.07,166.87,9,7.67,24.12,13.5,39.3,13.7h1.6c15.18-.2,30.31-6,39.3-13.7,41.13-35.07,155.43-139.7,185.07-166.87,4.54-4.16,7.09-13,7.09-19.69V505.94C688.66,545.7,572.91,650.66,540.1,678.64Z" transform="translate(-267.7 -233.05)"/></svg><strong>VictoriaMetrics</strong></a></div></div><div class="container-fluid">`)
//line lib/promscrape/targetstatus.qtpl:84
if err != nil {
//line lib/promscrape/targetstatus.qtpl:85
streamerrorNotification(qw422016, err)
//line lib/promscrape/targetstatus.qtpl:86
//line lib/promscrape/targetstatus.qtpl:44
func StreamTargetsResponseHTML(qw422016 *qt422016.Writer, scrapeTargets scrapeTargets) {
//line lib/promscrape/targetstatus.qtpl:46
targetsStatuses := scrapeTargets.targetsStatuses
filter := scrapeTargets.requestFilter
if filter.activeTab == "" {
filter.activeTab = "targets-tab"
}
//line lib/promscrape/targetstatus.qtpl:86
qw422016.N().S(`<div class="row"><main class="col-12"><h1>Scrape targets</h1><hr /><div class="row g-3 align-items-center mb-3"><div class="col-auto"><button type="button" class="btn`)
//line lib/promscrape/targetstatus.qtpl:51
qw422016.N().S(`<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link href="static/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"><title>Scrape targets</title><script>function collapse_all() {for (var i = 0; i <=`)
//line lib/promscrape/targetstatus.qtpl:61
qw422016.N().D(len(targetsStatuses.jobTargetsStatuses))
//line lib/promscrape/targetstatus.qtpl:61
qw422016.N().S(`; i++) {["table-"+i, "table-discovery-"+i, "table-empty-"+i].forEach((id) => {let el = document.getElementById(id);if (el) {el.style.display = 'none';}})}}function expand_all() {for (var i = 0; i <=`)
//line lib/promscrape/targetstatus.qtpl:71
qw422016.N().D(len(targetsStatuses.jobTargetsStatuses))
//line lib/promscrape/targetstatus.qtpl:71
qw422016.N().S(`; i++) {["table-"+i, "table-discovery-"+i, "table-empty-"+i].forEach((id) => {let el = document.getElementById(id);if (el) {el.style.display = 'block';}});}}</script></head><body><div class="navbar navbar-dark bg-dark box-shadow"><div class="d-flex justify-content-between"><a href="#" class="navbar-brand d-flex align-items-center ms-3" title="The High Performance Open Source Time Series Database &amp; Monitoring Solution "><svg xmlns="http://www.w3.org/2000/svg" id="VM_logo" viewBox="0 0 464.61 533.89" width="20" height="20" class="me-1"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M459.86,467.77c9,7.67,24.12,13.49,39.3,13.69v0h1.68v0c15.18-.2,30.31-6,39.3-13.69,47.43-40.45,184.65-166.24,184.65-166.24,36.84-34.27-65.64-68.28-223.95-68.47h-1.68c-158.31.19-260.79,34.2-224,68.47C275.21,301.53,412.43,427.32,459.86,467.77Z" transform="translate(-267.7 -233.05)"/><path class="cls-1" d="M540.1,535.88c-9,7.67-24.12,13.5-39.3,13.7h-1.6c-15.18-.2-30.31-6-39.3-13.7-32.81-28-148.56-132.93-192.16-172.7v60.74c0,6.67,2.55,15.52,7.09,19.68,29.64,27.18,143.94,131.8,185.07,166.88,9,7.67,24.12,13.49,39.3,13.69v0h1.6v0c15.18-.2,30.31-6,39.3-13.69,41.13-35.08,155.43-139.7,185.07-166.88,4.54-4.16,7.09-13,7.09-19.68V363.18C688.66,403,572.91,507.9,540.1,535.88Z" transform="translate(-267.7 -233.05)"/><path class="cls-1" d="M540.1,678.64c-9,7.67-24.12,13.49-39.3,13.69v0h-1.6v0c-15.18-.2-30.31-6-39.3-13.69-32.81-28-148.56-132.94-192.16-172.7v60.73c0,6.67,2.55,15.53,7.09,19.69,29.64,27.17,143.94,131.8,185.07,166.87,9,7.67,24.12,13.5,39.3,13.7h1.6c15.18-.2,30.31-6,39.3-13.7,41.13-35.07,155.43-139.7,185.07-166.87,4.54-4.16,7.09-13,7.09-19.69V505.94C688.66,545.7,572.91,650.66,540.1,678.64Z" transform="translate(-267.7 -233.05)"/></svg><strong>VictoriaMetrics</strong></a></div></div><div class="container-fluid">`)
//line lib/promscrape/targetstatus.qtpl:92
if targetsStatuses.err != nil {
//line lib/promscrape/targetstatus.qtpl:93
streamerrorNotification(qw422016, targetsStatuses.err)
//line lib/promscrape/targetstatus.qtpl:94
}
//line lib/promscrape/targetstatus.qtpl:94
qw422016.N().S(`<div class="row"><main class="col-12"><h1>Scrape targets</h1><hr /><div class="row g-3 align-items-center mb-3"><div class="col-auto"><button id="all-btn" type="button" class="btn`)
//line lib/promscrape/targetstatus.qtpl:101
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:93
if !showOnlyUnhealthy {
//line lib/promscrape/targetstatus.qtpl:93
//line lib/promscrape/targetstatus.qtpl:101
if !filter.showOnlyUnhealthy {
//line lib/promscrape/targetstatus.qtpl:101
qw422016.N().S(`btn-secondary`)
//line lib/promscrape/targetstatus.qtpl:93
//line lib/promscrape/targetstatus.qtpl:101
} else {
//line lib/promscrape/targetstatus.qtpl:93
//line lib/promscrape/targetstatus.qtpl:101
qw422016.N().S(`btn-success`)
//line lib/promscrape/targetstatus.qtpl:93
//line lib/promscrape/targetstatus.qtpl:101
}
//line lib/promscrape/targetstatus.qtpl:93
//line lib/promscrape/targetstatus.qtpl:101
qw422016.N().S(`" onclick="location.href='?`)
//line lib/promscrape/targetstatus.qtpl:93
//line lib/promscrape/targetstatus.qtpl:101
streamqueryArgs(qw422016, map[string]string{
"show_only_unhealthy": "false",
"endpoint_search": endpointSearch,
"label_search": labelSearch,
})
//line lib/promscrape/targetstatus.qtpl:97
qw422016.N().S(`'">All</button></div><div class="col-auto"><button type="button" class="btn`)
//line lib/promscrape/targetstatus.qtpl:102
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:102
if showOnlyUnhealthy {
//line lib/promscrape/targetstatus.qtpl:102
qw422016.N().S(`btn-secondary`)
//line lib/promscrape/targetstatus.qtpl:102
} else {
//line lib/promscrape/targetstatus.qtpl:102
qw422016.N().S(`btn-danger`)
//line lib/promscrape/targetstatus.qtpl:102
}
//line lib/promscrape/targetstatus.qtpl:102
qw422016.N().S(`" onclick="location.href='?`)
//line lib/promscrape/targetstatus.qtpl:102
streamqueryArgs(qw422016, map[string]string{
"show_only_unhealthy": "true",
"endpoint_search": endpointSearch,
"label_search": labelSearch,
"endpoint_search": filter.endpointSearch,
"label_search": filter.labelSearch,
"active_tab": filter.activeTab,
})
//line lib/promscrape/targetstatus.qtpl:106
qw422016.N().S(`'">Unhealthy</button></div><div class="col-auto"><button type="button" class="btn btn-primary" onclick="collapse_all()">Collapse all</button></div><div class="col-auto"><button type="button" class="btn btn-secondary" onclick="expand_all()">Expand all</button></div><div class="col-auto">`)
//line lib/promscrape/targetstatus.qtpl:121
if endpointSearch == "" && labelSearch == "" {
//line lib/promscrape/targetstatus.qtpl:121
qw422016.N().S(`<button type="button" class="btn btn-success" onclick="document.getElementById('filters').style.display='block'">Filter targets</button>`)
//line lib/promscrape/targetstatus.qtpl:125
qw422016.N().S(`'">All</button></div><div class="col-auto"><button id="unhealthy-btn" type="button" class="btn`)
//line lib/promscrape/targetstatus.qtpl:111
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:111
if filter.showOnlyUnhealthy {
//line lib/promscrape/targetstatus.qtpl:111
qw422016.N().S(`btn-secondary`)
//line lib/promscrape/targetstatus.qtpl:111
} else {
//line lib/promscrape/targetstatus.qtpl:125
//line lib/promscrape/targetstatus.qtpl:111
qw422016.N().S(`btn-danger`)
//line lib/promscrape/targetstatus.qtpl:111
}
//line lib/promscrape/targetstatus.qtpl:111
qw422016.N().S(`" onclick="location.href='?`)
//line lib/promscrape/targetstatus.qtpl:111
streamqueryArgs(qw422016, map[string]string{
"show_only_unhealthy": "true",
"endpoint_search": filter.endpointSearch,
"label_search": filter.labelSearch,
"active_tab": filter.activeTab,
})
//line lib/promscrape/targetstatus.qtpl:116
qw422016.N().S(`'">Unhealthy</button></div><div class="col-auto"><button type="button" class="btn btn-primary" onclick="collapse_all()">Collapse all</button></div><div class="col-auto"><button type="button" class="btn btn-secondary" onclick="expand_all()">Expand all</button></div><div class="col-auto">`)
//line lib/promscrape/targetstatus.qtpl:131
if filter.endpointSearch == "" && filter.labelSearch == "" {
//line lib/promscrape/targetstatus.qtpl:131
qw422016.N().S(`<button type="button" class="btn btn-success" onclick="document.getElementById('filters').style.display='block'">Filter targets</button>`)
//line lib/promscrape/targetstatus.qtpl:135
} else {
//line lib/promscrape/targetstatus.qtpl:135
qw422016.N().S(`<button type="button" class="btn btn-danger" onclick="location.href='?'">Clear target filters</button>`)
//line lib/promscrape/targetstatus.qtpl:129
//line lib/promscrape/targetstatus.qtpl:139
}
//line lib/promscrape/targetstatus.qtpl:129
//line lib/promscrape/targetstatus.qtpl:139
qw422016.N().S(`</div></div><div id="filters"`)
//line lib/promscrape/targetstatus.qtpl:132
if endpointSearch == "" && labelSearch == "" {
//line lib/promscrape/targetstatus.qtpl:132
//line lib/promscrape/targetstatus.qtpl:142
if filter.endpointSearch == "" && filter.labelSearch == "" {
//line lib/promscrape/targetstatus.qtpl:142
qw422016.N().S(`style="display:none"`)
//line lib/promscrape/targetstatus.qtpl:132
//line lib/promscrape/targetstatus.qtpl:142
}
//line lib/promscrape/targetstatus.qtpl:132
//line lib/promscrape/targetstatus.qtpl:142
qw422016.N().S(`><form class="form-horizontal"><div class="form-group mb-3"><label for="endpoint_search" class="col-sm-10 control-label">Endpoint filter (<a target="_blank" href="https://github.com/google/re2/wiki/Syntax">Regexp</a> is accepted)</label><div class="col-sm-10"><input type="text" id="endpoint_search" name="endpoint_search"placeholder="For example, 127.0.0.1" class="form-control" value="`)
//line lib/promscrape/targetstatus.qtpl:138
qw422016.E().S(endpointSearch)
//line lib/promscrape/targetstatus.qtpl:138
//line lib/promscrape/targetstatus.qtpl:148
qw422016.E().S(filter.endpointSearch)
//line lib/promscrape/targetstatus.qtpl:148
qw422016.N().S(`"/></div></div><div class="form-group mb-3"><label for="label_search" class="col-sm-10 control-label">Labels filter (<a target="_blank" href="https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors">Arbitrary time series selectors</a> are accepted)</label><div class="col-sm-10"><input type="text" id="label_search" name="label_search"placeholder="For example, {instance=~'.+:9100'}" class="form-control" value="`)
//line lib/promscrape/targetstatus.qtpl:145
qw422016.E().S(labelSearch)
//line lib/promscrape/targetstatus.qtpl:145
qw422016.N().S(`"/></div></div><input type="hidden" name="show_only_unhealthy" value="`)
//line lib/promscrape/targetstatus.qtpl:148
qw422016.E().V(showOnlyUnhealthy)
//line lib/promscrape/targetstatus.qtpl:148
qw422016.N().S(`"/><button type="submit" class="btn btn-success mb-3">Submit</button></form></div><hr /><div class="row"><div class="col-12">`)
//line lib/promscrape/targetstatus.qtpl:155
for i, js := range jts {
//line lib/promscrape/targetstatus.qtpl:156
if showOnlyUnhealthy && js.upCount == js.targetsTotal {
//line lib/promscrape/targetstatus.qtpl:156
continue
//line lib/promscrape/targetstatus.qtpl:156
}
//line lib/promscrape/targetstatus.qtpl:156
qw422016.N().S(`<div class="row mb-4"><div class="col-12"><h4><span class="me-2">`)
//line lib/promscrape/targetstatus.qtpl:160
qw422016.E().S(js.job)
//line lib/promscrape/targetstatus.qtpl:160
qw422016.E().S(filter.labelSearch)
//line lib/promscrape/targetstatus.qtpl:155
qw422016.N().S(`"/></div></div><input type="hidden" name="show_only_unhealthy" value="`)
//line lib/promscrape/targetstatus.qtpl:158
qw422016.E().V(filter.showOnlyUnhealthy)
//line lib/promscrape/targetstatus.qtpl:158
qw422016.N().S(`"/><input id="tab_input" type="hidden" name="active_tab" value="`)
//line lib/promscrape/targetstatus.qtpl:159
qw422016.E().S(filter.activeTab)
//line lib/promscrape/targetstatus.qtpl:159
qw422016.N().S(`" /><button type="submit" class="btn btn-success mb-3">Submit</button></form></div><hr /><ul class="nav nav-tabs" id="myTab" role="tablist"><li class="nav-item" role="presentation"><button id="targets-tab" class="nav-link`)
//line lib/promscrape/targetstatus.qtpl:166
if filter.activeTab == "targets-tab" {
//line lib/promscrape/targetstatus.qtpl:166
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:160
qw422016.N().S(`(`)
//line lib/promscrape/targetstatus.qtpl:160
qw422016.N().D(js.upCount)
//line lib/promscrape/targetstatus.qtpl:160
qw422016.N().S(`/`)
//line lib/promscrape/targetstatus.qtpl:160
qw422016.N().D(js.targetsTotal)
//line lib/promscrape/targetstatus.qtpl:160
//line lib/promscrape/targetstatus.qtpl:166
qw422016.N().S(`active`)
//line lib/promscrape/targetstatus.qtpl:166
}
//line lib/promscrape/targetstatus.qtpl:166
qw422016.N().S(`" data-bs-toggle="tab" data-bs-target="#targets" type="button" role="tab" aria-controls="home" aria-selected="true">Targets</button></li><li class="nav-item" role="presentation"><button id="discovery-tab" class="nav-link`)
//line lib/promscrape/targetstatus.qtpl:169
if filter.activeTab == "discovery-tab" {
//line lib/promscrape/targetstatus.qtpl:169
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:160
qw422016.N().S(`up)</span><button type="button" class="btn btn-primary btn-sm me-1"onclick="document.getElementById('table-`)
//line lib/promscrape/targetstatus.qtpl:162
qw422016.N().D(i)
//line lib/promscrape/targetstatus.qtpl:162
qw422016.N().S(`').style.display='none'">collapse</button><button type="button" class="btn btn-secondary btn-sm me-1"onclick="document.getElementById('table-`)
//line lib/promscrape/targetstatus.qtpl:165
qw422016.N().D(i)
//line lib/promscrape/targetstatus.qtpl:165
qw422016.N().S(`').style.display='block'">expand</button></h4><div id="table-`)
//line lib/promscrape/targetstatus.qtpl:168
qw422016.N().D(i)
//line lib/promscrape/targetstatus.qtpl:168
qw422016.N().S(`" class="table-responsive"><table class="table table-striped table-hover table-bordered table-sm"><thead><tr><th scope="col">Endpoint</th><th scope="col">State</th><th scope="col" title="scrape target labels">Labels</th><th scope="col" title="total scrapes">Scrapes</th><th scope="col" title="total scrape errors">Errors</th><th scope="col" title="the time of the last scrape">Last Scrape</th><th scope="col" title="the duration of the last scrape">Duration</th><th scope="col" title="the number of metrics scraped during the last scrape">Samples</th><th scope="col" title="error from the last scrape (if any)">Last error</th></tr></thead><tbody class="list-`)
//line lib/promscrape/targetstatus.qtpl:183
qw422016.N().D(i)
//line lib/promscrape/targetstatus.qtpl:183
qw422016.N().S(`">`)
//line lib/promscrape/targetstatus.qtpl:184
for _, ts := range js.targetsStatus {
//line lib/promscrape/targetstatus.qtpl:186
endpoint := ts.sw.Config.ScrapeURL
targetID := getTargetID(ts.sw)
lastScrapeTime := ts.getDurationFromLastScrape()
//line lib/promscrape/targetstatus.qtpl:190
if showOnlyUnhealthy && ts.up {
//line lib/promscrape/targetstatus.qtpl:190
continue
//line lib/promscrape/targetstatus.qtpl:190
}
//line lib/promscrape/targetstatus.qtpl:190
qw422016.N().S(`<tr`)
//line lib/promscrape/targetstatus.qtpl:191
if !ts.up {
//line lib/promscrape/targetstatus.qtpl:191
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:191
qw422016.N().S(`class="alert alert-danger" role="alert"`)
//line lib/promscrape/targetstatus.qtpl:191
}
//line lib/promscrape/targetstatus.qtpl:191
qw422016.N().S(`><td class="endpoint"><a href="`)
//line lib/promscrape/targetstatus.qtpl:192
qw422016.E().S(endpoint)
//line lib/promscrape/targetstatus.qtpl:192
qw422016.N().S(`" target="_blank">`)
//line lib/promscrape/targetstatus.qtpl:192
qw422016.E().S(endpoint)
//line lib/promscrape/targetstatus.qtpl:192
qw422016.N().S(`</a> (<a href="target_response?id=`)
//line lib/promscrape/targetstatus.qtpl:193
qw422016.E().S(targetID)
//line lib/promscrape/targetstatus.qtpl:193
qw422016.N().S(`" target="_blank"title="click to fetch target response on behalf of the scraper">response</a>)</td><td>`)
//line lib/promscrape/targetstatus.qtpl:197
if ts.up {
//line lib/promscrape/targetstatus.qtpl:197
qw422016.N().S(`UP`)
//line lib/promscrape/targetstatus.qtpl:197
} else {
//line lib/promscrape/targetstatus.qtpl:197
qw422016.N().S(`DOWN`)
//line lib/promscrape/targetstatus.qtpl:197
}
//line lib/promscrape/targetstatus.qtpl:197
qw422016.N().S(`</td><td class="labels"><div title="click to show original labels"onclick="document.getElementById('original_labels_`)
//line lib/promscrape/targetstatus.qtpl:200
qw422016.E().S(targetID)
//line lib/promscrape/targetstatus.qtpl:200
qw422016.N().S(`').style.display='block'">`)
//line lib/promscrape/targetstatus.qtpl:201
streamformatLabel(qw422016, promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels))
//line lib/promscrape/targetstatus.qtpl:201
qw422016.N().S(`</div><div style="display:none" id="original_labels_`)
//line lib/promscrape/targetstatus.qtpl:203
qw422016.E().S(targetID)
//line lib/promscrape/targetstatus.qtpl:203
qw422016.N().S(`">`)
//line lib/promscrape/targetstatus.qtpl:204
streamformatLabel(qw422016, ts.sw.Config.OriginalLabels)
//line lib/promscrape/targetstatus.qtpl:204
qw422016.N().S(`</div></td><td>`)
//line lib/promscrape/targetstatus.qtpl:207
qw422016.N().D(ts.scrapesTotal)
//line lib/promscrape/targetstatus.qtpl:207
qw422016.N().S(`</td><td>`)
//line lib/promscrape/targetstatus.qtpl:208
qw422016.N().D(ts.scrapesFailed)
//line lib/promscrape/targetstatus.qtpl:208
qw422016.N().S(`</td><td>`)
//line lib/promscrape/targetstatus.qtpl:210
if lastScrapeTime < 365*24*time.Hour {
//line lib/promscrape/targetstatus.qtpl:211
qw422016.N().FPrec(lastScrapeTime.Seconds(), 3)
//line lib/promscrape/targetstatus.qtpl:211
qw422016.N().S(`s ago`)
//line lib/promscrape/targetstatus.qtpl:212
} else {
//line lib/promscrape/targetstatus.qtpl:212
qw422016.N().S(`none`)
//line lib/promscrape/targetstatus.qtpl:214
}
//line lib/promscrape/targetstatus.qtpl:214
qw422016.N().S(`<td>`)
//line lib/promscrape/targetstatus.qtpl:215
qw422016.N().D(int(ts.scrapeDuration))
//line lib/promscrape/targetstatus.qtpl:215
qw422016.N().S(`ms</td><td>`)
//line lib/promscrape/targetstatus.qtpl:216
qw422016.N().D(ts.samplesScraped)
//line lib/promscrape/targetstatus.qtpl:216
qw422016.N().S(`</td><td>`)
//line lib/promscrape/targetstatus.qtpl:217
if ts.err != nil {
//line lib/promscrape/targetstatus.qtpl:217
qw422016.E().S(ts.err.Error())
//line lib/promscrape/targetstatus.qtpl:217
}
//line lib/promscrape/targetstatus.qtpl:217
qw422016.N().S(`</td></tr>`)
//line lib/promscrape/targetstatus.qtpl:219
}
//line lib/promscrape/targetstatus.qtpl:219
qw422016.N().S(`</tbody></table></div></div></div>`)
//line lib/promscrape/targetstatus.qtpl:225
//line lib/promscrape/targetstatus.qtpl:169
qw422016.N().S(`active`)
//line lib/promscrape/targetstatus.qtpl:169
}
//line lib/promscrape/targetstatus.qtpl:225
qw422016.N().S(`</div></div>`)
//line lib/promscrape/targetstatus.qtpl:229
for _, jobName := range emptyJobs {
//line lib/promscrape/targetstatus.qtpl:229
qw422016.N().S(`<div><h4><a>`)
//line lib/promscrape/targetstatus.qtpl:232
qw422016.E().S(jobName)
//line lib/promscrape/targetstatus.qtpl:232
qw422016.N().S(`(0/0 up)</a></h4><table class="table table-striped table-hover table-bordered table-sm"><thead><tr><th scope="col">Endpoint</th><th scope="col">State</th><th scope="col">Labels</th><th scope="col">Last Scrape</th><th scope="col">Scrape Duration</th><th scope="col">Samples Scraped</th><th scope="col">Error</th></tr></thead></table></div>`)
//line lib/promscrape/targetstatus.qtpl:248
//line lib/promscrape/targetstatus.qtpl:169
qw422016.N().S(`" data-bs-toggle="tab" data-bs-target="#discovery" type="button" role="tab" aria-controls="profile" aria-selected="false">Service Discovery</button></li></ul><div class="tab-content"><div id="targets" class="tab-pane`)
//line lib/promscrape/targetstatus.qtpl:173
if filter.activeTab == "targets-tab" {
//line lib/promscrape/targetstatus.qtpl:173
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:173
qw422016.N().S(`active`)
//line lib/promscrape/targetstatus.qtpl:173
}
//line lib/promscrape/targetstatus.qtpl:248
qw422016.N().S(`</main></div></div></body></html>`)
//line lib/promscrape/targetstatus.qtpl:254
//line lib/promscrape/targetstatus.qtpl:173
qw422016.N().S(`" role="tabpanel" aria-labelledby="targets-tab">`)
//line lib/promscrape/targetstatus.qtpl:174
StreamTargets(qw422016, targetsStatuses.jobTargetsStatuses, targetsStatuses.emptyJobs, filter.showOnlyUnhealthy)
//line lib/promscrape/targetstatus.qtpl:174
qw422016.N().S(`</div><div id="discovery" class="tab-pane`)
//line lib/promscrape/targetstatus.qtpl:176
if filter.activeTab == "discovery-tab" {
//line lib/promscrape/targetstatus.qtpl:176
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:176
qw422016.N().S(`active`)
//line lib/promscrape/targetstatus.qtpl:176
}
//line lib/promscrape/targetstatus.qtpl:176
qw422016.N().S(`" role="tabpanel" aria-labelledby="profile-tab">`)
//line lib/promscrape/targetstatus.qtpl:177
StreamServiceDiscovery(qw422016, targetsStatuses.jobTargetsStatuses, targetsStatuses.emptyJobs, filter.showOnlyUnhealthy, targetsStatuses.droppedKeyStatuses)
//line lib/promscrape/targetstatus.qtpl:177
qw422016.N().S(`</div></div></main></div></div><script src="static/js/jquery-3.6.0.min.js" type="text/javascript"></script><script src="static/js/bootstrap.bundle.min.js" type="text/javascript"></script><script>(function(){const navBtns = document.querySelectorAll(".nav-link");const tabInput = document.getElementById("tab_input");const unhealthyBtn = document.getElementById("unhealthy-btn");const allBtn = document.getElementById("all-btn");navBtns.forEach((btn) => {if (btn) {btn.addEventListener("click", (e) => {if (window.history.replaceState) {var url = new URL(window.location.href);url.searchParams.set("active_tab", e.target.id);tabInput.value = e.target.id;unhealthyBtn.onclick = () => {url.searchParams.set("show_only_unhealthy", "true");window.location.href=url;};allBtn.onclick = () => {url.searchParams.set("show_only_unhealthy", "false");window.location.href=url;};window.history.replaceState({}, "", url);}});}})})()</script></body></html>`)
//line lib/promscrape/targetstatus.qtpl:215
}
//line lib/promscrape/targetstatus.qtpl:254
func WriteTargetsResponseHTML(qq422016 qtio422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, endpointSearch, labelSearch string, err error) {
//line lib/promscrape/targetstatus.qtpl:254
//line lib/promscrape/targetstatus.qtpl:215
func WriteTargetsResponseHTML(qq422016 qtio422016.Writer, scrapeTargets scrapeTargets) {
//line lib/promscrape/targetstatus.qtpl:215
qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:254
StreamTargetsResponseHTML(qw422016, jts, emptyJobs, showOnlyUnhealthy, endpointSearch, labelSearch, err)
//line lib/promscrape/targetstatus.qtpl:254
//line lib/promscrape/targetstatus.qtpl:215
StreamTargetsResponseHTML(qw422016, scrapeTargets)
//line lib/promscrape/targetstatus.qtpl:215
qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:254
//line lib/promscrape/targetstatus.qtpl:215
}
//line lib/promscrape/targetstatus.qtpl:254
func TargetsResponseHTML(jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, endpointSearch, labelSearch string, err error) string {
//line lib/promscrape/targetstatus.qtpl:254
//line lib/promscrape/targetstatus.qtpl:215
func TargetsResponseHTML(scrapeTargets scrapeTargets) string {
//line lib/promscrape/targetstatus.qtpl:215
qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:254
WriteTargetsResponseHTML(qb422016, jts, emptyJobs, showOnlyUnhealthy, endpointSearch, labelSearch, err)
//line lib/promscrape/targetstatus.qtpl:254
//line lib/promscrape/targetstatus.qtpl:215
WriteTargetsResponseHTML(qb422016, scrapeTargets)
//line lib/promscrape/targetstatus.qtpl:215
qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:254
//line lib/promscrape/targetstatus.qtpl:215
qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:254
//line lib/promscrape/targetstatus.qtpl:215
return qs422016
//line lib/promscrape/targetstatus.qtpl:254
//line lib/promscrape/targetstatus.qtpl:215
}
//line lib/promscrape/targetstatus.qtpl:256
//line lib/promscrape/targetstatus.qtpl:217
func streamqueryArgs(qw422016 *qt422016.Writer, m map[string]string) {
//line lib/promscrape/targetstatus.qtpl:258
//line lib/promscrape/targetstatus.qtpl:219
qa := make(url.Values, len(m))
for k, v := range m {
qa[k] = []string{v}
}
//line lib/promscrape/targetstatus.qtpl:263
//line lib/promscrape/targetstatus.qtpl:224
qw422016.E().S(qa.Encode())
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
}
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
func writequeryArgs(qq422016 qtio422016.Writer, m map[string]string) {
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
streamqueryArgs(qw422016, m)
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
}
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
func queryArgs(m map[string]string) string {
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
writequeryArgs(qb422016, m)
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
return qs422016
//line lib/promscrape/targetstatus.qtpl:264
//line lib/promscrape/targetstatus.qtpl:225
}
//line lib/promscrape/targetstatus.qtpl:266
//line lib/promscrape/targetstatus.qtpl:227
func streamformatLabel(qw422016 *qt422016.Writer, labels []prompbmarshal.Label) {
//line lib/promscrape/targetstatus.qtpl:266
//line lib/promscrape/targetstatus.qtpl:227
qw422016.N().S(`{`)
//line lib/promscrape/targetstatus.qtpl:268
//line lib/promscrape/targetstatus.qtpl:229
for i, label := range labels {
//line lib/promscrape/targetstatus.qtpl:269
//line lib/promscrape/targetstatus.qtpl:230
qw422016.E().S(label.Name)
//line lib/promscrape/targetstatus.qtpl:269
//line lib/promscrape/targetstatus.qtpl:230
qw422016.N().S(`=`)
//line lib/promscrape/targetstatus.qtpl:269
//line lib/promscrape/targetstatus.qtpl:230
qw422016.E().Q(label.Value)
//line lib/promscrape/targetstatus.qtpl:270
//line lib/promscrape/targetstatus.qtpl:231
if i+1 < len(labels) {
//line lib/promscrape/targetstatus.qtpl:270
//line lib/promscrape/targetstatus.qtpl:231
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:270
//line lib/promscrape/targetstatus.qtpl:231
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:270
//line lib/promscrape/targetstatus.qtpl:231
}
//line lib/promscrape/targetstatus.qtpl:271
//line lib/promscrape/targetstatus.qtpl:232
}
//line lib/promscrape/targetstatus.qtpl:271
//line lib/promscrape/targetstatus.qtpl:232
qw422016.N().S(`}`)
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
}
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
func writeformatLabel(qq422016 qtio422016.Writer, labels []prompbmarshal.Label) {
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
streamformatLabel(qw422016, labels)
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
}
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
func formatLabel(labels []prompbmarshal.Label) string {
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
writeformatLabel(qb422016, labels)
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
return qs422016
//line lib/promscrape/targetstatus.qtpl:273
//line lib/promscrape/targetstatus.qtpl:234
}
//line lib/promscrape/targetstatus.qtpl:275
//line lib/promscrape/targetstatus.qtpl:236
func streamerrorNotification(qw422016 *qt422016.Writer, err error) {
//line lib/promscrape/targetstatus.qtpl:275
//line lib/promscrape/targetstatus.qtpl:236
qw422016.N().S(`<div class="alert alert-danger d-flex align-items-center" role="alert"><svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Danger:"><use xlink:href="#exclamation-triangle-fill"/></svg><div>`)
//line lib/promscrape/targetstatus.qtpl:280
//line lib/promscrape/targetstatus.qtpl:241
qw422016.E().S(err.Error())
//line lib/promscrape/targetstatus.qtpl:280
//line lib/promscrape/targetstatus.qtpl:241
qw422016.N().S(`</div></div>`)
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
}
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
func writeerrorNotification(qq422016 qtio422016.Writer, err error) {
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
streamerrorNotification(qw422016, err)
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
}
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
func errorNotification(err error) string {
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
writeerrorNotification(qb422016, err)
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
return qs422016
//line lib/promscrape/targetstatus.qtpl:283
//line lib/promscrape/targetstatus.qtpl:244
}