@@ -6,13 +6,8 @@ package collector
66import (
77 "context"
88 "database/sql"
9- "errors"
10- "fmt"
11- "github.com/godror/godror"
12- "github.com/godror/godror/dsn"
139 "github.com/prometheus/client_golang/prometheus"
1410 "log/slog"
15- "strings"
1611 "time"
1712)
1813
@@ -34,28 +29,6 @@ func (d *Database) UpMetric(exporterLabels map[string]string) prometheus.Metric
3429 )
3530}
3631
37- // ping the database. If the database is disconnected, try to reconnect.
38- // If the database type is unknown, try to reload it.
39- func (d * Database ) ping (logger * slog.Logger ) error {
40- ctx , cancel := context .WithTimeout (context .Background (), 5 * time .Second )
41- defer cancel ()
42- err := d .Session .PingContext (ctx )
43- if err != nil {
44- d .Up = 0
45- if isInvalidCredentialsError (err ) {
46- d .invalidate ()
47- return err
48- }
49- // If database is closed, try to reconnect
50- if strings .Contains (err .Error (), "sql: database is closed" ) {
51- d .Session = connect (logger , d .Name , d .Config )
52- }
53- return err
54- }
55- d .Up = 1
56- return nil
57- }
58-
5932func (d * Database ) constLabels (labels map [string ]string ) map [string ]string {
6033 labels ["database" ] = d .Name
6134
@@ -125,101 +98,3 @@ func (d *Database) IsValid() bool {
12598func (d * Database ) invalidate () {
12699 d .Valid = false
127100}
128-
129- func isInvalidCredentialsError (err error ) bool {
130- err = errors .Unwrap (err )
131- if err == nil {
132- return false
133- }
134- oraErr , ok := err .(* godror.OraErr )
135- if ! ok {
136- return false
137- }
138- return oraErr .Code () == ora01017code || oraErr .Code () == ora28000code
139- }
140-
141- func connect (logger * slog.Logger , dbname string , dbconfig DatabaseConfig ) * sql.DB {
142- logger .Debug ("Launching connection to " + maskDsn (dbconfig .URL ), "database" , dbname )
143-
144- var P godror.ConnectionParams
145- password := dbconfig .GetPassword ()
146- username := dbconfig .GetUsername ()
147- // If password is not specified, externalAuth will be true, and we'll ignore user input
148- dbconfig .ExternalAuth = password == ""
149- logger .Debug (fmt .Sprintf ("external authentication set to %t" , dbconfig .ExternalAuth ), "database" , dbname )
150- msg := "Using Username/Password Authentication."
151- if dbconfig .ExternalAuth {
152- msg = "Database Password not specified; will attempt to use external authentication (ignoring user input)."
153- dbconfig .Username = ""
154- }
155- logger .Info (msg , "database" , dbname )
156- externalAuth := sql.NullBool {
157- Bool : dbconfig .ExternalAuth ,
158- Valid : true ,
159- }
160- P .Username , P .Password , P .ConnectString , P .ExternalAuth = username , godror .NewPassword (password ), dbconfig .URL , externalAuth
161-
162- if dbconfig .GetPoolIncrement () > 0 {
163- logger .Debug (fmt .Sprintf ("set pool increment to %d" , dbconfig .PoolIncrement ), "database" , dbname )
164- P .PoolParams .SessionIncrement = dbconfig .GetPoolIncrement ()
165- }
166- if dbconfig .GetPoolMaxConnections () > 0 {
167- logger .Debug (fmt .Sprintf ("set pool max connections to %d" , dbconfig .PoolMaxConnections ), "database" , dbname )
168- P .PoolParams .MaxSessions = dbconfig .GetPoolMaxConnections ()
169- }
170- if dbconfig .GetPoolMinConnections () > 0 {
171- logger .Debug (fmt .Sprintf ("set pool min connections to %d" , dbconfig .PoolMinConnections ), "database" , dbname )
172- P .PoolParams .MinSessions = dbconfig .GetPoolMinConnections ()
173- }
174-
175- P .PoolParams .WaitTimeout = time .Second * 5
176-
177- // if TNS_ADMIN env var is set, set ConfigDir to that location
178- P .ConfigDir = dbconfig .TNSAdmin
179-
180- switch dbconfig .Role {
181- case "SYSDBA" :
182- P .AdminRole = dsn .SysDBA
183- case "SYSOPER" :
184- P .AdminRole = dsn .SysOPER
185- case "SYSBACKUP" :
186- P .AdminRole = dsn .SysBACKUP
187- case "SYSDG" :
188- P .AdminRole = dsn .SysDG
189- case "SYSKM" :
190- P .AdminRole = dsn .SysKM
191- case "SYSRAC" :
192- P .AdminRole = dsn .SysRAC
193- case "SYSASM" :
194- P .AdminRole = dsn .SysASM
195- default :
196- P .AdminRole = dsn .NoRole
197- }
198-
199- // note that this just configures the connection, it does not actually connect until later
200- // when we call db.Ping()
201- db := sql .OpenDB (godror .NewConnector (P ))
202- logger .Debug (fmt .Sprintf ("set max idle connections to %d" , dbconfig .MaxIdleConns ), "database" , dbname )
203- db .SetMaxIdleConns (dbconfig .GetMaxIdleConns ())
204- logger .Debug (fmt .Sprintf ("set max open connections to %d" , dbconfig .MaxOpenConns ), "database" , dbname )
205- db .SetMaxOpenConns (dbconfig .GetMaxOpenConns ())
206- db .SetConnMaxLifetime (0 )
207- logger .Debug (fmt .Sprintf ("Successfully configured connection to %s" , maskDsn (dbconfig .URL )), "database" , dbname )
208-
209- ctx , cancel := context .WithTimeout (context .Background (), 15 * time .Second )
210- defer cancel ()
211- if _ , err := db .ExecContext (ctx , `
212- begin
213- dbms_application_info.set_client_info('oracledb_exporter');
214- end;` ); err != nil {
215- logger .Info ("Could not set CLIENT_INFO." , "database" , dbname )
216- }
217-
218- var sysdba string
219- if err := db .QueryRowContext (ctx , "select sys_context('USERENV', 'ISDBA') from dual" ).Scan (& sysdba ); err != nil {
220- logger .Error ("error checking my database role" , "error" , err , "database" , dbname )
221- }
222- logger .Info ("Connected as SYSDBA? " + sysdba , "database" , dbname )
223-
224- return db
225- }
0 commit comments