Update setup_instruments to all monitoring of stages
[pstop.git] / p_s / setup_instruments / setup_instruments.go
1 package setup_instruments
2
3 import (
4         "database/sql"
5         "log"
6
7         "github.com/sjmudd/pstop/lib"
8 )
9
10 // We only match on the error number
11 // Error 1142: UPDATE command denied to user
12 // Error 1290: The MySQL server is running with the --read-only option so it cannot execute this statement
13 var EXPECTED_UPDATE_ERRORS = []string { "Error 1142", "Error 1290" }
14
15 type setup_instruments_row struct {
16         NAME    string
17         ENABLED string
18         TIMED   string
19 }
20
21 type SetupInstruments struct {
22         update_succeeded bool
23         rows []setup_instruments_row
24 }
25
26 // Change settings to monitor stage/sql/%
27 func (si *SetupInstruments) EnableStageMonitoring(dbh *sql.DB) {
28         sql := "SELECT NAME, ENABLED, TIMED FROM setup_instruments WHERE NAME LIKE 'stage/sql/%' AND ( enabled <> 'YES' OR timed <> 'YES' )"
29         collecting := "Collecting p_s.setup_instruments stage/sql configuration settings"
30         updating   := "Updating p_s.setup_instruments to allow stage/sql configuration"
31
32         si.ConfigureSetupInstruments(dbh, sql, collecting, updating)
33 }
34
35 // Change settings to monitor wait/synch/mutex/%
36 func (si *SetupInstruments) EnableMutexMonitoring(dbh *sql.DB) {
37         sql := "SELECT NAME, ENABLED, TIMED FROM setup_instruments WHERE NAME LIKE 'wait/synch/mutex/%' AND ( enabled <> 'YES' OR timed <> 'YES' )"
38         collecting := "Collecting p_s.setup_instruments wait/synch/mutex configuration settings"
39         updating   := "Updating p_s.setup_instruments to allow wait/synch/mutex configuration"
40
41         si.ConfigureSetupInstruments(dbh, sql, collecting, updating)
42 }
43
44 // generic routine (now) to update some rows in setup instruments
45 func (si *SetupInstruments) ConfigureSetupInstruments(dbh *sql.DB, sql string, collecting, updating string) {
46         // setup the old values in case they're not set
47         if si.rows == nil {
48                 si.rows = make([]setup_instruments_row, 0, 500)
49         }
50
51         lib.Logger.Println(collecting)
52
53         rows, err := dbh.Query(sql)
54         if err != nil {
55                 log.Fatal(err)
56         }
57         defer rows.Close()
58
59         count := 0
60         for rows.Next() {
61                 var r setup_instruments_row
62                 if err := rows.Scan(
63                         &r.NAME,
64                         &r.ENABLED,
65                         &r.TIMED); err != nil {
66                         log.Fatal(err)
67                 }
68                 // we collect all information even if it's mainly empty as we may reference it later
69                 si.rows = append(si.rows, r)
70                 count++
71         }
72         if err := rows.Err(); err != nil {
73                 log.Fatal(err)
74         }
75         lib.Logger.Println("- found", count, "rows whose configuration need changing")
76
77         // update the rows which need to be set - do multiple updates but I don't care
78         lib.Logger.Println(updating)
79
80         count = 0
81         for i := range si.rows {
82                 sql := "UPDATE setup_instruments SET enabled = 'YES', TIMED = 'YES' WHERE NAME = '" + si.rows[i].NAME + "'"
83                 if _, err := dbh.Exec(sql); err == nil {
84                         si.update_succeeded = true
85                 } else {
86                         found_expected := false
87                         for i := range EXPECTED_UPDATE_ERRORS {
88                                 if err.Error()[0:10] == EXPECTED_UPDATE_ERRORS[i] {
89                                         found_expected = true
90                                         break
91                                 }
92                         }
93                         if ! found_expected {
94                                 log.Fatal(err)
95                         }
96                         lib.Logger.Println( "Insufficient privileges to UPDATE setup_instruments: " + err.Error() )
97                         break
98                 }
99                 count++
100         }
101         if si.update_succeeded {
102                 lib.Logger.Println(count, "rows changed in p_s.setup_instruments")
103         }
104 }
105
106
107 // restore any changed rows back to their original state
108 func (si *SetupInstruments) RestoreConfiguration(dbh *sql.DB) {
109         // If the previous update didn't work then don't try to restore
110         if ! si.update_succeeded {
111                 lib.Logger.Println("Not restoring p_s.setup_instruments to its original settings as previous UPDATE had failed")
112                 return
113         } else {
114                 lib.Logger.Println("Restoring p_s.setup_instruments to its original settings")
115         }
116
117         // update the rows which need to be set - do multiple updates but I don't care
118         count := 0
119         for i := range si.rows {
120                 sql := "UPDATE setup_instruments SET enabled = '" + si.rows[i].ENABLED + "', TIMED = '" + si.rows[i].TIMED + "' WHERE NAME = '" + si.rows[i].NAME + "'"
121                 if _, err := dbh.Exec(sql); err != nil {
122                         log.Fatal(err)
123                 }
124                 count++
125         }
126         lib.Logger.Println(count, "rows changed in p_s.setup_instruments")
127 }