lib/promscrape: Enable filters for endpoint and labels (#2466)

* lib/promscrape: Enable filters for endpoint and labels

* lib/promscrape: cleanup

* lib/promscrape: update template

* lib/promscrape: move logic filter logic to backend

* lib/promscrape: updated placeholder

* lib/promscrape: updated placeholder

* lib/promscrape: use two different fields for filters, updated form, added error on parsing queries

* lib/promscrape: rename functions

* lib/promscrape: removed unused values

* wip

* wip

* wip

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
This commit is contained in:
Dmytro Kozlov 2022-04-19 18:26:21 +03:00 committed by Aliaksandr Valialkin
parent 7a622a71ea
commit 17552dba8b
No known key found for this signature in database
GPG key ID: A72BEC6CD3D0DED1
6 changed files with 795 additions and 424 deletions

View file

@ -15,6 +15,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
## tip ## tip
* FEATUREL [vmagent](https://docs.victoriametrics.com/vmagent.html): allow filtering targets by target url and by target labels with [time series selector](https://prometheus.io/docs/prometheus/latest/querying/basics/#time-series-selectors) on `http://vmagent:8429/targets` page. This may be useful when `vmagent` scrapes big number of targets. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1796).
* FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): reduce `-promscrape.config` reload duration when the config contains big number of jobs (aka [scrape_config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) sections) and only a few of them are changed. Previously all the jobs were restarted. Now only the jobs with changed configs are restarted. This should reduce the probability of data miss because of slow config reload. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2270). * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): reduce `-promscrape.config` reload duration when the config contains big number of jobs (aka [scrape_config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config) sections) and only a few of them are changed. Previously all the jobs were restarted. Now only the jobs with changed configs are restarted. This should reduce the probability of data miss because of slow config reload. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2270).
* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): add support for DNS-based discovery for notifiers in the same way as Prometheus does. See [these docs](https://docs.victoriametrics.com/vmalert.html#notifier-configuration-file) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2460). * FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): add support for DNS-based discovery for notifiers in the same way as Prometheus does. See [these docs](https://docs.victoriametrics.com/vmalert.html#notifier-configuration-file) and [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2460).
* FEATURE: allow specifying TLS cipher suites for incoming https requests via `-tlsCipherSuites` command-line flag. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2404). * FEATURE: allow specifying TLS cipher suites for incoming https requests via `-tlsCipherSuites` command-line flag. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2404).

View file

@ -17,26 +17,34 @@ type IfExpression struct {
lfs []*labelFilter lfs []*labelFilter
} }
// Parse parses `if` expression from s and stores it to ie.
func (ie *IfExpression) Parse(s string) error {
expr, err := metricsql.Parse(s)
if err != nil {
return err
}
me, ok := expr.(*metricsql.MetricExpr)
if !ok {
return fmt.Errorf("expecting series selector; got %q", expr.AppendString(nil))
}
lfs, err := metricExprToLabelFilters(me)
if err != nil {
return fmt.Errorf("cannot parse series selector: %w", err)
}
ie.s = s
ie.lfs = lfs
return nil
}
// UnmarshalYAML unmarshals ie from YAML passed to f. // UnmarshalYAML unmarshals ie from YAML passed to f.
func (ie *IfExpression) UnmarshalYAML(f func(interface{}) error) error { func (ie *IfExpression) UnmarshalYAML(f func(interface{}) error) error {
var s string var s string
if err := f(&s); err != nil { if err := f(&s); err != nil {
return fmt.Errorf("cannot unmarshal `if` option: %w", err) return fmt.Errorf("cannot unmarshal `if` option: %w", err)
} }
expr, err := metricsql.Parse(s) if err := ie.Parse(s); err != nil {
if err != nil {
return fmt.Errorf("cannot parse `if` series selector: %w", err) return fmt.Errorf("cannot parse `if` series selector: %w", err)
} }
me, ok := expr.(*metricsql.MetricExpr)
if !ok {
return fmt.Errorf("expecting `if` series selector; got %q", expr.AppendString(nil))
}
lfs, err := metricExprToLabelFilters(me)
if err != nil {
return fmt.Errorf("cannot parse `if` filters: %w", err)
}
ie.s = s
ie.lfs = lfs
return nil return nil
} }

View file

