diff --git a/aws/database/describe/main.go b/aws/database/describe/main.go index 3a624fe..a5fdcc4 100644 --- a/aws/database/describe/main.go +++ b/aws/database/describe/main.go @@ -36,8 +36,9 @@ func NewCommand() *cobra.Command { return } - tbl := table.New("ATTRIBUTE", "VALUE") - tbl.Column(0, table.Column{Alignment: table.Right}) + tbl := table.New() + tbl.Column(0, table.Column{Name: "ATTRIBUTE", Alignment: table.Right}) + tbl.Column(1, table.Column{Name: "VALUE"}) for k, v := range instance.JSON() { tbl.Add(k, v) } diff --git a/aws/database/logs/list/main.go b/aws/database/logs/list/main.go index 3e4741b..67419a3 100644 --- a/aws/database/logs/list/main.go +++ b/aws/database/logs/list/main.go @@ -49,7 +49,9 @@ func NewCommand() *cobra.Command { logs.SortBySize() } - tbl := table.New("FILE", "SIZE") + tbl := table.New() + tbl.Column(0, table.Column{Name: "File"}) + tbl.Column(1, table.Column{Name: "Size"}) for _, log := range logs { tbl.Add(log.FileName, log.Size) } diff --git a/aws/database/parameters/describe/main.go b/aws/database/parameters/describe/main.go index c00971a..70d9d91 100644 --- a/aws/database/parameters/describe/main.go +++ b/aws/database/parameters/describe/main.go @@ -36,7 +36,12 @@ func NewCommand() *cobra.Command { return } - tbl := table.New("NAME", "VALUES", "APPLY METHOD", "APPLY TYPE", "MODIFIABLE") + tbl := table.New() + tbl.Column(0, table.Column{Name: "NAME"}) + tbl.Column(1, table.Column{Name: "VALUES"}) + tbl.Column(2, table.Column{Name: "APPLY METHOD"}) + tbl.Column(3, table.Column{Name: "APPLY TYPE"}) + tbl.Column(4, table.Column{Name: "MODIFIABLE"}) for _, parameter := range parameters { tbl.Add(parameter.Name, parameter.Value, parameter.ApplyMethod, parameter.ApplyType, parameter.IsModifiable) } diff --git a/aws/database/parameters/list/main.go b/aws/database/parameters/list/main.go index 9e7820b..a4b3566 100644 --- a/aws/database/parameters/list/main.go +++ b/aws/database/parameters/list/main.go @@ -36,7 +36,10 @@ func NewCommand() *cobra.Command { return } - tbl := table.New("NAME", "DESCRIPTION", "FAMILY") + tbl := table.New() + tbl.Column(0, table.Column{Name: "NAME"}) + tbl.Column(1, table.Column{Name: "DESCRIPTION"}) + tbl.Column(2, table.Column{Name: "FAMILY"}) for _, parameter := range parameters { tbl.Add(parameter.Name, parameter.Description, parameter.Family) } diff --git a/aws/databases/main.go b/aws/databases/main.go index 05a5e30..0630954 100644 --- a/aws/databases/main.go +++ b/aws/databases/main.go @@ -22,7 +22,12 @@ func NewCommand() *cobra.Command { instances := r.List() - tbl := table.New("ENGINE", "VERSION", "IDENTIFIER", "CLASS", "STATUS") + tbl := table.New() + tbl.Column(0, table.Column{Name: "ENGINE"}) + tbl.Column(1, table.Column{Name: "VERSION"}) + tbl.Column(2, table.Column{Name: "IDENTIFIER"}) + tbl.Column(3, table.Column{Name: "CLASS"}) + tbl.Column(4, table.Column{Name: "STATUS"}) for _, instance := range instances { tbl.Add(instance.Engine, instance.Version, instance.Identifier, instance.Class, instance.Status) } diff --git a/go.mod b/go.mod index 8590f71..46b1673 100644 --- a/go.mod +++ b/go.mod @@ -39,3 +39,5 @@ require ( golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect ) + +replace github.com/debeando/go-common => /Users/nsc/go/src/github.com/debeando/go-common diff --git a/mysql/digest/main.go b/mysql/digest/main.go index 4bf29f0..081f4c0 100644 --- a/mysql/digest/main.go +++ b/mysql/digest/main.go @@ -54,11 +54,14 @@ func NewCommand() *cobra.Command { queries.Analyzed(), queries.Unique())) - tbl := table.New( - "DIGEST ID", "SCORE", "COUNT", "Q. TIME", - "L. TIME", "R. SENT", "R. EXAMINED", - ) - + tbl := table.New() + tbl.Column(0, table.Column{Name: "DIGEST ID"}) + tbl.Column(1, table.Column{Name: "SCORE"}) + tbl.Column(2, table.Column{Name: "COUNT"}) + tbl.Column(3, table.Column{Name: "Q. TIME"}) + tbl.Column(4, table.Column{Name: "L. TIME"}) + tbl.Column(5, table.Column{Name: "R. SENT"}) + tbl.Column(6, table.Column{Name: "R. EXAMINED"}) queries.Clean() queries.SortByScore() diff --git a/mysql/main.go b/mysql/main.go index f673e3a..ba9faa0 100644 --- a/mysql/main.go +++ b/mysql/main.go @@ -2,6 +2,7 @@ package mysql import ( "zenit/mysql/digest" + "zenit/mysql/top" "github.com/spf13/cobra" ) @@ -16,6 +17,7 @@ func NewCommand() *cobra.Command { } cmd.AddCommand(digest.NewCommand()) + cmd.AddCommand(top.NewCommand()) return cmd } diff --git a/mysql/top/main.go b/mysql/top/main.go new file mode 100644 index 0000000..06a66a2 --- /dev/null +++ b/mysql/top/main.go @@ -0,0 +1,97 @@ +package top + +import ( + "fmt" + + // "github.com/debeando/go-common/aws/rds" + "github.com/debeando/go-common/mysql" + "github.com/debeando/go-common/table" + "github.com/debeando/go-common/terminal" + + "github.com/spf13/cobra" +) + +var delay int +var dsn string +var host string +var password string +var port int +var user string + +const SQLProcessList = `SELECT id, user, SUBSTRING_INDEX(host, ':', 1) AS host, db, command, time, state, info +FROM information_schema.processlist +WHERE id <> connection_id() + AND length(info) > 0 + AND command NOT IN ('Daemon', 'Sleep') + AND user NOT IN ('rdsadmin');` + +func NewCommand() *cobra.Command { + defer terminal.CursorShow() + + var cmd = &cobra.Command{ + Use: "top [IDENTIFIER] |", + Short: "Display MySQL server performance info like 'top'.", + Example: ` + # Connect to RDS: + zenit mysql top test-rds --password= + + # Connect to Host: + zenit mysql top --host=127.0.0.1 --user=root --password= + + # Refresh every one second: + zenit mysql top --host=127.0.0.1 --user=root --password= --delay=1`, + Run: func(cmd *cobra.Command, args []string) { + if len(args) == 0 && len(password) == 0 { + cmd.Help() + return + } else if len(host) == 0 && len(password) == 0 { + cmd.Help() + return + } + + // r := rds.RDS{} + + // if err := r.Init(); err != nil { + // log.Error(err.Error()) + // return + // } + + // instance, err := r.Describe(args[0]) + // if err != nil { + // fmt.Println(err) + // return + // } + + fmt.Printf("Connecting to %s:%d ...\n", host, port) + + dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/information_schema?timeout=3s", user, password, host, port) + + m := mysql.New("top", dsn) + m.Connect() + + terminal.Refresh(delay, func() { + processlist, _ := m.Query(SQLProcessList) + + tbl := table.New() + tbl.Title("Process List") + tbl.Column(0, table.Column{Name: "ID", Truncate: 10, Width: 10}) + tbl.Column(1, table.Column{Name: "User", Truncate: 10, Width: 10}) + tbl.Column(2, table.Column{Name: "Host", Truncate: 15, Width: 15}) + tbl.Column(3, table.Column{Name: "Time", Truncate: 4, Width: 4}) + tbl.Column(4, table.Column{Name: "Query", Truncate: 50, Width: 50}) + for _, row := range processlist { + tbl.Add(row["id"], row["user"], row["host"], row["time"], row["info"]) + } + tbl.Print() + }) + }, + } + + cmd.Flags().IntVar(&delay, "delay", 3, "How long between display refreshes.") + cmd.Flags().StringVar(&host, "host", "127.0.0.1", "Connect to host.") + cmd.Flags().StringVar(&password, "password", "", "Password to use when connecting to server.") + cmd.Flags().IntVar(&port, "port", 3306, "Port number to use for connection.") + cmd.Flags().StringVar(&user, "user", "root", "User for login if not current user.") + + return cmd +}