forked from ovhlabs/sail
-
Notifications
You must be signed in to change notification settings - Fork 0
/
logs.go
97 lines (79 loc) · 2.63 KB
/
logs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package service
import (
"encoding/json"
"fmt"
"os"
"strings"
"text/tabwriter"
"github.com/google/go-querystring/query"
"github.com/runabove/sail/internal"
"github.com/spf13/cobra"
)
var (
logsBody Logs
)
func logsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "logs",
Short: "Logs of a docker service: sail service logs <applicationName>/<serviceId>",
Long: `Logs of a docker service: sail service logs <applicationName>/<serviceId>`,
Run: cmdLogs,
}
cmd.Flags().IntVarP(&logsBody.Tail, "tail", "", 0, "Return N last lines, before offset")
cmd.Flags().IntVarP(&logsBody.Head, "head", "", 0, "Return N first lines, after offset")
cmd.Flags().IntVarP(&logsBody.Offset, "offset", "", 0, "Offset result by N line")
cmd.Flags().StringVarP(&logsBody.Period, "period", "", "24 hours ago", "Lucene compatible period")
cmd.Flags().StringVarP(&logsBody.Search, "search", "", "", "Only return matching lines")
return cmd
}
// Logs struct holds all parameters sent to /applications/%s/services/%s/logs
type Logs struct {
Application string `url:"-"`
Service string `url:"-"`
Repository string `url:"repository,omitempty"`
Tail int `url:"tail,omitempty"`
Head int `url:"head,omitempty"`
Offset int `url:"offset,omitempty"`
Period string `url:"period,omitempty"`
Search string `url:"search,omitempty"`
}
func cmdLogs(cmd *cobra.Command, args []string) {
usage := "Invalid usage. sail service logs [<applicationName>/]<serviceId>. Please see sail service logs --help\n"
if len(args) != 1 {
fmt.Fprintf(os.Stderr, usage)
return
}
// Split namespace and service
host, app, service, _, err := internal.ParseResourceName(args[0])
internal.Check(err)
if !internal.CheckHostConsistent(host) {
fmt.Fprintf(os.Stderr, "Error: Invalid Host %s for endpoint %s\n", host, internal.Host)
os.Exit(1)
}
// Get args
logsBody.Application = app
logsBody.Service = service
serviceLogs(logsBody)
}
func serviceLogs(args Logs) {
queryArgs, err := query.Values(args)
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal: %s\n", err)
return
}
path := fmt.Sprintf("/applications/%s/services/%s/logs?%s", args.Application, args.Service, queryArgs.Encode())
b := internal.GetWantJSON(path)
internal.FormatOutput(b, serviceLogsFormatter)
}
func serviceLogsFormatter(data []byte) {
logs := [][]string{}
err := json.Unmarshal(data, &logs)
internal.Check(err)
w := tabwriter.NewWriter(os.Stdout, 20, 1, 3, ' ', 0)
titles := []string{"TIMESTAMP", "ID", "LOG"}
fmt.Fprintln(w, strings.Join(titles, "\t"))
for i := range logs {
fmt.Fprintf(w, "%s\t%s\t%s\n", logs[i][0], logs[i][1], logs[i][2])
w.Flush()
}
}