From cae5a6eb23190a7aa18267d23352df11fad9853c Mon Sep 17 00:00:00 2001 From: Mark Studer Date: Fri, 5 Aug 2016 09:20:50 -0600 Subject: [PATCH] Adding additional logging of failed nodes and device errors as well as support for specifying the API version in the plugin.json --- Properties/AssemblyInfo.cs | 4 ++-- README.md | 8 ++++++- VTMAgent.cs | 46 +++++++++++++++++++++++++++++++++----- VTMAgentFactory.cs | 5 ++++- 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 5fdcc99..656b74a 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.4.0")] -[assembly: AssemblyFileVersion("1.4.0")] +[assembly: AssemblyVersion("1.5.0")] +[assembly: AssemblyFileVersion("1.5.0")] diff --git a/README.md b/README.md index 3197836..638ba9c 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,17 @@ New Relic plugin for Brocade Virtual Traffic Manager # Requirements 1. .Net 4.5 2. Brocade Virtual Traffic Manager v9.9+ or Stingray SteelApp Traffic Manager 9.9+ -3. Traffic Manager API 3.3 +3. Traffic Manager API v3.8 by default and for full functionality or version 3.3+ if specified in plugin.json "api_version" # Known Issues There is a memory leak in VTM appliances before version 10.1 - SR32022. This will cause increased memory usage over time based on my own results about 10-20% per month. +# Stats +Device Statistics: CPU %, Memory %, network traffic transmitted / received, connections, device errors, failed nodes +Virtual Servers: Connections, network traffic transmitted / received +Pools: Failed Nodes, Drained nodes, Disabled Nodes, network traffic transmitted / received +Nodes: Requests, Connections, Errors, Failures + # Traffic Manager Configuration It is highly recommended that you do not use the default or full admin user account, but create a specific account for NewRelic to use. diff --git a/VTMAgent.cs b/VTMAgent.cs index e70d3ae..4a46e2e 100644 --- a/VTMAgent.cs +++ b/VTMAgent.cs @@ -3,6 +3,7 @@ using NewRelic.Platform.Sdk; using NewRelic.Platform.Sdk.Utils; using NewRelic.Platform.Sdk.Processors; +using System.Reflection; namespace Org.BeyondComputing.NewRelic.Brocade.VTM { @@ -20,20 +21,20 @@ public override string Version { get { - return "1.4.0"; + return Assembly.GetEntryAssembly().GetName().Version.ToString(); } } private string name; private VTM VTM; - private string APIVersion; + private double APIVersion; // Create Dictionary of EpochProcessors to track rate over time for unknown number of items private Dictionary processors = new Dictionary(); private Logger log = Logger.GetLogger(typeof(VTMAgent).Name); - public VTMAgent(string name, string host, int port, string username, string password, string APIVersion) + public VTMAgent(string name, string host, int port, string username, string password, double APIVersion) { this.name = name; this.VTM = new VTM(host, port, username, password); @@ -84,10 +85,20 @@ private void PollGlobal() ReportMetric("global/current_conn", "connections", globalStats.total_current_conn); ReportMetric("global/sys_mem_used", "percent",systemMemoryPercentUsed); ReportMetric("global/sys_cpu_busy_percent", "percent", globalStats.sys_cpu_busy_percent); + + // Get Global Status API v3.7+ + if (APIVersion >= 3.7) + { + dynamic globalStatus = VTM.fetchVTMObject($"/api/tm/{APIVersion}/status/local_tm/state"); + + ReportMetric("global/errors", "count", globalStatus.state.errors.Count); + ReportMetric("global/failedNodes", "count", globalStatus.state.failed_nodes.Count); + } } - catch + catch(Exception e) { log.Error("Unable to fetch Global information from the Virtual Traffic Manager '{0}'", this.name); + log.Error("Exception Thrown:'{0}'", e.Message); } } @@ -96,6 +107,13 @@ private void PollPool() try { Children pools = VTM.fetchVTMObject($"/api/tm/{APIVersion}/status/local_tm/statistics/pools"); + dynamic failedNodes = null; + + // Get Global Status API v3.7+ + if (APIVersion >= 3.7) + { + failedNodes = VTM.fetchVTMObject($"/api/tm/{APIVersion}/status/local_tm/state").state.failed_nodes; + } foreach (var pool in pools.children) { @@ -114,11 +132,29 @@ private void PollPool() ReportMetric("pools/" + pool.name + "/nodes", "nodes", poolStats.nodes); ReportMetric("pools/" + pool.name + "/disabled", "nodes", poolStats.disabled); ReportMetric("pools/" + pool.name + "/draining", "nodes", poolStats.draining); + + // Get Global Status API v3.7+ + if (failedNodes != null) + { + int failedCount = 0; + foreach (var node in failedNodes) + { + foreach (var p in node.pools) + { + if (p == pool.name) + { + failedCount += 1; + } + } + } + ReportMetric($"pools/{pool.name}/failed", "nodes", failedCount); + } } } - catch + catch(Exception e) { log.Error("Unable to fetch Pool information from the Virtual Traffic Manager '{0}'", this.name); + log.Error("Exception Thrown:'{0}'", e.Message); } } diff --git a/VTMAgentFactory.cs b/VTMAgentFactory.cs index 35ed5fc..5b9559c 100644 --- a/VTMAgentFactory.cs +++ b/VTMAgentFactory.cs @@ -11,12 +11,15 @@ class VTMAgentFactory : AgentFactory { public override Agent CreateAgentWithConfiguration(IDictionary properties) { + // Set the default version of the API to use if not found in the config file + const double _APIVersion = 3.8; + string name = (string)properties["name"]; string host = (string)properties["host"]; int port = int.Parse((string)properties["port"]); string username = (string)properties["username"]; string password = (string)properties["password"]; - string APIVersion = "3.3"; + double APIVersion = properties.ContainsKey("api_version") ? (double)properties["api_version"] : _APIVersion; if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(host) || string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) {