From f1c150e34a5c4b615fd9d622e5c83100821714ff Mon Sep 17 00:00:00 2001 From: TheBigHNF Date: Fri, 27 Feb 2015 00:53:47 -0600 Subject: [PATCH 1/5] Add LUA Version --- init.lua | 125 ++++++++++++++++++++++++++++++++++++ metrics.json | 149 +++++++++++++++++++++++++++++++++++++++++++ modules/boundary.lua | 12 ++++ plugin.json | 12 ++++ 4 files changed, 298 insertions(+) create mode 100644 init.lua create mode 100644 metrics.json create mode 100644 modules/boundary.lua diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..f188b36 --- /dev/null +++ b/init.lua @@ -0,0 +1,125 @@ +local boundary = require("boundary") +local os = require("os") +local timer = require("timer") +local http = require("http") +local json = require("json") +local fs = require("fs") + +-- set default parameters if not found in param.json +local param = boundary.param or { + source = os.hostname, + pollInterval = 5000, + hostname = "127.0.0.1", + port = "28017" +} + +-- lookup +-- use an array of attrs to drill down through nested tables to retrieve a value +function lookup(table, attrs) + local v = table; + for i, a in ipairs(attrs) do + v = v[a] + end + return v +end + +-- fnFactory returns a function(current, previous) that when called +-- will output the metric string ready for printing +-- name - name of metric +-- func - type of metric (diff, cur or ratio) +-- format - printf type format specifier for the result eg "%d" +-- params - parameters specific to build the required function +function fnFactory(name, func, format, params) + local mask = "MONGO_" .. name .. " " .. format .. " %s\n" + local str = function(v) return string.format(mask, v, param.source) end + + return ({ + -- diff calculates the difference between a current and previous values + diff = function (attrs, scale) + return function (c, p) + return str((scale or 1) * lookup(c, attrs) - lookup(p, attrs)) + end + end, + -- cur returns a current value + cur = function (attrs, scale) + return function (c) + return str((scale or 1) * lookup(c, attrs)) + end + end, + -- ratio takes values a and b from the current data and returns a/b + ratio = function (attrs1, attrs2, scale) + return function (c) + return str((scale or 1) * lookup(c, attrs1) / lookup(c, attrs2)) + end + end, + -- split takes values a and b from the current data and returns a/(a+b) + split = function (attrs1, attrs2, scale) + return function (c) + local a = lookup(c, attrs1) + return str((scale or 1) * a / (a + lookup(c, attrs2))) + end + end + })[func](unpack(params)) +end + +-- build a table of functions to convert metrics into strings +local conversions = {} +for i, v in ipairs({ + {"BTREE_ACCESSES", "diff", "%d", {{"indexCounters", "accesses"}}}, + {"BTREE_HITS", "diff", "%d", {{"indexCounters", "hits"}}}, + {"BTREE_MISSES", "diff", "%d", {{"indexCounters", "misses"}}}, + {"BTREE_RESETS", "diff", "%d", {{"indexCounters", "resets"}}}, + {"BTREE_MISS_RATIO", "diff", "%d", {{"indexCounters", "missRatio"}}}, + {"CONNECTIONS", "cur", "%d", {{"connections", "current"}}}, + {"CONNECTIONS_AVAILABLE", "cur", "%d", {{"connections", "available"}}}, + {"CONNECTION_LIMIT", "split", "%f", {{"connections", "current"}, {"connections", "available"}}}, + {"GLOBAL_LOCK", "ratio", "%f", {{"globalLock", "lockTime"}, {"globalLock", "totalTime"}}}, + {"MEM_RESIDENT", "cur", "%d", {{"mem", "resident"}, 1024*1024}}, + {"MEM_VIRTUAL", "cur", "%d", {{"mem", "virtual"}, 1024*1024}}, + {"MEM_MAPPED", "cur", "%d", {{"mem", "mapped"}, 1024*1024}}, + {"OPS_INSERTS", "diff", "%d", {{"opcounters", "insert"}}}, + {"OPS_QUERY", "diff", "%d", {{"opcounters", "query"}}}, + {"OPS_UPDATE", "diff", "%d", {{"opcounters", "update"}}}, + {"OPS_DELETE", "diff", "%d", {{"opcounters", "delete"}}}, + {"OPS_GETMORE", "diff", "%d", {{"opcounters", "getmore"}}}, + {"OPS_COMMAND", "diff", "%d", {{"opcounters", "command"}}} +}) do + table.insert(conversions, fnFactory(table.unpack(v))) +end + +print("_bevent:Boundary MongoDB plugin up : version 1.0|t:info|tags:lua,mongodb,plugin") + +local previous; + +-- poll the server every pollInterval and use the +-- conversion functions to extract relevent data +timer.setInterval(param.pollInterval, function () + local data = "" + local req = http.request({ + host = param.hostname, + port = param.port, + path = "/_status" + }, function (res) + res:on("end", function () + current = json.parse(data).serverStatus + if (previous) then + local t = {} + for i, f in ipairs(conversions) do + table.insert(t, f(current, previous)) + end + fs.writeSync(1, -1, table.concat(t)) + end + previous = current + res:destroy() + end) + res:on("data", function (chunk) data = data .. chunk end) + res:on("error", function (err) end) + end) + req:on("error", function(err) + msg = tostring(err) + print("Error while sending a request: " .. msg) + end) + + req:done() +end) + diff --git a/metrics.json b/metrics.json new file mode 100644 index 0000000..1d6d25f --- /dev/null +++ b/metrics.json @@ -0,0 +1,149 @@ +{ + "result": [ + { + "name": "MONGO_BTREE_ACCESSES", + "displayName": "MongoDB Index Accesses", + "description": "Number of times that database operations have accessed indexes.", + "unit": "number", + "displayNameShort": "MongoDB Accesses", + "defaultAggregate": "count" + }, + { + "name": "MONGO_BTREE_HITS", + "displayName": "MongoDB Index Accesses from Memory", + "description": "Number of index accesses from memory.", + "unit": "number", + "displayNameShort": "MongoDB Hits", + "defaultAggregate": "count" + }, + { + "name": "MONGO_BTREE_MISSES", + "displayName": "MongoDB Index Accesses from Store", + "description": "Number of index accesses requiring indexes to be loaded.", + "unit": "number", + "displayNameShort": "MongoDB Misses", + "defaultAggregate": "count" + }, + { + "name": "MONGO_BTREE_RESETS", + "displayName": "MongoDB Index Counter Resets", + "description": "Number of times that the index counters were reset.", + "unit": "number", + "displayNameShort": "MongoDB Resets", + "defaultAggregate": "count" + }, + { + "name": "MONGO_BTREE_MISS_RATIO", + "displayName": "MongoDB Ratio of Index Hits to Index Misses", + "description": "Ratio of hits to misses.", + "unit": "ratio", + "displayNameShort": "MongoDB Miss Ratio", + "defaultAggregate": "ratio" + }, + { + "name": "MONGO_CONNECTIONS", + "displayName": "MongoDB Client Connection Count", + "description": "Number of active client connections to the database.", + "unit": "number", + "displayNameShort": "MongoDB Connections", + "defaultAggregate": "count" + }, + { + "name": "MONGO_CONNECTIONS_AVAILABLE", + "displayName": "MongoDB Client Connection Available", + "description": "Number of unused client connections to the database.", + "unit": "number", + "displayNameShort": "MongoDB Connections Available", + "defaultAggregate": "count" + }, + { + "name": "MONGO_CONNECTION_LIMIT", + "displayName": "MongoDB Client Connection Limit", + "description": "Ratio of client connections to total available connections.", + "unit": "ratio", + "displayNameShort": "MongoDB Connection Limit", + "defaultAggregate": "ratio" + }, + { + "name": "MONGO_GLOBAL_LOCK", + "displayName": "MongoDB Global Lock Ratio", + "description": "Ratio of time locked to time running.", + "unit": "ratio", + "displayNameShort": "MongoDB Lock", + "defaultAggregate": "ratio" + }, + { + "name": "MONGO_MEM_RESIDENT", + "displayName": "MongoDB RAM Usage", + "description": "Number of bytes of RAM used.", + "unit": "number", + "displayNameShort": "MongoDB RAM", + "defaultAggregate": "number" + }, + { + "name": "MONGO_MEM_VIRTUAL", + "displayName": "MongoDB Virtual Memory Usage", + "description": "Number of bytes of virtual memory used.", + "unit": "number", + "displayNameShort": "MongoDB Vmem", + "defaultAggregate": "number" + }, + { + "name": "MONGO_MEM_MAPPED", + "displayName": "MongoDB Mapped Memory Usage", + "description": "Number of bytes of mapped memory used.", + "unit": "number", + "displayNameShort": "MongoDB Mmem", + "defaultAggregate": "number" + }, + { + "name": "MONGO_OPS_INSERTS", + "displayName": "MongoDB Insert Operation Count", + "description": "Count of insert operations.", + "unit": "number", + "displayNameShort": "MongoDB Insert", + "defaultAggregate": "number" + }, + { + "name": "MONGO_OPS_QUERY", + "displayName": "MongoDB Query Operation Count", + "description": "Count of query operations.", + "unit": "number", + "displayNameShort": "MongoDB Querie", + "defaultAggregate": "number" + }, + { + "name": "MONGO_OPS_UPDATE", + "displayName": "MongoDB Update Operation Count", + "description": "Count of update operations.", + "unit": "number", + "displayNameShort": "MongoDB Update", + "defaultAggregate": "number" + }, + { + "name": "MONGO_OPS_DELETE", + "displayName": "MongoDB Delete Operation Count", + "description": "Count of delete operations.", + "unit": "number", + "displayNameShort": "MongoDB Delete", + "defaultAggregate": "number" + }, + { + "name": "MONGO_OPS_GETMORE", + "displayName": "MongoDB GetMore Operation Count", + "description": "Count of getmore operations.", + "unit": "number", + "displayNameShort": "MongoDB GetMore", + "defaultAggregate": "number" + }, + { + "name": "MONGO_OPS_COMMAND", + "displayName": "MongoDB Command Operation Count", + "description": "Count of command operations.", + "unit": "number", + "displayNameShort": "MongoDB Command", + "defaultAggregate": "number" + } + ] +} + diff --git a/modules/boundary.lua b/modules/boundary.lua new file mode 100644 index 0000000..a2c28d3 --- /dev/null +++ b/modules/boundary.lua @@ -0,0 +1,12 @@ +-- Copyright 2015 Boundary +-- @brief convenience variables and functions for Lua scripts +-- @file boundary.lua +local fs = require('fs') +local json = require('json') +local boundary = {param = nil} +-- import param.json data into a Lua table (boundary.param) +local json_blob +if (pcall(function () json_blob = fs.readFileSync("param.json") end)) then +pcall(function () boundary.param = json.parse(json_blob) end) +end +return boundary diff --git a/plugin.json b/plugin.json index 8548e5a..31e6847 100644 --- a/plugin.json +++ b/plugin.json @@ -2,12 +2,16 @@ "description" : "Displays important mongodb metrics", "icon" : "icon.png", "command" : "node index.js", + "command_lua": "boundary-meter init.lua", "postExtract" : "npm install", + "postExtract_lua" : "", "ignore" : "node_modules", "metrics" : [ + "MONGO_BTREE_ACCESSES", "MONGO_BTREE_HITS", "MONGO_BTREE_MISSES", + "MONGO_BTREE_RESETS", "MONGO_BTREE_MISS_RATIO", "MONGO_CONNECTIONS", "MONGO_CONNECTIONS_AVAILABLE", @@ -58,6 +62,14 @@ "description" : "(optional) Pasword to access MongoDB", "type" : "password" }, + { + "title": "Poll Time (sec)", + "name": "pollInterval", + "description": "The Poll Interval to call the command. Defaults 5 seconds", + "type": "string", + "default": 5000, + "required": false + }, { "title" : "Source", "name" : "source", From 1e6a6731fd6b4ed47ae97c587fc9208ff893eaf9 Mon Sep 17 00:00:00 2001 From: TheBigHNF Date: Fri, 27 Feb 2015 00:58:49 -0600 Subject: [PATCH 2/5] Did not need to duplicate boundary.lua --- modules/boundary.lua | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 modules/boundary.lua diff --git a/modules/boundary.lua b/modules/boundary.lua deleted file mode 100644 index a2c28d3..0000000 --- a/modules/boundary.lua +++ /dev/null @@ -1,12 +0,0 @@ --- Copyright 2015 Boundary --- @brief convenience variables and functions for Lua scripts --- @file boundary.lua -local fs = require('fs') -local json = require('json') -local boundary = {param = nil} --- import param.json data into a Lua table (boundary.param) -local json_blob -if (pcall(function () json_blob = fs.readFileSync("param.json") end)) then -pcall(function () boundary.param = json.parse(json_blob) end) -end -return boundary From a06f824527ac93e1f738e59aa045d5fc59203ba1 Mon Sep 17 00:00:00 2001 From: TheBigHNF Date: Mon, 16 Mar 2015 14:59:10 -0500 Subject: [PATCH 3/5] Fixed error handling to go to stderr --- init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init.lua b/init.lua index f188b36..ae4a7e3 100644 --- a/init.lua +++ b/init.lua @@ -117,7 +117,7 @@ timer.setInterval(param.pollInterval, function () end) req:on("error", function(err) msg = tostring(err) - print("Error while sending a request: " .. msg) + process.stderr:write("Error while sending a request: " .. msg) end) req:done() From 515ec62bf81dd51fc1cf3b7a61ed912d698d8866 Mon Sep 17 00:00:00 2001 From: TheBigHNF Date: Thu, 19 Mar 2015 18:21:10 -0500 Subject: [PATCH 4/5] Used README Template --- README.md | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 696427f..3c26e37 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,29 @@ -Boundary MongoDB Plugin ------------------------ +# Boundary MongoDB Plugin + Collects metrics from a MongoDB server instance. MongoDB statistics are pulled via a REST API call. See video [walkthrough](https://help.boundary.com/hc/articles/201842211). -### Prerequisites +## Prerequisites + +### Supported OS | OS | Linux | Windows | SmartOS | OS X | |:----------|:-----:|:-------:|:-------:|:----:| | Supported | v | v | v | v | +##### The statistics are pulled from http://hostname:(port+1000)/_status. If you did not change the MongoDB default port, we will use 28107. + +#### Boundary Meter Versions V4.0 Or Greater + +To get the new meter: + + curl -fsS \ + -d "{\"token\":\"\"}" \ + -H "Content-Type: application/json" \ + "https://meter.boundary.com/setup_meter" > setup_meter.sh + chmod +x setup_meter.sh + ./setup_meter.sh + +#### For Boundary Meter less than V4.0 | Runtime | node.js | Python | Java | |:---------|:-------:|:------:|:----:| @@ -27,7 +43,9 @@ The statistics are pulled from http://hostname:(port+1000)/_status. If you did 3. If after enabling the Mongo REST interface, you are still unable to collect information from the REST interface and if you are polling remotely, ensure that the port that is serving the Mongo REST interfaces is open. You can bypasss any firewall restrictions by running locally where the MongoDB is running. -#### Plugin Configuration Fields +### Plugin Configuration Fields + +#### For All Versions |Field Name|Description | |:---------|:---------------------------------------------------------------------------------------------------------------------| @@ -39,7 +57,7 @@ The statistics are pulled from http://hostname:(port+1000)/_status. If you did ### Metrics Collected -Tracks the following metrics for [MongoDB](http://www.mongodb.org/) +#### For All Versions |Metric Name |Description | |:----------------------|:--------------------------------------------------------------------| @@ -59,3 +77,8 @@ Tracks the following metrics for [MongoDB](http://www.mongodb.org/) |Mongo deletes |The number of mongo delete operations | |Mongo getmore |The number of mongo getmore operations | |Mongo commands |The number of mongo commands issued | + +### References + +Tracks the following metrics for [MongoDB](http://www.mongodb.org/) + From 5cda04ad92df465d24195c136fb3ec8157d68070 Mon Sep 17 00:00:00 2001 From: TheBigHNF Date: Sun, 10 May 2015 22:08:51 -0500 Subject: [PATCH 5/5] Updated README --- README.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3c26e37..d4f87a5 100644 --- a/README.md +++ b/README.md @@ -12,16 +12,10 @@ Collects metrics from a MongoDB server instance. MongoDB statistics are pulled v ##### The statistics are pulled from http://hostname:(port+1000)/_status. If you did not change the MongoDB default port, we will use 28107. -#### Boundary Meter Versions V4.0 Or Greater +#### Boundary Meter Versions V4.0 Or Later -To get the new meter: - - curl -fsS \ - -d "{\"token\":\"\"}" \ - -H "Content-Type: application/json" \ - "https://meter.boundary.com/setup_meter" > setup_meter.sh - chmod +x setup_meter.sh - ./setup_meter.sh +- To install new meter go to Settings->Installation or [see instructons|https://help.boundary.com/hc/en-us/sections/200634331-Installation]. +- To upgrade the meter to the latest version - [see instructons|https://help.boundary.com/hc/en-us/articles/201573102-Upgrading-the-Boundary-Meter]. #### For Boundary Meter less than V4.0