From 5b7d90d17872391093f140341cdc9ba72e1cb819 Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Wed, 13 Oct 2021 15:59:55 +0300 Subject: [PATCH] lib/promscrape: add ability to show the original labels for discovered targets at /targets page See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1698 --- docs/CHANGELOG.md | 1 + lib/promscrape/targets_response.qtpl | 13 +- lib/promscrape/targets_response.qtpl.go | 154 ++++++++++++++---------- 3 files changed, 102 insertions(+), 66 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index d191f66088..f0fc76894d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -7,6 +7,7 @@ sort: 15 ## tip * FEATURE: vmagent: expose `-promscrape.config` contents at `/config` page as Prometheus does. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1695). +* FEATURE: vmagent: add `show original labels` button per each scrape target displayed at `http://vmagent;8429/targets` page. This should improve debuggability for service discovery issues similar to [this one](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1664). See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1698). * FEATURE: vmagent: shard targets among cluster nodes after the relabeling is applied. This should guarantee that targets with the same set of labels go to the same `vmagent` node in the cluster. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1687). * FEATURE: add trigonometric functions, which are going to be added in [Prometheus 2.31](https://github.com/prometheus/prometheus/pull/9239): [acosh](https://docs.victoriametrics.com/MetricsQL.html#acosh), [asinh](https://docs.victoriametrics.com/MetricsQL.html#asinh), [atan](https://docs.victoriametrics.com/MetricsQL.html#atan), [atanh](https://docs.victoriametrics.com/MetricsQL.html#atanh), [cosh](https://docs.victoriametrics.com/MetricsQL.html#cosh), [deg](https://docs.victoriametrics.com/MetricsQL.html#deg), [rad](https://docs.victoriametrics.com/MetricsQL.html#rad), [sinh](https://docs.victoriametrics.com/MetricsQL.html#sinh), [tan](https://docs.victoriametrics.com/MetricsQL.html#tan), [tanh](https://docs.victoriametrics.com/MetricsQL.html#tanh). Also add `atan2` binary operator. See [this pull request](https://github.com/prometheus/prometheus/pull/9248). * FEATURE: consistently return the same set of time series from [limitk](https://docs.victoriametrics.com/MetricsQL.html#limitk) function. This improves the usability of periodically refreshed graphs. diff --git a/lib/promscrape/targets_response.qtpl b/lib/promscrape/targets_response.qtpl index 72a445f917..d842a4bae5 100644 --- a/lib/promscrape/targets_response.qtpl +++ b/lib/promscrape/targets_response.qtpl @@ -53,7 +53,7 @@ job={%q= jobName %} (0/0 up) Unhealthy - {% for _, js := range jts %} + {% for i, js := range jts %} {% if onlyUnhealthy && js.upCount == js.targetsTotal %}{% continue %}{% endif %}

