From 81081c8164ec9df1467aaff2787b90424db48f2e Mon Sep 17 00:00:00 2001 From: cuigh Date: Fri, 23 Feb 2018 11:06:45 +0800 Subject: [PATCH] Add task logs page --- biz/docker/task.go | 33 ++++++++++++-- controller/task.go | 22 +++++++++ misc/perm.go | 2 + views/task/detail.jet | 1 + views/task/logs.jet | 103 ++++++++++++++++++++++++++++++++++++++++++ views/task/raw.jet | 1 + 6 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 views/task/logs.jet diff --git a/biz/docker/task.go b/biz/docker/task.go index edc9794..a73ba10 100644 --- a/biz/docker/task.go +++ b/biz/docker/task.go @@ -1,10 +1,12 @@ package docker import ( + "bytes" "context" "io" "math" "sort" + "strconv" "github.com/cuigh/swirl/misc" "github.com/cuigh/swirl/model" @@ -12,6 +14,7 @@ import ( "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/client" + "github.com/docker/docker/pkg/stdcopy" ) // TaskList return all running tasks of a service or a node. @@ -88,11 +91,31 @@ func TaskInspect(id string) (task swarm.Task, raw []byte, err error) { // TaskLogs returns the logs generated by a task in an io.ReadCloser. // It's up to the caller to close the stream. -func TaskLogs(id string) (rc io.ReadCloser, err error) { - err = mgr.Do(func(ctx context.Context, cli *client.Client) (err error) { - opts := types.ContainerLogsOptions{} - rc, err = cli.TaskLogs(ctx, id, opts) +func TaskLogs(id string, line int, timestamps bool) (stdout, stderr *bytes.Buffer, err error) { + var ( + ctx context.Context + cli *client.Client + rc io.ReadCloser + ) + + ctx, cli, err = mgr.Client() + if err != nil { return - }) + } + + opts := types.ContainerLogsOptions{ + ShowStdout: true, + ShowStderr: true, + Tail: strconv.Itoa(line), + Timestamps: timestamps, + //Since: (time.Hour * 24).String() + } + if rc, err = cli.TaskLogs(ctx, id, opts); err == nil { + defer rc.Close() + + stdout = &bytes.Buffer{} + stderr = &bytes.Buffer{} + _, err = stdcopy.StdCopy(stdout, stderr, rc) + } return } diff --git a/controller/task.go b/controller/task.go index c2f24c3..eb8770c 100644 --- a/controller/task.go +++ b/controller/task.go @@ -2,6 +2,7 @@ package controller import ( "github.com/cuigh/auxo/net/web" + "github.com/cuigh/auxo/util/cast" "github.com/cuigh/swirl/biz/docker" "github.com/cuigh/swirl/misc" "github.com/cuigh/swirl/model" @@ -12,6 +13,7 @@ type TaskController struct { List web.HandlerFunc `path:"/" name:"task.list" authorize:"!" desc:"task list page"` Detail web.HandlerFunc `path:"/:id/detail" name:"task.detail" authorize:"!" desc:"task detail page"` Raw web.HandlerFunc `path:"/:id/raw" name:"task.raw" authorize:"!" desc:"task raw page"` + Logs web.HandlerFunc `path:"/:id/logs" name:"task.logs" authorize:"!" desc:"task logs page"` } // Task creates an instance of TaskController @@ -20,6 +22,7 @@ func Task() (c *TaskController) { List: taskList, Detail: taskDetail, Raw: taskRaw, + Logs: taskLogs, } } @@ -71,3 +74,22 @@ func taskRaw(ctx web.Context) error { m := newModel(ctx).Set("Task", task).Set("Raw", j) return ctx.Render("task/raw", m) } + +func taskLogs(ctx web.Context) error { + id := ctx.P("id") + task, _, err := docker.TaskInspect(id) + if err != nil { + return err + } + + line := cast.ToInt(ctx.Q("line"), 500) + timestamps := cast.ToBool(ctx.Q("timestamps"), false) + stdout, stderr, err := docker.TaskLogs(id, line, timestamps) + if err != nil { + return err + } + + m := newModel(ctx).Set("Task", task).Set("Line", line).Set("Timestamps", timestamps). + Set("Stdout", stdout.String()).Set("Stderr", stderr.String()) + return ctx.Render("task/logs", m) +} diff --git a/misc/perm.go b/misc/perm.go index ed3d738..738ee90 100644 --- a/misc/perm.go +++ b/misc/perm.go @@ -91,6 +91,7 @@ var Perms = []PermGroup{ {Key: "task.list", Text: "View list"}, {Key: "task.detail", Text: "View detail"}, {Key: "task.raw", Text: "View raw"}, + {Key: "task.logs", Text: "View logs"}, }, }, { @@ -108,6 +109,7 @@ var Perms = []PermGroup{ {Key: "container.list", Text: "View list"}, {Key: "container.detail", Text: "View detail"}, {Key: "container.raw", Text: "View raw"}, + {Key: "container.logs", Text: "View logs"}, {Key: "container.delete", Text: "Delete"}, }, }, diff --git a/views/task/detail.jet b/views/task/detail.jet index b525e6c..92934e7 100644 --- a/views/task/detail.jet +++ b/views/task/detail.jet @@ -24,6 +24,7 @@ diff --git a/views/task/logs.jet b/views/task/logs.jet new file mode 100644 index 0000000..309b6e4 --- /dev/null +++ b/views/task/logs.jet @@ -0,0 +1,103 @@ +{{ extends "../_layouts/default" }} + +{{ block body() }} +
+
+
+

{{ i18n("container.title") }}

+

{{ i18n("container.description") }}

+
+
+
+ +
+ +
+ +
+
+
+

+ {{ .Task.Name ? .Task.Name : .Task.ID }} +

+
+
+
+ + + +
+
+ + +
+ +
+
+
+
+ {{ if .Stdout }}{{ end }} +
+
+ +
+ + + {{ i18n("button.return") }} + +
+
+{{ end }} \ No newline at end of file diff --git a/views/task/raw.jet b/views/task/raw.jet index 799e5ed..7906d31 100644 --- a/views/task/raw.jet +++ b/views/task/raw.jet @@ -33,6 +33,7 @@