Skip to content

Commit

Permalink
Merge pull request #744 from kongfei605/mongo_back
Browse files Browse the repository at this point in the history
mongodb back
  • Loading branch information
kongfei605 authored Dec 24, 2023
2 parents 518b41a + 1d6a5ab commit c252d63
Show file tree
Hide file tree
Showing 20 changed files with 3,626 additions and 151 deletions.
20 changes: 16 additions & 4 deletions conf/input.mongodb/mongodb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
log_level = "info"
# append some const labels to metrics
# NOTICE! the instance label is required for dashboards
labels = { cluster="mongo-cluster-01" }
labels = { instance="mongo-cluster-01" }

# mongodb dsn, see https://www.mongodb.com/docs/manual/reference/connection-string/
# mongodb_uri = "mongodb://admin:abcdef@127.0.0.1:27017/?connect=direct&authSource=admin&tlsinsecure=true"
# servers = ["mongodb://admin:1234@127.0.0.1:27017/?connect=direct&authSource=admin&tlsinsecure=true"]
# if you don't specify the username or password in the mongodb_uri, you can set here.
# mongodb_uri = "mongodb://127.0.0.1:27017"
mongodb_uri = ""
# if you don't specify the username or password in the mongodb_uri, you can set here.
# This will overwrite the dsn, it would be helpful when special characters existing in the username or password and you don't want to encode them.
# NOTICE! this user must be granted enough rights to query needed stats, see ../inputs/mongodb/README.md
username = "username@Bj"
Expand All @@ -26,11 +26,22 @@ collect_all = true
# enable_replicaset_status = true
# if set to true, collect top metrics by admin command
# enable_top_metrics = true
# if set to true, collect index metrics. You should specify one of the coll_stats_namespaces and the discovering_mode flags.
# enable_index_stats = true
# if set to true, collect collections metrics. You should specify one of the coll_stats_namespaces and the discovering_mode flags.
# enable_coll_stats = true

# Only get stats for the collections matching this list of namespaces. if none set, discovering_mode will be enabled.
# Example: db1.col1,db.col1
# coll_stats_namespaces = []
# Only get stats for index with the collections matching this list of namespaces.
# Example: db1.col1,db.col1
# index_stats_collections = []
# if set to true, replace -1 to DESC for label key_name of the descending_index metrics
# enable_override_descending_index = true

# which exposes metrics with 0.1x compatible metric names has been implemented which simplifies migration from the old version to the current version.
# compatible_mode = true


