2015-07-07 09:20:11 +08:00
|
|
|
package mongodb
|
|
|
|
|
|
|
|
|
|
import (
|
2021-07-23 04:50:23 +08:00
|
|
|
"context"
|
2015-07-10 04:06:18 +08:00
|
|
|
"crypto/tls"
|
|
|
|
|
"crypto/x509"
|
2015-07-07 09:20:11 +08:00
|
|
|
"fmt"
|
|
|
|
|
"net/url"
|
2017-06-09 07:52:01 +08:00
|
|
|
"strings"
|
2015-07-07 09:20:11 +08:00
|
|
|
"sync"
|
|
|
|
|
"time"
|
|
|
|
|
|
2016-01-28 05:21:36 +08:00
|
|
|
"github.com/influxdata/telegraf"
|
2020-06-26 02:44:22 +08:00
|
|
|
tlsint "github.com/influxdata/telegraf/plugins/common/tls"
|
2016-01-21 02:57:35 +08:00
|
|
|
"github.com/influxdata/telegraf/plugins/inputs"
|
2021-07-23 04:50:23 +08:00
|
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
|
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
|
|
|
"go.mongodb.org/mongo-driver/mongo/readpref"
|
2015-07-07 09:20:11 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type MongoDB struct {
|
2020-05-22 15:11:00 +08:00
|
|
|
Servers []string
|
|
|
|
|
Ssl Ssl
|
|
|
|
|
GatherClusterStatus bool
|
|
|
|
|
GatherPerdbStats bool
|
|
|
|
|
GatherColStats bool
|
2021-03-17 04:54:57 +08:00
|
|
|
GatherTopStat bool
|
2020-05-22 15:11:00 +08:00
|
|
|
ColStatsDbs []string
|
2018-05-05 07:33:23 +08:00
|
|
|
tlsint.ClientConfig
|
2019-09-24 06:39:50 +08:00
|
|
|
|
2021-07-23 04:50:23 +08:00
|
|
|
Log telegraf.Logger `toml:"-"`
|
|
|
|
|
|
|
|
|
|
clients []*Server
|
2015-07-07 09:20:11 +08:00
|
|
|
}
|
|
|
|
|
|
2015-07-10 04:06:18 +08:00
|
|
|
type Ssl struct {
|
2022-03-02 06:05:53 +08:00
|
|
|
Enabled bool `toml:"ssl_enabled" deprecated:"1.3.0;use 'tls_*' options instead"`
|
|
|
|
|
CaCerts []string `toml:"cacerts" deprecated:"1.3.0;use 'tls_ca' instead"`
|
2015-07-10 04:06:18 +08:00
|
|
|
}
|
|
|
|
|
|
2021-07-23 04:50:23 +08:00
|
|
|
func (m *MongoDB) Init() error {
|
|
|
|
|
var tlsConfig *tls.Config
|
|
|
|
|
if m.Ssl.Enabled {
|
|
|
|
|
// Deprecated TLS config
|
|
|
|
|
tlsConfig = &tls.Config{
|
|
|
|
|
InsecureSkipVerify: m.ClientConfig.InsecureSkipVerify,
|
|
|
|
|
}
|
|
|
|
|
if len(m.Ssl.CaCerts) == 0 {
|
|
|
|
|
return fmt.Errorf("you must explicitly set insecure_skip_verify to skip cerificate validation")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
roots := x509.NewCertPool()
|
|
|
|
|
for _, caCert := range m.Ssl.CaCerts {
|
|
|
|
|
if ok := roots.AppendCertsFromPEM([]byte(caCert)); !ok {
|
|
|
|
|
return fmt.Errorf("failed to parse root certificate")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tlsConfig.RootCAs = roots
|
|
|
|
|
} else {
|
|
|
|
|
var err error
|
|
|
|
|
tlsConfig, err = m.ClientConfig.TLSConfig()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-07 09:20:11 +08:00
|
|
|
|
|
|
|
|
if len(m.Servers) == 0 {
|
2021-07-23 04:50:23 +08:00
|
|
|
m.Servers = []string{"mongodb://127.0.0.1:27017"}
|
2015-07-07 09:20:11 +08:00
|
|
|
}
|
|
|
|
|
|
2021-07-23 04:50:23 +08:00
|
|
|
for _, connURL := range m.Servers {
|
|
|
|
|
if !strings.HasPrefix(connURL, "mongodb://") && !strings.HasPrefix(connURL, "mongodb+srv://") {
|
2017-06-09 07:52:01 +08:00
|
|
|
// Preserve backwards compatibility for hostnames without a
|
|
|
|
|
// scheme, broken in go 1.8. Remove in Telegraf 2.0
|
2021-07-23 04:50:23 +08:00
|
|
|
connURL = "mongodb://" + connURL
|
|
|
|
|
m.Log.Warnf("Using %q as connection URL; please update your configuration to use an URL", connURL)
|
2017-06-09 07:52:01 +08:00
|
|
|
}
|
|
|
|
|
|
2021-07-23 04:50:23 +08:00
|
|
|
u, err := url.Parse(connURL)
|
2015-07-07 09:20:11 +08:00
|
|
|
if err != nil {
|
2021-07-23 04:50:23 +08:00
|
|
|
return fmt.Errorf("unable to parse connection URL: %q", err)
|
2017-06-09 07:52:01 +08:00
|
|
|
}
|
|
|
|
|
|
2021-07-23 04:50:23 +08:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
|
|
|
defer cancel() //nolint:revive
|
2015-07-07 09:20:11 +08:00
|
|
|
|
2021-07-23 04:50:23 +08:00
|
|
|
opts := options.Client().ApplyURI(connURL)
|
|
|
|
|
if tlsConfig != nil {
|
|
|
|
|
opts.TLSConfig = tlsConfig
|
2015-07-07 09:20:11 +08:00
|
|
|
}
|
2021-07-23 04:50:23 +08:00
|
|
|
if opts.ReadPreference == nil {
|
|
|
|
|
opts.ReadPreference = readpref.Nearest()
|
2015-07-07 09:20:11 +08:00
|
|
|
}
|
2021-07-23 04:50:23 +08:00
|
|
|
|
|
|
|
|
client, err := mongo.Connect(ctx, opts)
|
2015-07-07 09:20:11 +08:00
|
|
|
if err != nil {
|
2021-07-23 04:50:23 +08:00
|
|
|
return fmt.Errorf("unable to connect to MongoDB: %q", err)
|
2017-03-11 03:27:55 +08:00
|
|
|
}
|
|
|
|
|
|
2021-07-23 04:50:23 +08:00
|
|
|
err = client.Ping(ctx, opts.ReadPreference)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf("unable to connect to MongoDB: %s", err)
|
2015-07-10 04:06:18 +08:00
|
|
|
}
|
|
|
|
|
|
2021-07-23 04:50:23 +08:00
|
|
|
server := &Server{
|
|
|
|
|
client: client,
|
|
|
|
|
hostname: u.Host,
|
|
|
|
|
Log: m.Log,
|
2015-07-07 09:20:11 +08:00
|
|
|
}
|
2021-07-23 04:50:23 +08:00
|
|
|
m.clients = append(m.clients, server)
|
2015-07-07 09:20:11 +08:00
|
|
|
}
|
2021-07-23 04:50:23 +08:00
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reads stats from all configured servers accumulates stats.
|
|
|
|
|
// Returns one of the errors encountered while gather stats (if any).
|
|
|
|
|
func (m *MongoDB) Gather(acc telegraf.Accumulator) error {
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
for _, client := range m.clients {
|
|
|
|
|
wg.Add(1)
|
|
|
|
|
go func(srv *Server) {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
err := srv.gatherData(acc, m.GatherClusterStatus, m.GatherPerdbStats, m.GatherColStats, m.GatherTopStat, m.ColStatsDbs)
|
|
|
|
|
if err != nil {
|
|
|
|
|
m.Log.Errorf("failed to gather data: %q", err)
|
|
|
|
|
}
|
|
|
|
|
}(client)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
return nil
|
2015-07-07 09:20:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func init() {
|
2016-01-28 05:21:36 +08:00
|
|
|
inputs.Add("mongodb", func() telegraf.Input {
|
2015-07-07 09:20:11 +08:00
|
|
|
return &MongoDB{
|
2020-05-22 15:11:00 +08:00
|
|
|
GatherClusterStatus: true,
|
|
|
|
|
GatherPerdbStats: false,
|
|
|
|
|
GatherColStats: false,
|
2021-03-17 04:54:57 +08:00
|
|
|
GatherTopStat: false,
|
2020-05-22 15:11:00 +08:00
|
|
|
ColStatsDbs: []string{"local"},
|
2015-07-07 09:20:11 +08:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|