Skip to content
Snippets Groups Projects
Select Git revision
  • main default protected
  • v3.0
  • v3-alpha-1
  • v2.0
  • v1.1.0
  • v1.0.0
6 results

monitor_http.go

Blame
  • monitor_http.go 2.09 KiB
    package main
    
    import (
    	"crypto/tls"
    	"github.com/sirupsen/logrus"
    	"io/ioutil"
    	"net/http"
    	"regexp"
    	"time"
    )
    
    type HttpMonitor struct {
    	config     ConfigComponent
    	bodyRegexp *regexp.Regexp
    }
    
    func NewHttpMonitor(config ConfigComponent) *HttpMonitor {
    	bodyRegexp, _ := regexp.Compile(config.Http.Expected.Body)
    	return &HttpMonitor{
    		config:     config,
    		bodyRegexp: bodyRegexp,
    	}
    }
    
    func (m *HttpMonitor) Config() *ConfigComponent {
    	return &m.config
    }
    
    func (m *HttpMonitor) Measure() (Datapoint, error) {
    	req, err := http.NewRequest(m.config.Http.Method, m.config.Http.Url, nil)
    	if err != nil {
    		return Datapoint{}, err
    	}
    	for k, v := range m.config.Http.Headers {
    		req.Header.Add(k, v)
    	}
    
    	transport := http.DefaultTransport.(*http.Transport)
    	transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: m.config.Http.Insecure}
    	client := &http.Client{
    		Timeout:   time.Duration(m.config.LatencyThresholds.Down) * time.Millisecond,
    		Transport: transport,
    	}
    
    	before := time.Now()
    	resp, err := client.Do(req)
    	after := time.Now()
    	latency := int(after.Sub(before).Nanoseconds() / 1000000)
    	if err != nil {
    		logrus.Infof("Monitor %s: %s", err.Error())
    		return Datapoint{
    			Time:    after,
    			Up:      false,
    			Latency: latency,
    		}, nil
    	}
    
    	defer resp.Body.Close()
    
    	if m.config.Http.Expected.StatusCode > 0 && resp.StatusCode != m.config.Http.Expected.StatusCode {
    		logrus.Infof("Monitor %s: Expected HTTP response status: %d, got: %d", m.config.Name, m.config.Http.Expected.StatusCode, resp.StatusCode)
    		return Datapoint{
    			Time:    after,
    			Up:      false,
    			Latency: latency,
    		}, nil
    	}
    
    	if m.bodyRegexp != nil {
    		// check response body
    		responseBody, err := ioutil.ReadAll(resp.Body)
    		if err != nil {
    			return Datapoint{}, err
    		}
    
    		if !m.bodyRegexp.Match(responseBody) {
    			logrus.Infof("Monitor %s: Unexpected body: %\nExpected to match: %s", m.config.Name, string(responseBody), m.config.Http.Expected.Body)
    			return Datapoint{
    				Time:    after,
    				Up:      false,
    				Latency: latency,
    			}, nil
    		}
    	}
    
    	return Datapoint{
    		Time:    after,
    		Up:      true,
    		Latency: latency,
    	}, nil
    }