@ -10,6 +10,32 @@ import (
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
func TestIfExpressionParseFailure(t *testing.T) {
f := func(s string) {
t.Helper()
var ie IfExpression
if err := ie.Parse(s); err == nil {
t.Fatalf("expecting non-nil error when parsing %q", s)
}
}
f(`{`)
f(`{foo`)
f(`foo{`)
}
func TestIfExpressionParseSuccess(t *testing.T) {
f := func(s string) {
t.Helper()
var ie IfExpression
if err := ie.Parse(s); err != nil {
t.Fatalf("unexpected error: %s", err)
}
}
f(`foo`)
f(`{foo="bar"}`)
f(`foo{bar=~"baz", x!="y"}`)
}
func TestIfExpressionUnmarshalFailure(t *testing.T) { func TestIfExpressionUnmarshalFailure(t *testing.T) {
f := func(s string) { f := func(s string) {
t.Helper() t.Helper()

View file

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"regexp"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -45,12 +46,14 @@ func WriteTargetResponse(w http.ResponseWriter, r *http.Request) error {
func WriteHumanReadableTargetsStatus(w http.ResponseWriter, r *http.Request) { func WriteHumanReadableTargetsStatus(w http.ResponseWriter, r *http.Request) {
showOriginalLabels, _ := strconv.ParseBool(r.FormValue("show_original_labels")) showOriginalLabels, _ := strconv.ParseBool(r.FormValue("show_original_labels"))
showOnlyUnhealthy, _ := strconv.ParseBool(r.FormValue("show_only_unhealthy")) showOnlyUnhealthy, _ := strconv.ParseBool(r.FormValue("show_only_unhealthy"))
endpointSearch := strings.TrimSpace(r.FormValue("endpoint_search"))
labelSearch := strings.TrimSpace(r.FormValue("label_search"))
if accept := r.Header.Get("Accept"); strings.Contains(accept, "text/html") { if accept := r.Header.Get("Accept"); strings.Contains(accept, "text/html") {
w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Content-Type", "text/html; charset=utf-8")
tsmGlobal.WriteTargetsHTML(w, showOnlyUnhealthy) tsmGlobal.WriteTargetsHTML(w, showOnlyUnhealthy, endpointSearch, labelSearch)
} else { } else {
w.Header().Set("Content-Type", "text/plain; charset=utf-8") w.Header().Set("Content-Type", "text/plain; charset=utf-8")
tsmGlobal.WriteTargetsPlain(w, showOriginalLabels) tsmGlobal.WriteTargetsPlain(w, showOriginalLabels, showOnlyUnhealthy, endpointSearch, labelSearch)
} }
} }
@ -318,7 +321,7 @@ type jobTargetsStatuses struct {
targetsStatus []targetStatus targetsStatus []targetStatus
} }
func (tsm *targetStatusMap) getTargetsStatusByJob() ([]jobTargetsStatuses, []string) { func (tsm *targetStatusMap) getTargetsStatusByJob(endpointSearch, labelSearch string) ([]jobTargetsStatuses, []string, error) {
byJob := make(map[string][]targetStatus) byJob := make(map[string][]targetStatus)
tsm.mu.Lock() tsm.mu.Lock()
for _, st := range tsm.m { for _, st := range tsm.m {
@ -352,7 +355,78 @@ func (tsm *targetStatusMap) getTargetsStatusByJob() ([]jobTargetsStatuses, []str
return jts[i].job < jts[j].job return jts[i].job < jts[j].job
}) })
emptyJobs := getEmptyJobs(jts, jobNames) emptyJobs := getEmptyJobs(jts, jobNames)
return jts, emptyJobs var err error
jts, err = filterTargets(jts, endpointSearch, labelSearch)
if len(endpointSearch) > 0 || len(labelSearch) > 0 {
// Do not show empty jobs if target filters are set.
emptyJobs = nil
}
return jts, emptyJobs, err
}
func filterTargetsByEndpoint(jts []jobTargetsStatuses, searchQuery string) ([]jobTargetsStatuses, error) {
if searchQuery == "" {
return jts, nil
}
finder, err := regexp.Compile(searchQuery)
if err != nil {
return nil, fmt.Errorf("cannot parse %s: %w", searchQuery, err)
}
var jtsFiltered []jobTargetsStatuses
for _, job := range jts {
var tss []targetStatus
for _, ts := range job.targetsStatus {
if finder.MatchString(ts.sw.Config.ScrapeURL) {
tss = append(tss, ts)
}
}
if len(tss) == 0 {
// Skip jobs with zero targets after filtering, so users could see only the requested targets
continue
}
job.targetsStatus = tss
jtsFiltered = append(jtsFiltered, job)
}
return jtsFiltered, nil
}
func filterTargetsByLabels(jts []jobTargetsStatuses, searchQuery string) ([]jobTargetsStatuses, error) {
if searchQuery == "" {
return jts, nil
}
var ie promrelabel.IfExpression
if err := ie.Parse(searchQuery); err != nil {
return nil, fmt.Errorf("cannot parse %s: %w", searchQuery, err)
}
var jtsFiltered []jobTargetsStatuses
for _, job := range jts {
var tss []targetStatus
for _, ts := range job.targetsStatus {
if ie.Match(ts.sw.Config.Labels) {
tss = append(tss, ts)
}
}
if len(tss) == 0 {
// Skip jobs with zero targets after filtering, so users could see only the requested targets
continue
}
job.targetsStatus = tss
jtsFiltered = append(jtsFiltered, job)
}
return jtsFiltered, nil
}
func filterTargets(jts []jobTargetsStatuses, endpointQuery, labelQuery string) ([]jobTargetsStatuses, error) {
var err error
jts, err = filterTargetsByEndpoint(jts, endpointQuery)
if err != nil {
return nil, err
}
jts, err = filterTargetsByLabels(jts, labelQuery)
if err != nil {
return nil, err
}
return jts, nil
} }
func getEmptyJobs(jts []jobTargetsStatuses, jobNames []string) []string { func getEmptyJobs(jts []jobTargetsStatuses, jobNames []string) []string {
@ -373,14 +447,14 @@ func getEmptyJobs(jts []jobTargetsStatuses, jobNames []string) []string {
// WriteTargetsHTML writes targets status grouped by job into writer w in html table, // WriteTargetsHTML writes targets status grouped by job into writer w in html table,
// accepts filter to show only unhealthy targets. // accepts filter to show only unhealthy targets.
func (tsm *targetStatusMap) WriteTargetsHTML(w io.Writer, showOnlyUnhealthy bool) { func (tsm *targetStatusMap) WriteTargetsHTML(w io.Writer, showOnlyUnhealthy bool, endpointSearch, labelSearch string) {
jss, emptyJobs := tsm.getTargetsStatusByJob() jss, emptyJobs, err := tsm.getTargetsStatusByJob(endpointSearch, labelSearch)
WriteTargetsResponseHTML(w, jss, emptyJobs, showOnlyUnhealthy) WriteTargetsResponseHTML(w, jss, emptyJobs, showOnlyUnhealthy, endpointSearch, labelSearch, err)
} }
// WriteTargetsPlain writes targets grouped by job into writer w in plain text, // WriteTargetsPlain writes targets grouped by job into writer w in plain text,
// accept filter to show original labels. // accept filter to show original labels.
func (tsm *targetStatusMap) WriteTargetsPlain(w io.Writer, showOriginalLabels bool) { func (tsm *targetStatusMap) WriteTargetsPlain(w io.Writer, showOriginalLabels, showOnlyUnhealthy bool, endpointSearch, labelSearch string) {
jss, emptyJobs := tsm.getTargetsStatusByJob() jss, emptyJobs, err := tsm.getTargetsStatusByJob(endpointSearch, labelSearch)
WriteTargetsResponsePlain(w, jss, emptyJobs, showOriginalLabels) WriteTargetsResponsePlain(w, jss, emptyJobs, showOriginalLabels, showOnlyUnhealthy, err)
} }

View file

@ -1,4 +1,5 @@
{% import ( {% import (
"net/url"
"time" "time"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal" "github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel" "github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
@ -6,25 +7,32 @@
{% stripspace %} {% stripspace %}
{% func TargetsResponsePlain(jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels bool) %} {% func TargetsResponsePlain(jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels, showOnlyUnhealthy bool, err error) %}
{% if err != nil %}
{%s= err.Error() %}
{% return %}
{% endif %}
{% for _, js := range jts %} {% for _, js := range jts %}
job={%q= js.job %} ({%d js.upCount %}/{%d js.targetsTotal %}{% space %}up) {% if showOnlyUnhealthy && js.upCount == js.targetsTotal %}{% continue %}{% endif %}
{% newline %} job={%q= js.job %} ({%d js.upCount %}/{%d js.targetsTotal %}{% space %}up)
{% for _, ts := range js.targetsStatus %} {% newline %}
{%s= "\t" %} {% for _, ts := range js.targetsStatus %}
state={% if ts.up %}up{% else %}down{% endif %},{% space %} {% if showOnlyUnhealthy && ts.up %}{% continue %}{% endif %}
endpoint={%s= ts.sw.Config.ScrapeURL %},{% space %} {%s= "\t" %}
labels={%s= promLabelsString(promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels)) %},{% space %} state={% if ts.up %}up{% else %}down{% endif %},{% space %}
{% if showOriginLabels %}originalLabels={%s= promLabelsString(ts.sw.Config.OriginalLabels) %},{% space %}{% endif %} endpoint={%s= ts.sw.Config.ScrapeURL %},{% space %}
scrapes_total={%d ts.scrapesTotal %},{% space %} labels={%s= promLabelsString(promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels)) %},{% space %}
scrapes_failed={%d ts.scrapesFailed %},{% space %} {% if showOriginLabels %}originalLabels={%s= promLabelsString(ts.sw.Config.OriginalLabels) %},{% space %}{% endif %}
last_scrape={%f.3 ts.getDurationFromLastScrape().Seconds() %}s ago,{% space %} scrapes_total={%d ts.scrapesTotal %},{% space %}
scrape_duration={%d int(ts.scrapeDuration) %}ms,{% space %} scrapes_failed={%d ts.scrapesFailed %},{% space %}
samples_scraped={%d ts.samplesScraped %},{% space %} last_scrape={%f.3 ts.getDurationFromLastScrape().Seconds() %}s ago,{% space %}
error={% if ts.err != nil %}{%s= ts.err.Error() %}{% endif %} scrape_duration={%d int(ts.scrapeDuration) %}ms,{% space %}
{% newline %} samples_scraped={%d ts.samplesScraped %},{% space %}
{% endfor %} error={% if ts.err != nil %}{%s= ts.err.Error() %}{% endif %}
{% newline %}
{% endfor %}
{% endfor %} {% endfor %}
{% for _, jobName := range emptyJobs %} {% for _, jobName := range emptyJobs %}
@ -34,7 +42,7 @@ job={%q= jobName %} (0/0 up)
{% endfunc %} {% endfunc %}
{% func TargetsResponseHTML(jts []jobTargetsStatuses, emptyJobs []string, onlyUnhealthy bool) %} {% func TargetsResponseHTML(jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, endpointSearch, labelSearch string, err error) %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@ -63,109 +71,194 @@ function expand_all() {
} }
</script> </script>
</head> </head>
<body class="m-3"> <body class="py-3">
<h1>Scrape targets</h1> <div class="container-fluid">
<div style="padding: 3px"> {% if err != nil %}
<button type="button" class="btn{% space %}{% if !onlyUnhealthy %}btn-primary{% else %}btn-secondary{% endif %}" onclick="location.href='targets'"> {%= errorNotification(err) %}
All {% endif %}
</button> <div class="row">
<button type="button" class="btn{% space %}{% if onlyUnhealthy %}btn-primary{% else %}btn-secondary{% endif %}" onclick="location.href='targets?show_only_unhealthy=true'"> <main class="col-12">
Unhealthy <h1>Scrape targets</h1>
</button> <hr />
<button type="button" class="btn btn-primary" onclick="collapse_all()"> <div class="row g-3 align-items-center mb-3">
Collapse all <div class="col-auto">
</button> <button type="button" class="btn{% space %}{% if !showOnlyUnhealthy %}btn-primary{% else %}btn-secondary{% endif %}" onclick="location.href='?{%= queryArgs(map[string]string{
<button type="button" class="btn btn-secondary" onclick="expand_all()"> "show_only_unhealthy": "false",
Expand all "endpoint_search": endpointSearch,
</button> "label_search": labelSearch,
</div> }) %}'">
{% for i, js := range jts %} All
{% if onlyUnhealthy && js.upCount == js.targetsTotal %}{% continue %}{% endif %} </button>
<div> </div>
<h4> <div class="col-auto">
{%s js.job %}{% space %}({%d js.upCount %}/{%d js.targetsTotal %}{% space %}up) <button type="button" class="btn{% space %}{% if showOnlyUnhealthy %}btn-primary{% else %}btn-secondary{% endif %}" onclick="location.href='?{%= queryArgs(map[string]string{
<button type="button" class="btn btn-primary" onclick="document.getElementById('table-{%d i %}').style.display='none'">collapse</button> "show_only_unhealthy": "true",
<button type="button" class="btn btn-secondary" onclick="document.getElementById('table-{%d i %}').style.display='block'">expand</button> "endpoint_search": endpointSearch,
</h4> "label_search": labelSearch,
<div id="table-{%d i %}"> }) %}'">
<table class="table table-striped table-hover table-bordered table-sm"> Unhealthy
<thead> </button>
<tr> </div>
<th scope="col">Endpoint</th> <div class="col-auto">
<th scope="col">State</th> <button type="button" class="btn btn-primary" onclick="collapse_all()">
<th scope="col" title="scrape target labels">Labels</th> Collapse all
<th scope="col" title="total scrapes">Scrapes</th> </button>
<th scope="col" title="total scrape errors">Errors</th> </div>
<th scope="col" title="the time of the last scrape">Last Scrape</th> <div class="col-auto">
<th scope="col" title="the duration of the last scrape">Duration</th> <button type="button" class="btn btn-secondary" onclick="expand_all()">
<th scope="col" title="the number of metrics scraped during the last scrape">Samples</th> Expand all
<th scope="col" title="error from the last scrape (if any)">Last error</th> </button>
</tr> </div>
</thead> <div class="col-auto">
<tbody> {% if endpointSearch == "" && labelSearch == "" %}
{% for _, ts := range js.targetsStatus %} <button type="button" class="btn btn-primary" onclick="document.getElementById('filters').style.display='block'">
{% code Filter targets
endpoint := ts.sw.Config.ScrapeURL </button>
targetID := getTargetID(ts.sw) {% else %}
lastScrapeTime := ts.getDurationFromLastScrape() <button type="button" class="btn btn-primary" onclick="location.href='?'">
%} Clear target filters
{% if onlyUnhealthy && ts.up %}{% continue %}{% endif %} </button>
<tr {% if !ts.up %}{%space%}class="alert alert-danger" role="alert"{% endif %}> {% endif %}
<td><a href="{%s endpoint %}" target="_blank">{%s endpoint %}</a> ( </div>
<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>
<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>
<div style="display:none" id="original_labels_{%s targetID %}"> <div id="filters" {% if endpointSearch == "" && labelSearch == "" %}style="display:none"{% endif %}>
{%= formatLabel(ts.sw.Config.OriginalLabels) %} <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 %}"/>
</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 %}"/>
</div>
</div>
<input type="hidden" name="show_only_unhealthy" value="{%v showOnlyUnhealthy %}"/>
<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>
{%s js.job %}{% space %}({%d js.upCount %}/{%d js.targetsTotal %}{% space %}up)
</h4>
<div class="row mb-2">
<div class="col-12">
<button type="button" class="btn btn-primary me-1"
onclick="document.getElementById('table-{%d i %}').style.display='none'">collapse
</button>
<button type="button" class="btn btn-secondary me-1"
onclick="document.getElementById('table-{%d i %}').style.display='block'">expand
</button>
</div>
</div>
<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 %}
</div>
</div> </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>
{% endfor %}
{% for _, jobName := range emptyJobs %} {% for _, jobName := range emptyJobs %}
<div> <div>
<h4> <h4>
<a>{%s jobName %} (0/0 up)</a> <a>{%s jobName %} (0/0 up)</a>
</h4> </h4>
<table class="table table-striped table-hover table-bordered table-sm"> <table class="table table-striped table-hover table-bordered table-sm">
<thead> <thead>
<tr> <tr>
<th scope="col">Endpoint</th> <th scope="col">Endpoint</th>
<th scope="col">State</th> <th scope="col">State</th>
<th scope="col">Labels</th> <th scope="col">Labels</th>
<th scope="col">Last Scrape</th> <th scope="col">Last Scrape</th>
<th scope="col">Scrape Duration</th> <th scope="col">Scrape Duration</th>
<th scope="col">Samples Scraped</th> <th scope="col">Samples Scraped</th>
<th scope="col">Error</th> <th scope="col">Error</th>
</tr> </tr>
</thead> </thead>
</table> </table>
</div>
{% endfor %}
</main>
</div>
</div> </div>
{% endfor %}
</body> </body>
</html> </html>
{% endfunc %} {% endfunc %}
{% func queryArgs(m map[string]string) %}
{% code
qa := make(url.Values, len(m))
for k, v := range m {
qa[k] = []string{v}
}
%}
{%s qa.Encode() %}
{% endfunc %}
{% func formatLabel(labels []prompbmarshal.Label) %} {% func formatLabel(labels []prompbmarshal.Label) %}
{ {
{% for i, label := range labels %} {% for i, label := range labels %}
@ -175,4 +268,14 @@ function expand_all() {
} }
{% endfunc %} {% endfunc %}
{% func errorNotification(err error) %}
<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>
{%s err.Error() %}
</div>
</div>
{% endfunc %}
{% endstripspace %} {% endstripspace %}

View file

@ -8,467 +8,626 @@ package promscrape
import ( import (
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal" "github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel" "github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
"net/url"
"time" "time"
) )
//line lib/promscrape/targetstatus.qtpl:9 //line lib/promscrape/targetstatus.qtpl:10
import ( import (
qtio422016 "io" qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate" qt422016 "github.com/valyala/quicktemplate"
) )
//line lib/promscrape/targetstatus.qtpl:9 //line lib/promscrape/targetstatus.qtpl:10
var ( var (
_ = qtio422016.Copy _ = qtio422016.Copy
_ = qt422016.AcquireByteBuffer _ = qt422016.AcquireByteBuffer
) )
//line lib/promscrape/targetstatus.qtpl:9 //line lib/promscrape/targetstatus.qtpl:10
func StreamTargetsResponsePlain(qw422016 *qt422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels bool) { func StreamTargetsResponsePlain(qw422016 *qt422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels, showOnlyUnhealthy bool, err error) {
//line lib/promscrape/targetstatus.qtpl:11
for _, js := range jts {
//line lib/promscrape/targetstatus.qtpl:11
qw422016.N().S(`job=`)
//line lib/promscrape/targetstatus.qtpl:12 //line lib/promscrape/targetstatus.qtpl:12
qw422016.N().Q(js.job) if err != nil {
//line lib/promscrape/targetstatus.qtpl:12
qw422016.N().S(`(`)
//line lib/promscrape/targetstatus.qtpl:12
qw422016.N().D(js.upCount)
//line lib/promscrape/targetstatus.qtpl:12
qw422016.N().S(`/`)
//line lib/promscrape/targetstatus.qtpl:12
qw422016.N().D(js.targetsTotal)
//line lib/promscrape/targetstatus.qtpl:12
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:12
qw422016.N().S(`up)`)
//line lib/promscrape/targetstatus.qtpl:13 //line lib/promscrape/targetstatus.qtpl:13
qw422016.N().S(err.Error())
//line lib/promscrape/targetstatus.qtpl:14
return
//line lib/promscrape/targetstatus.qtpl:15
}
//line lib/promscrape/targetstatus.qtpl:17
for _, js := range jts {
//line lib/promscrape/targetstatus.qtpl:18
if showOnlyUnhealthy && js.upCount == js.targetsTotal {
//line lib/promscrape/targetstatus.qtpl:18
continue
//line lib/promscrape/targetstatus.qtpl:18
}
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().S(`job=`)
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().Q(js.job)
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(`(`)
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().D(js.upCount)
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(`/`)
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().D(js.targetsTotal)
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(`up)`)
//line lib/promscrape/targetstatus.qtpl:20
qw422016.N().S(` qw422016.N().S(`
`) `)
//line lib/promscrape/targetstatus.qtpl:14 //line lib/promscrape/targetstatus.qtpl:21
for _, ts := range js.targetsStatus { for _, ts := range js.targetsStatus {
//line lib/promscrape/targetstatus.qtpl:15 //line lib/promscrape/targetstatus.qtpl:22
if showOnlyUnhealthy && ts.up {
//line lib/promscrape/targetstatus.qtpl:22
continue
//line lib/promscrape/targetstatus.qtpl:22
}
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S("\t") qw422016.N().S("\t")
//line lib/promscrape/targetstatus.qtpl:15 //line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S(`state=`) qw422016.N().S(`state=`)
//line lib/promscrape/targetstatus.qtpl:16 //line lib/promscrape/targetstatus.qtpl:24
if ts.up { if ts.up {
//line lib/promscrape/targetstatus.qtpl:16 //line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(`up`) qw422016.N().S(`up`)
//line lib/promscrape/targetstatus.qtpl:16 //line lib/promscrape/targetstatus.qtpl:24
} else { } else {
//line lib/promscrape/targetstatus.qtpl:16 //line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(`down`) qw422016.N().S(`down`)
//line lib/promscrape/targetstatus.qtpl:16 //line lib/promscrape/targetstatus.qtpl:24
} }
//line lib/promscrape/targetstatus.qtpl:16 //line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(`,`) qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:16 //line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(` `) qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:16 //line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(`endpoint=`) qw422016.N().S(`endpoint=`)
//line lib/promscrape/targetstatus.qtpl:17 //line lib/promscrape/targetstatus.qtpl:25
qw422016.N().S(ts.sw.Config.ScrapeURL) qw422016.N().S(ts.sw.Config.ScrapeURL)
//line lib/promscrape/targetstatus.qtpl:17 //line lib/promscrape/targetstatus.qtpl:25
qw422016.N().S(`,`) qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:17 //line lib/promscrape/targetstatus.qtpl:25
qw422016.N().S(` `) qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:17 //line lib/promscrape/targetstatus.qtpl:25
qw422016.N().S(`labels=`) qw422016.N().S(`labels=`)
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().S(promLabelsString(promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels)))
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:18
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:19
if showOriginLabels {
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(`originalLabels=`)
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(promLabelsString(ts.sw.Config.OriginalLabels))
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:19
}
//line lib/promscrape/targetstatus.qtpl:19
qw422016.N().S(`scrapes_total=`)
//line lib/promscrape/targetstatus.qtpl:20
qw422016.N().D(ts.scrapesTotal)
//line lib/promscrape/targetstatus.qtpl:20
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:20
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:20
qw422016.N().S(`scrapes_failed=`)
//line lib/promscrape/targetstatus.qtpl:21
qw422016.N().D(ts.scrapesFailed)
//line lib/promscrape/targetstatus.qtpl:21
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:21
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:21
qw422016.N().S(`last_scrape=`)
//line lib/promscrape/targetstatus.qtpl:22
qw422016.N().FPrec(ts.getDurationFromLastScrape().Seconds(), 3)
//line lib/promscrape/targetstatus.qtpl:22
qw422016.N().S(`s ago,`)
//line lib/promscrape/targetstatus.qtpl:22
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:22
qw422016.N().S(`scrape_duration=`)
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().D(int(ts.scrapeDuration))
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S(`ms,`)
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:23
qw422016.N().S(`samples_scraped=`)
//line lib/promscrape/targetstatus.qtpl:24
qw422016.N().D(ts.samplesScraped)
//line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:24
qw422016.N().S(`error=`)
//line lib/promscrape/targetstatus.qtpl:25
if ts.err != nil {
//line lib/promscrape/targetstatus.qtpl:25
qw422016.N().S(ts.err.Error())
//line lib/promscrape/targetstatus.qtpl:25
}
//line lib/promscrape/targetstatus.qtpl:26 //line lib/promscrape/targetstatus.qtpl:26
qw422016.N().S(promLabelsString(promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels)))
//line lib/promscrape/targetstatus.qtpl:26
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:26
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:27
if showOriginLabels {
//line lib/promscrape/targetstatus.qtpl:27
qw422016.N().S(`originalLabels=`)
//line lib/promscrape/targetstatus.qtpl:27
qw422016.N().S(promLabelsString(ts.sw.Config.OriginalLabels))
//line lib/promscrape/targetstatus.qtpl:27
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:27
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:27
}
//line lib/promscrape/targetstatus.qtpl:27
qw422016.N().S(`scrapes_total=`)
//line lib/promscrape/targetstatus.qtpl:28
qw422016.N().D(ts.scrapesTotal)
//line lib/promscrape/targetstatus.qtpl:28
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:28
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:28
qw422016.N().S(`scrapes_failed=`)
//line lib/promscrape/targetstatus.qtpl:29
qw422016.N().D(ts.scrapesFailed)
//line lib/promscrape/targetstatus.qtpl:29
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:29
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:29
qw422016.N().S(`last_scrape=`)
//line lib/promscrape/targetstatus.qtpl:30
qw422016.N().FPrec(ts.getDurationFromLastScrape().Seconds(), 3)
//line lib/promscrape/targetstatus.qtpl:30
qw422016.N().S(`s ago,`)
//line lib/promscrape/targetstatus.qtpl:30
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:30
qw422016.N().S(`scrape_duration=`)
//line lib/promscrape/targetstatus.qtpl:31
qw422016.N().D(int(ts.scrapeDuration))
//line lib/promscrape/targetstatus.qtpl:31
qw422016.N().S(`ms,`)
//line lib/promscrape/targetstatus.qtpl:31
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:31
qw422016.N().S(`samples_scraped=`)
//line lib/promscrape/targetstatus.qtpl:32
qw422016.N().D(ts.samplesScraped)
//line lib/promscrape/targetstatus.qtpl:32
qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:32
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:32
qw422016.N().S(`error=`)
//line lib/promscrape/targetstatus.qtpl:33
if ts.err != nil {
//line lib/promscrape/targetstatus.qtpl:33
qw422016.N().S(ts.err.Error())
//line lib/promscrape/targetstatus.qtpl:33
}
//line lib/promscrape/targetstatus.qtpl:34
qw422016.N().S(` qw422016.N().S(`
`) `)
//line lib/promscrape/targetstatus.qtpl:27 //line lib/promscrape/targetstatus.qtpl:35
} }
//line lib/promscrape/targetstatus.qtpl:28 //line lib/promscrape/targetstatus.qtpl:36
} }
//line lib/promscrape/targetstatus.qtpl:30 //line lib/promscrape/targetstatus.qtpl:38
for _, jobName := range emptyJobs { for _, jobName := range emptyJobs {
//line lib/promscrape/targetstatus.qtpl:30 //line lib/promscrape/targetstatus.qtpl:38
qw422016.N().S(`job=`) qw422016.N().S(`job=`)
//line lib/promscrape/targetstatus.qtpl:31 //line lib/promscrape/targetstatus.qtpl:39
qw422016.N().Q(jobName) qw422016.N().Q(jobName)
//line lib/promscrape/targetstatus.qtpl:31 //line lib/promscrape/targetstatus.qtpl:39
qw422016.N().S(`(0/0 up)`) qw422016.N().S(`(0/0 up)`)
//line lib/promscrape/targetstatus.qtpl:32 //line lib/promscrape/targetstatus.qtpl:40
qw422016.N().S(` qw422016.N().S(`
`) `)
//line lib/promscrape/targetstatus.qtpl:33 //line lib/promscrape/targetstatus.qtpl:41
} }
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
} }
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
func WriteTargetsResponsePlain(qq422016 qtio422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels bool) { func WriteTargetsResponsePlain(qq422016 qtio422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels, showOnlyUnhealthy bool, err error) {
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
StreamTargetsResponsePlain(qw422016, jts, emptyJobs, showOriginLabels) StreamTargetsResponsePlain(qw422016, jts, emptyJobs, showOriginLabels, showOnlyUnhealthy, err)
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
} }
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
func TargetsResponsePlain(jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels bool) string { func TargetsResponsePlain(jts []jobTargetsStatuses, emptyJobs []string, showOriginLabels, showOnlyUnhealthy bool, err error) string {
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
WriteTargetsResponsePlain(qb422016, jts, emptyJobs, showOriginLabels) WriteTargetsResponsePlain(qb422016, jts, emptyJobs, showOriginLabels, showOnlyUnhealthy, err)
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
return qs422016 return qs422016
//line lib/promscrape/targetstatus.qtpl:35 //line lib/promscrape/targetstatus.qtpl:43
} }
//line lib/promscrape/targetstatus.qtpl:37 //line lib/promscrape/targetstatus.qtpl:45
func StreamTargetsResponseHTML(qw422016 *qt422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, onlyUnhealthy bool) { func StreamTargetsResponseHTML(qw422016 *qt422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, endpointSearch, labelSearch string, err error) {
//line lib/promscrape/targetstatus.qtpl:37 //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="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"><title>Scrape targets</title><script>function collapse_all() {for (var i = 0; i <`) 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="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"><title>Scrape targets</title><script>function collapse_all() {for (var i = 0; i <`)
//line lib/promscrape/targetstatus.qtpl:47 //line lib/promscrape/targetstatus.qtpl:55
qw422016.N().D(len(jts)) qw422016.N().D(len(jts))
//line lib/promscrape/targetstatus.qtpl:47 //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 <`) 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:56 //line lib/promscrape/targetstatus.qtpl:64
qw422016.N().D(len(jts)) qw422016.N().D(len(jts))
//line lib/promscrape/targetstatus.qtpl:56 //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 class="m-3"><h1>Scrape targets</h1><div style="padding: 3px"><button type="button" class="btn`) qw422016.N().S(`; i++) {let el = document.getElementById("table-" + i);if (!el) {continue;}el.style.display = 'block';}}</script></head><body class="py-3"><div class="container-fluid">`)
//line lib/promscrape/targetstatus.qtpl:69 //line lib/promscrape/targetstatus.qtpl:76
qw422016.N().S(` `) if err != nil {
//line lib/promscrape/targetstatus.qtpl:69 //line lib/promscrape/targetstatus.qtpl:77
if !onlyUnhealthy { streamerrorNotification(qw422016, err)
//line lib/promscrape/targetstatus.qtpl:69 //line lib/promscrape/targetstatus.qtpl:78
qw422016.N().S(`btn-primary`)
//line lib/promscrape/targetstatus.qtpl:69
} else {
//line lib/promscrape/targetstatus.qtpl:69
qw422016.N().S(`btn-secondary`)
//line lib/promscrape/targetstatus.qtpl:69
} }
//line lib/promscrape/targetstatus.qtpl:69 //line lib/promscrape/targetstatus.qtpl:78
qw422016.N().S(`" onclick="location.href='targets'">All</button><button type="button" class="btn`) 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:72 //line lib/promscrape/targetstatus.qtpl:85
qw422016.N().S(` `) qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:72 //line lib/promscrape/targetstatus.qtpl:85
if onlyUnhealthy { if !showOnlyUnhealthy {
//line lib/promscrape/targetstatus.qtpl:72 //line lib/promscrape/targetstatus.qtpl:85
qw422016.N().S(`btn-primary`) qw422016.N().S(`btn-primary`)
//line lib/promscrape/targetstatus.qtpl:72 //line lib/promscrape/targetstatus.qtpl:85
} else { } else {
//line lib/promscrape/targetstatus.qtpl:72 //line lib/promscrape/targetstatus.qtpl:85
qw422016.N().S(`btn-secondary`) qw422016.N().S(`btn-secondary`)
//line lib/promscrape/targetstatus.qtpl:72 //line lib/promscrape/targetstatus.qtpl:85
} }
//line lib/promscrape/targetstatus.qtpl:72 //line lib/promscrape/targetstatus.qtpl:85
qw422016.N().S(`" onclick="location.href='targets?show_only_unhealthy=true'">Unhealthy</button><button type="button" class="btn btn-primary" onclick="collapse_all()">Collapse all</button><button type="button" class="btn btn-secondary" onclick="expand_all()">Expand all</button></div>`) qw422016.N().S(`" onclick="location.href='?`)
//line lib/promscrape/targetstatus.qtpl:82 //line lib/promscrape/targetstatus.qtpl:85
streamqueryArgs(qw422016, map[string]string{
"show_only_unhealthy": "false",
"endpoint_search": endpointSearch,
"label_search": labelSearch,
})
//line lib/promscrape/targetstatus.qtpl:89
qw422016.N().S(`'">All</button></div><div class="col-auto"><button type="button" class="btn`)
//line lib/promscrape/targetstatus.qtpl:94
qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:94
if showOnlyUnhealthy {
//line lib/promscrape/targetstatus.qtpl:94
qw422016.N().S(`btn-primary`)
//line lib/promscrape/targetstatus.qtpl:94
} else {
//line lib/promscrape/targetstatus.qtpl:94
qw422016.N().S(`btn-secondary`)
//line lib/promscrape/targetstatus.qtpl:94
}
//line lib/promscrape/targetstatus.qtpl:94
qw422016.N().S(`" onclick="location.href='?`)
//line lib/promscrape/targetstatus.qtpl:94
streamqueryArgs(qw422016, map[string]string{
"show_only_unhealthy": "true",
"endpoint_search": endpointSearch,
"label_search": labelSearch,
})
//line lib/promscrape/targetstatus.qtpl:98
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:113
if endpointSearch == "" && labelSearch == "" {
//line lib/promscrape/targetstatus.qtpl:113
qw422016.N().S(`<button type="button" class="btn btn-primary" onclick="document.getElementById('filters').style.display='block'">Filter targets</button>`)
//line lib/promscrape/targetstatus.qtpl:117
} else {
//line lib/promscrape/targetstatus.qtpl:117
qw422016.N().S(`<button type="button" class="btn btn-primary" onclick="location.href='?'">Clear target filters</button>`)
//line lib/promscrape/targetstatus.qtpl:121
}
//line lib/promscrape/targetstatus.qtpl:121
qw422016.N().S(`</div></div><div id="filters"`)
//line lib/promscrape/targetstatus.qtpl:124
if endpointSearch == "" && labelSearch == "" {
//line lib/promscrape/targetstatus.qtpl:124
qw422016.N().S(`style="display:none"`)
//line lib/promscrape/targetstatus.qtpl:124
}
//line lib/promscrape/targetstatus.qtpl:124
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:130
qw422016.E().S(endpointSearch)
//line lib/promscrape/targetstatus.qtpl:130
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:137
qw422016.E().S(labelSearch)
//line lib/promscrape/targetstatus.qtpl:137
qw422016.N().S(`"/></div></div><input type="hidden" name="show_only_unhealthy" value="`)
//line lib/promscrape/targetstatus.qtpl:140
qw422016.E().V(showOnlyUnhealthy)
//line lib/promscrape/targetstatus.qtpl:140
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:147
for i, js := range jts { for i, js := range jts {
//line lib/promscrape/targetstatus.qtpl:83 //line lib/promscrape/targetstatus.qtpl:148
if onlyUnhealthy && js.upCount == js.targetsTotal { if showOnlyUnhealthy && js.upCount == js.targetsTotal {
//line lib/promscrape/targetstatus.qtpl:83 //line lib/promscrape/targetstatus.qtpl:148
continue continue
//line lib/promscrape/targetstatus.qtpl:83 //line lib/promscrape/targetstatus.qtpl:148
} }
//line lib/promscrape/targetstatus.qtpl:83 //line lib/promscrape/targetstatus.qtpl:148
qw422016.N().S(`<div><h4>`) qw422016.N().S(`<div class="row mb-4"><div class="col-12"><h4>`)
//line lib/promscrape/targetstatus.qtpl:86 //line lib/promscrape/targetstatus.qtpl:152
qw422016.E().S(js.job) qw422016.E().S(js.job)
//line lib/promscrape/targetstatus.qtpl:86 //line lib/promscrape/targetstatus.qtpl:152
qw422016.N().S(` `) qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:86 //line lib/promscrape/targetstatus.qtpl:152
qw422016.N().S(`(`) qw422016.N().S(`(`)
//line lib/promscrape/targetstatus.qtpl:86 //line lib/promscrape/targetstatus.qtpl:152
qw422016.N().D(js.upCount) qw422016.N().D(js.upCount)
//line lib/promscrape/targetstatus.qtpl:86 //line lib/promscrape/targetstatus.qtpl:152
qw422016.N().S(`/`) qw422016.N().S(`/`)
//line lib/promscrape/targetstatus.qtpl:86 //line lib/promscrape/targetstatus.qtpl:152
qw422016.N().D(js.targetsTotal) qw422016.N().D(js.targetsTotal)
//line lib/promscrape/targetstatus.qtpl:86 //line lib/promscrape/targetstatus.qtpl:152
qw422016.N().S(` `) qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:86 //line lib/promscrape/targetstatus.qtpl:152
qw422016.N().S(`up)<button type="button" class="btn btn-primary" onclick="document.getElementById('table-`) qw422016.N().S(`up)</h4><div class="row mb-2"><div class="col-12"><button type="button" class="btn btn-primary me-1"onclick="document.getElementById('table-`)
//line lib/promscrape/targetstatus.qtpl:87 //line lib/promscrape/targetstatus.qtpl:157
qw422016.N().D(i) qw422016.N().D(i)
//line lib/promscrape/targetstatus.qtpl:87 //line lib/promscrape/targetstatus.qtpl:157
qw422016.N().S(`').style.display='none'">collapse</button><button type="button" class="btn btn-secondary" onclick="document.getElementById('table-`) qw422016.N().S(`').style.display='none'">collapse</button><button type="button" class="btn btn-secondary me-1"onclick="document.getElementById('table-`)
//line lib/promscrape/targetstatus.qtpl:88 //line lib/promscrape/targetstatus.qtpl:160
qw422016.N().D(i) qw422016.N().D(i)
//line lib/promscrape/targetstatus.qtpl:88 //line lib/promscrape/targetstatus.qtpl:160
qw422016.N().S(`').style.display='block'">expand</button></h4><div id="table-`) qw422016.N().S(`').style.display='block'">expand</button></div></div><div id="table-`)
//line lib/promscrape/targetstatus.qtpl:90 //line lib/promscrape/targetstatus.qtpl:164
qw422016.N().D(i) qw422016.N().D(i)
//line lib/promscrape/targetstatus.qtpl:90 //line lib/promscrape/targetstatus.qtpl:164
qw422016.N().S(`"><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>`) 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:106 //line lib/promscrape/targetstatus.qtpl:179
qw422016.N().D(i)
//line lib/promscrape/targetstatus.qtpl:179
qw422016.N().S(`">`)
//line lib/promscrape/targetstatus.qtpl:180
for _, ts := range js.targetsStatus { for _, ts := range js.targetsStatus {
//line lib/promscrape/targetstatus.qtpl:108 //line lib/promscrape/targetstatus.qtpl:182
endpoint := ts.sw.Config.ScrapeURL endpoint := ts.sw.Config.ScrapeURL
targetID := getTargetID(ts.sw) targetID := getTargetID(ts.sw)
lastScrapeTime := ts.getDurationFromLastScrape() lastScrapeTime := ts.getDurationFromLastScrape()
//line lib/promscrape/targetstatus.qtpl:112 //line lib/promscrape/targetstatus.qtpl:186
if onlyUnhealthy && ts.up { if showOnlyUnhealthy && ts.up {
//line lib/promscrape/targetstatus.qtpl:112 //line lib/promscrape/targetstatus.qtpl:186
continue continue
//line lib/promscrape/targetstatus.qtpl:112 //line lib/promscrape/targetstatus.qtpl:186
} }
//line lib/promscrape/targetstatus.qtpl:112 //line lib/promscrape/targetstatus.qtpl:186
qw422016.N().S(`<tr`) qw422016.N().S(`<tr`)
//line lib/promscrape/targetstatus.qtpl:113 //line lib/promscrape/targetstatus.qtpl:187
if !ts.up { if !ts.up {
//line lib/promscrape/targetstatus.qtpl:113 //line lib/promscrape/targetstatus.qtpl:187
qw422016.N().S(` `) qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:113 //line lib/promscrape/targetstatus.qtpl:187
qw422016.N().S(`class="alert alert-danger" role="alert"`) qw422016.N().S(`class="alert alert-danger" role="alert"`)
//line lib/promscrape/targetstatus.qtpl:113 //line lib/promscrape/targetstatus.qtpl:187
} }
//line lib/promscrape/targetstatus.qtpl:113 //line lib/promscrape/targetstatus.qtpl:187
qw422016.N().S(`><td><a href="`) qw422016.N().S(`><td class="endpoint"><a href="`)
//line lib/promscrape/targetstatus.qtpl:114 //line lib/promscrape/targetstatus.qtpl:188
qw422016.E().S(endpoint) qw422016.E().S(endpoint)
//line lib/promscrape/targetstatus.qtpl:114 //line lib/promscrape/targetstatus.qtpl:188
qw422016.N().S(`" target="_blank">`) qw422016.N().S(`" target="_blank">`)
//line lib/promscrape/targetstatus.qtpl:114 //line lib/promscrape/targetstatus.qtpl:188
qw422016.E().S(endpoint) qw422016.E().S(endpoint)
//line lib/promscrape/targetstatus.qtpl:114 //line lib/promscrape/targetstatus.qtpl:188
qw422016.N().S(`</a> (<a href="target_response?id=`) qw422016.N().S(`</a> (<a href="target_response?id=`)
//line lib/promscrape/targetstatus.qtpl:115 //line lib/promscrape/targetstatus.qtpl:189
qw422016.E().S(targetID) qw422016.E().S(targetID)
//line lib/promscrape/targetstatus.qtpl:115 //line lib/promscrape/targetstatus.qtpl:189
qw422016.N().S(`" target="_blank" title="click to fetch target response on behalf of the scraper">response</a>)</td><td>`) 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:117 //line lib/promscrape/targetstatus.qtpl:193
if ts.up { if ts.up {
//line lib/promscrape/targetstatus.qtpl:117 //line lib/promscrape/targetstatus.qtpl:193
qw422016.N().S(`UP`) qw422016.N().S(`UP`)
//line lib/promscrape/targetstatus.qtpl:117 //line lib/promscrape/targetstatus.qtpl:193
} else { } else {
//line lib/promscrape/targetstatus.qtpl:117 //line lib/promscrape/targetstatus.qtpl:193
qw422016.N().S(`DOWN`) qw422016.N().S(`DOWN`)
//line lib/promscrape/targetstatus.qtpl:117 //line lib/promscrape/targetstatus.qtpl:193
} }
//line lib/promscrape/targetstatus.qtpl:117 //line lib/promscrape/targetstatus.qtpl:193
qw422016.N().S(`</td><td><div title="click to show original labels" onclick="document.getElementById('original_labels_`) qw422016.N().S(`</td><td class="labels"><div title="click to show original labels"onclick="document.getElementById('original_labels_`)
//line lib/promscrape/targetstatus.qtpl:119 //line lib/promscrape/targetstatus.qtpl:196
qw422016.E().S(targetID) qw422016.E().S(targetID)
//line lib/promscrape/targetstatus.qtpl:119 //line lib/promscrape/targetstatus.qtpl:196
qw422016.N().S(`').style.display='block'">`) qw422016.N().S(`').style.display='block'">`)
//line lib/promscrape/targetstatus.qtpl:120 //line lib/promscrape/targetstatus.qtpl:197
streamformatLabel(qw422016, promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels)) streamformatLabel(qw422016, promrelabel.FinalizeLabels(nil, ts.sw.Config.Labels))
//line lib/promscrape/targetstatus.qtpl:120 //line lib/promscrape/targetstatus.qtpl:197
qw422016.N().S(`</div><div style="display:none" id="original_labels_`) qw422016.N().S(`</div><div style="display:none" id="original_labels_`)
//line lib/promscrape/targetstatus.qtpl:122 //line lib/promscrape/targetstatus.qtpl:199
qw422016.E().S(targetID) qw422016.E().S(targetID)
//line lib/promscrape/targetstatus.qtpl:122 //line lib/promscrape/targetstatus.qtpl:199
qw422016.N().S(`">`) qw422016.N().S(`">`)
//line lib/promscrape/targetstatus.qtpl:123 //line lib/promscrape/targetstatus.qtpl:200
streamformatLabel(qw422016, ts.sw.Config.OriginalLabels) streamformatLabel(qw422016, ts.sw.Config.OriginalLabels)
//line lib/promscrape/targetstatus.qtpl:123 //line lib/promscrape/targetstatus.qtpl:200
qw422016.N().S(`</div></td><td>`) qw422016.N().S(`</div></td><td>`)
//line lib/promscrape/targetstatus.qtpl:126 //line lib/promscrape/targetstatus.qtpl:203
qw422016.N().D(ts.scrapesTotal) qw422016.N().D(ts.scrapesTotal)
//line lib/promscrape/targetstatus.qtpl:126 //line lib/promscrape/targetstatus.qtpl:203
qw422016.N().S(`</td><td>`) qw422016.N().S(`</td><td>`)
//line lib/promscrape/targetstatus.qtpl:127 //line lib/promscrape/targetstatus.qtpl:204
qw422016.N().D(ts.scrapesFailed) qw422016.N().D(ts.scrapesFailed)
//line lib/promscrape/targetstatus.qtpl:127 //line lib/promscrape/targetstatus.qtpl:204
qw422016.N().S(`</td><td>`) qw422016.N().S(`</td><td>`)
//line lib/promscrape/targetstatus.qtpl:129 //line lib/promscrape/targetstatus.qtpl:206
if lastScrapeTime < 365*24*time.Hour { if lastScrapeTime < 365*24*time.Hour {
//line lib/promscrape/targetstatus.qtpl:130 //line lib/promscrape/targetstatus.qtpl:207
qw422016.N().FPrec(lastScrapeTime.Seconds(), 3) qw422016.N().FPrec(lastScrapeTime.Seconds(), 3)
//line lib/promscrape/targetstatus.qtpl:130 //line lib/promscrape/targetstatus.qtpl:207
qw422016.N().S(`s ago`) qw422016.N().S(`s ago`)
//line lib/promscrape/targetstatus.qtpl:131 //line lib/promscrape/targetstatus.qtpl:208
} else { } else {
//line lib/promscrape/targetstatus.qtpl:131 //line lib/promscrape/targetstatus.qtpl:208
qw422016.N().S(`none`) qw422016.N().S(`none`)
//line lib/promscrape/targetstatus.qtpl:133 //line lib/promscrape/targetstatus.qtpl:210
} }
//line lib/promscrape/targetstatus.qtpl:133 //line lib/promscrape/targetstatus.qtpl:210
qw422016.N().S(`<td>`) qw422016.N().S(`<td>`)
//line lib/promscrape/targetstatus.qtpl:134 //line lib/promscrape/targetstatus.qtpl:211
qw422016.N().D(int(ts.scrapeDuration)) qw422016.N().D(int(ts.scrapeDuration))
//line lib/promscrape/targetstatus.qtpl:134 //line lib/promscrape/targetstatus.qtpl:211
qw422016.N().S(`ms</td><td>`) qw422016.N().S(`ms</td><td>`)
//line lib/promscrape/targetstatus.qtpl:135 //line lib/promscrape/targetstatus.qtpl:212
qw422016.N().D(ts.samplesScraped) qw422016.N().D(ts.samplesScraped)
//line lib/promscrape/targetstatus.qtpl:135 //line lib/promscrape/targetstatus.qtpl:212
qw422016.N().S(`</td><td>`) qw422016.N().S(`</td><td>`)
//line lib/promscrape/targetstatus.qtpl:136 //line lib/promscrape/targetstatus.qtpl:213
if ts.err != nil { if ts.err != nil {
//line lib/promscrape/targetstatus.qtpl:136 //line lib/promscrape/targetstatus.qtpl:213
qw422016.E().S(ts.err.Error()) qw422016.E().S(ts.err.Error())
//line lib/promscrape/targetstatus.qtpl:136 //line lib/promscrape/targetstatus.qtpl:213
} }
//line lib/promscrape/targetstatus.qtpl:136 //line lib/promscrape/targetstatus.qtpl:213
qw422016.N().S(`</td></tr>`) qw422016.N().S(`</td></tr>`)
//line lib/promscrape/targetstatus.qtpl:138 //line lib/promscrape/targetstatus.qtpl:215
} }
//line lib/promscrape/targetstatus.qtpl:138 //line lib/promscrape/targetstatus.qtpl:215
qw422016.N().S(`</tbody></table></div></div>`) qw422016.N().S(`</tbody></table></div></div></div>`)
//line lib/promscrape/targetstatus.qtpl:143 //line lib/promscrape/targetstatus.qtpl:221
} }
//line lib/promscrape/targetstatus.qtpl:145 //line lib/promscrape/targetstatus.qtpl:221
qw422016.N().S(`</div></div>`)
//line lib/promscrape/targetstatus.qtpl:225
for _, jobName := range emptyJobs { for _, jobName := range emptyJobs {
//line lib/promscrape/targetstatus.qtpl:145 //line lib/promscrape/targetstatus.qtpl:225
qw422016.N().S(`<div><h4><a>`) qw422016.N().S(`<div><h4><a>`)
//line lib/promscrape/targetstatus.qtpl:148 //line lib/promscrape/targetstatus.qtpl:228
qw422016.E().S(jobName) qw422016.E().S(jobName)
//line lib/promscrape/targetstatus.qtpl:148 //line lib/promscrape/targetstatus.qtpl:228
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>`) 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:164 //line lib/promscrape/targetstatus.qtpl:244
} }
//line lib/promscrape/targetstatus.qtpl:164 //line lib/promscrape/targetstatus.qtpl:244
qw422016.N().S(`</body></html>`) qw422016.N().S(`</main></div></div></body></html>`)
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
} }
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
func WriteTargetsResponseHTML(qq422016 qtio422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, onlyUnhealthy bool) { func WriteTargetsResponseHTML(qq422016 qtio422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, endpointSearch, labelSearch string, err error) {
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
StreamTargetsResponseHTML(qw422016, jts, emptyJobs, onlyUnhealthy) StreamTargetsResponseHTML(qw422016, jts, emptyJobs, showOnlyUnhealthy, endpointSearch, labelSearch, err)
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
} }
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
func TargetsResponseHTML(jts []jobTargetsStatuses, emptyJobs []string, onlyUnhealthy bool) string { func TargetsResponseHTML(jts []jobTargetsStatuses, emptyJobs []string, showOnlyUnhealthy bool, endpointSearch, labelSearch string, err error) string {
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
WriteTargetsResponseHTML(qb422016, jts, emptyJobs, onlyUnhealthy) WriteTargetsResponseHTML(qb422016, jts, emptyJobs, showOnlyUnhealthy, endpointSearch, labelSearch, err)
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
return qs422016 return qs422016
//line lib/promscrape/targetstatus.qtpl:167 //line lib/promscrape/targetstatus.qtpl:250
} }
//line lib/promscrape/targetstatus.qtpl:169 //line lib/promscrape/targetstatus.qtpl:252
func streamqueryArgs(qw422016 *qt422016.Writer, m map[string]string) {
//line lib/promscrape/targetstatus.qtpl:254
qa := make(url.Values, len(m))
for k, v := range m {
qa[k] = []string{v}
}
//line lib/promscrape/targetstatus.qtpl:259
qw422016.E().S(qa.Encode())
//line lib/promscrape/targetstatus.qtpl:260
}
//line lib/promscrape/targetstatus.qtpl:260
func writequeryArgs(qq422016 qtio422016.Writer, m map[string]string) {
//line lib/promscrape/targetstatus.qtpl:260
qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:260
streamqueryArgs(qw422016, m)
//line lib/promscrape/targetstatus.qtpl:260
qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:260
}
//line lib/promscrape/targetstatus.qtpl:260
func queryArgs(m map[string]string) string {
//line lib/promscrape/targetstatus.qtpl:260
qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:260
writequeryArgs(qb422016, m)
//line lib/promscrape/targetstatus.qtpl:260
qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:260
qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:260
return qs422016
//line lib/promscrape/targetstatus.qtpl:260
}
//line lib/promscrape/targetstatus.qtpl:262
func streamformatLabel(qw422016 *qt422016.Writer, labels []prompbmarshal.Label) { func streamformatLabel(qw422016 *qt422016.Writer, labels []prompbmarshal.Label) {
//line lib/promscrape/targetstatus.qtpl:169 //line lib/promscrape/targetstatus.qtpl:262
qw422016.N().S(`{`) qw422016.N().S(`{`)
//line lib/promscrape/targetstatus.qtpl:171 //line lib/promscrape/targetstatus.qtpl:264
for i, label := range labels { for i, label := range labels {
//line lib/promscrape/targetstatus.qtpl:172 //line lib/promscrape/targetstatus.qtpl:265
qw422016.E().S(label.Name) qw422016.E().S(label.Name)
//line lib/promscrape/targetstatus.qtpl:172 //line lib/promscrape/targetstatus.qtpl:265
qw422016.N().S(`=`) qw422016.N().S(`=`)
//line lib/promscrape/targetstatus.qtpl:172 //line lib/promscrape/targetstatus.qtpl:265
qw422016.E().Q(label.Value) qw422016.E().Q(label.Value)
//line lib/promscrape/targetstatus.qtpl:173 //line lib/promscrape/targetstatus.qtpl:266
if i+1 < len(labels) { if i+1 < len(labels) {
//line lib/promscrape/targetstatus.qtpl:173 //line lib/promscrape/targetstatus.qtpl:266
qw422016.N().S(`,`) qw422016.N().S(`,`)
//line lib/promscrape/targetstatus.qtpl:173 //line lib/promscrape/targetstatus.qtpl:266
qw422016.N().S(` `) qw422016.N().S(` `)
//line lib/promscrape/targetstatus.qtpl:173 //line lib/promscrape/targetstatus.qtpl:266
} }
//line lib/promscrape/targetstatus.qtpl:174 //line lib/promscrape/targetstatus.qtpl:267
} }
//line lib/promscrape/targetstatus.qtpl:174 //line lib/promscrape/targetstatus.qtpl:267
qw422016.N().S(`}`) qw422016.N().S(`}`)
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
} }
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
func writeformatLabel(qq422016 qtio422016.Writer, labels []prompbmarshal.Label) { func writeformatLabel(qq422016 qtio422016.Writer, labels []prompbmarshal.Label) {
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
streamformatLabel(qw422016, labels) streamformatLabel(qw422016, labels)
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
} }
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
func formatLabel(labels []prompbmarshal.Label) string { func formatLabel(labels []prompbmarshal.Label) string {
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
writeformatLabel(qb422016, labels) writeformatLabel(qb422016, labels)
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
return qs422016 return qs422016
//line lib/promscrape/targetstatus.qtpl:176 //line lib/promscrape/targetstatus.qtpl:269
}
//line lib/promscrape/targetstatus.qtpl:271
func streamerrorNotification(qw422016 *qt422016.Writer, err error) {
//line lib/promscrape/targetstatus.qtpl:271
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:276
qw422016.E().S(err.Error())
//line lib/promscrape/targetstatus.qtpl:276
qw422016.N().S(`</div></div>`)
//line lib/promscrape/targetstatus.qtpl:279
}
//line lib/promscrape/targetstatus.qtpl:279
func writeerrorNotification(qq422016 qtio422016.Writer, err error) {
//line lib/promscrape/targetstatus.qtpl:279
qw422016 := qt422016.AcquireWriter(qq422016)
//line lib/promscrape/targetstatus.qtpl:279
streamerrorNotification(qw422016, err)
//line lib/promscrape/targetstatus.qtpl:279
qt422016.ReleaseWriter(qw422016)
//line lib/promscrape/targetstatus.qtpl:279
}
//line lib/promscrape/targetstatus.qtpl:279
func errorNotification(err error) string {
//line lib/promscrape/targetstatus.qtpl:279
qb422016 := qt422016.AcquireByteBuffer()
//line lib/promscrape/targetstatus.qtpl:279
writeerrorNotification(qb422016, err)
//line lib/promscrape/targetstatus.qtpl:279
qs422016 := string(qb422016.B)
//line lib/promscrape/targetstatus.qtpl:279
qt422016.ReleaseByteBuffer(qb422016)
//line lib/promscrape/targetstatus.qtpl:279
return qs422016
//line lib/promscrape/targetstatus.qtpl:279
} }