From d56db64dc6a8ba2f50e9a70a03674914c875f67a Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Mon, 7 May 2018 18:00:24 -0400 Subject: [PATCH] Add cursor metrics to mongodb input (#4114) --- plugins/inputs/mongodb/README.md | 6 +++- plugins/inputs/mongodb/mongodb_data.go | 4 +++ plugins/inputs/mongodb/mongodb_data_test.go | 8 +++++ plugins/inputs/mongodb/mongostat.go | 36 ++++++++++++++++++--- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/plugins/inputs/mongodb/README.md b/plugins/inputs/mongodb/README.md index a78d7b954..96852d724 100644 --- a/plugins/inputs/mongodb/README.md +++ b/plugins/inputs/mongodb/README.md @@ -48,6 +48,10 @@ Error in input [mongodb]: not authorized on admin to execute command { serverSta - active_reads (integer) - active_writes (integer) - commands_per_sec (integer) + - cursor_timed_out (integer) + - cursor_no_timeout (integer) + - cursor_pinned (integer) + - cursor_total (integer) - deletes_per_sec (integer) - flushes_per_sec (integer) - getmores_per_sec (integer) @@ -120,7 +124,7 @@ Error in input [mongodb]: not authorized on admin to execute command { serverSta ### Example Output: ``` -mongodb,hostname=127.0.0.1:27017 active_reads=0i,active_writes=0i,commands_per_sec=6i,deletes_per_sec=0i,flushes_per_sec=0i,getmores_per_sec=1i,inserts_per_sec=0i,jumbo_chunks=0i,member_status="PRI",net_in_bytes=851i,net_out_bytes=23904i,open_connections=6i,percent_cache_dirty=0,percent_cache_used=0,queries_per_sec=2i,queued_reads=0i,queued_writes=0i,repl_commands_per_sec=0i,repl_deletes_per_sec=0i,repl_getmores_per_sec=0i,repl_inserts_per_sec=0i,repl_lag=0i,repl_queries_per_sec=0i,repl_updates_per_sec=0i,resident_megabytes=67i,state="PRIMARY",total_available=0i,total_created=0i,total_in_use=0i,total_refreshing=0i,ttl_deletes_per_sec=0i,ttl_passes_per_sec=0i,updates_per_sec=0i,vsize_megabytes=729i,wtcache_app_threads_page_read_count=4i,wtcache_app_threads_page_read_time=18i,wtcache_app_threads_page_write_count=6i,wtcache_bytes_read_into=10075i,wtcache_bytes_written_from=115711i,wtcache_current_bytes=86038i,wtcache_max_bytes_configured=1073741824i,wtcache_pages_evicted_by_app_thread=0i,wtcache_pages_queued_for_eviction=0i,wtcache_server_evicting_pages=0i,wtcache_tracked_dirty_bytes=0i,wtcache_worker_thread_evictingpages=0i 1522798796000000000 +mongodb,hostname=127.0.0.1:27017 active_reads=0i,active_writes=0i,commands_per_sec=6i,cursor_no_timeout=0i,cursor_pinned=0i,cursor_timed_out=0i,cursor_total=0i,deletes_per_sec=0i,flushes_per_sec=0i,getmores_per_sec=1i,inserts_per_sec=0i,jumbo_chunks=0i,member_status="PRI",net_in_bytes=851i,net_out_bytes=23904i,open_connections=6i,percent_cache_dirty=0,percent_cache_used=0,queries_per_sec=2i,queued_reads=0i,queued_writes=0i,repl_commands_per_sec=0i,repl_deletes_per_sec=0i,repl_getmores_per_sec=0i,repl_inserts_per_sec=0i,repl_lag=0i,repl_queries_per_sec=0i,repl_updates_per_sec=0i,resident_megabytes=67i,state="PRIMARY",total_available=0i,total_created=0i,total_in_use=0i,total_refreshing=0i,ttl_deletes_per_sec=0i,ttl_passes_per_sec=0i,updates_per_sec=0i,vsize_megabytes=729i,wtcache_app_threads_page_read_count=4i,wtcache_app_threads_page_read_time=18i,wtcache_app_threads_page_write_count=6i,wtcache_bytes_read_into=10075i,wtcache_bytes_written_from=115711i,wtcache_current_bytes=86038i,wtcache_max_bytes_configured=1073741824i,wtcache_pages_evicted_by_app_thread=0i,wtcache_pages_queued_for_eviction=0i,wtcache_server_evicting_pages=0i,wtcache_tracked_dirty_bytes=0i,wtcache_worker_thread_evictingpages=0i 1522798796000000000 mongodb_db_stats,db_name=local,hostname=127.0.0.1:27017 avg_obj_size=818.625,collections=5i,data_size=6549i,index_size=86016i,indexes=4i,num_extents=0i,objects=8i,ok=1i,storage_size=118784i,type="db_stat" 1522799074000000000 mongodb_shard_stats,hostname=127.0.0.1:27017,in_use=3i,available=3i,created=4i,refreshing=0i 1522799074000000000 ``` diff --git a/plugins/inputs/mongodb/mongodb_data.go b/plugins/inputs/mongodb/mongodb_data.go index 9b4aa7580..19c15bd37 100644 --- a/plugins/inputs/mongodb/mongodb_data.go +++ b/plugins/inputs/mongodb/mongodb_data.go @@ -49,6 +49,10 @@ var DefaultStats = map[string]string{ "open_connections": "NumConnections", "ttl_deletes_per_sec": "DeletedDocuments", "ttl_passes_per_sec": "Passes", + "cursor_timed_out": "TimedOutC", + "cursor_no_timeout": "NoTimeoutC", + "cursor_pinned": "PinnedC", + "cursor_total": "TotalC", } var DefaultReplStats = map[string]string{ diff --git a/plugins/inputs/mongodb/mongodb_data_test.go b/plugins/inputs/mongodb/mongodb_data_test.go index 21541dd95..56256e062 100644 --- a/plugins/inputs/mongodb/mongodb_data_test.go +++ b/plugins/inputs/mongodb/mongodb_data_test.go @@ -34,6 +34,10 @@ func TestAddNonReplStats(t *testing.T) { NumConnections: 0, Passes: 0, DeletedDocuments: 0, + TimedOutC: 0, + NoTimeoutC: 0, + PinnedC: 0, + TotalC: 0, }, tags, ) @@ -211,6 +215,10 @@ func TestStateTag(t *testing.T) { "total_available": int64(0), "total_created": int64(0), "total_refreshing": int64(0), + "cursor_timed_out": int64(0), + "cursor_no_timeout": int64(0), + "cursor_pinned": int64(0), + "cursor_total": int64(0), } acc.AssertContainsTaggedFields(t, "mongodb", fields, stateTags) } diff --git a/plugins/inputs/mongodb/mongostat.go b/plugins/inputs/mongodb/mongostat.go index 92f2bb2f9..bb4158053 100644 --- a/plugins/inputs/mongodb/mongostat.go +++ b/plugins/inputs/mongodb/mongostat.go @@ -289,7 +289,8 @@ type OpcountStats struct { // MetricsStats stores information related to metrics type MetricsStats struct { - TTL *TTLStats `bson:"ttl"` + TTL *TTLStats `bson:"ttl"` + Cursor *CursorStats `bson:"cursor"` } // TTLStats stores information related to documents with a ttl index. @@ -298,6 +299,19 @@ type TTLStats struct { Passes int64 `bson:"passes"` } +// CursorStats stores information related to cursor metrics. +type CursorStats struct { + TimedOut int64 `bson:"timedOut"` + Open *OpenCursorStats `bson:"open"` +} + +// OpenCursorStats stores information related to open cursor metrics +type OpenCursorStats struct { + NoTimeout int64 `bson:"noTimeout"` + Pinned int64 `bson:"pinned"` + Total int64 `bson:"total"` +} + // ReadWriteLockTimes stores time spent holding read/write locks. type ReadWriteLockTimes struct { Read int64 `bson:"R"` @@ -439,6 +453,10 @@ type StatLine struct { // TTL fields Passes, DeletedDocuments int64 + // Cursor fields + TimedOutC int64 + NoTimeoutC, PinnedC, TotalC int64 + // Collection locks (3.0 mmap only) CollectionLocks *CollectionLockStatus @@ -582,9 +600,19 @@ func NewStatLine(oldMongo, newMongo MongoStatus, key string, all bool, sampleSec returnVal.Command = diff(newStat.Opcounters.Command, oldStat.Opcounters.Command, sampleSecs) } - if newStat.Metrics != nil && newStat.Metrics.TTL != nil && oldStat.Metrics != nil && oldStat.Metrics.TTL != nil { - returnVal.Passes = diff(newStat.Metrics.TTL.Passes, oldStat.Metrics.TTL.Passes, sampleSecs) - returnVal.DeletedDocuments = diff(newStat.Metrics.TTL.DeletedDocuments, oldStat.Metrics.TTL.DeletedDocuments, sampleSecs) + if newStat.Metrics != nil && oldStat.Metrics != nil { + if newStat.Metrics.TTL != nil && oldStat.Metrics.TTL != nil { + returnVal.Passes = diff(newStat.Metrics.TTL.Passes, oldStat.Metrics.TTL.Passes, sampleSecs) + returnVal.DeletedDocuments = diff(newStat.Metrics.TTL.DeletedDocuments, oldStat.Metrics.TTL.DeletedDocuments, sampleSecs) + } + if newStat.Metrics.Cursor != nil && oldStat.Metrics.Cursor != nil { + returnVal.TimedOutC = diff(newStat.Metrics.Cursor.TimedOut, oldStat.Metrics.Cursor.TimedOut, sampleSecs) + if newStat.Metrics.Cursor.Open != nil && oldStat.Metrics.Cursor.Open != nil { + returnVal.NoTimeoutC = diff(newStat.Metrics.Cursor.Open.NoTimeout, oldStat.Metrics.Cursor.Open.NoTimeout, sampleSecs) + returnVal.PinnedC = diff(newStat.Metrics.Cursor.Open.Pinned, oldStat.Metrics.Cursor.Open.Pinned, sampleSecs) + returnVal.TotalC = diff(newStat.Metrics.Cursor.Open.Total, oldStat.Metrics.Cursor.Open.Total, sampleSecs) + } + } } if newStat.OpcountersRepl != nil && oldStat.OpcountersRepl != nil {