This commit is contained in:
@@ -1059,6 +1059,12 @@ const docTemplate = `{
|
||||
"description": "Time period (e.g. 1h, 24h, 7d)",
|
||||
"name": "period",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Filter by agent ID",
|
||||
"name": "agent_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -1048,6 +1048,12 @@
|
||||
"description": "Time period (e.g. 1h, 24h, 7d)",
|
||||
"name": "period",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Filter by agent ID",
|
||||
"name": "agent_id",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -1229,6 +1229,10 @@ paths:
|
||||
in: query
|
||||
name: period
|
||||
type: string
|
||||
- description: Filter by agent ID
|
||||
in: query
|
||||
name: agent_id
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
||||
@@ -230,6 +230,7 @@ type JobMetricsOut struct {
|
||||
// @Tags jobs
|
||||
// @Produce json
|
||||
// @Param period query string false "Time period (e.g. 1h, 24h, 7d)" default(24h)
|
||||
// @Param agent_id query string false "Filter by agent ID"
|
||||
// @Success 200 {object} JobMetricsOut
|
||||
// @Failure 400 {object} map[string]string
|
||||
// @Security Bearer
|
||||
@@ -242,8 +243,9 @@ func (h *JobsHandlers) GetJobMetrics(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
agentID := c.Query("agent_id")
|
||||
since := time.Now().Add(-period)
|
||||
metrics, err := h.jobRepo.GetJobMetrics(c.Request.Context(), since)
|
||||
metrics, err := h.jobRepo.GetJobMetrics(c.Request.Context(), since, agentID)
|
||||
if err != nil {
|
||||
c.Error(err)
|
||||
return
|
||||
|
||||
@@ -113,18 +113,22 @@ type JobMetrics struct {
|
||||
}
|
||||
|
||||
// GetJobMetrics returns job success metrics for jobs updated since the given time.
|
||||
// A successful job has status == 0, failed has status != 0, pending has status == 0 with empty stdout/stderr.
|
||||
func (r *JobRepository) GetJobMetrics(ctx context.Context, since time.Time) (JobMetrics, error) {
|
||||
// If agentID is non-empty, results are filtered to that agent only.
|
||||
func (r *JobRepository) GetJobMetrics(ctx context.Context, since time.Time, agentID string) (JobMetrics, error) {
|
||||
var m JobMetrics
|
||||
err := r.DB.QueryRowContext(ctx,
|
||||
`SELECT
|
||||
COUNT(*),
|
||||
SUM(CASE WHEN status = 0 AND (stdout != '' OR stderr != '') THEN 1 ELSE 0 END),
|
||||
SUM(CASE WHEN status != 0 THEN 1 ELSE 0 END),
|
||||
SUM(CASE WHEN status = 0 AND stdout = '' AND stderr = '' THEN 1 ELSE 0 END)
|
||||
FROM jobs WHERE updated_at >= ?`,
|
||||
since,
|
||||
).Scan(&m.Total, &m.Success, &m.Failed, &m.Pending)
|
||||
query := `SELECT
|
||||
COUNT(*),
|
||||
SUM(CASE WHEN status = 0 AND (stdout != '' OR stderr != '') THEN 1 ELSE 0 END),
|
||||
SUM(CASE WHEN status != 0 THEN 1 ELSE 0 END),
|
||||
SUM(CASE WHEN status = 0 AND stdout = '' AND stderr = '' THEN 1 ELSE 0 END)
|
||||
FROM jobs WHERE updated_at >= ?`
|
||||
args := []any{since}
|
||||
if agentID != "" {
|
||||
query += " AND agent_id = ?"
|
||||
args = append(args, agentID)
|
||||
}
|
||||
|
||||
err := r.DB.QueryRowContext(ctx, query, args...).Scan(&m.Total, &m.Success, &m.Failed, &m.Pending)
|
||||
if err != nil {
|
||||
return JobMetrics{}, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user