6
6
gethostname:: gethostname,
7
7
lazy_static:: lazy_static,
8
8
log:: * ,
9
- solana_sdk:: hash:: hash,
9
+ solana_sdk:: { genesis_config :: ClusterType , hash:: hash} ,
10
10
std:: {
11
11
cmp,
12
12
collections:: HashMap ,
@@ -17,10 +17,31 @@ use {
17
17
thread,
18
18
time:: { Duration , Instant , UNIX_EPOCH } ,
19
19
} ,
20
+ thiserror:: Error ,
20
21
} ;
21
22
22
23
type CounterMap = HashMap < ( & ' static str , u64 ) , CounterPoint > ;
23
24
25
+ #[ derive( Debug , Error ) ]
26
+ pub enum MetricsError {
27
+ #[ error( transparent) ]
28
+ VarError ( #[ from] std:: env:: VarError ) ,
29
+ #[ error( transparent) ]
30
+ ReqwestError ( #[ from] reqwest:: Error ) ,
31
+ #[ error( "SOLANA_METRICS_CONFIG is invalid: '{0}'" ) ]
32
+ ConfigInvalid ( String ) ,
33
+ #[ error( "SOLANA_METRICS_CONFIG is incomplete" ) ]
34
+ ConfigIncomplete ,
35
+ #[ error( "SOLANA_METRICS_CONFIG database mismatch: {0}" ) ]
36
+ DbMismatch ( String ) ,
37
+ }
38
+
39
+ impl From < MetricsError > for String {
40
+ fn from ( error : MetricsError ) -> Self {
41
+ error. to_string ( )
42
+ }
43
+ }
44
+
24
45
impl From < & CounterPoint > for DataPoint {
25
46
fn from ( counter_point : & CounterPoint ) -> Self {
26
47
let mut point = Self :: new ( counter_point. name ) ;
@@ -58,7 +79,7 @@ impl InfluxDbMetricsWriter {
58
79
}
59
80
}
60
81
61
- fn build_write_url ( ) -> Result < String , String > {
82
+ fn build_write_url ( ) -> Result < String , MetricsError > {
62
83
let config = get_metrics_config ( ) . map_err ( |err| {
63
84
info ! ( "metrics disabled: {}" , err) ;
64
85
err
@@ -381,44 +402,57 @@ impl MetricsConfig {
381
402
}
382
403
}
383
404
384
- fn get_metrics_config ( ) -> Result < MetricsConfig , String > {
405
+ fn get_metrics_config ( ) -> Result < MetricsConfig , MetricsError > {
385
406
let mut config = MetricsConfig :: default ( ) ;
386
-
387
- let config_var =
388
- env:: var ( "SOLANA_METRICS_CONFIG" ) . map_err ( |err| format ! ( "SOLANA_METRICS_CONFIG: {err}" ) ) ?;
407
+ let config_var = env:: var ( "SOLANA_METRICS_CONFIG" ) ?;
389
408
390
409
for pair in config_var. split ( ',' ) {
391
410
let nv: Vec < _ > = pair. split ( '=' ) . collect ( ) ;
392
411
if nv. len ( ) != 2 {
393
- return Err ( format ! ( "SOLANA_METRICS_CONFIG is invalid: '{ pair}'" ) ) ;
412
+ return Err ( MetricsError :: ConfigInvalid ( pair. to_string ( ) ) ) ;
394
413
}
395
414
let v = nv[ 1 ] . to_string ( ) ;
396
415
match nv[ 0 ] {
397
416
"host" => config. host = v,
398
417
"db" => config. db = v,
399
418
"u" => config. username = v,
400
419
"p" => config. password = v,
401
- _ => return Err ( format ! ( "SOLANA_METRICS_CONFIG is invalid: '{ pair}'" ) ) ,
420
+ _ => return Err ( MetricsError :: ConfigInvalid ( pair. to_string ( ) ) ) ,
402
421
}
403
422
}
404
423
405
424
if !config. complete ( ) {
406
- return Err ( "SOLANA_METRICS_CONFIG is incomplete" . to_string ( ) ) ;
425
+ return Err ( MetricsError :: ConfigIncomplete ) ;
407
426
}
427
+
408
428
Ok ( config)
409
429
}
410
430
411
- pub fn query ( q : & str ) -> Result < String , String > {
431
+ pub fn metrics_config_sanity_check ( cluster_type : ClusterType ) -> Result < ( ) , MetricsError > {
432
+ let config = match get_metrics_config ( ) {
433
+ Ok ( config) => config,
434
+ Err ( MetricsError :: VarError ( std:: env:: VarError :: NotPresent ) ) => return Ok ( ( ) ) ,
435
+ Err ( e) => return Err ( e) ,
436
+ } ;
437
+ match & config. db [ ..] {
438
+ "mainnet-beta" if cluster_type != ClusterType :: MainnetBeta => ( ) ,
439
+ "tds" if cluster_type != ClusterType :: Testnet => ( ) ,
440
+ "devnet" if cluster_type != ClusterType :: Devnet => ( ) ,
441
+ _ => return Ok ( ( ) ) ,
442
+ } ;
443
+ let ( host, db) = ( & config. host , & config. db ) ;
444
+ let msg = format ! ( "cluster_type={cluster_type:?} host={host} database={db}" ) ;
445
+ Err ( MetricsError :: DbMismatch ( msg) )
446
+ }
447
+
448
+ pub fn query ( q : & str ) -> Result < String , MetricsError > {
412
449
let config = get_metrics_config ( ) ?;
413
450
let query_url = format ! (
414
451
"{}/query?u={}&p={}&q={}" ,
415
452
& config. host, & config. username, & config. password, & q
416
453
) ;
417
454
418
- let response = reqwest:: blocking:: get ( query_url. as_str ( ) )
419
- . map_err ( |err| err. to_string ( ) ) ?
420
- . text ( )
421
- . map_err ( |err| err. to_string ( ) ) ?;
455
+ let response = reqwest:: blocking:: get ( query_url. as_str ( ) ) ?. text ( ) ?;
422
456
423
457
Ok ( response)
424
458
}
0 commit comments