1
1
package utils
2
2
3
3
import (
4
+ "fmt"
5
+ "io"
6
+ "net"
7
+ "os"
8
+ "runtime"
9
+ "strings"
10
+ "time"
11
+
12
+ "github.com/ethereum/go-ethereum/log"
4
13
"github.com/ethereum/go-ethereum/metrics"
5
- "github.com/ethereum/go-ethereum/node"
14
+ "github.com/ethereum/go-ethereum/metrics/exp"
15
+ "github.com/ethereum/go-ethereum/metrics/influxdb"
6
16
"github.com/optimism-java/shisui2/internal/flags"
7
17
"github.com/optimism-java/shisui2/portalwire"
8
18
"github.com/urfave/cli/v2"
@@ -107,7 +117,7 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
107
117
PortalRPCPortFlag = & cli.IntFlag {
108
118
Name : "rpc.port" ,
109
119
Usage : "HTTP-RPC server listening port" ,
110
- Value : node . DefaultHTTPPort ,
120
+ Value : 8545 ,
111
121
Category : flags .PortalNetworkCategory ,
112
122
}
113
123
@@ -132,24 +142,17 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
132
142
Category : flags .PortalNetworkCategory ,
133
143
}
134
144
135
- PortalUDPListenAddrFlag = & cli.StringFlag {
136
- Name : "udp.addr" ,
137
- Usage : "Protocol UDP server listening interface" ,
138
- Value : "" ,
139
- Category : flags .PortalNetworkCategory ,
140
- }
141
-
142
145
PortalUDPPortFlag = & cli.IntFlag {
143
146
Name : "udp.port" ,
144
147
Usage : "Protocol UDP server listening port" ,
145
- Value : node . DefaultUDPPort ,
148
+ Value : 9009 ,
146
149
Category : flags .PortalNetworkCategory ,
147
150
}
148
151
149
152
PortalLogLevelFlag = & cli.IntFlag {
150
153
Name : "loglevel" ,
151
154
Usage : "Loglevel of portal network" ,
152
- Value : node . DefaultLoglevel ,
155
+ Value : 3 ,
153
156
Category : flags .PortalNetworkCategory ,
154
157
}
155
158
@@ -178,3 +181,154 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
178
181
Value : cli .NewStringSlice (portalwire .History .Name ()),
179
182
}
180
183
)
184
+
185
+ func SetupMetrics (ctx * cli.Context ) {
186
+ if metrics .Enabled {
187
+ log .Info ("Enabling metrics collection" )
188
+
189
+ var (
190
+ enableExport = ctx .Bool (MetricsEnableInfluxDBFlag .Name )
191
+ enableExportV2 = ctx .Bool (MetricsEnableInfluxDBV2Flag .Name )
192
+ )
193
+
194
+ if enableExport || enableExportV2 {
195
+ CheckExclusive (ctx , MetricsEnableInfluxDBFlag , MetricsEnableInfluxDBV2Flag )
196
+
197
+ v1FlagIsSet := ctx .IsSet (MetricsInfluxDBUsernameFlag .Name ) ||
198
+ ctx .IsSet (MetricsInfluxDBPasswordFlag .Name )
199
+
200
+ v2FlagIsSet := ctx .IsSet (MetricsInfluxDBTokenFlag .Name ) ||
201
+ ctx .IsSet (MetricsInfluxDBOrganizationFlag .Name ) ||
202
+ ctx .IsSet (MetricsInfluxDBBucketFlag .Name )
203
+
204
+ if enableExport && v2FlagIsSet {
205
+ Fatalf ("Flags --influxdb.metrics.organization, --influxdb.metrics.token, --influxdb.metrics.bucket are only available for influxdb-v2" )
206
+ } else if enableExportV2 && v1FlagIsSet {
207
+ Fatalf ("Flags --influxdb.metrics.username, --influxdb.metrics.password are only available for influxdb-v1" )
208
+ }
209
+ }
210
+
211
+ var (
212
+ endpoint = ctx .String (MetricsInfluxDBEndpointFlag .Name )
213
+ database = ctx .String (MetricsInfluxDBDatabaseFlag .Name )
214
+ username = ctx .String (MetricsInfluxDBUsernameFlag .Name )
215
+ password = ctx .String (MetricsInfluxDBPasswordFlag .Name )
216
+
217
+ token = ctx .String (MetricsInfluxDBTokenFlag .Name )
218
+ bucket = ctx .String (MetricsInfluxDBBucketFlag .Name )
219
+ organization = ctx .String (MetricsInfluxDBOrganizationFlag .Name )
220
+ )
221
+
222
+ if enableExport {
223
+ tagsMap := SplitTagsFlag (ctx .String (MetricsInfluxDBTagsFlag .Name ))
224
+
225
+ log .Info ("Enabling metrics export to InfluxDB" )
226
+
227
+ go influxdb .InfluxDBWithTags (metrics .DefaultRegistry , 10 * time .Second , endpoint , database , username , password , "geth." , tagsMap )
228
+ } else if enableExportV2 {
229
+ tagsMap := SplitTagsFlag (ctx .String (MetricsInfluxDBTagsFlag .Name ))
230
+
231
+ log .Info ("Enabling metrics export to InfluxDB (v2)" )
232
+
233
+ go influxdb .InfluxDBV2WithTags (metrics .DefaultRegistry , 10 * time .Second , endpoint , token , bucket , organization , "geth." , tagsMap )
234
+ }
235
+
236
+ if ctx .IsSet (MetricsHTTPFlag .Name ) {
237
+ address := net .JoinHostPort (ctx .String (MetricsHTTPFlag .Name ), fmt .Sprintf ("%d" , ctx .Int (MetricsPortFlag .Name )))
238
+ log .Info ("Enabling stand-alone metrics HTTP endpoint" , "address" , address )
239
+ exp .Setup (address )
240
+ } else if ctx .IsSet (MetricsPortFlag .Name ) {
241
+ log .Warn (fmt .Sprintf ("--%s specified without --%s, metrics server will not start." , MetricsPortFlag .Name , MetricsHTTPFlag .Name ))
242
+ }
243
+ }
244
+ }
245
+
246
+ // CheckExclusive verifies that only a single instance of the provided flags was
247
+ // set by the user. Each flag might optionally be followed by a string type to
248
+ // specialize it further.
249
+ func CheckExclusive (ctx * cli.Context , args ... interface {}) {
250
+ set := make ([]string , 0 , 1 )
251
+ for i := 0 ; i < len (args ); i ++ {
252
+ // Make sure the next argument is a flag and skip if not set
253
+ flag , ok := args [i ].(cli.Flag )
254
+ if ! ok {
255
+ panic (fmt .Sprintf ("invalid argument, not cli.Flag type: %T" , args [i ]))
256
+ }
257
+ // Check if next arg extends current and expand its name if so
258
+ name := flag .Names ()[0 ]
259
+
260
+ if i + 1 < len (args ) {
261
+ switch option := args [i + 1 ].(type ) {
262
+ case string :
263
+ // Extended flag check, make sure value set doesn't conflict with passed in option
264
+ if ctx .String (flag .Names ()[0 ]) == option {
265
+ name += "=" + option
266
+ set = append (set , "--" + name )
267
+ }
268
+ // shift arguments and continue
269
+ i ++
270
+ continue
271
+
272
+ case cli.Flag :
273
+ default :
274
+ panic (fmt .Sprintf ("invalid argument, not cli.Flag or string extension: %T" , args [i + 1 ]))
275
+ }
276
+ }
277
+ // Mark the flag if it's set
278
+ if ctx .IsSet (flag .Names ()[0 ]) {
279
+ set = append (set , "--" + name )
280
+ }
281
+ }
282
+ if len (set ) > 1 {
283
+ Fatalf ("Flags %v can't be used at the same time" , strings .Join (set , ", " ))
284
+ }
285
+ }
286
+
287
+ // Fatalf formats a message to standard error and exits the program.
288
+ // The message is also printed to standard output if standard error
289
+ // is redirected to a different file.
290
+ func Fatalf (format string , args ... interface {}) {
291
+ w := io .MultiWriter (os .Stdout , os .Stderr )
292
+ if runtime .GOOS == "windows" {
293
+ // The SameFile check below doesn't work on Windows.
294
+ // stdout is unlikely to get redirected though, so just print there.
295
+ w = os .Stdout
296
+ } else {
297
+ outf , _ := os .Stdout .Stat ()
298
+ errf , _ := os .Stderr .Stat ()
299
+ if outf != nil && errf != nil && os .SameFile (outf , errf ) {
300
+ w = os .Stderr
301
+ }
302
+ }
303
+ fmt .Fprintf (w , "Fatal: " + format + "\n " , args ... )
304
+ os .Exit (1 )
305
+ }
306
+
307
+ func SplitTagsFlag (tagsFlag string ) map [string ]string {
308
+ tags := strings .Split (tagsFlag , "," )
309
+ tagsMap := map [string ]string {}
310
+
311
+ for _ , t := range tags {
312
+ if t != "" {
313
+ kv := strings .Split (t , "=" )
314
+
315
+ if len (kv ) == 2 {
316
+ tagsMap [kv [0 ]] = kv [1 ]
317
+ }
318
+ }
319
+ }
320
+
321
+ return tagsMap
322
+ }
323
+
324
+ // SplitAndTrim splits input separated by a comma
325
+ // and trims excessive white space from the substrings.
326
+ func SplitAndTrim (input string ) (ret []string ) {
327
+ l := strings .Split (input , "," )
328
+ for _ , r := range l {
329
+ if r = strings .TrimSpace (r ); r != "" {
330
+ ret = append (ret , r )
331
+ }
332
+ }
333
+ return ret
334
+ }
0 commit comments