/
cli.go
108 lines (92 loc) · 2.38 KB
/
cli.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
99
100
101
102
103
104
105
106
107
108
// Command-line options and utilities used by multiple cmds.
package cli
import (
"fmt"
"html/template"
"log"
"net"
"net/http"
"github.com/Sirupsen/logrus"
"gopkg.in/alecthomas/kingpin.v2"
)
var Log *logrus.Logger = logrus.StandardLogger()
func init() {
kingpin.HelpFlag.Short('h')
}
// Initialize sets the app name. Must be called before flag.Parse()
func Initialize(appName string, baseConfig *BaseConfig) {
if appName == "" {
panic("appName cannot be empty")
}
kingpin.Version(versionString(appName))
kingpin.Parse()
initializeLogger(appName, baseConfig)
if baseConfig.ServeDebug {
initializeDebugServer(baseConfig)
}
}
func initializeLogger(appName string, baseConfig *BaseConfig) {
Log = baseConfig.createLogger()
// Redirect standard logger (used by fuse) to our logger.
log.SetOutput(Log.Writer())
// Disable standard log timestamps, logrus has its own.
log.SetFlags(0)
Log.Println(versionString(appName))
}
func initializeDebugServer(baseConfig *BaseConfig) {
Log.Debug("starting debug server...")
listener, err := net.ListenTCP("tcp", &net.TCPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: 0, // Bind to a random port.
})
if err != nil {
Log.Errorln("error starting debug server:", err)
return
}
// Publish basic table of contents.
template, err := template.New("").Parse(`
<html><body>
{{range .}}
<p><a href="{{.Path}}">{{.Text}}</a></p>
{{end}}
</body></html>`)
if err != nil {
panic(err)
}
toc := []struct {
Text string
Path string
}{
{"Profiling", "/debug/pprof"},
{"Download a 30-second CPU profile", "/debug/pprof/profile"},
{"Download a trace file (add ?seconds=x to specify sample length)", "/debug/pprof/trace"},
{"Requests", "/debug/requests"},
{"Event log", "/debug/events"},
}
http.HandleFunc("/debug", func(w http.ResponseWriter, req *http.Request) {
template.Execute(w, toc)
})
go func() {
defer listener.Close()
if err := http.Serve(listener, nil); err != nil {
Log.Errorln("debug server error:", err)
return
}
}()
Log.Printf("debug server listening on http://%s/debug", listener.Addr())
}
func formatFlag(name string, value interface{}) string {
switch value := value.(type) {
case bool:
if value {
return "--" + name
}
return "--no-" + name
default:
// if !reflect.ValueOf(value).IsValid() {
// Default/zero value.
return fmt.Sprintf("--%s=%v", name, value)
// }
// return ""
}
}