diff --git a/pkg/datasource/datasource.go b/pkg/datasource/datasource.go index e8a6f8d..621c709 100644 --- a/pkg/datasource/datasource.go +++ b/pkg/datasource/datasource.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "errors" + "strconv" "time" "github.com/alexanderzobnin/grafana-zabbix/pkg/gtime" @@ -49,18 +50,18 @@ func newZabbixDatasourceInstance(settings backend.DataSourceInstanceSettings) (i logger := log.New() logger.Debug("Initializing new data source instance") - zabbixAPI, err := zabbixapi.New(settings.URL, &settings) - if err != nil { - logger.Error("Error initializing Zabbix API", "error", err) - return nil, err - } - zabbixSettings, err := readZabbixSettings(&settings) if err != nil { logger.Error("Error parsing Zabbix settings", "error", err) return nil, err } + zabbixAPI, err := zabbixapi.New(&settings, zabbixSettings.Timeout) + if err != nil { + logger.Error("Error initializing Zabbix API", "error", err) + return nil, err + } + return &ZabbixDatasourceInstance{ dsInfo: &settings, zabbixAPI: zabbixAPI, @@ -154,6 +155,10 @@ func readZabbixSettings(dsInstanceSettings *backend.DataSourceInstanceSettings) zabbixSettingsDTO.CacheTTL = "1h" } + if zabbixSettingsDTO.Timeout == "" { + zabbixSettingsDTO.Timeout = "30" + } + trendsFrom, err := gtime.ParseInterval(zabbixSettingsDTO.TrendsFrom) if err != nil { return nil, err @@ -169,11 +174,17 @@ func readZabbixSettings(dsInstanceSettings *backend.DataSourceInstanceSettings) return nil, err } + timeout, err := strconv.Atoi(zabbixSettingsDTO.Timeout) + if err != nil { + return nil, errors.New("failed to parse timeout: " + err.Error()) + } + zabbixSettings := &ZabbixDatasourceSettings{ Trends: zabbixSettingsDTO.Trends, TrendsFrom: trendsFrom, TrendsRange: trendsRange, CacheTTL: cacheTTL, + Timeout: time.Duration(timeout) * time.Second, } return zabbixSettings, nil diff --git a/pkg/datasource/models.go b/pkg/datasource/models.go index 03813d9..b2291e1 100644 --- a/pkg/datasource/models.go +++ b/pkg/datasource/models.go @@ -14,6 +14,7 @@ type ZabbixDatasourceSettingsDTO struct { TrendsFrom string `json:"trendsFrom"` TrendsRange string `json:"trendsRange"` CacheTTL string `json:"cacheTTL"` + Timeout string `json:"timeout"` DisableReadOnlyUsersAck bool `json:"disableReadOnlyUsersAck"` } @@ -24,6 +25,7 @@ type ZabbixDatasourceSettings struct { TrendsFrom time.Duration TrendsRange time.Duration CacheTTL time.Duration + Timeout time.Duration DisableReadOnlyUsersAck bool `json:"disableReadOnlyUsersAck"` } diff --git a/pkg/httpclient/httpclient.go b/pkg/httpclient/httpclient.go index 991d0e7..d7240c2 100644 --- a/pkg/httpclient/httpclient.go +++ b/pkg/httpclient/httpclient.go @@ -13,6 +13,7 @@ import ( simplejson "github.com/bitly/go-simplejson" "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" ) type proxyTransportCache struct { @@ -46,14 +47,16 @@ var ptc = proxyTransportCache{ } // GetHttpClient returns new http.Client. Transport either initialized or got from cache. -func GetHttpClient(ds *backend.DataSourceInstanceSettings) (*http.Client, error) { +func GetHttpClient(ds *backend.DataSourceInstanceSettings, timeout time.Duration) (*http.Client, error) { transport, err := getHttpTransport(ds) if err != nil { return nil, err } + log.DefaultLogger.Debug("Initializing new HTTP client", "timeout", timeout.Seconds()) + return &http.Client{ - Timeout: time.Duration(time.Second * 30), + Timeout: timeout, Transport: transport, }, nil } diff --git a/pkg/zabbixapi/zabbix_api.go b/pkg/zabbixapi/zabbix_api.go index dfc4f86..812d41d 100644 --- a/pkg/zabbixapi/zabbix_api.go +++ b/pkg/zabbixapi/zabbix_api.go @@ -9,6 +9,7 @@ import ( "io/ioutil" "net/http" "net/url" + "time" "github.com/alexanderzobnin/grafana-zabbix/pkg/httpclient" "github.com/bitly/go-simplejson" @@ -31,14 +32,14 @@ type ZabbixAPI struct { type ZabbixAPIParams = map[string]interface{} // New returns new ZabbixAPI instance initialized with given URL or error. -func New(api_url string, dsInfo *backend.DataSourceInstanceSettings) (*ZabbixAPI, error) { +func New(dsInfo *backend.DataSourceInstanceSettings, timeout time.Duration) (*ZabbixAPI, error) { apiLogger := log.New() - zabbixURL, err := url.Parse(api_url) + zabbixURL, err := url.Parse(dsInfo.URL) if err != nil { return nil, err } - client, err := httpclient.GetHttpClient(dsInfo) + client, err := httpclient.GetHttpClient(dsInfo, timeout) if err != nil { return nil, err } diff --git a/src/datasource-zabbix/components/ConfigEditor.tsx b/src/datasource-zabbix/components/ConfigEditor.tsx index 66f1bb2..9e47d50 100644 --- a/src/datasource-zabbix/components/ConfigEditor.tsx +++ b/src/datasource-zabbix/components/ConfigEditor.tsx @@ -154,6 +154,17 @@ export const ConfigEditor = (props: Props) => { tooltip="Zabbix data source caches metric names in memory. Specify how often data will be updated." /> +
+ +
diff --git a/src/datasource-zabbix/types.ts b/src/datasource-zabbix/types.ts index 1828e5d..a39f134 100644 --- a/src/datasource-zabbix/types.ts +++ b/src/datasource-zabbix/types.ts @@ -7,6 +7,7 @@ export interface ZabbixDSOptions extends DataSourceJsonData { trendsFrom: string; trendsRange: string; cacheTTL: string; + timeout?: string; dbConnectionEnable: boolean; dbConnectionDatasourceId?: number; dbConnectionDatasourceName?: string;