Skip to content

Commit 5c8981d

Browse files
authored
Merge pull request #24 from SDxKeeper/queue_length
Working version of queue length metric
2 parents daf064c + 080d9c8 commit 5c8981d

File tree

4 files changed

+93
-22
lines changed

4 files changed

+93
-22
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ Metrics
5252
|-------------------------------------------------|---------------|--------------------------------------------------------------------------------------|
5353
| `azure_devops_stats` | live | General scraper stats |
5454
| `azure_devops_agentpool_info` | live | Agent Pool informations |
55-
| `azure_devops_agentpool_size` | live | Queue size per agent pool |
55+
| `azure_devops_agentpool_size` | live | Number of agents per agent pool |
56+
| `azure_devops_agentpool_queue_length` | live | Queue length per agent pool |
5657
| `azure_devops_agentpool_agent_info` | live | Agent information per agent pool |
5758
| `azure_devops_agentpool_agent_status` | live | Status informations (eg. created date) for each agent in a agent pool |
5859
| `azure_devops_agentpool_agent_job` | live | Currently running jobs on each agent |
@@ -155,7 +156,7 @@ Agent pool usage (without PoolMaintenance)
155156
count by(agentPoolID) (
156157
azure_devops_agentpool_agent_job{planType!="PoolMaintenance"}
157158
* on(agentPoolAgentID) group_left(agentPoolID) (azure_devops_agentpool_agent_info)
158-
)
159+
)
159160
/ on (agentPoolID) group_left() (azure_devops_agentpool_size)
160161
* on (agentPoolID) group_left(agentPoolName) (azure_devops_agentpool_info)
161162
```

azure-devops-client/agentpool.go

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,25 +63,26 @@ type AgentPoolAgent struct {
6363
Status string
6464
Version string
6565
CreatedOn time.Time
66+
AssignedRequest JobRequest
67+
}
6668

67-
AssignedRequest struct {
68-
RequestId int64
69-
Demands []string
70-
QueueTime time.Time
71-
AssignTime time.Time
72-
ReceiveTime time.Time
73-
LockedUntil time.Time
74-
ServiceOwner string
75-
HostId string
76-
ScopeId string
77-
PlanType string
78-
PlanId string
79-
JobId string
80-
Definition struct {
81-
Id int64
82-
Name string
83-
Links Links `json:"_links"`
84-
}
69+
type JobRequest struct {
70+
RequestId int64
71+
Demands []string
72+
QueueTime time.Time
73+
AssignTime *time.Time
74+
ReceiveTime time.Time
75+
LockedUntil time.Time
76+
ServiceOwner string
77+
HostId string
78+
ScopeId string
79+
PlanType string
80+
PlanId string
81+
JobId string
82+
Definition struct {
83+
Id int64
84+
Name string
85+
Links Links `json:"_links"`
8586
}
8687
}
8788

@@ -107,3 +108,31 @@ func (c *AzureDevopsClient) ListAgentPoolAgents(agentPoolId int64) (list AgentPo
107108

108109
return
109110
}
111+
112+
type AgentPoolJobList struct {
113+
Count int `json:"count"`
114+
List []JobRequest `json:"value"`
115+
}
116+
117+
func (c *AzureDevopsClient) ListAgentPoolJobs(agentPoolId int64) (list AgentPoolJobList, error error) {
118+
defer c.concurrencyUnlock()
119+
c.concurrencyLock()
120+
121+
url := fmt.Sprintf(
122+
"/_apis/distributedtask/pools/%v/jobrequests",
123+
fmt.Sprintf("%d", agentPoolId),
124+
)
125+
response, err := c.rest().R().Get(url)
126+
if err := c.checkResponse(response, err); err != nil {
127+
error = err
128+
return
129+
}
130+
131+
err = json.Unmarshal(response.Body(), &list)
132+
if err != nil {
133+
error = err
134+
return
135+
}
136+
137+
return
138+
}

collector_structs.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ func (m *MetricCollectorList) AddBool(labels prometheus.Labels, state bool) {
7171
m.list = append(m.list, MetricCollectorRow{labels: labels, value: value})
7272
}
7373

74-
7574
func (m *MetricCollectorList) GaugeSet(gauge *prometheus.GaugeVec) {
7675
for _, metric := range m.list {
7776
gauge.With(metric.labels).Set(metric.value)

metrics_agentpool.go

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type MetricsCollectorAgentPool struct {
1515
agentPoolAgent *prometheus.GaugeVec
1616
agentPoolAgentStatus *prometheus.GaugeVec
1717
agentPoolAgentJob *prometheus.GaugeVec
18+
agentPoolQueueLength *prometheus.GaugeVec
1819
}
1920
}
2021

@@ -89,11 +90,22 @@ func (m *MetricsCollectorAgentPool) Setup(collector *CollectorAgentPool) {
8990
},
9091
)
9192

93+
m.prometheus.agentPoolQueueLength = prometheus.NewGaugeVec(
94+
prometheus.GaugeOpts{
95+
Name: "azure_devops_agentpool_queue_length",
96+
Help: "Azure DevOps agentpool",
97+
},
98+
[]string{
99+
"agentPoolID",
100+
},
101+
)
102+
92103
prometheus.MustRegister(m.prometheus.agentPool)
93104
prometheus.MustRegister(m.prometheus.agentPoolSize)
94105
prometheus.MustRegister(m.prometheus.agentPoolAgent)
95106
prometheus.MustRegister(m.prometheus.agentPoolAgentStatus)
96107
prometheus.MustRegister(m.prometheus.agentPoolAgentJob)
108+
prometheus.MustRegister(m.prometheus.agentPoolQueueLength)
97109
}
98110

99111
func (m *MetricsCollectorAgentPool) Reset() {
@@ -102,6 +114,7 @@ func (m *MetricsCollectorAgentPool) Reset() {
102114
m.prometheus.agentPoolAgent.Reset()
103115
m.prometheus.agentPoolAgentStatus.Reset()
104116
m.prometheus.agentPoolAgentJob.Reset()
117+
m.prometheus.agentPoolQueueLength.Reset()
105118
}
106119

107120
func (m *MetricsCollectorAgentPool) Collect(ctx context.Context, callback chan<- func()) {
@@ -111,6 +124,7 @@ func (m *MetricsCollectorAgentPool) Collect(ctx context.Context, callback chan<-
111124

112125
for _, agentPoolId := range m.CollectorReference.AgentPoolIdList {
113126
m.collectAgentQueues(ctx, callback, agentPoolId)
127+
m.collectAgentPoolJobs(ctx, callback, agentPoolId)
114128
}
115129
}
116130

@@ -185,7 +199,7 @@ func (m *MetricsCollectorAgentPool) collectAgentQueues(ctx context.Context, call
185199
"definitionName": agentPoolAgent.AssignedRequest.Definition.Name,
186200
"scopeID": agentPoolAgent.AssignedRequest.ScopeId,
187201
}
188-
agentPoolAgentJobMetric.Add(jobLabels, timeToFloat64(agentPoolAgent.AssignedRequest.AssignTime))
202+
agentPoolAgentJobMetric.Add(jobLabels, timeToFloat64(*agentPoolAgent.AssignedRequest.AssignTime))
189203
}
190204
}
191205

@@ -195,3 +209,31 @@ func (m *MetricsCollectorAgentPool) collectAgentQueues(ctx context.Context, call
195209
agentPoolAgentJobMetric.GaugeSet(m.prometheus.agentPoolAgentJob)
196210
}
197211
}
212+
213+
func (m *MetricsCollectorAgentPool) collectAgentPoolJobs(ctx context.Context, callback chan<- func(), agentPoolId int64) {
214+
list, err := AzureDevopsClient.ListAgentPoolJobs(agentPoolId)
215+
if err != nil {
216+
Logger.Errorf("agentpool[%v]call[ListAgentJobs]: %v", agentPoolId, err)
217+
return
218+
}
219+
220+
agentPoolQueueLengthMetric := NewMetricCollectorList()
221+
222+
notStartedJobCount := 0
223+
224+
for _, agentPoolJob := range list.List {
225+
if agentPoolJob.AssignTime == nil {
226+
notStartedJobCount++
227+
}
228+
}
229+
230+
infoLabels := prometheus.Labels{
231+
"agentPoolID": int64ToString(agentPoolId),
232+
}
233+
234+
agentPoolQueueLengthMetric.Add(infoLabels, float64(notStartedJobCount))
235+
236+
callback <- func() {
237+
agentPoolQueueLengthMetric.GaugeSet(m.prometheus.agentPoolQueueLength)
238+
}
239+
}

0 commit comments

Comments
 (0)