github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/clients/pkg/promtail/targets/manager.go (about) 1 package targets 2 3 import ( 4 "fmt" 5 6 "github.com/go-kit/log" 7 "github.com/go-kit/log/level" 8 "github.com/pkg/errors" 9 "github.com/prometheus/client_golang/prometheus" 10 11 "github.com/grafana/loki/clients/pkg/promtail/api" 12 "github.com/grafana/loki/clients/pkg/promtail/positions" 13 "github.com/grafana/loki/clients/pkg/promtail/scrapeconfig" 14 "github.com/grafana/loki/clients/pkg/promtail/targets/cloudflare" 15 "github.com/grafana/loki/clients/pkg/promtail/targets/docker" 16 "github.com/grafana/loki/clients/pkg/promtail/targets/file" 17 "github.com/grafana/loki/clients/pkg/promtail/targets/gcplog" 18 "github.com/grafana/loki/clients/pkg/promtail/targets/gelf" 19 "github.com/grafana/loki/clients/pkg/promtail/targets/heroku" 20 "github.com/grafana/loki/clients/pkg/promtail/targets/journal" 21 "github.com/grafana/loki/clients/pkg/promtail/targets/kafka" 22 "github.com/grafana/loki/clients/pkg/promtail/targets/lokipush" 23 "github.com/grafana/loki/clients/pkg/promtail/targets/stdin" 24 "github.com/grafana/loki/clients/pkg/promtail/targets/syslog" 25 "github.com/grafana/loki/clients/pkg/promtail/targets/target" 26 "github.com/grafana/loki/clients/pkg/promtail/targets/windows" 27 ) 28 29 const ( 30 FileScrapeConfigs = "fileScrapeConfigs" 31 JournalScrapeConfigs = "journalScrapeConfigs" 32 SyslogScrapeConfigs = "syslogScrapeConfigs" 33 GcplogScrapeConfigs = "gcplogScrapeConfigs" 34 PushScrapeConfigs = "pushScrapeConfigs" 35 WindowsEventsConfigs = "windowsEventsConfigs" 36 KafkaConfigs = "kafkaConfigs" 37 GelfConfigs = "gelfConfigs" 38 CloudflareConfigs = "cloudflareConfigs" 39 DockerConfigs = "dockerConfigs" 40 DockerSDConfigs = "dockerSDConfigs" 41 HerokuDrainConfigs = "herokuDrainConfigs" 42 ) 43 44 type targetManager interface { 45 Ready() bool 46 Stop() 47 ActiveTargets() map[string][]target.Target 48 AllTargets() map[string][]target.Target 49 } 50 51 // TargetManagers manages a list of target managers. 52 type TargetManagers struct { 53 targetManagers []targetManager 54 positions positions.Positions 55 } 56 57 // NewTargetManagers makes a new TargetManagers 58 func NewTargetManagers( 59 app stdin.Shutdownable, 60 reg prometheus.Registerer, 61 logger log.Logger, 62 positionsConfig positions.Config, 63 client api.EntryHandler, 64 scrapeConfigs []scrapeconfig.Config, 65 targetConfig *file.Config, 66 ) (*TargetManagers, error) { 67 if targetConfig.Stdin { 68 level.Debug(logger).Log("msg", "configured to read from stdin") 69 stdin, err := stdin.NewStdinTargetManager(reg, logger, app, client, scrapeConfigs) 70 if err != nil { 71 return nil, err 72 } 73 return &TargetManagers{targetManagers: []targetManager{stdin}}, nil 74 } 75 76 var targetManagers []targetManager 77 targetScrapeConfigs := make(map[string][]scrapeconfig.Config, 4) 78 79 for _, cfg := range scrapeConfigs { 80 switch { 81 case cfg.HasServiceDiscoveryConfig(): 82 targetScrapeConfigs[FileScrapeConfigs] = append(targetScrapeConfigs[FileScrapeConfigs], cfg) 83 case cfg.JournalConfig != nil: 84 targetScrapeConfigs[JournalScrapeConfigs] = append(targetScrapeConfigs[JournalScrapeConfigs], cfg) 85 case cfg.SyslogConfig != nil: 86 targetScrapeConfigs[SyslogScrapeConfigs] = append(targetScrapeConfigs[SyslogScrapeConfigs], cfg) 87 case cfg.GcplogConfig != nil: 88 targetScrapeConfigs[GcplogScrapeConfigs] = append(targetScrapeConfigs[GcplogScrapeConfigs], cfg) 89 case cfg.PushConfig != nil: 90 targetScrapeConfigs[PushScrapeConfigs] = append(targetScrapeConfigs[PushScrapeConfigs], cfg) 91 case cfg.WindowsConfig != nil: 92 targetScrapeConfigs[WindowsEventsConfigs] = append(targetScrapeConfigs[WindowsEventsConfigs], cfg) 93 case cfg.KafkaConfig != nil: 94 targetScrapeConfigs[KafkaConfigs] = append(targetScrapeConfigs[KafkaConfigs], cfg) 95 case cfg.GelfConfig != nil: 96 targetScrapeConfigs[GelfConfigs] = append(targetScrapeConfigs[GelfConfigs], cfg) 97 case cfg.CloudflareConfig != nil: 98 targetScrapeConfigs[CloudflareConfigs] = append(targetScrapeConfigs[CloudflareConfigs], cfg) 99 case cfg.DockerSDConfigs != nil: 100 targetScrapeConfigs[DockerSDConfigs] = append(targetScrapeConfigs[DockerSDConfigs], cfg) 101 case cfg.HerokuDrainConfig != nil: 102 targetScrapeConfigs[HerokuDrainConfigs] = append(targetScrapeConfigs[HerokuDrainConfigs], cfg) 103 default: 104 return nil, fmt.Errorf("no valid target scrape config defined for %q", cfg.JobName) 105 } 106 } 107 108 var positionFile positions.Positions 109 110 // position file is a singleton, we use a function to keep it so. 111 getPositionFile := func() (positions.Positions, error) { 112 if positionFile == nil { 113 var err error 114 positionFile, err = positions.New(logger, positionsConfig) 115 if err != nil { 116 return nil, err 117 } 118 } 119 return positionFile, nil 120 } 121 122 var ( 123 fileMetrics *file.Metrics 124 syslogMetrics *syslog.Metrics 125 gcplogMetrics *gcplog.Metrics 126 gelfMetrics *gelf.Metrics 127 cloudflareMetrics *cloudflare.Metrics 128 dockerMetrics *docker.Metrics 129 journalMetrics *journal.Metrics 130 herokuDrainMetrics *heroku.Metrics 131 ) 132 if len(targetScrapeConfigs[FileScrapeConfigs]) > 0 { 133 fileMetrics = file.NewMetrics(reg) 134 } 135 if len(targetScrapeConfigs[SyslogScrapeConfigs]) > 0 { 136 syslogMetrics = syslog.NewMetrics(reg) 137 } 138 if len(targetScrapeConfigs[GcplogScrapeConfigs]) > 0 { 139 gcplogMetrics = gcplog.NewMetrics(reg) 140 } 141 if len(targetScrapeConfigs[GelfConfigs]) > 0 { 142 gelfMetrics = gelf.NewMetrics(reg) 143 } 144 if len(targetScrapeConfigs[CloudflareConfigs]) > 0 { 145 cloudflareMetrics = cloudflare.NewMetrics(reg) 146 } 147 if len(targetScrapeConfigs[DockerConfigs]) > 0 || len(targetScrapeConfigs[DockerSDConfigs]) > 0 { 148 dockerMetrics = docker.NewMetrics(reg) 149 } 150 if len(targetScrapeConfigs[JournalScrapeConfigs]) > 0 { 151 journalMetrics = journal.NewMetrics(reg) 152 } 153 if len(targetScrapeConfigs[HerokuDrainConfigs]) > 0 { 154 herokuDrainMetrics = heroku.NewMetrics(reg) 155 } 156 157 for target, scrapeConfigs := range targetScrapeConfigs { 158 switch target { 159 case FileScrapeConfigs: 160 pos, err := getPositionFile() 161 if err != nil { 162 return nil, err 163 } 164 fileTargetManager, err := file.NewFileTargetManager( 165 fileMetrics, 166 logger, 167 pos, 168 client, 169 scrapeConfigs, 170 targetConfig, 171 ) 172 if err != nil { 173 return nil, errors.Wrap(err, "failed to make file target manager") 174 } 175 targetManagers = append(targetManagers, fileTargetManager) 176 case JournalScrapeConfigs: 177 pos, err := getPositionFile() 178 if err != nil { 179 return nil, err 180 } 181 journalTargetManager, err := journal.NewJournalTargetManager( 182 journalMetrics, 183 logger, 184 pos, 185 client, 186 scrapeConfigs, 187 ) 188 if err != nil { 189 return nil, errors.Wrap(err, "failed to make journal target manager") 190 } 191 targetManagers = append(targetManagers, journalTargetManager) 192 case SyslogScrapeConfigs: 193 syslogTargetManager, err := syslog.NewSyslogTargetManager( 194 syslogMetrics, 195 logger, 196 client, 197 scrapeConfigs, 198 ) 199 if err != nil { 200 return nil, errors.Wrap(err, "failed to make syslog target manager") 201 } 202 targetManagers = append(targetManagers, syslogTargetManager) 203 case GcplogScrapeConfigs: 204 pubsubTargetManager, err := gcplog.NewGcplogTargetManager( 205 gcplogMetrics, 206 logger, 207 client, 208 scrapeConfigs, 209 ) 210 if err != nil { 211 return nil, errors.Wrap(err, "failed to make syslog target manager") 212 } 213 targetManagers = append(targetManagers, pubsubTargetManager) 214 case PushScrapeConfigs: 215 pushTargetManager, err := lokipush.NewPushTargetManager( 216 reg, 217 logger, 218 client, 219 scrapeConfigs, 220 ) 221 if err != nil { 222 return nil, errors.Wrap(err, "failed to make Loki Push API target manager") 223 } 224 targetManagers = append(targetManagers, pushTargetManager) 225 case HerokuDrainConfigs: 226 herokuDrainTargetManager, err := heroku.NewHerokuDrainTargetManager(herokuDrainMetrics, reg, logger, client, scrapeConfigs) 227 if err != nil { 228 return nil, errors.Wrap(err, "failed to make Heroku drain target manager") 229 } 230 targetManagers = append(targetManagers, herokuDrainTargetManager) 231 case WindowsEventsConfigs: 232 windowsTargetManager, err := windows.NewTargetManager(reg, logger, client, scrapeConfigs) 233 if err != nil { 234 return nil, errors.Wrap(err, "failed to make windows target manager") 235 } 236 targetManagers = append(targetManagers, windowsTargetManager) 237 case KafkaConfigs: 238 kafkaTargetManager, err := kafka.NewTargetManager(reg, logger, client, scrapeConfigs) 239 if err != nil { 240 return nil, errors.Wrap(err, "failed to make kafka target manager") 241 } 242 targetManagers = append(targetManagers, kafkaTargetManager) 243 case GelfConfigs: 244 gelfTargetManager, err := gelf.NewTargetManager(gelfMetrics, logger, client, scrapeConfigs) 245 if err != nil { 246 return nil, errors.Wrap(err, "failed to make gelf target manager") 247 } 248 targetManagers = append(targetManagers, gelfTargetManager) 249 case CloudflareConfigs: 250 pos, err := getPositionFile() 251 if err != nil { 252 return nil, err 253 } 254 cfTargetManager, err := cloudflare.NewTargetManager(cloudflareMetrics, logger, pos, client, scrapeConfigs) 255 if err != nil { 256 return nil, errors.Wrap(err, "failed to make cloudflare target manager") 257 } 258 targetManagers = append(targetManagers, cfTargetManager) 259 case DockerConfigs: 260 pos, err := getPositionFile() 261 if err != nil { 262 return nil, err 263 } 264 cfTargetManager, err := docker.NewTargetManager(dockerMetrics, logger, pos, client, scrapeConfigs) 265 if err != nil { 266 return nil, errors.Wrap(err, "failed to make Docker target manager") 267 } 268 targetManagers = append(targetManagers, cfTargetManager) 269 case DockerSDConfigs: 270 pos, err := getPositionFile() 271 if err != nil { 272 return nil, err 273 } 274 cfTargetManager, err := docker.NewTargetManager(dockerMetrics, logger, pos, client, scrapeConfigs) 275 if err != nil { 276 return nil, errors.Wrap(err, "failed to make Docker service discovery target manager") 277 } 278 targetManagers = append(targetManagers, cfTargetManager) 279 default: 280 return nil, errors.New("unknown scrape config") 281 } 282 } 283 284 return &TargetManagers{ 285 targetManagers: targetManagers, 286 positions: positionFile, 287 }, nil 288 } 289 290 // ActiveTargets returns active targets per jobs 291 func (tm *TargetManagers) ActiveTargets() map[string][]target.Target { 292 result := map[string][]target.Target{} 293 for _, t := range tm.targetManagers { 294 for job, targets := range t.ActiveTargets() { 295 result[job] = append(result[job], targets...) 296 } 297 } 298 return result 299 } 300 301 // AllTargets returns all targets per jobs 302 func (tm *TargetManagers) AllTargets() map[string][]target.Target { 303 result := map[string][]target.Target{} 304 for _, t := range tm.targetManagers { 305 for job, targets := range t.AllTargets() { 306 result[job] = append(result[job], targets...) 307 } 308 } 309 return result 310 } 311 312 // Ready if there's at least one ready target manager. 313 func (tm *TargetManagers) Ready() bool { 314 for _, t := range tm.targetManagers { 315 if t.Ready() { 316 return true 317 } 318 } 319 return false 320 } 321 322 // Stop the TargetManagers. 323 func (tm *TargetManagers) Stop() { 324 for _, t := range tm.targetManagers { 325 t.Stop() 326 } 327 if tm.positions != nil { 328 tm.positions.Stop() 329 } 330 }