github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/scrape/discovery/discovery.go (about)

     1  // Copyright 2013 The Prometheus Authors
     2  // Copyright 2021 The Pyroscope Authors
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  // http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package discovery
    17  
    18  import (
    19  	"context"
    20  	"reflect"
    21  
    22  	"github.com/sirupsen/logrus"
    23  
    24  	"github.com/pyroscope-io/pyroscope/pkg/scrape/discovery/targetgroup"
    25  )
    26  
    27  // revive:disable:max-public-structs complex package
    28  
    29  // Discoverer provides information about target groups. It maintains a set
    30  // of sources from which TargetGroups can originate. Whenever a discovery provider
    31  // detects a potential change, it sends the TargetGroup through its channel.
    32  //
    33  // Discoverer does not know if an actual change happened.
    34  // It does guarantee that it sends the new TargetGroup whenever a change happens.
    35  //
    36  // Discoverers should initially send a full set of all discoverable TargetGroups.
    37  type Discoverer interface {
    38  	// Run hands a channel to the discovery provider (Consul, DNS, etc.) through which
    39  	// it can send updated target groups. It must return when the context is canceled.
    40  	// It should not close the update channel on returning.
    41  	Run(ctx context.Context, up chan<- []*targetgroup.Group)
    42  }
    43  
    44  // DiscovererOptions provides options for a Discoverer.
    45  type DiscovererOptions struct {
    46  	Logger logrus.FieldLogger
    47  }
    48  
    49  // A Config provides the configuration and constructor for a Discoverer.
    50  type Config interface {
    51  	// Name returns the name of the discovery mechanism.
    52  	Name() string
    53  
    54  	// NewDiscoverer returns a Discoverer for the Config
    55  	// with the given DiscovererOptions.
    56  	NewDiscoverer(DiscovererOptions) (Discoverer, error)
    57  }
    58  
    59  // Configs is a slice of Config values that uses custom YAML marshaling and unmarshaling
    60  // to represent itself as a mapping of the Config values grouped by their types.
    61  type Configs []Config
    62  
    63  // SetDirectory joins any relative file paths with dir.
    64  func (c *Configs) SetDirectory(dir string) {
    65  	for _, c := range *c {
    66  		if v, ok := c.(interface{ SetDirectory(string) }); ok {
    67  			v.SetDirectory(dir)
    68  		}
    69  	}
    70  }
    71  
    72  // UnmarshalYAML implements yaml.Unmarshaler.
    73  func (c *Configs) UnmarshalYAML(unmarshal func(interface{}) error) error {
    74  	cfgTyp := getConfigType(configsType)
    75  	cfgPtr := reflect.New(cfgTyp)
    76  	cfgVal := cfgPtr.Elem()
    77  
    78  	if err := unmarshal(cfgPtr.Interface()); err != nil {
    79  		return replaceYAMLTypeError(err, cfgTyp, configsType)
    80  	}
    81  
    82  	var err error
    83  	*c, err = readConfigs(cfgVal, 0)
    84  	return err
    85  }
    86  
    87  // MarshalYAML implements yaml.Marshaler.
    88  func (c Configs) MarshalYAML() (interface{}, error) {
    89  	cfgTyp := getConfigType(configsType)
    90  	cfgPtr := reflect.New(cfgTyp)
    91  	cfgVal := cfgPtr.Elem()
    92  
    93  	if err := writeConfigs(cfgVal, c); err != nil {
    94  		return nil, err
    95  	}
    96  
    97  	return cfgPtr.Interface(), nil
    98  }
    99  
   100  // A StaticConfig is a Config that provides a static list of targets.
   101  type StaticConfig []*targetgroup.Group
   102  
   103  // Name returns the name of the service discovery mechanism.
   104  func (StaticConfig) Name() string { return "static" }
   105  
   106  // NewDiscoverer returns a Discoverer for the Config.
   107  func (c StaticConfig) NewDiscoverer(DiscovererOptions) (Discoverer, error) {
   108  	return staticDiscoverer(c), nil
   109  }
   110  
   111  type staticDiscoverer []*targetgroup.Group
   112  
   113  func (c staticDiscoverer) Run(ctx context.Context, up chan<- []*targetgroup.Group) {
   114  	// TODO: existing implementation closes up chan, but documentation explicitly forbids it...?
   115  	defer close(up)
   116  	select {
   117  	case <-ctx.Done():
   118  	case up <- c:
   119  	}
   120  }