diff --git a/internal/pgscv/config.go b/internal/pgscv/config.go index 2d2f6e5..015bc3a 100644 --- a/internal/pgscv/config.go +++ b/internal/pgscv/config.go @@ -27,19 +27,19 @@ const ( // Config defines application's configuration. type Config struct { - NoTrackMode bool `yaml:"no_track_mode"` // controls tracking sensitive information (query texts, etc) - ListenAddress string `yaml:"listen_address"` // Network address and port where the application should listen on - ServicesConnsSettings service.ConnsSettings `yaml:"services"` // All connections settings for exact services - Defaults map[string]string `yaml:"defaults"` // Defaults - DisableCollectors []string `yaml:"disable_collectors"` // List of collectors which should be disabled. DEPRECATED in favor collectors settings - CollectorsSettings model.CollectorsSettings `yaml:"collectors"` // Collectors settings propagated from main YAML configuration - Databases string `yaml:"databases"` // Regular expression string specifies databases from which metrics should be collected - DatabasesRE *regexp.Regexp // Regular expression object compiled from Databases - AuthConfig http.AuthConfig `yaml:"authentication"` // TLS and Basic auth configuration - CollectTopTable int `yaml:"collect_top_table"` // Limit elements on Table collector - CollectTopIndex int `yaml:"collect_top_index"` // Limit elements on Indexes collector - CollectTopQuery int `yaml:"collect_top_query"` // Limit elements on Statements collector - TestDbConnectionOnStartup bool `yaml:"test_db_connection_on_startup"` // Check connection settings and try to connect using them. In case of failure, don't create a Service instance. + NoTrackMode bool `yaml:"no_track_mode"` // controls tracking sensitive information (query texts, etc) + ListenAddress string `yaml:"listen_address"` // Network address and port where the application should listen on + ServicesConnsSettings service.ConnsSettings `yaml:"services"` // All connections settings for exact services + Defaults map[string]string `yaml:"defaults"` // Defaults + DisableCollectors []string `yaml:"disable_collectors"` // List of collectors which should be disabled. DEPRECATED in favor collectors settings + CollectorsSettings model.CollectorsSettings `yaml:"collectors"` // Collectors settings propagated from main YAML configuration + Databases string `yaml:"databases"` // Regular expression string specifies databases from which metrics should be collected + DatabasesRE *regexp.Regexp // Regular expression object compiled from Databases + AuthConfig http.AuthConfig `yaml:"authentication"` // TLS and Basic auth configuration + CollectTopTable int `yaml:"collect_top_table"` // Limit elements on Table collector + CollectTopIndex int `yaml:"collect_top_index"` // Limit elements on Indexes collector + CollectTopQuery int `yaml:"collect_top_query"` // Limit elements on Statements collector + SkipConnErrorMode bool `yaml:"skip_conn_error_mode"` // Skipping connection errors and creating a Service instance. } // NewConfig creates new config based on config file or return default config if config file is not specified. @@ -65,7 +65,6 @@ func NewConfig(configFilePath string) (*Config, error) { // Get configuration from environment variables configFromEnv, err := newConfigFromEnv() - fmt.Println(configFromEnv.TestDbConnectionOnStartup) if err != nil { return nil, err } @@ -110,8 +109,8 @@ func NewConfig(configFilePath string) (*Config, error) { if configFromEnv.CollectTopQuery > 0 { configFromFile.CollectTopQuery = configFromEnv.CollectTopQuery } - if !configFromEnv.TestDbConnectionOnStartup { - configFromFile.TestDbConnectionOnStartup = false + if configFromEnv.SkipConnErrorMode { + configFromFile.SkipConnErrorMode = configFromEnv.SkipConnErrorMode } return configFromFile, nil } @@ -183,6 +182,10 @@ func (c *Config) Validate() error { log.Infoln("no-track disabled, for details check the documentation about 'no_track_mode' option.") } + if c.SkipConnErrorMode { + log.Infoln("skipping connection errors is enabled.") + } + // setup defaults if c.Defaults == nil { c.Defaults = map[string]string{} @@ -340,9 +343,8 @@ func newConfigFromEnv() (*Config, error) { log.Infoln("read configuration from environment") config := &Config{ - Defaults: map[string]string{}, - ServicesConnsSettings: map[string]service.ConnSetting{}, - TestDbConnectionOnStartup: true, + Defaults: map[string]string{}, + ServicesConnsSettings: map[string]service.ConnSetting{}, } for _, env := range os.Environ() { @@ -423,8 +425,8 @@ func newConfigFromEnv() (*Config, error) { return nil, fmt.Errorf("invalid setting PGSCV_COLLECT_TOP_INDEX, value '%s', allowed only digits", value) } config.CollectTopIndex = collectTopIndex - case "PGSCV_TEST_DB_CONNECTION_ON_STARTUP": - config.TestDbConnectionOnStartup = toBool(value) + case "PGSCV_SKIP_CONN_ERROR_MODE": + config.SkipConnErrorMode = toBool(value) } } return config, nil diff --git a/internal/pgscv/config_test.go b/internal/pgscv/config_test.go index d0fdb88..c7ce928 100644 --- a/internal/pgscv/config_test.go +++ b/internal/pgscv/config_test.go @@ -547,28 +547,28 @@ func Test_newConfigFromEnv(t *testing.T) { valid: true, // No env variables envvars: map[string]string{}, want: &Config{ - Defaults: map[string]string{}, - ServicesConnsSettings: map[string]service.ConnSetting{}, - TestDbConnectionOnStartup: true, + Defaults: map[string]string{}, + ServicesConnsSettings: map[string]service.ConnSetting{}, }, }, { valid: true, // Completely valid variables envvars: map[string]string{ - "PGSCV_LISTEN_ADDRESS": "127.0.0.1:12345", - "PGSCV_NO_TRACK_MODE": "yes", - "PGSCV_DATABASES": "exampledb", - "PGSCV_DISABLE_COLLECTORS": "example/1,example/2, example/3", - "POSTGRES_DSN": "example_dsn", - "POSTGRES_DSN_EXAMPLE1": "example_dsn", - "PGBOUNCER_DSN": "example_dsn", - "PGBOUNCER_DSN_EXAMPLE2": "example_dsn", - "PATRONI_URL": "example_url", - "PATRONI_URL_EXAMPLE3": "example_url", - "PGSCV_AUTH_USERNAME": "user", - "PGSCV_AUTH_PASSWORD": "pass", - "PGSCV_AUTH_KEYFILE": "keyfile.key", - "PGSCV_AUTH_CERTFILE": "certfile.cert", + "PGSCV_LISTEN_ADDRESS": "127.0.0.1:12345", + "PGSCV_NO_TRACK_MODE": "yes", + "PGSCV_DATABASES": "exampledb", + "PGSCV_DISABLE_COLLECTORS": "example/1,example/2, example/3", + "POSTGRES_DSN": "example_dsn", + "POSTGRES_DSN_EXAMPLE1": "example_dsn", + "PGBOUNCER_DSN": "example_dsn", + "PGBOUNCER_DSN_EXAMPLE2": "example_dsn", + "PATRONI_URL": "example_url", + "PATRONI_URL_EXAMPLE3": "example_url", + "PGSCV_AUTH_USERNAME": "user", + "PGSCV_AUTH_PASSWORD": "pass", + "PGSCV_AUTH_KEYFILE": "keyfile.key", + "PGSCV_AUTH_CERTFILE": "certfile.cert", + "PGSCV_SKIP_CONN_ERROR_MODE": "yes", }, want: &Config{ ListenAddress: "127.0.0.1:12345", @@ -589,8 +589,8 @@ func Test_newConfigFromEnv(t *testing.T) { Keyfile: "keyfile.key", Certfile: "certfile.cert", }, - Defaults: map[string]string{}, - TestDbConnectionOnStartup: true, + Defaults: map[string]string{}, + SkipConnErrorMode: true, }, }, { diff --git a/internal/pgscv/pgscv.go b/internal/pgscv/pgscv.go index b1d7e6e..a8d9c41 100644 --- a/internal/pgscv/pgscv.go +++ b/internal/pgscv/pgscv.go @@ -3,10 +3,11 @@ package pgscv import ( "context" "errors" + "sync" + "github.com/cherts/pgscv/internal/http" "github.com/cherts/pgscv/internal/log" "github.com/cherts/pgscv/internal/service" - "sync" ) // Start is the application's starting point. @@ -16,16 +17,16 @@ func Start(ctx context.Context, config *Config) error { serviceRepo := service.NewRepository() serviceConfig := service.Config{ - NoTrackMode: config.NoTrackMode, - ConnDefaults: config.Defaults, - ConnsSettings: config.ServicesConnsSettings, - DatabasesRE: config.DatabasesRE, - DisabledCollectors: config.DisableCollectors, - CollectorsSettings: config.CollectorsSettings, - CollectTopTable: config.CollectTopTable, - CollectTopIndex: config.CollectTopIndex, - CollectTopQuery: config.CollectTopQuery, - TestDbConnectionOnStartup: config.TestDbConnectionOnStartup, + NoTrackMode: config.NoTrackMode, + ConnDefaults: config.Defaults, + ConnsSettings: config.ServicesConnsSettings, + DatabasesRE: config.DatabasesRE, + DisabledCollectors: config.DisableCollectors, + CollectorsSettings: config.CollectorsSettings, + CollectTopTable: config.CollectTopTable, + CollectTopIndex: config.CollectTopIndex, + CollectTopQuery: config.CollectTopQuery, + SkipConnErrorMode: config.SkipConnErrorMode, } if len(config.ServicesConnsSettings) == 0 { diff --git a/internal/service/service.go b/internal/service/service.go index ebaa99f..8caedf3 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -41,11 +41,11 @@ type Config struct { DatabasesRE *regexp.Regexp DisabledCollectors []string // CollectorsSettings defines all collector settings propagated from main YAML configuration. - CollectorsSettings model.CollectorsSettings - CollectTopTable int - CollectTopIndex int - CollectTopQuery int - TestDbConnectionOnStartup bool + CollectorsSettings model.CollectorsSettings + CollectTopTable int + CollectTopIndex int + CollectTopQuery int + SkipConnErrorMode bool } // Collector is an interface for prometheus.Collector. @@ -155,11 +155,11 @@ func (repo *Repository) addServicesFromConfig(config Config) { // Check connection using created *ConnConfig, go next if connection failed. db, err := store.NewWithConfig(pgconfig) if err != nil { - if config.TestDbConnectionOnStartup { + if config.SkipConnErrorMode { + log.Warnf("%s: %s", cs.Conninfo, err) + } else { log.Warnf("%s: %s skip", cs.Conninfo, err) continue - } else { - log.Warnf("%s: %s", cs.Conninfo, err) } } else { msg = fmt.Sprintf("service [%s] available through: %s@%s:%d/%s", k, pgconfig.User, pgconfig.Host, pgconfig.Port, pgconfig.Database) diff --git a/internal/service/service_test.go b/internal/service/service_test.go index 4b5d9dc..013a9a5 100644 --- a/internal/service/service_test.go +++ b/internal/service/service_test.go @@ -1,10 +1,11 @@ package service import ( + "testing" + "github.com/cherts/pgscv/internal/model" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" - "testing" ) func TestRepository_addService(t *testing.T) { @@ -63,13 +64,23 @@ func TestRepository_addServicesFromConfig(t *testing.T) { { name: "valid", config: Config{ - TestDbConnectionOnStartup: true, + SkipConnErrorMode: false, ConnsSettings: ConnsSettings{ "test": {ServiceType: model.ServiceTypePostgresql, Conninfo: "host=127.0.0.1 port=5432 user=pgscv dbname=pgscv_fixtures"}, }}, expected: 2, }, + { + name: "valid_skip_error", + config: Config{ + SkipConnErrorMode: true, + ConnsSettings: ConnsSettings{ + "test": {ServiceType: model.ServiceTypePostgresql, + Conninfo: "host=127.0.0.1 port=5430 user=pgscv dbname=pgscv_fixtures"}, + }}, + expected: 2, + }, { name: "empty conn settings", config: Config{}, @@ -78,26 +89,18 @@ func TestRepository_addServicesFromConfig(t *testing.T) { { name: "invalid service", config: Config{ - TestDbConnectionOnStartup: true, - ConnsSettings: ConnsSettings{"test": {ServiceType: model.ServiceTypePostgresql, Conninfo: "invalid conninfo"}}}, + SkipConnErrorMode: true, + ConnsSettings: ConnsSettings{"test": {ServiceType: model.ServiceTypePostgresql, Conninfo: "invalid conninfo"}}}, expected: 1, }, { name: "unavailable service", config: Config{ - TestDbConnectionOnStartup: true, - ConnsSettings: ConnsSettings{"test": {ServiceType: model.ServiceTypePostgresql, Conninfo: "port=1"}}, + SkipConnErrorMode: false, + ConnsSettings: ConnsSettings{"test": {ServiceType: model.ServiceTypePostgresql, Conninfo: "port=1"}}, }, expected: 1, }, - { - name: "unavailable service", - config: Config{ - TestDbConnectionOnStartup: false, - ConnsSettings: ConnsSettings{"test": {ServiceType: model.ServiceTypePostgresql, Conninfo: "port=1"}}, - }, - expected: 2, - }, } for _, tc := range testCases {