forked from miniblade/remote-tail
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
141 lines (120 loc) · 3.32 KB
/
main.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"flag"
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"github.com/spf13/viper"
"github.com/mylxsw/remote-tail/command"
"github.com/mylxsw/remote-tail/console"
)
var mossSep = ".--. --- .-- . .-. . -.. -... -.-- -- -.-- .-.. -..- ... .-- \n"
var welcomeMessage = getWelcomeMessage() + console.ColorfulText(console.TextMagenta, mossSep)
var env string
var configFile string
var label string
var file string
var tailLine *int
var Version = "3.0"
func usageAndExit(message string) {
if message != "" {
_, _ = fmt.Fprintln(os.Stderr, message)
}
flag.Usage()
fmt.Println("remote-tail env.label.file")
_, _ = fmt.Fprint(os.Stderr, "\n")
os.Exit(1)
}
func printWelcomeMessage() {
fmt.Println(welcomeMessage)
for _, server := range viper.GetStringSlice(label) {
serverInfo := fmt.Sprintf("%s@%s:%s", viper.GetString("user"), server, viper.GetString("file."+file))
fmt.Println(console.ColorfulText(console.TextMagenta, serverInfo))
}
fmt.Printf("\n%s\n", console.ColorfulText(console.TextCyan, mossSep))
}
func main() {
flag.Usage = func() {
_, _ = fmt.Fprint(os.Stderr, welcomeMessage)
_, _ = fmt.Fprint(os.Stderr, "Options:\n\n")
flag.PrintDefaults()
}
tailLine = flag.Int("n", 0, "-n 1000")
flag.Parse()
args := flag.Args()
if len(args) < 1 {
usageAndExit("")
}
subArgs := args[0]
env = strings.Split(subArgs, ".")[0]
label = strings.Split(subArgs, ".")[1]
file = strings.Split(subArgs, ".")[2]
homeDir, _ := os.UserHomeDir()
configFile = filepath.Join(homeDir, ".remote", fmt.Sprintf("%s.yaml", env))
viper.SetConfigFile(configFile)
err := viper.ReadInConfig()
if err != nil {
panic(err)
}
printWelcomeMessage()
outputs := make(chan command.Message, 255)
done := make(chan struct{})
var wg sync.WaitGroup
for _, server := range viper.GetStringSlice(label) {
wg.Add(1)
go func(server command.Server) {
defer func() {
if err := recover(); err != nil {
fmt.Printf(console.ColorfulText(console.TextRed, "Error: %s\n"), err)
}
}()
defer wg.Done()
cmd := command.NewCommand(server)
cmd.Execute(outputs)
}(command.Server{
ServerName: "",
Hostname: server,
Port: 22,
User: viper.GetString("user"),
Password: viper.GetString("password"),
PrivateKeyPath: viper.GetString("private_key_path"),
TailFile: viper.GetString("file." + file),
TailLine: *tailLine,
})
}
if len(viper.GetStringSlice(label)) > 0 {
go func() {
for output := range outputs {
content := strings.Trim(output.Content, "\r\n")
// 去掉文件名称输出
if content == "" || (strings.HasPrefix(content, "==>") && strings.HasSuffix(content, "<==")) {
continue
}
fmt.Printf(
"%s %s %s\n",
console.ColorfulText(console.TextGreen, output.Host),
console.ColorfulText(console.TextYellow, "->"),
content,
)
}
done <- struct{}{}
}()
} else {
fmt.Println(console.ColorfulText(console.TextRed, "No target host is available"))
}
wg.Wait()
<-done
}
func getWelcomeMessage() string {
return `
____ _ _____ _ _
| _ \ ___ _ __ ___ ___ | |_ __|_ _|_ _(_) |
| |_) / _ \ '_ ' _ \ / _ \| __/ _ \| |/ _' | | |
| _ < __/ | | | | | (_) | || __/| | (_| | | |
|_| \_\___|_| |_| |_|\___/ \__\___||_|\__,_|_|_|
Author: liuwangchen
Version: ` + Version + `
`
}