forked from flynn/flynn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlog.go
98 lines (86 loc) · 2.18 KB
/
log.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
98
package main
import (
"encoding/json"
"fmt"
"io"
"os"
"strconv"
"github.com/flynn/flynn/controller/client"
ct "github.com/flynn/flynn/controller/types"
logaggc "github.com/flynn/flynn/logaggregator/client"
"github.com/flynn/flynn/Godeps/_workspace/src/github.com/flynn/go-docopt"
)
func init() {
register("log", runLog, `
usage: flynn log [-f] [-j <id>] [-n <lines>] [-r] [-s] [-t <type>]
Stream log for an app.
Options:
-f, --follow stream new lines after printing log buffer
-j, --job=<id> filter logs to a specific job ID
-n, --number=<lines> return at most n lines from the log buffer
-r, --raw-output output raw log messages with no prefix
-s, --split-stderr send stderr lines to stderr
-t, --process-type=<type> filter logs to a specific process type
`)
}
// like time.RFC3339Nano except it only goes to 6 decimals and doesn't drop
// trailing zeros
const rfc3339micro = "2006-01-02T15:04:05.000000Z07:00"
func runLog(args *docopt.Args, client *controller.Client) error {
rawOutput := args.Bool["--raw-output"]
opts := ct.LogOpts{
Follow: args.Bool["--follow"],
JobID: args.String["--job"],
}
if ptype, ok := args.String["--process-type"]; ok {
opts.ProcessType = &ptype
}
if strlines := args.String["--number"]; strlines != "" {
lines, err := strconv.Atoi(strlines)
if err != nil {
return err
}
opts.Lines = &lines
}
rc, err := client.GetAppLog(mustApp(), &opts)
if err != nil {
return err
}
defer rc.Close()
var stderr io.Writer = os.Stdout
if args.Bool["--split-stderr"] {
stderr = os.Stderr
}
dec := json.NewDecoder(rc)
for {
var msg logaggc.Message
err := dec.Decode(&msg)
if err == io.EOF {
return nil
} else if err != nil {
return err
}
var stream io.Writer = os.Stdout
if msg.Stream == "stderr" {
stream = stderr
}
if rawOutput {
fmt.Fprintln(stream, msg.Msg)
} else {
tstamp := msg.Timestamp.Format(rfc3339micro)
fmt.Fprintf(stream, "%s %s[%s.%s]: %s\n",
tstamp,
msg.Source,
msg.ProcessType,
msg.JobID,
msg.Msg,
)
}
}
}
func shorten(msg string, maxLength int) string {
if len(msg) > maxLength {
return msg[:maxLength]
}
return msg
}