123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- // Copyright The OpenTelemetry Authors
- // SPDX-License-Identifier: Apache-2.0
- package httpcheckreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/httpcheckreceiver"
- import (
- "context"
- "errors"
- "net/http"
- "sync"
- "time"
- "go.opentelemetry.io/collector/component"
- "go.opentelemetry.io/collector/pdata/pcommon"
- "go.opentelemetry.io/collector/pdata/pmetric"
- "go.opentelemetry.io/collector/receiver"
- "go.uber.org/multierr"
- "go.uber.org/zap"
- "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/httpcheckreceiver/internal/metadata"
- )
- var (
- errClientNotInit = errors.New("client not initialized")
- httpResponseClasses = map[string]int{"1xx": 1, "2xx": 2, "3xx": 3, "4xx": 4, "5xx": 5}
- )
- type httpcheckScraper struct {
- clients []*http.Client
- cfg *Config
- settings component.TelemetrySettings
- mb *metadata.MetricsBuilder
- }
- // start starts the scraper by creating a new HTTP Client on the scraper
- func (h *httpcheckScraper) start(_ context.Context, host component.Host) (err error) {
- for _, target := range h.cfg.Targets {
- client, clentErr := target.ToClient(host, h.settings)
- if clentErr != nil {
- err = multierr.Append(err, clentErr)
- }
- h.clients = append(h.clients, client)
- }
- return
- }
- // scrape connects to the endpoint and produces metrics based on the response
- func (h *httpcheckScraper) scrape(ctx context.Context) (pmetric.Metrics, error) {
- if h.clients == nil || len(h.clients) == 0 {
- return pmetric.NewMetrics(), errClientNotInit
- }
- var wg sync.WaitGroup
- wg.Add(len(h.clients))
- var mux sync.Mutex
- for idx, client := range h.clients {
- go func(targetClient *http.Client, targetIndex int) {
- defer wg.Done()
- now := pcommon.NewTimestampFromTime(time.Now())
- req, err := http.NewRequestWithContext(ctx, h.cfg.Targets[targetIndex].Method, h.cfg.Targets[targetIndex].Endpoint, http.NoBody)
- if err != nil {
- h.settings.Logger.Error("failed to create request", zap.Error(err))
- return
- }
- start := time.Now()
- resp, err := targetClient.Do(req)
- mux.Lock()
- h.mb.RecordHttpcheckDurationDataPoint(now, time.Since(start).Milliseconds(), h.cfg.Targets[targetIndex].Endpoint)
- statusCode := 0
- if err != nil {
- h.mb.RecordHttpcheckErrorDataPoint(now, int64(1), h.cfg.Targets[targetIndex].Endpoint, err.Error())
- } else {
- statusCode = resp.StatusCode
- }
- for class, intVal := range httpResponseClasses {
- if statusCode/100 == intVal {
- h.mb.RecordHttpcheckStatusDataPoint(now, int64(1), h.cfg.Targets[targetIndex].Endpoint, int64(statusCode), req.Method, class)
- } else {
- h.mb.RecordHttpcheckStatusDataPoint(now, int64(0), h.cfg.Targets[targetIndex].Endpoint, int64(statusCode), req.Method, class)
- }
- }
- mux.Unlock()
- }(client, idx)
- }
- wg.Wait()
- return h.mb.Emit(), nil
- }
- func newScraper(conf *Config, settings receiver.CreateSettings) *httpcheckScraper {
- return &httpcheckScraper{
- cfg: conf,
- settings: settings.TelemetrySettings,
- mb: metadata.NewMetricsBuilder(conf.MetricsBuilderConfig, settings),
- }
- }
|