# [[instances]]
Expand All @@ -43,3 +54,4 @@ collect_all = true
# labels = { instance="mongo-cluster-02" }
# mongodb_uri = "mongodb://username:password@127.0.0.1:27017"
# collect_all = true
# compatible_mode = true
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ require (
github.com/prometheus/common v0.39.0
github.com/prometheus/prometheus v0.37.0
github.com/shirou/gopsutil/v3 v3.22.5
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.8.4
github.com/toolkits/pkg v1.3.7
github.com/ulricqin/gosnmp v0.0.1
Expand Down Expand Up @@ -106,17 +106,20 @@ require (
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/resourcetotelemetry v0.54.0 // indirect
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheusremotewrite v0.54.0 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tidwall/tinylru v1.1.0 // indirect
github.com/tidwall/wal v1.1.7 // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
golang.org/x/arch v0.3.0 // indirect
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
)

require (
cloud.google.com/go/monitoring v1.13.0
github.com/AlekSi/pointer v1.2.0
github.com/IBM/sarama v1.42.1
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible
github.com/alibabacloud-go/cms-20190101/v8 v8.0.0
Expand All @@ -137,6 +140,7 @@ require (
github.com/likexian/whois-parser v1.24.8
github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusremotewriteexporter v0.54.0
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.54.0
github.com/percona/percona-toolkit v0.0.0-20211210121818-b2860eee3152
github.com/prometheus-community/pro-bing v0.1.0
github.com/tidwall/gjson v1.14.4
github.com/vmware/govmomi v0.29.0
Expand Down
9 changes: 9 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6/go.mod h1:wN/zk
contrib.go.opencensus.io/exporter/prometheus v0.4.1 h1:oObVeKo2NxpdF/fIfrPsNj6K0Prg0R0mHM+uANlYMiM=
contrib.go.opencensus.io/exporter/prometheus v0.4.1/go.mod h1:t9wvfitlUjGXG2IXAZsuFq26mDGid/JwCEXp+gTG/9U=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w=
github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0=
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw=
github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
Expand Down Expand Up @@ -92,6 +94,7 @@ github.com/IBM/sarama v1.42.1 h1:wugyWa15TDEHh2kvq2gAy1IHLjEjuYOYgXz/ruC/OSQ=
github.com/IBM/sarama v1.42.1/go.mod h1:Xxho9HkHd4K/MDUo/T/sOqwtX/17D33++E9Wib6hUdQ=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
Expand Down Expand Up @@ -1127,6 +1130,8 @@ github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhEC
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
github.com/percona/percona-toolkit v0.0.0-20211210121818-b2860eee3152 h1:3AOGevjw3JfLPqzos6VnF2L9T0UosjHu4IO8+Ogk08w=
github.com/percona/percona-toolkit v0.0.0-20211210121818-b2860eee3152/go.mod h1:CCa6vyT51VeEG5KcJ2smk4/HyxX6Aunt8RxfnwlC85A=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pierrec/cmdflag v0.0.2/go.mod h1:a3zKGZ3cdQUfxjd0RGMLZr8xI3nvpJOB+m6o/1X5BmU=
Expand Down Expand Up @@ -1224,6 +1229,8 @@ github.com/schollz/progressbar/v2 v2.13.2/go.mod h1:6YZjqdthH6SCZKv2rqGryrxPtfmR
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v3 v3.22.5 h1:atX36I/IXgFiB81687vSiBI5zrMsxcIBkP9cQMJQoJA=
github.com/shirou/gopsutil/v3 v3.22.5/go.mod h1:so9G9VzeHt/hsd0YwqprnjHnfARAUktauykSbr+y2gA=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
Expand Down Expand Up @@ -1985,6 +1992,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
Expand Down
2 changes: 1 addition & 1 deletion inputs/mongodb/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# mongodb

mongodb 监控采集插件,v0.3.30开始从telegraf/mongodb fork而来,支持mongodb 3.6+版本
mongodb 监控采集插件,由mongodb-exporter(https://github.com/percona/mongodb_exporter) 封装而来。v0.3.30-v0.3.42从telegraf/mongodb fork

## Configuration

Expand Down
83 changes: 83 additions & 0 deletions inputs/mongodb/exporter/base_collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// mongodb_exporter
// Copyright (C) 2022 Percona LLC
//
// 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.

package exporter

import (
"context"
"sync"

"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/mongo"
)

type baseCollector struct {
client *mongo.Client
logger *logrus.Logger

lock sync.Mutex
metricsCache []prometheus.Metric
}

// newBaseCollector creates a skeletal collector, which is used to create other collectors.
func newBaseCollector(client *mongo.Client, logger *logrus.Logger) *baseCollector {
return &baseCollector{
client: client,
logger: logger,
}
}

func (d *baseCollector) Describe(ctx context.Context, ch chan<- *prometheus.Desc, collect func(mCh chan<- prometheus.Metric)) {
select {
case <-ctx.Done():
return
default:
}

d.lock.Lock()
defer d.lock.Unlock()

d.metricsCache = make([]prometheus.Metric, 0, defaultCacheSize)

// This is a copy/paste of prometheus.DescribeByCollect(d, ch) with the aggreated functionality
// to populate the metrics cache. Since on each scrape Prometheus will call Describe and inmediatelly
// after it will call Collect, it is safe to populate the cache here.
metrics := make(chan prometheus.Metric)
go func() {
collect(metrics)
close(metrics)
}()

for m := range metrics {
d.metricsCache = append(d.metricsCache, m) // populate the cache
ch <- m.Desc()
}
}

func (d *baseCollector) Collect(ch chan<- prometheus.Metric, collect func(mCh chan<- prometheus.Metric)) {
d.lock.Lock()
defer d.lock.Unlock()

if len(d.metricsCache) > 0 {
for _, metric := range d.metricsCache {
ch <- metric
}

return
}

collect(ch)
}
147 changes: 147 additions & 0 deletions inputs/mongodb/exporter/collstats_collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// mongodb_exporter
// Copyright (C) 2017 Percona LLC
//
// 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.

package exporter

import (
"context"
"strings"

"github.com/prometheus/client_golang/prometheus"
"github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)

type collstatsCollector struct {
ctx context.Context
base *baseCollector

compatibleMode bool
discoveringMode bool
topologyInfo labelsGetter

collections []string
}

// newCollectionStatsCollector creates a collector for statistics about collections.
func newCollectionStatsCollector(ctx context.Context, client *mongo.Client, logger *logrus.Logger, compatible, discovery bool, topology labelsGetter, collections []string) *collstatsCollector {
return &collstatsCollector{
ctx: ctx,
base: newBaseCollector(client, logger),

compatibleMode: compatible,
discoveringMode: discovery,
topologyInfo: topology,

collections: collections,
}
}

func (d *collstatsCollector) Describe(ch chan<- *prometheus.Desc) {
d.base.Describe(d.ctx, ch, d.collect)
}

func (d *collstatsCollector) Collect(ch chan<- prometheus.Metric) {
d.base.Collect(ch, d.collect)
}

func (d *collstatsCollector) collect(ch chan<- prometheus.Metric) {

collections := d.collections

client := d.base.client
logger := d.base.logger

if d.discoveringMode {
namespaces, err := listAllCollections(d.ctx, client, d.collections, systemDBs)
if err != nil {
logger.Errorf("cannot auto discover databases and collections: %s", err.Error())

return
}

collections = fromMapToSlice(namespaces)
}

for _, dbCollection := range collections {
parts := strings.Split(dbCollection, ".")
if len(parts) < 2 { //nolint:gomnd
continue
}

database := parts[0]
collection := strings.Join(parts[1:], ".") // support collections having a .

aggregation := bson.D{
{
Key: "$collStats", Value: bson.M{
// TODO: PMM-9568 : Add support to handle histogram metrics
"latencyStats": bson.M{"histograms": false},
"storageStats": bson.M{"scale": 1},
},
},
}
project := bson.D{
{
Key: "$project", Value: bson.M{
"storageStats.wiredTiger": 0,
"storageStats.indexDetails": 0,
},
},
}

cursor, err := client.Database(database).Collection(collection).Aggregate(d.ctx, mongo.Pipeline{aggregation, project})
if err != nil {
logger.Errorf("cannot get $collstats cursor for collection %s.%s: %s", database, collection, err)

continue
}

var stats []bson.M
if err = cursor.All(d.ctx, &stats); err != nil {
logger.Errorf("cannot get $collstats for collection %s.%s: %s", database, collection, err)

continue
}

logger.Debugf("$collStats metrics for %s.%s", database, collection)
debugResult(logger, stats)

prefix := "collstats"
labels := d.topologyInfo.baseLabels()
labels["database"] = database
labels["collection"] = collection

for _, metrics := range stats {
for _, metric := range makeMetrics(prefix, metrics, labels, d.compatibleMode) {
ch <- metric
}
}
}
}

func fromMapToSlice(databases map[string][]string) []string {
var collections []string
for db, cols := range databases {
for _, value := range cols {
collections = append(collections, db+"."+value)
}
}

return collections
}

var _ prometheus.Collector = (*collstatsCollector)(nil)
Loading

0 comments on commit c252d63

Please sign in to comment.