@@ -18,6 +18,7 @@ import (
1818 "fmt"
1919 "sort"
2020
21+ "github.com/antonmedv/expr"
2122 "github.com/choria-io/fisk"
2223 "github.com/dustin/go-humanize"
2324 "github.com/fatih/color"
@@ -28,16 +29,17 @@ import (
2829type SrvReportCmd struct {
2930 json bool
3031
31- account string
32- waitFor int
33- sort string
34- topk int
35- reverse bool
36- compact bool
37- subject string
38- server string
39- cluster string
40- tags []string
32+ filterExpression string
33+ account string
34+ waitFor int
35+ sort string
36+ topk int
37+ reverse bool
38+ compact bool
39+ subject string
40+ server string
41+ cluster string
42+ tags []string
4143}
4244
4345type srvReportAccountInfo struct {
@@ -72,6 +74,7 @@ func configureServerReportCommand(srv *fisk.CmdClause) {
7274 conns .Flag ("top" , "Limit results to the top results" ).Default ("1000" ).IntVar (& c .topk )
7375 conns .Flag ("subject" , "Limits responses only to those connections with matching subscription interest" ).StringVar (& c .subject )
7476 conns .Flag ("json" , "Produce JSON output" ).Short ('j' ).UnNegatableBoolVar (& c .json )
77+ conns .Flag ("filter" , "Expression based filter for connections" ).StringVar (& c .filterExpression )
7578
7679 acct := report .Command ("accounts" , "Report on account activity" ).Alias ("acct" ).Action (c .reportAccount )
7780 acct .Arg ("account" , "Account to produce a report for" ).StringVar (& c .account )
@@ -492,7 +495,7 @@ func (c *SrvReportCmd) reportConnections(_ *fisk.ParseContext) error {
492495 return fmt .Errorf ("did not get results from any servers" )
493496 }
494497
495- conns := connz .flatConnInfo ()
498+ conns := connz .flatConnInfo (c . filterExpression )
496499
497500 if c .json {
498501 printJSON (conns )
@@ -624,10 +627,39 @@ func (c *SrvReportCmd) renderConnections(report []connInfo) {
624627
625628type connzList []* server.ServerAPIConnzResponse
626629
627- func (c connzList ) flatConnInfo () []connInfo {
630+ func (c connzList ) flatConnInfo (filter string ) []connInfo {
628631 var conns []connInfo
629632 for _ , conn := range c {
633+ srv := structWithoutOmitEmpty (* conn .Server )
634+
630635 for _ , c := range conn .Data .Conns {
636+ if filter != "" {
637+ ci := structWithoutOmitEmpty (* c )
638+ env := map [string ]any {
639+ "server" : srv ,
640+ "Server" : conn .Server ,
641+ "conns" : ci ,
642+ "Conns" : c ,
643+ }
644+
645+ program , err := expr .Compile (filter , expr .Env (env ), expr .AsBool ())
646+ fisk .FatalIfError (err , "Invalid expression: %v" , err )
647+
648+ out , err := expr .Run (program , env )
649+ if err != nil {
650+ fisk .FatalIfError (err , "Invalid expression: %v" , err )
651+ }
652+
653+ should , ok := out .(bool )
654+ if ! ok {
655+ fisk .FatalIfError (err , "expression did not return a boolean" )
656+ }
657+
658+ if ! should {
659+ continue
660+ }
661+ }
662+
631663 conns = append (conns , connInfo {c , conn .Server })
632664 }
633665 }
0 commit comments