@@ -24,6 +24,7 @@ import (
24
24
"os"
25
25
"time"
26
26
27
+ "github.com/cgi-fr/cat-balancer/pkg/catp"
27
28
"github.com/rs/zerolog"
28
29
"github.com/rs/zerolog/log"
29
30
"github.com/spf13/cobra"
@@ -44,9 +45,11 @@ func main() {
44
45
log .Logger = log .Output (zerolog.ConsoleWriter {Out : os .Stderr })
45
46
46
47
var (
47
- inAdrress string
48
- outAddress string
49
- verbosity string
48
+ inAdrress string
49
+ outAddress string
50
+ captureStderr string
51
+ captureStdout string
52
+ verbosity string
50
53
)
51
54
52
55
// nolint: exhaustivestruct
@@ -61,32 +64,26 @@ This is free software: you are free to change and redistribute it.
61
64
There is NO WARRANTY, to the extent permitted by law.` , version , commit , buildDate , builtBy ),
62
65
63
66
RunE : func (cmd * cobra.Command , args []string ) error {
64
- switch verbosity {
65
- case "trace" , "5" :
66
- zerolog .SetGlobalLevel (zerolog .TraceLevel )
67
- log .Info ().Msg ("Logger level set to trace" )
68
- case "debug" , "4" :
69
- zerolog .SetGlobalLevel (zerolog .DebugLevel )
70
- log .Info ().Msg ("Logger level set to debug" )
71
- case "info" , "3" :
72
- zerolog .SetGlobalLevel (zerolog .InfoLevel )
73
- log .Info ().Msg ("Logger level set to info" )
74
- case "warn" , "2" :
75
- zerolog .SetGlobalLevel (zerolog .WarnLevel )
76
- case "error" , "1" :
77
- zerolog .SetGlobalLevel (zerolog .ErrorLevel )
78
- default :
79
- zerolog .SetGlobalLevel (zerolog .Disabled )
67
+ initLog (verbosity )
68
+
69
+ command := []string {}
70
+
71
+ if cmd .ArgsLenAtDash () > - 1 {
72
+ command = args [cmd .ArgsLenAtDash ():]
80
73
}
81
74
82
- return run (cmd , inAdrress , outAddress )
75
+ return run (cmd , inAdrress , outAddress , command , captureStderr , captureStdout )
83
76
},
84
77
}
85
78
86
79
rootCmd .PersistentFlags ().StringVarP (& inAdrress , "in" , "i" , "" ,
87
80
"input server's address (empty for stdin by default)" )
88
81
rootCmd .PersistentFlags ().StringVarP (& outAddress , "out" , "o" , "" ,
89
82
"output server's address (empty for stdout by default)" )
83
+ rootCmd .PersistentFlags ().StringVarP (& captureStderr , "save-stderr" , "E" , "" ,
84
+ "capture stderr output into a file" )
85
+ rootCmd .PersistentFlags ().StringVarP (& captureStdout , "save-stdout" , "O" , "" ,
86
+ "capture stdout output into a file" )
90
87
rootCmd .PersistentFlags ().
91
88
StringVarP (& verbosity ,
92
89
"verbosity" ,
@@ -101,43 +98,83 @@ There is NO WARRANTY, to the extent permitted by law.`, version, commit, buildDa
101
98
}
102
99
}
103
100
104
- func run (cmd * cobra.Command , in string , out string ) error {
105
- streamIn := cmd .InOrStdin ()
106
- streamOut := cmd .OutOrStdout ()
101
+ func initLog (verbosity string ) {
102
+ switch verbosity {
103
+ case "trace" , "5" :
104
+ zerolog .SetGlobalLevel (zerolog .TraceLevel )
105
+ log .Info ().Msg ("Logger level set to trace" )
106
+ case "debug" , "4" :
107
+ zerolog .SetGlobalLevel (zerolog .DebugLevel )
108
+ log .Info ().Msg ("Logger level set to debug" )
109
+ case "info" , "3" :
110
+ zerolog .SetGlobalLevel (zerolog .InfoLevel )
111
+ log .Info ().Msg ("Logger level set to info" )
112
+ case "warn" , "2" :
113
+ zerolog .SetGlobalLevel (zerolog .WarnLevel )
114
+ case "error" , "1" :
115
+ zerolog .SetGlobalLevel (zerolog .ErrorLevel )
116
+ default :
117
+ zerolog .SetGlobalLevel (zerolog .Disabled )
118
+ }
119
+ }
107
120
108
- if in != "" {
109
- for {
110
- conIn , err := net .Dial ("tcp" , in )
111
- if err == nil {
112
- defer conIn .Close ()
121
+ // openTCP try to open tcp stream every second until success.
122
+ func openTCP (addr string ) io.ReadWriteCloser {
123
+ for {
124
+ conIn , err := net .Dial ("tcp" , addr )
125
+ if err == nil {
126
+ return conIn
127
+ }
113
128
114
- streamIn = conIn
129
+ log .Warn ().Err (err ).Msg ("tcp stream failed to connect" )
130
+ time .Sleep (time .Second )
131
+ }
132
+ }
115
133
116
- break
117
- }
134
+ func run (
135
+ cmd * cobra.Command ,
136
+ in string , out string ,
137
+ command []string ,
138
+ captureStderr string , captureStdout string ,
139
+ ) error {
140
+ streamIn := cmd .InOrStdin ()
141
+ streamOut := cmd .OutOrStdout ()
118
142
119
- log .Warn ().Err (err ).Msg ("input tcp stream failed to connect" )
120
- time .Sleep (time .Second )
121
- }
143
+ if in != "" {
144
+ conIn := openTCP (in )
145
+ defer conIn .Close ()
146
+ streamIn = conIn
122
147
}
123
148
124
149
if out != "" {
125
- for {
126
- conOut , err := net . Dial ( "tcp" , out )
127
- if err == nil {
128
- defer conOut . Close ()
150
+ conOut := openTCP ( out )
151
+ defer conOut . Close ( )
152
+ streamOut = conOut
153
+ }
129
154
130
- streamOut = conOut
155
+ streamCaptureStderr := cmd . ErrOrStderr ()
131
156
132
- break
133
- }
157
+ if captureStderr != "" {
158
+ captureFile , err := os .Create (captureStderr )
159
+ if err != nil {
160
+ return fmt .Errorf ("%w" , err )
161
+ }
162
+ defer captureFile .Close ()
134
163
135
- log .Warn ().Err (err ).Msg ("output tcp stream failed to connect" )
136
- time .Sleep (time .Second )
164
+ streamCaptureStderr = io .MultiWriter (captureFile , cmd .ErrOrStderr ())
165
+ }
166
+
167
+ if captureStdout != "" {
168
+ captureFile , err := os .Create (captureStdout )
169
+ if err != nil {
170
+ return fmt .Errorf ("%w" , err )
137
171
}
172
+ defer captureFile .Close ()
173
+
174
+ streamOut = io .MultiWriter (captureFile , streamOut )
138
175
}
139
176
140
- _ , err := io . Copy ( streamOut , streamIn )
177
+ err := catp . Start ( command , streamIn , streamOut , streamCaptureStderr )
141
178
if err != nil {
142
179
return fmt .Errorf ("%w" , err )
143
180
}
0 commit comments