github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/main/commands/all/api/balancer_info.go (about)

     1  package api
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strings"
     7  
     8  	routerService "github.com/xtls/xray-core/app/router/command"
     9  	"github.com/xtls/xray-core/main/commands/base"
    10  )
    11  
    12  // TODO: support "-json" flag for json output
    13  var cmdBalancerInfo = &base.Command{
    14  	CustomFlags: true,
    15  	UsageLine:   "{{.Exec}} api bi [--server=127.0.0.1:8080] [balancer]...",
    16  	Short:       "balancer information",
    17  	Long: `
    18  Get information of specified balancers, including health, strategy 
    19  and selecting. If no balancer tag specified, get information of 
    20  all balancers.
    21  
    22  > Make sure you have "RoutingService" set in "config.api.services" 
    23  of server config.
    24  
    25  Arguments:
    26  
    27  	-json
    28  		Use json output.
    29  
    30  	-s, -server <server:port>
    31  		The API server address. Default 127.0.0.1:8080
    32  
    33  	-t, -timeout <seconds>
    34  		Timeout seconds to call API. Default 3
    35  
    36  Example:
    37  
    38      {{.Exec}} {{.LongName}} --server=127.0.0.1:8080 balancer1 balancer2
    39  `,
    40  	Run: executeBalancerInfo,
    41  }
    42  
    43  func executeBalancerInfo(cmd *base.Command, args []string) {
    44  	setSharedFlags(cmd)
    45  	cmd.Flag.Parse(args)
    46  	unnamedArgs := cmd.Flag.Args()
    47  	if len(unnamedArgs) == 0 {
    48  		fmt.Println("set balancer tag")
    49  		unnamedArgs = []string{""}
    50  	}
    51  
    52  	conn, ctx, close := dialAPIServer()
    53  	defer close()
    54  	client := routerService.NewRoutingServiceClient(conn)
    55  	r := &routerService.GetBalancerInfoRequest{Tag: unnamedArgs[0]}
    56  	resp, err := client.GetBalancerInfo(ctx, r)
    57  	if err != nil {
    58  		base.Fatalf("failed to get health information: %s", err)
    59  	}
    60  
    61  	if apiJSON {
    62  		showJSONResponse(resp)
    63  		return
    64  	}
    65  
    66  	showBalancerInfo(resp.Balancer)
    67  
    68  }
    69  
    70  func showBalancerInfo(b *routerService.BalancerMsg) {
    71  	const tableIndent = 4
    72  	sb := new(strings.Builder)
    73  	// Override
    74  	if b.Override != nil {
    75  		sb.WriteString("  - Selecting Override:\n")
    76  		for i, s := range []string{b.Override.Target} {
    77  			writeRow(sb, tableIndent, i+1, []string{s}, nil)
    78  		}
    79  	}
    80  	// Selects
    81  	sb.WriteString("  - Selects:\n")
    82  	if b.PrincipleTarget != nil {
    83  		for i, o := range b.PrincipleTarget.Tag {
    84  			writeRow(sb, tableIndent, i+1, []string{o}, nil)
    85  		}
    86  	}
    87  	os.Stdout.WriteString(sb.String())
    88  }
    89  
    90  func getColumnFormats(titles []string) []string {
    91  	w := make([]string, len(titles))
    92  	for i, t := range titles {
    93  		w[i] = fmt.Sprintf("%%-%ds ", len(t))
    94  	}
    95  	return w
    96  }
    97  
    98  func writeRow(sb *strings.Builder, indent, index int, values, formats []string) {
    99  	if index == 0 {
   100  		// title line
   101  		sb.WriteString(strings.Repeat(" ", indent+4))
   102  	} else {
   103  		sb.WriteString(fmt.Sprintf("%s%-4d", strings.Repeat(" ", indent), index))
   104  	}
   105  	for i, v := range values {
   106  		format := "%-14s"
   107  		if i < len(formats) {
   108  			format = formats[i]
   109  		}
   110  		sb.WriteString(fmt.Sprintf(format, v))
   111  	}
   112  	sb.WriteByte('\n')
   113  }