github.com/netdata/go.d.plugin@v0.58.1/modules/httpcheck/httpcheck.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package httpcheck 4 5 import ( 6 _ "embed" 7 "net/http" 8 "regexp" 9 "time" 10 11 "github.com/netdata/go.d.plugin/pkg/web" 12 13 "github.com/netdata/go.d.plugin/agent/module" 14 ) 15 16 //go:embed "config_schema.json" 17 var configSchema string 18 19 func init() { 20 module.Register("httpcheck", module.Creator{ 21 JobConfigSchema: configSchema, 22 Defaults: module.Defaults{ 23 UpdateEvery: 5, 24 }, 25 Create: func() module.Module { return New() }, 26 }) 27 } 28 29 func New() *HTTPCheck { 30 return &HTTPCheck{ 31 Config: Config{ 32 HTTP: web.HTTP{ 33 Client: web.Client{ 34 Timeout: web.Duration{Duration: time.Second}, 35 }, 36 }, 37 AcceptedStatuses: []int{200}, 38 }, 39 acceptedStatuses: make(map[int]bool), 40 } 41 } 42 43 type ( 44 Config struct { 45 web.HTTP `yaml:",inline"` 46 UpdateEvery int `yaml:"update_every"` 47 AcceptedStatuses []int `yaml:"status_accepted"` 48 ResponseMatch string `yaml:"response_match"` 49 CookieFile string `yaml:"cookie_file"` 50 HeaderMatch []HeaderMatchConfig `yaml:"header_match"` 51 } 52 HeaderMatchConfig struct { 53 Exclude bool `yaml:"exclude"` 54 Key string `yaml:"key"` 55 Value string `yaml:"value"` 56 } 57 ) 58 59 type HTTPCheck struct { 60 module.Base 61 Config `yaml:",inline"` 62 63 httpClient *http.Client 64 65 charts *module.Charts 66 67 acceptedStatuses map[int]bool 68 reResponse *regexp.Regexp 69 headerMatch []headerMatch 70 71 cookieFileModTime time.Time 72 73 metrics metrics 74 } 75 76 func (hc *HTTPCheck) Init() bool { 77 if err := hc.validateConfig(); err != nil { 78 hc.Errorf("config validation: %v", err) 79 return false 80 } 81 82 hc.charts = hc.initCharts() 83 84 httpClient, err := hc.initHTTPClient() 85 if err != nil { 86 hc.Errorf("init HTTP client: %v", err) 87 return false 88 } 89 hc.httpClient = httpClient 90 91 re, err := hc.initResponseMatchRegexp() 92 if err != nil { 93 hc.Errorf("init response match regexp: %v", err) 94 return false 95 } 96 hc.reResponse = re 97 98 hm, err := hc.initHeaderMatch() 99 if err != nil { 100 hc.Errorf("init header match: %v", err) 101 return false 102 } 103 hc.headerMatch = hm 104 105 for _, v := range hc.AcceptedStatuses { 106 hc.acceptedStatuses[v] = true 107 } 108 109 hc.Debugf("using URL %s", hc.URL) 110 hc.Debugf("using HTTP timeout %s", hc.Timeout.Duration) 111 hc.Debugf("using accepted HTTP statuses %v", hc.AcceptedStatuses) 112 if hc.reResponse != nil { 113 hc.Debugf("using response match regexp %s", hc.reResponse) 114 } 115 116 return true 117 } 118 119 func (hc *HTTPCheck) Check() bool { 120 return len(hc.Collect()) > 0 121 } 122 123 func (hc *HTTPCheck) Charts() *module.Charts { 124 return hc.charts 125 } 126 127 func (hc *HTTPCheck) Collect() map[string]int64 { 128 mx, err := hc.collect() 129 if err != nil { 130 hc.Error(err) 131 } 132 133 if len(mx) == 0 { 134 return nil 135 } 136 return mx 137 } 138 139 func (hc *HTTPCheck) Cleanup() { 140 if hc.httpClient != nil { 141 hc.httpClient.CloseIdleConnections() 142 } 143 }