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 }