feat(inputs.jenkins): Add option for node labels as tag (#13649)

This commit is contained in:
Joshua Powers 2023-07-28 07:23:53 -06:00 committed by GitHub
parent 80ce606cef
commit 043aa0374b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 128 additions and 4 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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{}{

View File

@ -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