@@ -72,13 +72,18 @@ job={%q= jobName %} (0/0 up) - {% for _, ts := range js.targetsStatus %} + {% for j, ts := range js.targetsStatus %} {% if onlyUnhealthy && ts.up %}{% continue %}{% endif %} {%s ts.endpoint %}
{% if ts.up %}UP{% else %}DOWN{% endif %} - + + {% space %} {%= formatLabel(ts.labels) %} + {%f.3 ts.lastScrapeTime.Seconds() %}s ago {%f.3 ts.scrapeDuration.Seconds() %}s @@ -119,7 +124,7 @@ job={%q= jobName %} (0/0 up) { {% for i, label := range labels %} {%s label.Name %}={%q label.Value %} - {% if i+1 < len(labels) %},{% endif %} + {% if i+1 < len(labels) %},{% space %}{% endif %} {% endfor %} } {% endfunc %} diff --git a/lib/promscrape/targets_response.qtpl.go b/lib/promscrape/targets_response.qtpl.go index 1a2015e24e..0ee64550d7 100644 --- a/lib/promscrape/targets_response.qtpl.go +++ b/lib/promscrape/targets_response.qtpl.go @@ -225,7 +225,7 @@ func StreamTargetsResponseHTML(qw422016 *qt422016.Writer, jts []jobTargetsStatus //line lib/promscrape/targets_response.qtpl:52 qw422016.N().S(`>Unhealthy

`) //line lib/promscrape/targets_response.qtpl:56 - for _, js := range jts { + for i, js := range jts { //line lib/promscrape/targets_response.qtpl:57 if onlyUnhealthy && js.upCount == js.targetsTotal { //line lib/promscrape/targets_response.qtpl:57 @@ -247,7 +247,7 @@ func StreamTargetsResponseHTML(qw422016 *qt422016.Writer, jts []jobTargetsStatus //line lib/promscrape/targets_response.qtpl:60 qw422016.N().S(`up)`) //line lib/promscrape/targets_response.qtpl:75 - for _, ts := range js.targetsStatus { + for j, ts := range js.targetsStatus { //line lib/promscrape/targets_response.qtpl:76 if onlyUnhealthy && ts.up { //line lib/promscrape/targets_response.qtpl:76 @@ -285,125 +285,155 @@ func StreamTargetsResponseHTML(qw422016 *qt422016.Writer, jts []jobTargetsStatus //line lib/promscrape/targets_response.qtpl:79 } //line lib/promscrape/targets_response.qtpl:79 - qw422016.N().S(``) -//line lib/promscrape/targets_response.qtpl:88 +//line lib/promscrape/targets_response.qtpl:93 } -//line lib/promscrape/targets_response.qtpl:88 +//line lib/promscrape/targets_response.qtpl:93 qw422016.N().S(`
EndpointStateLabelsLast ScrapeScrape DurationSamples ScrapedError
`) + qw422016.N().S(``) +//line lib/promscrape/targets_response.qtpl:81 + qw422016.N().S(` `) +//line lib/promscrape/targets_response.qtpl:82 streamformatLabel(qw422016, ts.labels) -//line lib/promscrape/targets_response.qtpl:81 - qw422016.N().S(``) +//line lib/promscrape/targets_response.qtpl:82 + qw422016.N().S(``) +//line lib/promscrape/targets_response.qtpl:88 qw422016.N().FPrec(ts.lastScrapeTime.Seconds(), 3) -//line lib/promscrape/targets_response.qtpl:83 +//line lib/promscrape/targets_response.qtpl:88 qw422016.N().S(`s ago`) -//line lib/promscrape/targets_response.qtpl:84 +//line lib/promscrape/targets_response.qtpl:89 qw422016.N().FPrec(ts.scrapeDuration.Seconds(), 3) -//line lib/promscrape/targets_response.qtpl:84 +//line lib/promscrape/targets_response.qtpl:89 qw422016.N().S(`s`) -//line lib/promscrape/targets_response.qtpl:85 +//line lib/promscrape/targets_response.qtpl:90 qw422016.N().D(ts.samplesScraped) -//line lib/promscrape/targets_response.qtpl:85 +//line lib/promscrape/targets_response.qtpl:90 qw422016.N().S(``) -//line lib/promscrape/targets_response.qtpl:86 +//line lib/promscrape/targets_response.qtpl:91 qw422016.E().S(ts.errMsg) -//line lib/promscrape/targets_response.qtpl:86 +//line lib/promscrape/targets_response.qtpl:91 qw422016.N().S(`
`) -//line lib/promscrape/targets_response.qtpl:92 +//line lib/promscrape/targets_response.qtpl:97 } -//line lib/promscrape/targets_response.qtpl:94 +//line lib/promscrape/targets_response.qtpl:99 for _, jobName := range emptyJobs { -//line lib/promscrape/targets_response.qtpl:94 +//line lib/promscrape/targets_response.qtpl:99 qw422016.N().S(`

`) -//line lib/promscrape/targets_response.qtpl:97 +//line lib/promscrape/targets_response.qtpl:102 qw422016.E().S(jobName) -//line lib/promscrape/targets_response.qtpl:97 +//line lib/promscrape/targets_response.qtpl:102 qw422016.N().S(`(0/0 up)

