Skip to content

Commit

Permalink
Job Logs (#202)
Browse files Browse the repository at this point in the history
* feat: job logs

* test: add job log tests

* refactor: linting
  • Loading branch information
arthurcgc authored Jun 19, 2023
1 parent 6a3eb3a commit 830193a
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 3 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ require (
github.com/pmorie/go-open-service-broker-client v0.0.0-20180330214919-dca737037ce6
github.com/sabhiram/go-gitignore v0.0.0-20171017070213-362f9845770f
github.com/tsuru/gnuflag v0.0.0-20151217162021-86b8c1b864aa
github.com/tsuru/go-tsuruclient v0.0.0-20230410125939-b9d68773f7b6
github.com/tsuru/go-tsuruclient v0.0.0-20230612145111-83c76176241f
github.com/tsuru/tablecli v0.0.0-20190131152944-7ded8a3383c6
github.com/tsuru/tsuru v0.0.0-20221019183903-abc5e18fa173
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,10 @@ github.com/tsuru/gnuflag v0.0.0-20151217162021-86b8c1b864aa h1:JlLQP1xa13a994p/A
github.com/tsuru/gnuflag v0.0.0-20151217162021-86b8c1b864aa/go.mod h1:UibOSvkMFKRe/eiwktAPAvQG8L+p8nYsECJvu3Dgw7I=
github.com/tsuru/go-tsuruclient v0.0.0-20230410125939-b9d68773f7b6 h1:6YyC5ZaJgWYu9hMa00jOYXBeTQ9Ease8js/PQJUsQRo=
github.com/tsuru/go-tsuruclient v0.0.0-20230410125939-b9d68773f7b6/go.mod h1:P2AL93lzpzJlgOvu37SOhee4pnLWod1GMJ8YYQq2b7o=
github.com/tsuru/go-tsuruclient v0.0.0-20230605133042-56d04166e039 h1:W3uDizGxzjBt4T+EnjxSGCBC33yEM25xO+k/oGPJ7ik=
github.com/tsuru/go-tsuruclient v0.0.0-20230605133042-56d04166e039/go.mod h1:P2AL93lzpzJlgOvu37SOhee4pnLWod1GMJ8YYQq2b7o=
github.com/tsuru/go-tsuruclient v0.0.0-20230612145111-83c76176241f h1:JOkngwIMzp01ZC2v+srUT7TLI91dC59gYmnYMZTPzYQ=
github.com/tsuru/go-tsuruclient v0.0.0-20230612145111-83c76176241f/go.mod h1:P2AL93lzpzJlgOvu37SOhee4pnLWod1GMJ8YYQq2b7o=
github.com/tsuru/monsterqueue v0.0.0-20160909010522-70e946ec66c3 h1:+aJngj5cQjYyx/qSjffQceop25t97hLS0+t8bvx9hg4=
github.com/tsuru/monsterqueue v0.0.0-20160909010522-70e946ec66c3/go.mod h1:3KR1vkjfm5b7Lhu5OXuO0NMIyZNG0d0d9xh6ufWYVxg=
github.com/tsuru/tablecli v0.0.0-20180215113938-82de88f75181/go.mod h1:ztYpOhW+u1k21FEqp7nZNgpWbr0dUKok5lgGCZi+1AQ=
Expand Down
60 changes: 59 additions & 1 deletion tsuru/client/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
"text/template"
"time"

"github.com/antihax/optional"
"github.com/mattn/go-shellwords"
"github.com/tsuru/gnuflag"
"github.com/tsuru/go-tsuruclient/pkg/client"
Expand Down Expand Up @@ -237,7 +239,6 @@ func (c *JobInfo) Run(ctx *cmd.Context, cli *cmd.Client) error {
}

func renderJobUnits(buf *bytes.Buffer, units []tsuru.Unit) {

titles := []string{"Name", "Status", "Restarts", "Age"}
unitsTable := tablecli.NewTable()
tablecli.TableConfig.ForceWrap = false
Expand Down Expand Up @@ -577,3 +578,60 @@ func (c *JobUpdate) Run(ctx *cmd.Context, cli *cmd.Client) error {
fmt.Fprintf(ctx.Stdout, "Job updated\nUse \"tsuru job info %s\" to check the status of the job\n", jobName)
return nil
}

type JobLog struct {
follow bool
fs *gnuflag.FlagSet
}

func (c *JobLog) Info() *cmd.Info {
return &cmd.Info{
Name: "job-log",
Usage: "job log <job-name>",
Desc: "Retrieve logs a job",
MinArgs: 1,
MaxArgs: 1,
}
}

func (c *JobLog) Flags() *gnuflag.FlagSet {
if c.fs == nil {
c.fs = gnuflag.NewFlagSet("job-log", gnuflag.ExitOnError)
followMsg := "Follow logs"
c.fs.BoolVar(&c.follow, "f", false, followMsg)
c.fs.BoolVar(&c.follow, "follow", false, followMsg)
}
return c.fs
}

func (c *JobLog) Run(ctx *cmd.Context, cli *cmd.Client) error {
jobName := ctx.Args[0]
apiClient, err := client.ClientFromEnvironment(&tsuru.Configuration{
HTTPClient: cli.HTTPClient,
})
if err != nil {
return err
}

resp, err := apiClient.JobApi.JobLog(context.Background(), jobName, &tsuru.JobLogOpts{
Follow: optional.NewBool(c.follow),
})
if err != nil {
return err
}
defer resp.Body.Close()
formatter := logFormatter{}
dec := json.NewDecoder(resp.Body)
ctx.RawOutput()
for {
err = formatter.Format(ctx.Stdout, dec)
if err != nil {
if err != io.EOF {
fmt.Fprintf(ctx.Stdout, "Error: %v", err)
}
break
}
}

return nil
}
95 changes: 95 additions & 0 deletions tsuru/client/jobs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"fmt"
"io"
"net/http"
"net/url"

"github.com/tsuru/go-tsuruclient/pkg/tsuru"
"github.com/tsuru/tsuru/cmd"
Expand Down Expand Up @@ -532,3 +533,97 @@ func (s *S) TestJobUpdateApiError(c *check.C) {
c.Assert(err, check.NotNil)
c.Assert(err.Error(), check.Equals, expected)
}

func (s *S) TestJobLog(c *check.C) {
var stdout, stderr bytes.Buffer
context := cmd.Context{
Args: []string{"cerrone"},
Stdout: &stdout,
Stderr: &stderr,
}
log := `
[{
"Date": "2023-06-06T17:45:57.11625803Z",
"Message": "Hello World!",
"Source": "",
"Name": "cerrone",
"Type": "job",
"Unit": "cerrone-7k2c8"
}]
`
expectedPrefix := "2023-06-06 12:45:57 -0500 [cerrone-7k2c8]:"
expectedMessage := "Hello World!"
expected := fmt.Sprintf("%s %s\n", cmd.Colorfy(expectedPrefix, "blue", "", ""), expectedMessage)
trans := cmdtest.ConditionalTransport{
Transport: cmdtest.Transport{Message: log, Status: http.StatusOK},
CondFunc: func(r *http.Request) bool {
c.Assert(r.URL.Path, check.Equals, "/1.13/jobs/cerrone/log")
c.Assert(r.URL.Query(), check.DeepEquals, url.Values{"follow": []string{"false"}})
c.Assert(r.Method, check.Equals, "GET")
c.Assert(r.Header.Get("Accept"), check.Equals, "application/x-json-stream")
c.Assert(r.Body, check.IsNil)
return true
},
}
client := cmd.NewClient(&http.Client{Transport: &trans}, nil, manager)
command := JobLog{}
err := command.Run(&context, client)
c.Assert(err, check.IsNil)
c.Assert(stdout.String(), check.DeepEquals, expected)
}

func (s *S) TestJobLogFollow(c *check.C) {
var stdout, stderr bytes.Buffer
context := cmd.Context{
Args: []string{"frank-ocean"},
Stdout: &stdout,
Stderr: &stderr,
}
log := `
[{
"Date": "2023-06-06T17:45:57.11625803Z",
"Message": "Hello World!",
"Source": "",
"Name": "frank-ocean",
"Type": "job",
"Unit": "frank-ocean-7k2c8"
}]
`
expectedPrefix := "2023-06-06 12:45:57 -0500 [frank-ocean-7k2c8]:"
expectedMessage := "Hello World!"
expected := fmt.Sprintf("%s %s\n", cmd.Colorfy(expectedPrefix, "blue", "", ""), expectedMessage)
trans := cmdtest.ConditionalTransport{
Transport: cmdtest.Transport{Message: log, Status: http.StatusOK},
CondFunc: func(r *http.Request) bool {
c.Assert(r.URL.Query(), check.DeepEquals, url.Values{"follow": []string{"true"}})
return true
},
}
client := cmd.NewClient(&http.Client{Transport: &trans}, nil, manager)
command := JobLog{}
command.Flags().Parse(true, []string{"-f"})
err := command.Run(&context, client)
c.Assert(err, check.IsNil)
c.Assert(stdout.String(), check.DeepEquals, expected)
}

func (s *S) TestJobLogApiError(c *check.C) {
var stdout, stderr bytes.Buffer
context := cmd.Context{
Args: []string{"gorillaz"},
Stdout: &stdout,
Stderr: &stderr,
}
expected := "500 Internal Server Error: some error"
trans := cmdtest.ConditionalTransport{
Transport: cmdtest.Transport{Message: "some error", Status: http.StatusInternalServerError},
CondFunc: func(r *http.Request) bool {
return true
},
}
client := cmd.NewClient(&http.Client{Transport: &trans}, nil, manager)
command := JobLog{}
err := command.Run(&context, client)
c.Assert(err, check.NotNil)
c.Assert(err.Error(), check.Equals, expected)
}
4 changes: 3 additions & 1 deletion tsuru/client/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@ func (f logFormatter) prefix(l log) string {
parts = append(parts, formatter.Local(l.Date).Format("2006-01-02 15:04:05 -0700"))
}
if !f.noSource {
if l.Unit != "" {
if l.Unit != "" && l.Source != "" {
parts = append(parts, fmt.Sprintf("[%s][%s]", l.Source, l.Unit))
} else if l.Unit != "" {
parts = append(parts, fmt.Sprintf("[%s]", l.Unit))
} else {
parts = append(parts, fmt.Sprintf("[%s]", l.Source))
}
Expand Down
1 change: 1 addition & 0 deletions tsuru/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Services aren’t managed by tsuru, but by their creators.`)
m.Register(&client.JobList{})
m.Register(&client.JobDelete{})
m.Register(&client.JobTrigger{})
m.Register(&client.JobLog{})

m.Register(&client.PluginInstall{})
m.Register(&client.PluginRemove{})
Expand Down

0 comments on commit 830193a

Please sign in to comment.