Skip to content

Commit 671c971

Browse files
committed
Show last cron messages on monitor page
As discussed on go-gitea#19221 we should store the results of the last task message on the crontask and show them on the monitor page. Signed-off-by: Andrew Thornton <[email protected]>
1 parent c119828 commit 671c971

File tree

6 files changed

+108
-67
lines changed

6 files changed

+108
-67
lines changed

options/locale/locale_en-US.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2815,6 +2815,7 @@ monitor.process = Running Processes
28152815
monitor.desc = Description
28162816
monitor.start = Start Time
28172817
monitor.execute_time = Execution Time
2818+
monitor.last_execution_result = Success?
28182819
monitor.process.cancel = Cancel process
28192820
monitor.process.cancel_desc = Cancelling a process may cause data loss
28202821
monitor.process.cancel_notices = Cancel: <strong>%s</strong>?

services/cron/cron.go

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,23 @@ func NewContext() {
4747

4848
// TaskTableRow represents a task row in the tasks table
4949
type TaskTableRow struct {
50-
Name string
51-
Spec string
52-
Next time.Time
53-
Prev time.Time
54-
ExecTimes int64
50+
Name string
51+
Spec string
52+
Next time.Time
53+
Prev time.Time
54+
Status string
55+
LastMessage string
56+
LastDoer string
57+
ExecTimes int64
58+
task *Task
59+
}
60+
61+
func (t *TaskTableRow) FormatLastMessage(locale string) string {
62+
if t.Status == "finished" {
63+
return t.task.GetConfig().FormatMessage(locale, t.Name, t.Status, t.LastDoer)
64+
}
65+
66+
return t.task.GetConfig().FormatMessage(locale, t.Name, t.Status, t.LastDoer, t.LastMessage)
5567
}
5668

5769
// TaskTable represents a table of tasks
@@ -80,11 +92,15 @@ func ListTasks() TaskTable {
8092
}
8193
task.lock.Lock()
8294
tTable = append(tTable, &TaskTableRow{
83-
Name: task.Name,
84-
Spec: spec,
85-
Next: next,
86-
Prev: prev,
87-
ExecTimes: task.ExecTimes,
95+
Name: task.Name,
96+
Spec: spec,
97+
Next: next,
98+
Prev: prev,
99+
ExecTimes: task.ExecTimes,
100+
LastMessage: task.LastMessage,
101+
Status: task.Status,
102+
LastDoer: task.LastDoer,
103+
task: task,
88104
})
89105
task.lock.Unlock()
90106
}

services/cron/setting.go

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ package cron
77
import (
88
"time"
99

10-
user_model "code.gitea.io/gitea/models/user"
11-
1210
"github.com/unknwon/i18n"
1311
)
1412

@@ -17,7 +15,7 @@ type Config interface {
1715
IsEnabled() bool
1816
DoRunAtStart() bool
1917
GetSchedule() string
20-
FormatMessage(name, status string, doer *user_model.User, args ...interface{}) string
18+
FormatMessage(locale, name, status, doer string, args ...interface{}) string
2119
DoNoticeOnSuccess() bool
2220
}
2321

@@ -70,19 +68,19 @@ func (b *BaseConfig) DoNoticeOnSuccess() bool {
7068
}
7169