EndpointStateLabelsLast ScrapeScrape DurationSamples ScrapedError
`) -//line lib/promscrape/targets_response.qtpl:113 +//line lib/promscrape/targets_response.qtpl:118 } -//line lib/promscrape/targets_response.qtpl:113 +//line lib/promscrape/targets_response.qtpl:118 qw422016.N().S(``) -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 } -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 func WriteTargetsResponseHTML(qq422016 qtio422016.Writer, jts []jobTargetsStatuses, emptyJobs []string, redirectPath string, onlyUnhealthy bool) { -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 qw422016 := qt422016.AcquireWriter(qq422016) -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 StreamTargetsResponseHTML(qw422016, jts, emptyJobs, redirectPath, onlyUnhealthy) -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 qt422016.ReleaseWriter(qw422016) -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 } -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 func TargetsResponseHTML(jts []jobTargetsStatuses, emptyJobs []string, redirectPath string, onlyUnhealthy bool) string { -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 qb422016 := qt422016.AcquireByteBuffer() -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 WriteTargetsResponseHTML(qb422016, jts, emptyJobs, redirectPath, onlyUnhealthy) -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 qs422016 := string(qb422016.B) -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 qt422016.ReleaseByteBuffer(qb422016) -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 return qs422016 -//line lib/promscrape/targets_response.qtpl:116 +//line lib/promscrape/targets_response.qtpl:121 } -//line lib/promscrape/targets_response.qtpl:118 +//line lib/promscrape/targets_response.qtpl:123 func streamformatLabel(qw422016 *qt422016.Writer, labels []prompbmarshal.Label) { -//line lib/promscrape/targets_response.qtpl:118 +//line lib/promscrape/targets_response.qtpl:123 qw422016.N().S(`{`) -//line lib/promscrape/targets_response.qtpl:120 +//line lib/promscrape/targets_response.qtpl:125 for i, label := range labels { -//line lib/promscrape/targets_response.qtpl:121 +//line lib/promscrape/targets_response.qtpl:126 qw422016.E().S(label.Name) -//line lib/promscrape/targets_response.qtpl:121 +//line lib/promscrape/targets_response.qtpl:126 qw422016.N().S(`=`) -//line lib/promscrape/targets_response.qtpl:121 +//line lib/promscrape/targets_response.qtpl:126 qw422016.E().Q(label.Value) -//line lib/promscrape/targets_response.qtpl:122 +//line lib/promscrape/targets_response.qtpl:127 if i+1 < len(labels) { -//line lib/promscrape/targets_response.qtpl:122 +//line lib/promscrape/targets_response.qtpl:127 qw422016.N().S(`,`) -//line lib/promscrape/targets_response.qtpl:122 +//line lib/promscrape/targets_response.qtpl:127 + qw422016.N().S(` `) +//line lib/promscrape/targets_response.qtpl:127 } -//line lib/promscrape/targets_response.qtpl:123 +//line lib/promscrape/targets_response.qtpl:128 } -//line lib/promscrape/targets_response.qtpl:123 +//line lib/promscrape/targets_response.qtpl:128 qw422016.N().S(`}`) -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 } -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 func writeformatLabel(qq422016 qtio422016.Writer, labels []prompbmarshal.Label) { -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 qw422016 := qt422016.AcquireWriter(qq422016) -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 streamformatLabel(qw422016, labels) -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 qt422016.ReleaseWriter(qw422016) -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 } -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 func formatLabel(labels []prompbmarshal.Label) string { -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 qb422016 := qt422016.AcquireByteBuffer() -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 writeformatLabel(qb422016, labels) -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 qs422016 := string(qb422016.B) -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 qt422016.ReleaseByteBuffer(qb422016) -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 return qs422016 -//line lib/promscrape/targets_response.qtpl:125 +//line lib/promscrape/targets_response.qtpl:130 }