Move to i_s / p_s and add user info (not quite complete)
[pstop.git] / i_s / pl_by_user.go
1 package i_s
2
3 import (
4         "fmt"
5         "sort"
6
7         "github.com/sjmudd/pstop/lib"
8 )
9
10 /*
11 root@localhost [i_s]> show create table i_s\G
12 *************************** 1. row ***************************
13 CREATE TEMPORARY TABLE `PROCESSLIST` (
14         `ID` bigint(21) unsigned NOT NULL DEFAULT '0',
15         `USER` varchar(16) NOT NULL DEFAULT '',
16         `HOST` varchar(64) NOT NULL DEFAULT '',
17         `DB` varchar(64) DEFAULT NULL, `COMMAND` varchar(16) NOT NULL DEFAULT '', `TIME` int(7) NOT NULL DEFAULT '0', `STATE` varchar(64) DEFAULT NULL,
18         `INFO` longtext
19 ) ENGINE=MyISAM DEFAULT CHARSET=utf8
20 1 row in set (0.02 sec)
21 */
22
23 // a summary row of information taken from information_schema.processlist
24 type pl_by_user_row struct {
25         username    string
26         runtime     uint64
27         connections uint64
28         active      uint64
29         hosts       uint64
30         dbs         uint64
31         selects     uint64
32         inserts     uint64
33         updates     uint64
34         deletes     uint64
35         other       uint64
36 }
37 type pl_by_user_rows []pl_by_user_row
38
39 /*
40 username      |Run Time   %age|Conn Actv|Hosts DBs|Select Insert Update Delete  Other|
41 xxxxxxxxxxxxxx|hh:mm:ss 100.0%|9999 9999|9999  999|100.0% 100.0% 100.0% 100.0% 100.0%|
42 */
43
44 func (r *pl_by_user_row) headings() string {
45         return fmt.Sprintf("%-14s|%10s %6s|%5s %4s|%4s %3s|%6s %6s %6s %6s %6s|",
46                 "username", "Run Time", "%", "Conn", "Actv", "Hosts", "DBs", "Select", "Insert", "Update", "Delete", "Other")
47 }
48
49 // generate a printable result
50 func (r *pl_by_user_row) row_content(totals pl_by_user_row) string {
51         var u string
52         if len(r.username) == 0 {
53                 u = ""
54         } else if len(r.username) > 14 {
55                 u = r.username[0:14]
56         } else {
57                 u = r.username
58         }
59         return fmt.Sprintf("%-14s|%10s %6s|%5s %4s|%4s %3s|%6s %6s %6s %6s %6s|",
60                 u,
61                 lib.FormatTime(r.runtime),
62                 lib.FormatPct(lib.MyDivide(r.runtime, totals.runtime)),
63                 lib.FormatAmount(r.connections),
64                 lib.FormatAmount(r.active),
65                 lib.FormatAmount(r.hosts),
66                 lib.FormatAmount(r.dbs),
67                 lib.FormatAmount(r.selects),
68                 lib.FormatAmount(r.inserts),
69                 lib.FormatAmount(r.updates),
70                 lib.FormatAmount(r.deletes),
71                 lib.FormatAmount(r.other))
72 }
73
74 // generate a row of totals from a table
75 func (t pl_by_user_rows) totals() pl_by_user_row {
76         var totals pl_by_user_row
77         totals.username = "TOTALS"
78
79         for i := range t {
80                 totals.runtime += t[i].runtime
81                 totals.connections += t[i].connections
82                 totals.active += t[i].active
83                 //              totals.hosts += t[i].hosts              This needs to be done differently to get the total number of distinct hosts
84                 //              totals.dbs += t[i].dbs                  This needs to be done differently to get the total number of distinct dbs
85                 totals.selects += t[i].selects
86                 totals.inserts += t[i].inserts
87                 totals.updates += t[i].updates
88                 totals.deletes += t[i].deletes
89                 totals.other += t[i].other
90         }
91
92         return totals
93 }
94
95 func (t pl_by_user_rows) Headings() string {
96         var r pl_by_user_row
97         return r.headings()
98 }
99
100 // describe a whole row
101 func (r pl_by_user_row) String() string {
102         return fmt.Sprintf("%v %v %v %v %v %v %v %v %v", r.username, r.runtime, r.connections, r.active, r.hosts, r.dbs, r.selects, r.inserts, r.updates, r.deletes, r.other)
103 }
104
105 // describe a whole table
106 func (t pl_by_user_rows) String() string {
107         s := ""
108         for i := range t {
109                 s = s + t[i].String() + "\n"
110         }
111         return s
112 }
113
114 // for sorting
115 type ByRunTime pl_by_user_rows
116
117 func (t ByRunTime) Len() int      { return len(t) }
118 func (t ByRunTime) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
119 func (t ByRunTime) Less(i, j int) bool {
120         return (t[i].runtime > t[j].runtime) ||
121                 ((t[i].runtime == t[j].runtime) && (t[i].connections > t[j].connections))
122 }
123
124 func (t pl_by_user_rows) Sort() {
125         sort.Sort(ByRunTime(t))
126 }
127
128 func (r pl_by_user_row) Description() string {
129         return "no description"
130 }
131
132 func (t pl_by_user_rows) emptyRowContent() string {
133         var r pl_by_user_row
134         return r.row_content(r)
135 }