zotregistry.dev/zot@v1.4.4-0.20240314164342-eec277e14d20/pkg/extensions/monitoring/minimal_client.go (about) 1 //go:build !metrics 2 // +build !metrics 3 4 package monitoring 5 6 import ( 7 "context" 8 "crypto/tls" 9 "encoding/json" 10 "fmt" 11 "net/http" 12 "time" 13 14 "zotregistry.dev/zot/pkg/log" 15 ) 16 17 const ( 18 httpTimeout = 1 * time.Minute 19 ) 20 21 // MetricsConfig is used to configure the creation of a Node Exporter http client 22 // that will connect to a particular zot instance. 23 type MetricsConfig struct { 24 // Address of the zot http server 25 Address string 26 27 // Transport to use for the http client. 28 Transport *http.Transport 29 30 // HTTPClient is the client to use. 31 HTTPClient *http.Client 32 } 33 34 type MetricsClient struct { 35 headers http.Header 36 config MetricsConfig 37 log log.Logger 38 } 39 40 func newHTTPMetricsClient() *http.Client { 41 defaultTransport := http.DefaultTransport.(*http.Transport).Clone() //nolint: forcetypeassert 42 defaultTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} //nolint: gosec 43 44 return &http.Client{ 45 Timeout: httpTimeout, 46 Transport: defaultTransport, 47 } 48 } 49 50 // Creates a MetricsClient that can be used to retrieve in memory metrics 51 // The new MetricsClient retrieved must be cached and reused by the Node Exporter 52 // in order to prevent concurrent memory leaks. 53 func NewMetricsClient(config *MetricsConfig, logger log.Logger) *MetricsClient { 54 if config.HTTPClient == nil { 55 config.HTTPClient = newHTTPMetricsClient() 56 } 57 58 return &MetricsClient{config: *config, headers: make(http.Header), log: logger} 59 } 60 61 func (mc *MetricsClient) GetMetrics() (*MetricsInfo, error) { 62 metrics := &MetricsInfo{} 63 if _, err := mc.makeGETRequest(mc.config.Address+"/metrics", metrics); err != nil { 64 return nil, err 65 } 66 67 return metrics, nil 68 } 69 70 func (mc *MetricsClient) makeGETRequest(url string, resultsPtr interface{}) (http.Header, error) { 71 req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil) 72 if err != nil { 73 return nil, fmt.Errorf("metric scraping failed: %w", err) 74 } 75 76 resp, err := mc.config.HTTPClient.Do(req) 77 if err != nil { 78 return nil, fmt.Errorf("metric scraping failed: %w", err) 79 } 80 81 defer resp.Body.Close() 82 83 if err := json.NewDecoder(resp.Body).Decode(resultsPtr); err != nil { 84 return nil, fmt.Errorf("metric scraping failed: %w", err) 85 } 86 87 return resp.Header, nil 88 }