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  }