2017-11-25 13:13:54 +00:00
// Copyright 2013 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2018-02-01 09:55:07 +00:00
package scrape
2017-11-25 13:13:54 +00:00
import (
"fmt"
2018-01-18 11:49:42 +00:00
"reflect"
2018-01-17 11:46:17 +00:00
"sync"
2017-11-25 13:13:54 +00:00
"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/prometheus/prometheus/config"
Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
2017-12-30 01:31:34 +05:30
"github.com/prometheus/prometheus/discovery/targetgroup"
2017-11-25 13:13:54 +00:00
"github.com/prometheus/prometheus/storage"
)
// Appendable returns an Appender.
type Appendable interface {
Appender ( ) ( storage . Appender , error )
}
2018-02-01 10:06:24 +00:00
// NewManager is the Manager constructor
func NewManager ( logger log . Logger , app Appendable ) * Manager {
return & Manager {
2017-11-25 13:13:54 +00:00
append : app ,
logger : logger ,
scrapeConfigs : make ( map [ string ] * config . ScrapeConfig ) ,
scrapePools : make ( map [ string ] * scrapePool ) ,
2017-11-26 15:15:15 +00:00
graceShut : make ( chan struct { } ) ,
2018-04-09 17:18:25 +03:00
targetsAll : make ( map [ string ] [ ] * Target ) ,
2017-11-25 13:13:54 +00:00
}
}
2018-02-01 10:06:24 +00:00
// Manager maintains a set of scrape pools and manages start/stop cycles
2017-11-25 13:13:54 +00:00
// when receiving new target groups form the discovery manager.
2018-02-01 10:06:24 +00:00
type Manager struct {
2018-04-09 17:18:25 +03:00
logger log . Logger
append Appendable
graceShut chan struct { }
mtxTargets sync . Mutex // Guards the fields below.
targetsActive [ ] * Target
targetsDropped [ ] * Target
targetsAll map [ string ] [ ] * Target
mtxScrape sync . Mutex // Guards the fields below.
2017-11-25 13:13:54 +00:00
scrapeConfigs map [ string ] * config . ScrapeConfig
scrapePools map [ string ] * scrapePool
}
// Run starts background processing to handle target updates and reload the scraping loops.
2018-02-01 10:06:24 +00:00
func ( m * Manager ) Run ( tsets <- chan map [ string ] [ ] * targetgroup . Group ) error {
2017-11-25 13:13:54 +00:00
for {
select {
case ts := <- tsets :
2017-12-30 17:27:50 +00:00
m . reload ( ts )
2017-11-26 15:15:15 +00:00
case <- m . graceShut :
return nil
2017-11-25 13:13:54 +00:00
}
}
}
2017-11-26 15:15:15 +00:00
// Stop cancels all running scrape pools and blocks until all have exited.
2018-02-01 10:06:24 +00:00
func ( m * Manager ) Stop ( ) {
2018-04-09 17:18:25 +03:00
m . mtxScrape . Lock ( )
defer m . mtxScrape . Unlock ( )
2017-11-26 15:15:15 +00:00
for _ , sp := range m . scrapePools {
sp . stop ( )
}
close ( m . graceShut )
}
2017-11-25 13:13:54 +00:00
// ApplyConfig resets the manager's target providers and job configurations as defined by the new cfg.
2018-02-01 10:06:24 +00:00
func ( m * Manager ) ApplyConfig ( cfg * config . Config ) error {
2018-04-09 17:18:25 +03:00
m . mtxScrape . Lock ( )
defer m . mtxScrape . Unlock ( )
2018-01-17 11:46:17 +00:00
c := make ( map [ string ] * config . ScrapeConfig )
for _ , scfg := range cfg . ScrapeConfigs {
c [ scfg . JobName ] = scfg
2017-11-25 13:13:54 +00:00
}
2018-01-17 11:46:17 +00:00
m . scrapeConfigs = c
2018-01-18 11:49:42 +00:00
// Cleanup and reload pool if config has changed.
for name , sp := range m . scrapePools {
if cfg , ok := m . scrapeConfigs [ name ] ; ! ok {
sp . stop ( )
delete ( m . scrapePools , name )
} else if ! reflect . DeepEqual ( sp . config , cfg ) {
sp . reload ( cfg )
}
}
2017-11-25 13:13:54 +00:00
return nil
}
2018-04-09 17:18:25 +03:00
// TargetsAll returns active and dropped targets grouped by job_name.
func ( m * Manager ) TargetsAll ( ) map [ string ] [ ] * Target {
m . mtxTargets . Lock ( )
defer m . mtxTargets . Unlock ( )
return m . targetsAll
}
2018-01-17 11:46:17 +00:00
2018-04-09 17:18:25 +03:00
// TargetsActive returns the active targets currently being scraped.
func ( m * Manager ) TargetsActive ( ) [ ] * Target {
m . mtxTargets . Lock ( )
defer m . mtxTargets . Unlock ( )
return m . targetsActive
2017-11-25 13:13:54 +00:00
}
2018-04-09 17:18:25 +03:00
// TargetsDropped returns the dropped targets during relabelling.
func ( m * Manager ) TargetsDropped ( ) [ ] * Target {
m . mtxTargets . Lock ( )
defer m . mtxTargets . Unlock ( )
return m . targetsDropped
}
2018-01-17 11:46:17 +00:00
2018-04-09 17:18:25 +03:00
func ( m * Manager ) targetsUpdate ( active , dropped map [ string ] [ ] * Target ) {
m . mtxTargets . Lock ( )
defer m . mtxTargets . Unlock ( )
2018-01-17 11:46:17 +00:00
2018-04-09 17:18:25 +03:00
m . targetsAll = make ( map [ string ] [ ] * Target )
m . targetsActive = nil
m . targetsDropped = nil
for jobName , targets := range active {
m . targetsAll [ jobName ] = append ( m . targetsAll [ jobName ] , targets ... )
m . targetsActive = append ( m . targetsActive , targets ... )
2017-11-25 13:13:54 +00:00
2018-02-21 17:26:18 +00:00
}
2018-04-09 17:18:25 +03:00
for jobName , targets := range dropped {
m . targetsAll [ jobName ] = append ( m . targetsAll [ jobName ] , targets ... )
m . targetsDropped = append ( m . targetsDropped , targets ... )
}
2018-02-21 17:26:18 +00:00
}
2018-02-01 10:06:24 +00:00
func ( m * Manager ) reload ( t map [ string ] [ ] * targetgroup . Group ) {
2018-04-09 17:18:25 +03:00
m . mtxScrape . Lock ( )
defer m . mtxScrape . Unlock ( )
2017-11-25 13:13:54 +00:00
2018-04-09 17:18:25 +03:00
tDropped := make ( map [ string ] [ ] * Target )
tActive := make ( map [ string ] [ ] * Target )
2017-11-25 13:13:54 +00:00
2018-04-09 17:18:25 +03:00
for tsetName , tgroup := range t {
var sp * scrapePool
if existing , ok := m . scrapePools [ tsetName ] ; ! ok {
scrapeConfig , ok := m . scrapeConfigs [ tsetName ]
if ! ok {
level . Error ( m . logger ) . Log ( "msg" , "error reloading target set" , "err" , fmt . Sprintf ( "invalid config id:%v" , tsetName ) )
continue
}
sp = newScrapePool ( scrapeConfig , m . append , log . With ( m . logger , "scrape_pool" , tsetName ) )
m . scrapePools [ tsetName ] = sp
2017-11-25 13:13:54 +00:00
} else {
2018-04-09 17:18:25 +03:00
sp = existing
2017-11-25 13:13:54 +00:00
}
2018-04-09 17:18:25 +03:00
tActive [ tsetName ] , tDropped [ tsetName ] = sp . Sync ( tgroup )
2018-01-14 19:42:31 +00:00
}
2018-04-09 17:18:25 +03:00
m . targetsUpdate ( tActive , tDropped )
2017-11-25 13:13:54 +00:00
}