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
|
||||
## Empty this field will use default value 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
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
|
@ -41,6 +42,7 @@ type Jenkins struct {
|
|||
MaxBuildAge config.Duration `toml:"max_build_age"`
|
||||
MaxSubJobDepth int `toml:"max_subjob_depth"`
|
||||
MaxSubJobPerLayer int `toml:"max_subjob_per_layer"`
|
||||
NodeLabelsAsTag bool `toml:"node_labels_as_tag"`
|
||||
JobExclude []string `toml:"job_exclude"`
|
||||
JobInclude []string `toml:"job_include"`
|
||||
jobFilter filter.Filter
|
||||
|
|
@ -172,6 +174,20 @@ func (j *Jenkins) gatherNodeData(n node, acc telegraf.Accumulator) error {
|
|||
fields := make(map[string]interface{})
|
||||
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 {
|
||||
fields["response_time"] = monitorData.HudsonNodeMonitorsResponseTimeMonitor.Average
|
||||
}
|
||||
|
|
@ -313,10 +329,15 @@ type nodeResponse struct {
|
|||
}
|
||||
|
||||
type node struct {
|
||||
DisplayName string `json:"displayName"`
|
||||
Offline bool `json:"offline"`
|
||||
NumExecutors int `json:"numExecutors"`
|
||||
MonitorData monitorData `json:"monitorData"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Offline bool `json:"offline"`
|
||||
NumExecutors int `json:"numExecutors"`
|
||||
MonitorData monitorData `json:"monitorData"`
|
||||
AssignedLabels []label `json:"assignedLabels"`
|
||||
}
|
||||
|
||||
type label struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type monitorData struct {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
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) {
|
||||
mh := mockHandler{
|
||||
responseMap: map[string]interface{}{
|
||||
|
|
|
|||
|
|
@ -45,3 +45,8 @@
|
|||
## Worker pool for jenkins plugin only
|
||||
## Empty this field will use default value 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