feat(inputs.jenkins): Add option for node labels as tag (#13649)
This commit is contained in:
parent
80ce606cef
commit
043aa0374b
|
|
@ -65,6 +65,11 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
|
||||||
## Worker pool for jenkins plugin only
|
## Worker pool for jenkins plugin only
|
||||||
## Empty this field will use default value 5
|
## Empty this field will use default value 5
|
||||||
# max_connections = 5
|
# max_connections = 5
|
||||||
|
|
||||||
|
## When set to true will add node labels as a comma-seperated tag. If none,
|
||||||
|
## are found, then a tag with the value of 'none' is used. Finally, if a
|
||||||
|
## lable contains a comma it is replaced with an underscore.
|
||||||
|
# node_labels_as_tag = false
|
||||||
```
|
```
|
||||||
|
|
||||||
## Metrics
|
## Metrics
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -41,6 +42,7 @@ type Jenkins struct {
|
||||||
MaxBuildAge config.Duration `toml:"max_build_age"`
|
MaxBuildAge config.Duration `toml:"max_build_age"`
|
||||||
MaxSubJobDepth int `toml:"max_subjob_depth"`
|
MaxSubJobDepth int `toml:"max_subjob_depth"`
|
||||||
MaxSubJobPerLayer int `toml:"max_subjob_per_layer"`
|
MaxSubJobPerLayer int `toml:"max_subjob_per_layer"`
|
||||||
|
NodeLabelsAsTag bool `toml:"node_labels_as_tag"`
|
||||||
JobExclude []string `toml:"job_exclude"`
|
JobExclude []string `toml:"job_exclude"`
|
||||||
JobInclude []string `toml:"job_include"`
|
JobInclude []string `toml:"job_include"`
|
||||||
jobFilter filter.Filter
|
jobFilter filter.Filter
|
||||||
|
|
@ -172,6 +174,20 @@ func (j *Jenkins) gatherNodeData(n node, acc telegraf.Accumulator) error {
|
||||||
fields := make(map[string]interface{})
|
fields := make(map[string]interface{})
|
||||||
fields["num_executors"] = n.NumExecutors
|
fields["num_executors"] = n.NumExecutors
|
||||||
|
|
||||||
|
if j.NodeLabelsAsTag {
|
||||||
|
labels := make([]string, 0, len(n.AssignedLabels))
|
||||||
|
for _, label := range n.AssignedLabels {
|
||||||
|
labels = append(labels, strings.ReplaceAll(label.Name, ",", "_"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(labels) == 0 {
|
||||||
|
tags["labels"] = "none"
|
||||||
|
} else {
|
||||||
|
sort.Strings(labels)
|
||||||
|
tags["labels"] = strings.Join(labels, ",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if monitorData.HudsonNodeMonitorsResponseTimeMonitor != nil {
|
if monitorData.HudsonNodeMonitorsResponseTimeMonitor != nil {
|
||||||
fields["response_time"] = monitorData.HudsonNodeMonitorsResponseTimeMonitor.Average
|
fields["response_time"] = monitorData.HudsonNodeMonitorsResponseTimeMonitor.Average
|
||||||
}
|
}
|
||||||
|
|
@ -313,10 +329,15 @@ type nodeResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type node struct {
|
type node struct {
|
||||||
DisplayName string `json:"displayName"`
|
DisplayName string `json:"displayName"`
|
||||||
Offline bool `json:"offline"`
|
Offline bool `json:"offline"`
|
||||||
NumExecutors int `json:"numExecutors"`
|
NumExecutors int `json:"numExecutors"`
|
||||||
MonitorData monitorData `json:"monitorData"`
|
MonitorData monitorData `json:"monitorData"`
|
||||||
|
AssignedLabels []label `json:"assignedLabels"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type label struct {
|
||||||
|
Name string `json:"name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type monitorData struct {
|
type monitorData struct {
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/influxdata/telegraf"
|
||||||
"github.com/influxdata/telegraf/config"
|
"github.com/influxdata/telegraf/config"
|
||||||
"github.com/influxdata/telegraf/testutil"
|
"github.com/influxdata/telegraf/testutil"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestJobRequest(t *testing.T) {
|
func TestJobRequest(t *testing.T) {
|
||||||
|
|
@ -369,6 +371,97 @@ func TestGatherNodeData(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLabels(t *testing.T) {
|
||||||
|
input := mockHandler{
|
||||||
|
responseMap: map[string]interface{}{
|
||||||
|
"/api/json": struct{}{},
|
||||||
|
"/computer/api/json": nodeResponse{
|
||||||
|
BusyExecutors: 4,
|
||||||
|
TotalExecutors: 8,
|
||||||
|
Computers: []node{
|
||||||
|
{
|
||||||
|
DisplayName: "master",
|
||||||
|
AssignedLabels: []label{
|
||||||
|
{"project_a"},
|
||||||
|
{"testing"},
|
||||||
|
},
|
||||||
|
MonitorData: monitorData{
|
||||||
|
HudsonNodeMonitorsResponseTimeMonitor: &responseTimeMonitor{
|
||||||
|
Average: 54321,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DisplayName: "secondary",
|
||||||
|
MonitorData: monitorData{
|
||||||
|
HudsonNodeMonitorsResponseTimeMonitor: &responseTimeMonitor{
|
||||||
|
Average: 12345,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := []telegraf.Metric{
|
||||||
|
testutil.MustMetric("jenkins",
|
||||||
|
map[string]string{
|
||||||
|
"source": "127.0.0.1",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"busy_executors": 4,
|
||||||
|
"total_executors": 8,
|
||||||
|
},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
testutil.MustMetric("jenkins_node",
|
||||||
|
map[string]string{
|
||||||
|
"node_name": "master",
|
||||||
|
"status": "online",
|
||||||
|
"source": "127.0.0.1",
|
||||||
|
"labels": "project_a,testing",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"num_executors": int64(0),
|
||||||
|
"response_time": int64(54321),
|
||||||
|
},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
testutil.MustMetric("jenkins_node",
|
||||||
|
map[string]string{
|
||||||
|
"node_name": "secondary",
|
||||||
|
"status": "online",
|
||||||
|
"source": "127.0.0.1",
|
||||||
|
"labels": "none",
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"num_executors": int64(0),
|
||||||
|
"response_time": int64(12345),
|
||||||
|
},
|
||||||
|
time.Unix(0, 0),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := httptest.NewServer(input)
|
||||||
|
defer ts.Close()
|
||||||
|
j := &Jenkins{
|
||||||
|
Log: testutil.Logger{},
|
||||||
|
URL: ts.URL,
|
||||||
|
ResponseTimeout: config.Duration(time.Microsecond),
|
||||||
|
NodeLabelsAsTag: true,
|
||||||
|
}
|
||||||
|
require.NoError(t, j.initialize(&http.Client{Transport: &http.Transport{}}))
|
||||||
|
acc := new(testutil.Accumulator)
|
||||||
|
j.gatherNodesData(acc)
|
||||||
|
require.NoError(t, acc.FirstError())
|
||||||
|
results := acc.GetTelegrafMetrics()
|
||||||
|
for _, metric := range results {
|
||||||
|
metric.RemoveTag("port")
|
||||||
|
}
|
||||||
|
testutil.RequireMetricsEqual(t, expected, results, testutil.IgnoreTime())
|
||||||
|
}
|
||||||
|
|
||||||
func TestInitialize(t *testing.T) {
|
func TestInitialize(t *testing.T) {
|
||||||
mh := mockHandler{
|
mh := mockHandler{
|
||||||
responseMap: map[string]interface{}{
|
responseMap: map[string]interface{}{
|
||||||
|
|
|
||||||
|
|
@ -45,3 +45,8 @@
|
||||||
## Worker pool for jenkins plugin only
|
## Worker pool for jenkins plugin only
|
||||||
## Empty this field will use default value 5
|
## Empty this field will use default value 5
|
||||||
# max_connections = 5
|
# max_connections = 5
|
||||||
|
|
||||||
|
## When set to true will add node labels as a comma-seperated tag. If none,
|
||||||
|
## are found, then a tag with the value of 'none' is used. Finally, if a
|
||||||
|
## lable contains a comma it is replaced with an underscore.
|
||||||
|
# node_labels_as_tag = false
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue