fix(http): Stop plugins from leaking file descriptors on telegraf reload (#15213)
This commit is contained in:
parent
1e57608a21
commit
96d6da63f2
|
|
@ -353,6 +353,9 @@ func (c *CtrlXDataLayer) gatherLoop(ctx context.Context) {
|
||||||
func (c *CtrlXDataLayer) Stop() {
|
func (c *CtrlXDataLayer) Stop() {
|
||||||
c.cancel()
|
c.cancel()
|
||||||
c.wg.Wait()
|
c.wg.Wait()
|
||||||
|
if c.connection != nil {
|
||||||
|
c.connection.CloseIdleConnections()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather is called by telegraf to collect the metrics.
|
// Gather is called by telegraf to collect the metrics.
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,10 @@ func (e *Elasticsearch) Init() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Elasticsearch) Start(_ telegraf.Accumulator) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Gather reads the stats from Elasticsearch and writes it to the
|
// Gather reads the stats from Elasticsearch and writes it to the
|
||||||
// Accumulator.
|
// Accumulator.
|
||||||
func (e *Elasticsearch) Gather(acc telegraf.Accumulator) error {
|
func (e *Elasticsearch) Gather(acc telegraf.Accumulator) error {
|
||||||
|
|
@ -282,6 +286,12 @@ func (e *Elasticsearch) Gather(acc telegraf.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Elasticsearch) Stop() {
|
||||||
|
if e.client != nil {
|
||||||
|
e.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Elasticsearch) createHTTPClient() (*http.Client, error) {
|
func (e *Elasticsearch) createHTTPClient() (*http.Client, error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
if e.HTTPTimeout != 0 {
|
if e.HTTPTimeout != 0 {
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,10 @@ func (e *ElasticsearchQuery) connectToES() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *ElasticsearchQuery) Start(_ telegraf.Accumulator) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Gather writes the results of the queries from Elasticsearch to the Accumulator.
|
// Gather writes the results of the queries from Elasticsearch to the Accumulator.
|
||||||
func (e *ElasticsearchQuery) Gather(acc telegraf.Accumulator) error {
|
func (e *ElasticsearchQuery) Gather(acc telegraf.Accumulator) error {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
@ -197,6 +201,12 @@ func (e *ElasticsearchQuery) Gather(acc telegraf.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *ElasticsearchQuery) Stop() {
|
||||||
|
if e.httpclient != nil {
|
||||||
|
e.httpclient.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (e *ElasticsearchQuery) createHTTPClient() (*http.Client, error) {
|
func (e *ElasticsearchQuery) createHTTPClient() (*http.Client, error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
return e.HTTPClientConfig.CreateClient(ctx, e.Log)
|
return e.HTTPClientConfig.CreateClient(ctx, e.Log)
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,10 @@ func (h *HTTP) Init() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *HTTP) Start(_ telegraf.Accumulator) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Gather takes in an accumulator and adds the metrics that the Input
|
// Gather takes in an accumulator and adds the metrics that the Input
|
||||||
// gathers. This is called every "interval"
|
// gathers. This is called every "interval"
|
||||||
func (h *HTTP) Gather(acc telegraf.Accumulator) error {
|
func (h *HTTP) Gather(acc telegraf.Accumulator) error {
|
||||||
|
|
@ -99,6 +103,12 @@ func (h *HTTP) Gather(acc telegraf.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *HTTP) Stop() {
|
||||||
|
if h.client != nil {
|
||||||
|
h.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetParserFunc takes the data_format from the config and finds the right parser for that format
|
// SetParserFunc takes the data_format from the config and finds the right parser for that format
|
||||||
func (h *HTTP) SetParserFunc(fn telegraf.ParserFunc) {
|
func (h *HTTP) SetParserFunc(fn telegraf.ParserFunc) {
|
||||||
h.parserFunc = fn
|
h.parserFunc = fn
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,10 @@ func (*Kibana) SampleConfig() string {
|
||||||
return sampleConfig
|
return sampleConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k *Kibana) Start(_ telegraf.Accumulator) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (k *Kibana) Gather(acc telegraf.Accumulator) error {
|
func (k *Kibana) Gather(acc telegraf.Accumulator) error {
|
||||||
if k.client == nil {
|
if k.client == nil {
|
||||||
client, err := k.createHTTPClient()
|
client, err := k.createHTTPClient()
|
||||||
|
|
@ -150,6 +154,12 @@ func (k *Kibana) Gather(acc telegraf.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k *Kibana) Stop() {
|
||||||
|
if k.client != nil {
|
||||||
|
k.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (k *Kibana) createHTTPClient() (*http.Client, error) {
|
func (k *Kibana) createHTTPClient() (*http.Client, error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
return k.HTTPClientConfig.CreateClient(ctx, k.Log)
|
return k.HTTPClientConfig.CreateClient(ctx, k.Log)
|
||||||
|
|
|
||||||
|
|
@ -454,6 +454,10 @@ func (logstash *Logstash) gatherPipelinesStats(address string, accumulator teleg
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (logstash *Logstash) Start(_ telegraf.Accumulator) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Gather ask this plugin to start gathering metrics
|
// Gather ask this plugin to start gathering metrics
|
||||||
func (logstash *Logstash) Gather(accumulator telegraf.Accumulator) error {
|
func (logstash *Logstash) Gather(accumulator telegraf.Accumulator) error {
|
||||||
if logstash.client == nil {
|
if logstash.client == nil {
|
||||||
|
|
@ -508,6 +512,12 @@ func (logstash *Logstash) Gather(accumulator telegraf.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (logstash *Logstash) Stop() {
|
||||||
|
if logstash.client != nil {
|
||||||
|
logstash.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// init registers this plugin instance
|
// init registers this plugin instance
|
||||||
func init() {
|
func init() {
|
||||||
inputs.Add("logstash", func() telegraf.Input {
|
inputs.Add("logstash", func() telegraf.Input {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -79,6 +80,8 @@ type OpenStack struct {
|
||||||
Log telegraf.Logger `toml:"-"`
|
Log telegraf.Logger `toml:"-"`
|
||||||
httpconfig.HTTPClientConfig
|
httpconfig.HTTPClientConfig
|
||||||
|
|
||||||
|
client *http.Client
|
||||||
|
|
||||||
// Locally cached clients
|
// Locally cached clients
|
||||||
identity *gophercloud.ServiceClient
|
identity *gophercloud.ServiceClient
|
||||||
compute *gophercloud.ServiceClient
|
compute *gophercloud.ServiceClient
|
||||||
|
|
@ -153,7 +156,8 @@ func (o *OpenStack) Start(_ telegraf.Accumulator) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
provider.HTTPClient = *client
|
o.client = client
|
||||||
|
provider.HTTPClient = *o.client
|
||||||
|
|
||||||
// Authenticate to the endpoint
|
// Authenticate to the endpoint
|
||||||
authOption := gophercloud.AuthOptions{
|
authOption := gophercloud.AuthOptions{
|
||||||
|
|
@ -226,7 +230,11 @@ func (o *OpenStack) Start(_ telegraf.Accumulator) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OpenStack) Stop() {}
|
func (o *OpenStack) Stop() {
|
||||||
|
if o.client != nil {
|
||||||
|
o.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Gather gathers resources from the OpenStack API and accumulates metrics. This
|
// Gather gathers resources from the OpenStack API and accumulates metrics. This
|
||||||
// implements the Input interface.
|
// implements the Input interface.
|
||||||
|
|
|
||||||
|
|
@ -588,6 +588,10 @@ func (p *Prometheus) Start(_ telegraf.Accumulator) error {
|
||||||
func (p *Prometheus) Stop() {
|
func (p *Prometheus) Stop() {
|
||||||
p.cancel()
|
p.cancel()
|
||||||
p.wg.Wait()
|
p.wg.Wait()
|
||||||
|
|
||||||
|
if p.client != nil {
|
||||||
|
p.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,10 @@ func (n *Vault) Init() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Vault) Start(_ telegraf.Accumulator) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Gather, collects metrics from Vault endpoint
|
// Gather, collects metrics from Vault endpoint
|
||||||
func (n *Vault) Gather(acc telegraf.Accumulator) error {
|
func (n *Vault) Gather(acc telegraf.Accumulator) error {
|
||||||
sysMetrics, err := n.loadJSON(n.URL + "/v1/sys/metrics")
|
sysMetrics, err := n.loadJSON(n.URL + "/v1/sys/metrics")
|
||||||
|
|
@ -80,6 +84,12 @@ func (n *Vault) Gather(acc telegraf.Accumulator) error {
|
||||||
return buildVaultMetrics(acc, sysMetrics)
|
return buildVaultMetrics(acc, sysMetrics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Vault) Stop() {
|
||||||
|
if n.client != nil {
|
||||||
|
n.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Vault) loadJSON(url string) (*SysMetrics, error) {
|
func (n *Vault) loadJSON(url string) (*SysMetrics, error) {
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"math"
|
"math"
|
||||||
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -30,6 +31,7 @@ type CloudWatch struct {
|
||||||
Log telegraf.Logger `toml:"-"`
|
Log telegraf.Logger `toml:"-"`
|
||||||
internalaws.CredentialConfig
|
internalaws.CredentialConfig
|
||||||
httpconfig.HTTPClientConfig
|
httpconfig.HTTPClientConfig
|
||||||
|
client *http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
type statisticType int
|
type statisticType int
|
||||||
|
|
@ -170,14 +172,20 @@ func (c *CloudWatch) Connect() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.client = client
|
||||||
|
|
||||||
c.svc = cloudwatch.NewFromConfig(cfg, func(options *cloudwatch.Options) {
|
c.svc = cloudwatch.NewFromConfig(cfg, func(options *cloudwatch.Options) {
|
||||||
options.HTTPClient = client
|
options.HTTPClient = c.client
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CloudWatch) Close() error {
|
func (c *CloudWatch) Close() error {
|
||||||
|
if c.client != nil {
|
||||||
|
c.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,10 @@ func (h *HTTP) Connect() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HTTP) Close() error {
|
func (h *HTTP) Close() error {
|
||||||
|
if h.client != nil {
|
||||||
|
h.client.CloseIdleConnections()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/blues/jsonata-go"
|
"github.com/blues/jsonata-go"
|
||||||
|
|
||||||
|
|
@ -23,6 +24,8 @@ import (
|
||||||
//go:embed sample.conf
|
//go:embed sample.conf
|
||||||
var sampleConfig string
|
var sampleConfig string
|
||||||
|
|
||||||
|
const defaultIdleConnTimeoutMinutes = 5
|
||||||
|
|
||||||
type HTTP struct {
|
type HTTP struct {
|
||||||
URL string `toml:"url"`
|
URL string `toml:"url"`
|
||||||
Headers map[string]string `toml:"headers"`
|
Headers map[string]string `toml:"headers"`
|
||||||
|
|
@ -47,6 +50,12 @@ func (h *HTTP) SampleConfig() string {
|
||||||
|
|
||||||
func (h *HTTP) Init() error {
|
func (h *HTTP) Init() error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// Prevent idle connections from hanging around forever on telegraf reload
|
||||||
|
if h.HTTPClientConfig.IdleConnTimeout == 0 {
|
||||||
|
h.HTTPClientConfig.IdleConnTimeout = config.Duration(defaultIdleConnTimeoutMinutes * time.Minute)
|
||||||
|
}
|
||||||
|
|
||||||
client, err := h.HTTPClientConfig.CreateClient(ctx, h.Log)
|
client, err := h.HTTPClientConfig.CreateClient(ctx, h.Log)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue