Path: blob/main/pkg/integrations/blackbox_exporter/blackbox_exporter.go
5398 views
package blackbox_exporter12import (3"context"4"fmt"5"net/http"6"net/url"78"github.com/go-kit/log"9"github.com/grafana/agent/pkg/integrations"10"github.com/grafana/agent/pkg/integrations/config"11blackbox_config "github.com/prometheus/blackbox_exporter/config"12"github.com/prometheus/blackbox_exporter/prober"13)1415// DefaultConfig holds the default settings for the blackbox_exporter integration.16var DefaultConfig = Config{17// Default value taken from https://github.com/prometheus/blackbox_exporter/blob/master/main.go#L6118ProbeTimeoutOffset: 0.5,19}2021func loadFile(filename string, log log.Logger) (*blackbox_config.Config, error) {22sc := &blackbox_config.SafeConfig{23C: &blackbox_config.Config{},24}25err := sc.ReloadConfig(filename, log)26if err != nil {27return nil, err28}29return sc.C, nil30}3132// BlackboxTarget defines a target device to be used by the integration.33type BlackboxTarget struct {34Name string `yaml:"name"`35Target string `yaml:"address"`36Module string `yaml:"module"`37}3839// Config configures the Blackbox integration.40type Config struct {41BlackboxConfigFile string `yaml:"config_file,omitempty"`42BlackboxTargets []BlackboxTarget `yaml:"blackbox_targets"`43BlackboxConfig blackbox_config.Config `yaml:"blackbox_config,omitempty"`44ProbeTimeoutOffset float64 `yaml:"probe_timeout_offset,omitempty"`45}4647// UnmarshalYAML implements yaml.Unmarshaler for Config.48func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {49*c = DefaultConfig5051type plain Config52return unmarshal((*plain)(c))53}5455// Name returns the name of the integration.56func (c *Config) Name() string {57return "blackbox"58}5960// InstanceKey returns the hostname:port of the agent.61func (c *Config) InstanceKey(agentKey string) (string, error) {62return agentKey, nil63}6465// NewIntegration creates a new blackbox integration.66func (c *Config) NewIntegration(l log.Logger) (integrations.Integration, error) {67return New(l, c)68}6970func init() {71integrations.RegisterIntegration(&Config{})72}7374// LoadBlackboxConfig loads the blackbox config from the given file or from embedded yaml block75// it also validates that targets are properly defined76func LoadBlackboxConfig(log log.Logger, configFile string, targets []BlackboxTarget, modules *blackbox_config.Config) (*blackbox_config.Config, error) {77var err error7879if configFile != "" {80modules, err = loadFile(configFile, log)81if err != nil {82return nil, fmt.Errorf("failed to load blackbox config from file %v: %w", configFile, err)83}84}8586// The `name` and `address` fields are mandatory for the Blackbox targets are mandatory.87// Enforce this check and fail the creation of the integration if they're missing.88for _, target := range targets {89if target.Name == "" || target.Target == "" {90return nil, fmt.Errorf("failed to load blackbox_targets; the `name` and `address` fields are mandatory")91}92}93return modules, nil94}9596// New creates a new blackbox_exporter integration97func New(log log.Logger, c *Config) (integrations.Integration, error) {98modules, err := LoadBlackboxConfig(log, c.BlackboxConfigFile, c.BlackboxTargets, &c.BlackboxConfig)99if err != nil {100return nil, err101}102103integration := &Integration{104cfg: c,105modules: modules,106log: log,107}108return integration, nil109}110111// Integration is the blackbox integration. The integration scrapes metrics112// probing of endpoints over HTTP, HTTPS, DNS, TCP, ICMP and gRPC.113type Integration struct {114cfg *Config115modules *blackbox_config.Config116log log.Logger117}118119// MetricsHandler implements Integration.120func (i *Integration) MetricsHandler() (http.Handler, error) {121return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {122prober.Handler(w, r, i.modules, i.log, &prober.ResultHistory{}, i.cfg.ProbeTimeoutOffset, nil)123}), nil124}125126// Run satisfies Integration.Run.127func (i *Integration) Run(ctx context.Context) error {128// We don't need to do anything here, so we can just wait for the context to129// finish.130<-ctx.Done()131return ctx.Err()132}133134// ScrapeConfigs satisfies Integration.ScrapeConfigs.135func (i *Integration) ScrapeConfigs() []config.ScrapeConfig {136var res []config.ScrapeConfig137for _, target := range i.cfg.BlackboxTargets {138queryParams := url.Values{}139queryParams.Add("target", target.Target)140if target.Module != "" {141queryParams.Add("module", target.Module)142}143res = append(res, config.ScrapeConfig{144JobName: i.cfg.Name() + "/" + target.Name,145MetricsPath: "/metrics",146QueryParams: queryParams,147})148}149return res150}151152153