7270
// FormatMessage returns a message for the task
73-
func (b *BaseConfig) FormatMessage(name, status string, doer *user_model.User, args ...interface{}) string {
71+
func (b *BaseConfig) FormatMessage(locale, name, status, doer string, args ...interface{}) string {
7472
realArgs := make([]interface{}, 0, len(args)+2)
75-
realArgs = append(realArgs, i18n.Tr("en-US", "admin.dashboard."+name))
76-
if doer == nil {
73+
realArgs = append(realArgs, i18n.Tr(locale, "admin.dashboard."+name))
74+
if doer == "" {
7775
realArgs = append(realArgs, "(Cron)")
7876
} else {
79-
realArgs = append(realArgs, doer.Name)
77+
realArgs = append(realArgs, doer)
8078
}
8179
if len(args) > 0 {
8280
realArgs = append(realArgs, args...)
8381
}
84-
if doer == nil || (doer.ID == -1 && doer.Name == "(Cron)") {
85-
return i18n.Tr("en-US", "admin.dashboard.cron."+status, realArgs...)
82+
if doer == "" {
83+
return i18n.Tr(locale, "admin.dashboard.cron."+status, realArgs...)
8684
}
87-
return i18n.Tr("en-US", "admin.dashboard.task."+status, realArgs...)
85+
return i18n.Tr(locale, "admin.dashboard.task."+status, realArgs...)
8886
}

services/cron/tasks.go

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@ var (
2929

3030
// Task represents a Cron task
3131
type Task struct {
32-
lock sync.Mutex
33-
Name string
34-
config Config
35-
fun func(context.Context, *user_model.User, Config) error
36-
ExecTimes int64
32+
lock sync.Mutex
33+
Name string
34+
config Config
35+
fun func(context.Context, *user_model.User, Config) error
36+
Status string
37+
LastMessage string
38+
LastDoer string
39+
ExecTimes int64
3740
}
3841

3942
// DoRunAtStart returns if this task should run at the start
@@ -86,24 +89,45 @@ func (t *Task) RunWithUser(doer *user_model.User, config Config) {
8689
}()
8790
graceful.GetManager().RunWithShutdownContext(func(baseCtx context.Context) {
8891
pm := process.GetManager()
89-
ctx, _, finished := pm.AddContext(baseCtx, config.FormatMessage(t.Name, "process", doer))
92+
doerName := ""
93+
if doer != nil && doer.ID != -1 {
94+
doerName = doer.Name
95+
}
96+
97+
ctx, _, finished := pm.AddContext(baseCtx, config.FormatMessage("en-US", t.Name, "process", doerName))
9098
defer finished()
9199

92100
if err := t.fun(ctx, doer, config); err != nil {
101+
var message string
102+
var status string
93103
if db.IsErrCancelled(err) {
94-
message := err.(db.ErrCancelled).Message
95-
if err := admin_model.CreateNotice(ctx, admin_model.NoticeTask, config.FormatMessage(t.Name, "aborted", doer, message)); err != nil {
96-
log.Error("CreateNotice: %v", err)
97-
}
98-
return
104+
status = "aborted"
105+
message = err.(db.ErrCancelled).Message
106+
} else {
107+
status = "error"
108+
message = err.Error()
99109
}
100-
if err := admin_model.CreateNotice(ctx, admin_model.NoticeTask, config.FormatMessage(t.Name, "error", doer, err)); err != nil {
110+
111+
t.lock.Lock()
112+
t.LastMessage = message
113+
t.Status = status
114+
t.LastDoer = doerName
115+
t.lock.Unlock()
116+
117+
if err := admin_model.CreateNotice(ctx, admin_model.NoticeTask, config.FormatMessage("en-US", t.Name, "aborted", doerName, message)); err != nil {
101118
log.Error("CreateNotice: %v", err)
102119
}
103120
return
104121
}
122+
123+
t.lock.Lock()
124+
t.Status = "finished"
125+
t.LastMessage = ""
126+
t.LastDoer = doerName
127+
t.lock.Unlock()
128+
105129
if config.DoNoticeOnSuccess() {
106-
if err := admin_model.CreateNotice(ctx, admin_model.NoticeTask, config.FormatMessage(t.Name, "finished", doer)); err != nil {
130+
if err := admin_model.CreateNotice(ctx, admin_model.NoticeTask, config.FormatMessage("en-US", t.Name, "finished", doerName)); err != nil {
107131
log.Error("CreateNotice: %v", err)
108132
}
109133
}

templates/admin/cron.tmpl

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<h4 class="ui top attached header">
2+
{{.i18n.Tr "admin.monitor.cron"}}
3+
</h4>
4+
<div class="ui attached table segment">
5+
<form method="post" action="{{AppSubUrl}}/admin">
6+
<table class="ui very basic striped table">
7+
<thead>
8+
<tr>
9+
<th></th>
10+
<th>{{.i18n.Tr "admin.monitor.name"}}</th>
11+
<th>{{.i18n.Tr "admin.monitor.schedule"}}</th>
12+
<th>{{.i18n.Tr "admin.monitor.next"}}</th>
13+
<th>{{.i18n.Tr "admin.monitor.previous"}}</th>
14+
<th>{{.i18n.Tr "admin.monitor.execute_times"}}</th>
15+
<th>{{.i18n.Tr "admin.monitor.last_execution_result"}}</th>
16+
</tr>
17+
</thead>
18+
<tbody>
19+
{{range .Entries}}
20+
<tr>
21+
<td><button type="submit" class="ui green button" name="op" value="{{.Name}}" title="{{$.i18n.Tr "admin.dashboard.operation_run"}}">{{svg "octicon-triangle-right"}}</button></td>
22+
<td>{{$.i18n.Tr (printf "admin.dashboard.%s" .Name)}}</td>
23+
<td>{{.Spec}}</td>
24+
<td>{{DateFmtLong .Next}}</td>
25+
<td>{{if gt .Prev.Year 1 }}{{DateFmtLong .Prev}}{{else}}N/A{{end}}</td>
26+
<td>{{.ExecTimes}}</td>
27+
<td {{if ne .Status ""}}class="tooltip" data-content="{{.FormatLastMessage $.i18n.Language}}"{{end}} >{{if eq .Status "" }}—{{else if eq .Status "finished"}}{{svg "octicon-check" 16}}{{else}}{{svg "octicon-x" 16}}{{end}}</td>
28+
</tr>
29+
{{end}}
30+
</tbody>
31+
</table>
32+
<input type="hidden" name="from" value="monitor"/>
33+
{{.CsrfTokenHtml}}
34+
</form>
35+
</div>

templates/admin/monitor.tmpl

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,7 @@
33
{{template "admin/navbar" .}}
44
<div class="ui container">
55
{{template "base/alert" .}}
6-
<h4 class="ui top attached header">
7-
{{.i18n.Tr "admin.monitor.cron"}}
8-
</h4>
9-
<div class="ui attached table segment">
10-
<form method="post" action="{{AppSubUrl}}/admin">
11-
<table class="ui very basic striped table">
12-
<thead>
13-
<tr>
14-
<th></th>
15-
<th>{{.i18n.Tr "admin.monitor.name"}}</th>
16-
<th>{{.i18n.Tr "admin.monitor.schedule"}}</th>
17-
<th>{{.i18n.Tr "admin.monitor.next"}}</th>
18-
<th>{{.i18n.Tr "admin.monitor.previous"}}</th>
19-
<th>{{.i18n.Tr "admin.monitor.execute_times"}}</th>
20-
</tr>
21-
</thead>
22-
<tbody>
23-
{{range .Entries}}
24-
<tr>
25-
<td><button type="submit" class="ui green button" name="op" value="{{.Name}}" title="{{$.i18n.Tr "admin.dashboard.operation_run"}}">{{svg "octicon-triangle-right"}}</button></td>
26-
<td>{{$.i18n.Tr (printf "admin.dashboard.%s" .Name)}}</td>
27-
<td>{{.Spec}}</td>
28-
<td>{{DateFmtLong .Next}}</td>
29-
<td>{{if gt .Prev.Year 1 }}{{DateFmtLong .Prev}}{{else}}N/A{{end}}</td>
30-
<td>{{.ExecTimes}}</td>
31-
</tr>
32-
{{end}}
33-
</tbody>
34-
</table>
35-
<input type="hidden" name="from" value="monitor"/>
36-
{{.CsrfTokenHtml}}
37-
</form>
38-
</div>
39-
6+
{{template "admin/cron" .}}
407
<h4 class="ui top attached header">
418
{{.i18n.Tr "admin.monitor.queues"}}
429
</h4>

0 commit comments

Comments
 (0)