@@ -12,18 +12,18 @@ import (
12
12
13
13
"cdr.dev/slog"
14
14
15
+ "github.com/coder/quartz"
15
16
"github.com/google/uuid"
16
17
17
18
"github.com/coder/coder/v2/coderd/database"
18
19
"github.com/coder/coder/v2/coderd/database/dbauthz"
19
20
"github.com/coder/coder/v2/coderd/database/dbtime"
20
21
"github.com/coder/coder/v2/coderd/notifications"
21
22
"github.com/coder/coder/v2/codersdk"
22
- "github.com/coder/quartz"
23
23
)
24
24
25
25
const (
26
- delay = 5 * time .Minute
26
+ delay = 15 * time .Minute
27
27
)
28
28
29
29
func NewReportGenerator (ctx context.Context , logger slog.Logger , db database.Store , enqueur notifications.Enqueuer , clk quartz.Clock ) io.Closer {
@@ -99,30 +99,32 @@ func (i *reportGenerator) Close() error {
99
99
func reportFailedWorkspaceBuilds (ctx context.Context , logger slog.Logger , db database.Store , enqueuer notifications.Enqueuer , clk quartz.Clock ) error {
100
100
const frequencyDays = 7
101
101
102
- templates , err := db .GetTemplatesWithFilter (ctx , database.GetTemplatesWithFilterParams {
103
- Deleted : false ,
104
- Deprecated : sql.NullBool {Bool : false , Valid : true },
105
- })
102
+ statsRows , err := db .GetWorkspaceBuildStatsByTemplates (ctx , dbtime .Time (clk .Now ()).UTC ())
106
103
if err != nil {
107
- return xerrors .Errorf ("unable to fetch active templates : %w" , err )
104
+ return xerrors .Errorf ("unable to fetch failed workspace builds : %w" , err )
108
105
}
109
106
110
- for _ , template := range templates {
111
- failedBuilds , err := db .GetFailedWorkspaceBuildsByTemplateID (ctx , database.GetFailedWorkspaceBuildsByTemplateIDParams {
112
- TemplateID : template .ID ,
113
- Since : dbtime .Time (clk .Now ()).UTC (),
114
- })
115
- if err != nil {
116
- logger .Error (ctx , "unable to fetch failed workspace builds" , slog .F ("template_id" , template .ID ), slog .Error (err ))
117
- continue
118
- }
119
-
120
- // TODO Lazy-render the report.
107
+ for _ , stats := range statsRows {
108
+ var failedBuilds []database.WorkspaceBuild
121
109
reportData := map [string ]any {}
122
110
123
- templateAdmins , err := findTemplateAdmins (ctx , db , template )
111
+ if stats .FailedBuilds > 0 {
112
+ failedBuilds , err = db .GetFailedWorkspaceBuildsByTemplateID (ctx , database.GetFailedWorkspaceBuildsByTemplateIDParams {
113
+ TemplateID : stats .TemplateID ,
114
+ Since : dbtime .Time (clk .Now ()).UTC (),
115
+ })
116
+ if err != nil {
117
+ logger .Error (ctx , "unable to fetch failed workspace builds" , slog .F ("template_id" , template .ID ), slog .Error (err ))
118
+ continue
119
+ }
120
+
121
+ // TODO Lazy-render the report.
122
+ reportData = map [string ]any {}
123
+ }
124
+
125
+ templateAdmins , err := findTemplateAdmins (ctx , db , stats )
124
126
if err != nil {
125
- logger .Error (ctx , "unable to find template admins" , slog .F ("template_id" , template . ID ), slog .Error (err ))
127
+ logger .Error (ctx , "unable to find template admins" , slog .F ("template_id" , stats . TemplateID ), slog .Error (err ))
126
128
continue
127
129
}
128
130
@@ -145,7 +147,7 @@ func reportFailedWorkspaceBuilds(ctx context.Context, logger slog.Logger, db dat
145
147
LastGeneratedAt : dbtime .Time (clk .Now ()).UTC (),
146
148
})
147
149
if err != nil {
148
- logger .Error (ctx , "unable to update report generator logs" , slog .F ("template_id" , template . ID ), slog .F ("user_id" , templateAdmin .ID ), slog .F ("failed_builds" , len (failedBuilds )), slog .Error (err ))
150
+ logger .Error (ctx , "unable to update report generator logs" , slog .F ("template_id" , stats . TemplateID ), slog .F ("user_id" , templateAdmin .ID ), slog .F ("failed_builds" , len (failedBuilds )), slog .Error (err ))
149
151
continue
150
152
}
151
153
}
@@ -158,24 +160,24 @@ func reportFailedWorkspaceBuilds(ctx context.Context, logger slog.Logger, db dat
158
160
LastGeneratedAt : dbtime .Time (clk .Now ()).UTC (),
159
161
})
160
162
if err != nil {
161
- logger .Error (ctx , "unable to update report generator logs" , slog .F ("template_id" , template . ID ), slog .F ("user_id" , templateAdmin .ID ), slog .F ("failed_builds" , len (failedBuilds )), slog .Error (err ))
163
+ logger .Error (ctx , "unable to update report generator logs" , slog .F ("template_id" , stats . TemplateID ), slog .F ("user_id" , templateAdmin .ID ), slog .F ("failed_builds" , len (failedBuilds )), slog .Error (err ))
162
164
continue
163
165
}
164
166
}
165
167
166
- templateDisplayName := template . DisplayName
168
+ templateDisplayName := stats . TemplateDisplayName
167
169
if templateDisplayName == "" {
168
- templateDisplayName = template . Name
170
+ templateDisplayName = stats . TemplateName
169
171
}
170
172
171
173
if _ , err := enqueuer .EnqueueData (ctx , templateAdmin .ID , notifications .TemplateWorkspaceBuildsFailedReport ,
172
174
map [string ]string {
173
- "template_name" : template . Name ,
175
+ "template_name" : stats . TemplateName ,
174
176
"template_display_name" : templateDisplayName ,
175
177
},
176
178
reportData ,
177
179
"report_generator" ,
178
- template . ID , template . OrganizationID ,
180
+ stats . TemplateID , stats . TemplateOrganizationID ,
179
181
); err != nil {
180
182
logger .Warn (ctx , "failed to send a report with failed workspace builds" , slog .Error (err ))
181
183
}
@@ -186,7 +188,7 @@ func reportFailedWorkspaceBuilds(ctx context.Context, logger slog.Logger, db dat
186
188
LastGeneratedAt : dbtime .Time (clk .Now ()).UTC (),
187
189
})
188
190
if err != nil {
189
- logger .Error (ctx , "unable to update report generator logs" , slog .F ("template_id" , template . ID ), slog .F ("user_id" , templateAdmin .ID ), slog .F ("failed_builds" , len (failedBuilds )), slog .Error (err ))
191
+ logger .Error (ctx , "unable to update report generator logs" , slog .F ("template_id" , stats . TemplateID ), slog .F ("user_id" , templateAdmin .ID ), slog .F ("failed_builds" , len (failedBuilds )), slog .Error (err ))
190
192
continue
191
193
}
192
194
}
@@ -206,7 +208,7 @@ func buildDataForReportFailedWorkspaceBuilds() map[string]any {
206
208
return reportData
207
209
}
208
210
209
- func findTemplateAdmins (ctx context.Context , db database.Store , template database.Template ) ([]database.GetUsersRow , error ) {
211
+ func findTemplateAdmins (ctx context.Context , db database.Store , stats database.GetWorkspaceBuildStatsByTemplatesRow ) ([]database.GetUsersRow , error ) {
210
212
users , err := db .GetUsers (ctx , database.GetUsersParams {
211
213
RbacRole : []string {codersdk .RoleTemplateAdmin },
212
214
})
@@ -229,7 +231,7 @@ func findTemplateAdmins(ctx context.Context, db database.Store, template databas
229
231
}
230
232
231
233
for _ , entry := range orgIDsByMemberIDs {
232
- if slices .Contains (entry .OrganizationIDs , template . OrganizationID ) {
234
+ if slices .Contains (entry .OrganizationIDs , stats . TemplateOrganizationID ) {
233
235
templateAdmins = append (templateAdmins , usersByIDs [entry .UserID ])
234
236
}
235
237
}
0 commit comments