github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/promtail/promtail.go (about)

     1  package promtail
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/go-kit/log"
     7  	"github.com/prometheus/client_golang/prometheus"
     8  
     9  	"github.com/grafana/loki/clients/pkg/logentry/stages"
    10  	"github.com/grafana/loki/clients/pkg/promtail/client"
    11  	"github.com/grafana/loki/clients/pkg/promtail/config"
    12  	"github.com/grafana/loki/clients/pkg/promtail/server"
    13  	"github.com/grafana/loki/clients/pkg/promtail/targets"
    14  	"github.com/grafana/loki/clients/pkg/promtail/targets/target"
    15  
    16  	util_log "github.com/grafana/loki/pkg/util/log"
    17  )
    18  
    19  // Option is a function that can be passed to the New method of Promtail and
    20  // customize the Promtail that is created.
    21  type Option func(p *Promtail)
    22  
    23  // WithLogger overrides the default logger for Promtail.
    24  func WithLogger(log log.Logger) Option {
    25  	return func(p *Promtail) {
    26  		p.logger = log
    27  	}
    28  }
    29  
    30  // WithRegisterer overrides the default registerer for Promtail.
    31  func WithRegisterer(reg prometheus.Registerer) Option {
    32  	return func(p *Promtail) {
    33  		p.reg = reg
    34  	}
    35  }
    36  
    37  // Promtail is the root struct for Promtail.
    38  type Promtail struct {
    39  	client         client.Client
    40  	targetManagers *targets.TargetManagers
    41  	server         server.Server
    42  	logger         log.Logger
    43  	reg            prometheus.Registerer
    44  
    45  	stopped bool
    46  	mtx     sync.Mutex
    47  }
    48  
    49  // New makes a new Promtail.
    50  func New(cfg config.Config, metrics *client.Metrics, dryRun bool, opts ...Option) (*Promtail, error) {
    51  	// Initialize promtail with some defaults and allow the options to override
    52  	// them.
    53  	promtail := &Promtail{
    54  		logger: util_log.Logger,
    55  		reg:    prometheus.DefaultRegisterer,
    56  	}
    57  	for _, o := range opts {
    58  		// todo (callum) I don't understand why I needed to add this check
    59  		if o == nil {
    60  			continue
    61  		}
    62  		o(promtail)
    63  	}
    64  
    65  	cfg.Setup(promtail.logger)
    66  
    67  	if cfg.LimitsConfig.ReadlineRateEnabled {
    68  		stages.SetReadLineRateLimiter(cfg.LimitsConfig.ReadlineRate, cfg.LimitsConfig.ReadlineBurst, cfg.LimitsConfig.ReadlineRateDrop)
    69  	}
    70  	var err error
    71  	if dryRun {
    72  		promtail.client, err = client.NewLogger(metrics, cfg.Options.StreamLagLabels, promtail.logger, cfg.ClientConfigs...)
    73  		if err != nil {
    74  			return nil, err
    75  		}
    76  		cfg.PositionsConfig.ReadOnly = true
    77  	} else {
    78  		promtail.client, err = client.NewMulti(metrics, cfg.Options.StreamLagLabels, promtail.logger, cfg.ClientConfigs...)
    79  		if err != nil {
    80  			return nil, err
    81  		}
    82  	}
    83  
    84  	tms, err := targets.NewTargetManagers(promtail, promtail.reg, promtail.logger, cfg.PositionsConfig, promtail.client, cfg.ScrapeConfig, &cfg.TargetConfig)
    85  	if err != nil {
    86  		return nil, err
    87  	}
    88  	promtail.targetManagers = tms
    89  	server, err := server.New(cfg.ServerConfig, promtail.logger, tms, cfg.String())
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	promtail.server = server
    94  	return promtail, nil
    95  }
    96  
    97  // Run the promtail; will block until a signal is received.
    98  func (p *Promtail) Run() error {
    99  	p.mtx.Lock()
   100  	// if we stopped promtail before the server even started we can return without starting.
   101  	if p.stopped {
   102  		p.mtx.Unlock()
   103  		return nil
   104  	}
   105  	p.mtx.Unlock() // unlock before blocking
   106  	return p.server.Run()
   107  }
   108  
   109  // Client returns the underlying client Promtail uses to write to Loki.
   110  func (p *Promtail) Client() client.Client {
   111  	return p.client
   112  }
   113  
   114  // Shutdown the promtail.
   115  func (p *Promtail) Shutdown() {
   116  	p.mtx.Lock()
   117  	defer p.mtx.Unlock()
   118  	if p.stopped {
   119  		return
   120  	}
   121  	p.stopped = true
   122  	if p.server != nil {
   123  		p.server.Shutdown()
   124  	}
   125  	if p.targetManagers != nil {
   126  		p.targetManagers.Stop()
   127  	}
   128  	// todo work out the stop.
   129  	p.client.Stop()
   130  }
   131  
   132  // ActiveTargets returns active targets per jobs from the target manager
   133  func (p *Promtail) ActiveTargets() map[string][]target.Target {
   134  	return p.targetManagers.ActiveTargets()
   135  }