1
0
Fork 0
telegraf/plugins/inputs/mongodb/mongodb_data.go
Daniel Baumann 4978089aab
Adding upstream version 1.34.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-24 07:26:29 +02:00

478 lines
16 KiB
Go

package mongodb
import (
"fmt"
"reflect"
"strconv"
"github.com/influxdata/telegraf"
)
type mongoDBData struct {
StatLine *statLine
Fields map[string]interface{}
Tags map[string]string
DBData []bbData
ColData []colData
ShardHostData []bbData
TopStatsData []bbData
}
type bbData struct {
Name string
Fields map[string]interface{}
}
type colData struct {
Name string
DBName string
Fields map[string]interface{}
}
func newMongodbData(statLine *statLine, tags map[string]string) *mongoDBData {
return &mongoDBData{
StatLine: statLine,
Tags: tags,
Fields: make(map[string]interface{}),
}
}
var defaultStats = map[string]string{
"uptime_ns": "UptimeNanos",
"inserts": "InsertCnt",
"inserts_per_sec": "Insert",
"queries": "QueryCnt",
"queries_per_sec": "Query",
"updates": "UpdateCnt",
"updates_per_sec": "Update",
"deletes": "DeleteCnt",
"deletes_per_sec": "Delete",
"getmores": "GetMoreCnt",
"getmores_per_sec": "GetMore",
"commands": "CommandCnt",
"commands_per_sec": "Command",
"flushes": "FlushesCnt",
"flushes_per_sec": "Flushes",
"flushes_total_time_ns": "FlushesTotalTime",
"vsize_megabytes": "Virtual",
"resident_megabytes": "Resident",
"queued_reads": "QueuedReaders",
"queued_writes": "QueuedWriters",
"active_reads": "ActiveReaders",
"active_writes": "ActiveWriters",
"available_reads": "AvailableReaders",
"available_writes": "AvailableWriters",
"total_tickets_reads": "TotalTicketsReaders",
"total_tickets_writes": "TotalTicketsWriters",
"net_in_bytes_count": "NetInCnt",
"net_in_bytes": "NetIn",
"net_out_bytes_count": "NetOutCnt",
"net_out_bytes": "NetOut",
"open_connections": "NumConnections",
"ttl_deletes": "DeletedDocumentsCnt",
"ttl_deletes_per_sec": "DeletedDocuments",
"ttl_passes": "PassesCnt",
"ttl_passes_per_sec": "Passes",
"cursor_timed_out": "TimedOutC",
"cursor_timed_out_count": "TimedOutCCnt",
"cursor_no_timeout": "NoTimeoutC",
"cursor_no_timeout_count": "NoTimeoutCCnt",
"cursor_pinned": "PinnedC",
"cursor_pinned_count": "PinnedCCnt",
"cursor_total": "TotalC",
"cursor_total_count": "TotalCCnt",
"document_deleted": "DeletedD",
"document_inserted": "InsertedD",
"document_returned": "ReturnedD",
"document_updated": "UpdatedD",
"connections_current": "CurrentC",
"connections_available": "AvailableC",
"connections_total_created": "TotalCreatedC",
"operation_scan_and_order": "ScanAndOrderOp",
"operation_write_conflicts": "WriteConflictsOp",
"total_keys_scanned": "TotalKeysScanned",
"total_docs_scanned": "TotalObjectsScanned",
}
var defaultAssertsStats = map[string]string{
"assert_regular": "Regular",
"assert_warning": "Warning",
"assert_msg": "Msg",
"assert_user": "User",
"assert_rollovers": "Rollovers",
}
var defaultCommandsStats = map[string]string{
"aggregate_command_total": "AggregateCommandTotal",
"aggregate_command_failed": "AggregateCommandFailed",
"count_command_total": "CountCommandTotal",
"count_command_failed": "CountCommandFailed",
"delete_command_total": "DeleteCommandTotal",
"delete_command_failed": "DeleteCommandFailed",
"distinct_command_total": "DistinctCommandTotal",
"distinct_command_failed": "DistinctCommandFailed",
"find_command_total": "FindCommandTotal",
"find_command_failed": "FindCommandFailed",
"find_and_modify_command_total": "FindAndModifyCommandTotal",
"find_and_modify_command_failed": "FindAndModifyCommandFailed",
"get_more_command_total": "GetMoreCommandTotal",
"get_more_command_failed": "GetMoreCommandFailed",
"insert_command_total": "InsertCommandTotal",
"insert_command_failed": "InsertCommandFailed",
"update_command_total": "UpdateCommandTotal",
"update_command_failed": "UpdateCommandFailed",
}
var defaultLatencyStats = map[string]string{
"latency_writes_count": "WriteOpsCnt",
"latency_writes": "WriteLatency",
"latency_reads_count": "ReadOpsCnt",
"latency_reads": "ReadLatency",
"latency_commands_count": "CommandOpsCnt",
"latency_commands": "CommandLatency",
}
var defaultReplStats = map[string]string{
"repl_inserts": "InsertRCnt",
"repl_inserts_per_sec": "InsertR",
"repl_queries": "QueryRCnt",
"repl_queries_per_sec": "QueryR",
"repl_updates": "UpdateRCnt",
"repl_updates_per_sec": "UpdateR",
"repl_deletes": "DeleteRCnt",
"repl_deletes_per_sec": "DeleteR",
"repl_getmores": "GetMoreRCnt",
"repl_getmores_per_sec": "GetMoreR",
"repl_commands": "CommandRCnt",
"repl_commands_per_sec": "CommandR",
"member_status": "NodeType",
"state": "NodeState",
"repl_state": "NodeStateInt",
"repl_member_health": "NodeHealthInt",
"repl_health_avg": "ReplHealthAvg",
"repl_lag": "ReplLag",
"repl_network_bytes": "ReplNetworkBytes",
"repl_network_getmores_num": "ReplNetworkGetmoresNum",
"repl_network_getmores_total_millis": "ReplNetworkGetmoresTotalMillis",
"repl_network_ops": "ReplNetworkOps",
"repl_buffer_count": "ReplBufferCount",
"repl_buffer_size_bytes": "ReplBufferSizeBytes",
"repl_apply_batches_num": "ReplApplyBatchesNum",
"repl_apply_batches_total_millis": "ReplApplyBatchesTotalMillis",
"repl_apply_ops": "ReplApplyOps",
"repl_executor_pool_in_progress_count": "ReplExecutorPoolInProgressCount",
"repl_executor_queues_network_in_progress": "ReplExecutorQueuesNetworkInProgress",
"repl_executor_queues_sleepers": "ReplExecutorQueuesSleepers",
"repl_executor_unsignaled_events": "ReplExecutorUnsignaledEvents",
}
var defaultClusterStats = map[string]string{
"jumbo_chunks": "JumboChunksCount",
}
var defaultShardStats = map[string]string{
"total_in_use": "TotalInUse",
"total_available": "TotalAvailable",
"total_created": "TotalCreated",
"total_refreshing": "TotalRefreshing",
}
var shardHostStats = map[string]string{
"in_use": "InUse",
"available": "Available",
"created": "Created",
"refreshing": "Refreshing",
}
var mmapStats = map[string]string{
"mapped_megabytes": "Mapped",
"non-mapped_megabytes": "NonMapped",
"page_faults": "FaultsCnt",
"page_faults_per_sec": "Faults",
}
var wiredTigerStats = map[string]string{
"percent_cache_dirty": "CacheDirtyPercent",
"percent_cache_used": "CacheUsedPercent",
}
var wiredTigerExtStats = map[string]string{
"wtcache_tracked_dirty_bytes": "TrackedDirtyBytes",
"wtcache_current_bytes": "CurrentCachedBytes",
"wtcache_max_bytes_configured": "MaxBytesConfigured",
"wtcache_app_threads_page_read_count": "AppThreadsPageReadCount",
"wtcache_app_threads_page_read_time": "AppThreadsPageReadTime",
"wtcache_app_threads_page_write_count": "AppThreadsPageWriteCount",
"wtcache_bytes_written_from": "BytesWrittenFrom",
"wtcache_bytes_read_into": "BytesReadInto",
"wtcache_pages_evicted_by_app_thread": "PagesEvictedByAppThread",
"wtcache_pages_queued_for_eviction": "PagesQueuedForEviction",
"wtcache_pages_read_into": "PagesReadIntoCache",
"wtcache_pages_written_from": "PagesWrittenFromCache",
"wtcache_pages_requested_from": "PagesRequestedFromCache",
"wtcache_server_evicting_pages": "ServerEvictingPages",
"wtcache_worker_thread_evictingpages": "WorkerThreadEvictingPages",
"wtcache_internal_pages_evicted": "InternalPagesEvicted",
"wtcache_modified_pages_evicted": "ModifiedPagesEvicted",
"wtcache_unmodified_pages_evicted": "UnmodifiedPagesEvicted",
}
var wiredTigerConnectionStats = map[string]string{
"wt_connection_files_currently_open": "FilesCurrentlyOpen",
}
var wiredTigerDataHandleStats = map[string]string{
"wt_data_handles_currently_active": "DataHandlesCurrentlyActive",
}
var defaultTCMallocStats = map[string]string{
"tcmalloc_current_allocated_bytes": "TCMallocCurrentAllocatedBytes",
"tcmalloc_heap_size": "TCMallocHeapSize",
"tcmalloc_central_cache_free_bytes": "TCMallocCentralCacheFreeBytes",
"tcmalloc_current_total_thread_cache_bytes": "TCMallocCurrentTotalThreadCacheBytes",
"tcmalloc_max_total_thread_cache_bytes": "TCMallocMaxTotalThreadCacheBytes",
"tcmalloc_total_free_bytes": "TCMallocTotalFreeBytes",
"tcmalloc_transfer_cache_free_bytes": "TCMallocTransferCacheFreeBytes",
"tcmalloc_thread_cache_free_bytes": "TCMallocThreadCacheFreeBytes",
"tcmalloc_spinlock_total_delay_ns": "TCMallocSpinLockTotalDelayNanos",
"tcmalloc_pageheap_free_bytes": "TCMallocPageheapFreeBytes",
"tcmalloc_pageheap_unmapped_bytes": "TCMallocPageheapUnmappedBytes",
"tcmalloc_pageheap_committed_bytes": "TCMallocPageheapComittedBytes",
"tcmalloc_pageheap_scavenge_count": "TCMallocPageheapScavengeCount",
"tcmalloc_pageheap_commit_count": "TCMallocPageheapCommitCount",
"tcmalloc_pageheap_total_commit_bytes": "TCMallocPageheapTotalCommitBytes",
"tcmalloc_pageheap_decommit_count": "TCMallocPageheapDecommitCount",
"tcmalloc_pageheap_total_decommit_bytes": "TCMallocPageheapTotalDecommitBytes",
"tcmalloc_pageheap_reserve_count": "TCMallocPageheapReserveCount",
"tcmalloc_pageheap_total_reserve_bytes": "TCMallocPageheapTotalReserveBytes",
}
var defaultStorageStats = map[string]string{
"storage_freelist_search_bucket_exhausted": "StorageFreelistSearchBucketExhausted",
"storage_freelist_search_requests": "StorageFreelistSearchRequests",
"storage_freelist_search_scanned": "StorageFreelistSearchScanned",
}
var dbDataStats = map[string]string{
"collections": "Collections",
"objects": "Objects",
"avg_obj_size": "AvgObjSize",
"data_size": "DataSize",
"storage_size": "StorageSize",
"num_extents": "NumExtents",
"indexes": "Indexes",
"index_size": "IndexSize",
"ok": "Ok",
"fs_used_size": "FsUsedSize",
"fs_total_size": "FsTotalSize",
}
var colDataStats = map[string]string{
"count": "Count",
"size": "Size",
"avg_obj_size": "AvgObjSize",
"storage_size": "StorageSize",
"total_index_size": "TotalIndexSize",
"ok": "Ok",
}
var topDataStats = map[string]string{
"total_time": "TotalTime",
"total_count": "TotalCount",
"read_lock_time": "ReadLockTime",
"read_lock_count": "ReadLockCount",
"write_lock_time": "WriteLockTime",
"write_lock_count": "WriteLockCount",
"queries_time": "QueriesTime",
"queries_count": "QueriesCount",
"get_more_time": "GetMoreTime",
"get_more_count": "GetMoreCount",
"insert_time": "InsertTime",
"insert_count": "InsertCount",
"update_time": "UpdateTime",
"update_count": "UpdateCount",
"remove_time": "RemoveTime",
"remove_count": "RemoveCount",
"commands_time": "CommandsTime",
"commands_count": "CommandsCount",
}
func (d *mongoDBData) addDBStats() {
for i := range d.StatLine.DBStatsLines {
dbStat := d.StatLine.DBStatsLines[i]
dbStatLine := reflect.ValueOf(&dbStat).Elem()
newDBData := &bbData{
Name: dbStat.Name,
Fields: make(map[string]interface{}),
}
newDBData.Fields["type"] = "db_stat"
for key, value := range dbDataStats {
val := dbStatLine.FieldByName(value).Interface()
newDBData.Fields[key] = val
}
d.DBData = append(d.DBData, *newDBData)
}
}
func (d *mongoDBData) addColStats() {
for i := range d.StatLine.ColStatsLines {
colstat := d.StatLine.ColStatsLines[i]
colStatLine := reflect.ValueOf(&colstat).Elem()
newColData := &colData{
Name: colstat.Name,
DBName: colstat.DBName,
Fields: make(map[string]interface{}),
}
newColData.Fields["type"] = "col_stat"
for key, value := range colDataStats {
val := colStatLine.FieldByName(value).Interface()
newColData.Fields[key] = val
}
d.ColData = append(d.ColData, *newColData)
}
}
func (d *mongoDBData) addShardHostStats() {
for host := range d.StatLine.ShardHostStatsLines {
hostStat := d.StatLine.ShardHostStatsLines[host]
hostStatLine := reflect.ValueOf(&hostStat).Elem()
newDBData := &bbData{
Name: host,
Fields: make(map[string]interface{}),
}
newDBData.Fields["type"] = "shard_host_stat"
for k, v := range shardHostStats {
val := hostStatLine.FieldByName(v).Interface()
newDBData.Fields[k] = val
}
d.ShardHostData = append(d.ShardHostData, *newDBData)
}
}
func (d *mongoDBData) addTopStats() {
for i := range d.StatLine.TopStatLines {
topStat := d.StatLine.TopStatLines[i]
topStatLine := reflect.ValueOf(&topStat).Elem()
newTopStatData := &bbData{
Name: topStat.CollectionName,
Fields: make(map[string]interface{}),
}
newTopStatData.Fields["type"] = "top_stat"
for key, value := range topDataStats {
val := topStatLine.FieldByName(value).Interface()
newTopStatData.Fields[key] = val
}
d.TopStatsData = append(d.TopStatsData, *newTopStatData)
}
}
func (d *mongoDBData) addDefaultStats() {
statLine := reflect.ValueOf(d.StatLine).Elem()
d.addStat(statLine, defaultStats)
if d.StatLine.NodeType != "" {
d.addStat(statLine, defaultReplStats)
d.Tags["node_type"] = d.StatLine.NodeType
}
if d.StatLine.ReadLatency > 0 {
d.addStat(statLine, defaultLatencyStats)
}
if d.StatLine.ReplSetName != "" {
d.Tags["rs_name"] = d.StatLine.ReplSetName
}
if d.StatLine.OplogStats != nil {
d.add("repl_oplog_window_sec", d.StatLine.OplogStats.TimeDiff)
}
if d.StatLine.Version != "" {
d.add("version", d.StatLine.Version)
}
d.addStat(statLine, defaultAssertsStats)
d.addStat(statLine, defaultClusterStats)
d.addStat(statLine, defaultCommandsStats)
d.addStat(statLine, defaultShardStats)
d.addStat(statLine, defaultStorageStats)
d.addStat(statLine, defaultTCMallocStats)
if d.StatLine.StorageEngine == "mmapv1" || d.StatLine.StorageEngine == "rocksdb" {
d.addStat(statLine, mmapStats)
} else if d.StatLine.StorageEngine == "wiredTiger" {
for key, value := range wiredTigerStats {
val := statLine.FieldByName(value).Interface()
percentVal := fmt.Sprintf("%.1f", val.(float64)*100)
//nolint:errcheck // guaranteed to be formatted properly because of the above
floatVal, _ := strconv.ParseFloat(percentVal, 64)
d.add(key, floatVal)
}
d.addStat(statLine, wiredTigerExtStats)
d.addStat(statLine, wiredTigerConnectionStats)
d.addStat(statLine, wiredTigerDataHandleStats)
d.add("page_faults", d.StatLine.FaultsCnt)
}
}
func (d *mongoDBData) addStat(statLine reflect.Value, stats map[string]string) {
for key, value := range stats {
val := statLine.FieldByName(value).Interface()
d.add(key, val)
}
}
func (d *mongoDBData) add(key string, val interface{}) {
d.Fields[key] = val
}
func (d *mongoDBData) flush(acc telegraf.Accumulator) {
acc.AddFields(
"mongodb",
d.Fields,
d.Tags,
d.StatLine.Time,
)
d.Fields = make(map[string]interface{})
for _, db := range d.DBData {
d.Tags["db_name"] = db.Name
acc.AddFields(
"mongodb_db_stats",
db.Fields,
d.Tags,
d.StatLine.Time,
)
db.Fields = make(map[string]interface{})
}
for _, col := range d.ColData {
d.Tags["collection"] = col.Name
d.Tags["db_name"] = col.DBName
acc.AddFields(
"mongodb_col_stats",
col.Fields,
d.Tags,
d.StatLine.Time,
)
col.Fields = make(map[string]interface{})
}
for _, host := range d.ShardHostData {
d.Tags["hostname"] = host.Name
acc.AddFields(
"mongodb_shard_stats",
host.Fields,
d.Tags,
d.StatLine.Time,
)
host.Fields = make(map[string]interface{})
}
for _, col := range d.TopStatsData {
d.Tags["collection"] = col.Name
acc.AddFields(
"mongodb_top_stats",
col.Fields,
d.Tags,
d.StatLine.Time,
)
col.Fields = make(map[string]interface{})
}
}