- Fix metrics double-counting: track deltas for WaitCount/WaitDuration instead of adding cumulative values each tick - Replace fmt.Printf with structured logging in pool monitor - Add PoolOptions validation (MaxConns > 0, MinConns >= 0) - Warn when DATABASE_URI overrides non-default PoolOptions - Improve findAndParseConfig to report all tried files and errors - Remove dead code in pgdb/config.go (unreachable host default) - Fix errcheck lint issues for file.Close() calls - Add context parameter to OpenDBMonitor() (breaking change)
79 lines
2.1 KiB
Go
79 lines
2.1 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"os"
|
|
|
|
"go.ntppool.org/common/logger"
|
|
)
|
|
|
|
// OpenDB opens a database connection with the specified configuration options
|
|
func OpenDB(ctx context.Context, options ConfigOptions) (*sql.DB, error) {
|
|
log := logger.Setup()
|
|
|
|
configFile, err := findConfigFile(options.ConfigFiles)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
dbconn := sql.OpenDB(Driver{
|
|
CreateConnectorFunc: createConnector(configFile),
|
|
})
|
|
|
|
// Set connection pool parameters
|
|
dbconn.SetConnMaxLifetime(options.ConnMaxLifetime)
|
|
dbconn.SetMaxOpenConns(options.MaxOpenConns)
|
|
dbconn.SetMaxIdleConns(options.MaxIdleConns)
|
|
|
|
err = dbconn.Ping()
|
|
if err != nil {
|
|
log.Error("could not connect to database", "err", err)
|
|
return nil, err
|
|
}
|
|
|
|
// Start optional connection pool monitoring
|
|
if options.EnablePoolMonitoring && options.PrometheusRegisterer != nil {
|
|
go monitorConnectionPool(ctx, dbconn, options.PrometheusRegisterer)
|
|
}
|
|
|
|
return dbconn, nil
|
|
}
|
|
|
|
// OpenDBWithConfigFile opens a database connection using an explicit config file path
|
|
// This is a convenience function for API package compatibility
|
|
func OpenDBWithConfigFile(ctx context.Context, configFile string) (*sql.DB, error) {
|
|
options := DefaultConfigOptions()
|
|
options.ConfigFiles = []string{configFile}
|
|
return OpenDB(ctx, options)
|
|
}
|
|
|
|
// OpenDBMonitor opens a database connection with monitor-specific defaults
|
|
// This is a convenience function for Monitor package compatibility
|
|
func OpenDBMonitor(ctx context.Context) (*sql.DB, error) {
|
|
options := MonitorConfigOptions()
|
|
return OpenDB(ctx, options)
|
|
}
|
|
|
|
// findConfigFile searches for the first existing config file from the list
|
|
func findConfigFile(configFiles []string) (string, error) {
|
|
var firstErr error
|
|
|
|
for _, configFile := range configFiles {
|
|
if configFile == "" {
|
|
continue
|
|
}
|
|
if _, err := os.Stat(configFile); err == nil {
|
|
return configFile, nil
|
|
} else if firstErr == nil {
|
|
firstErr = err
|
|
}
|
|
}
|
|
|
|
if firstErr != nil {
|
|
return "", fmt.Errorf("no config file found: %w", firstErr)
|
|
}
|
|
return "", fmt.Errorf("no valid config files provided")
|
|
}
|