public float CollectMetric(PluginResource pluginResource, string option = null)
        {
            // get a handle on the service first
            var service = ServiceController.GetServices().FirstOrDefault(s => s.DisplayName == option);
            if (service == null)
            {
                throw new Exception(string.Format("Windows service by name '{0}' not found", option));
            }

            if (service.Status == ServiceControllerStatus.Stopped)
            {
                return default(float);
            }
            else if (pluginResource.ResourceTextKey == StatusResource)
            {
                return 1;
            }

            // get a handle on the process
            var serviceMgtObj = new ManagementObject(@"Win32_Service.Name='" + service.ServiceName + "'");
            var serviceProcess = Process.GetProcessById(Convert.ToInt32(serviceMgtObj["ProcessId"]));

            // return perfomance counter value for process
            var perfCounter = new PerformanceCounter("Process", pluginResource.Label, serviceProcess.ProcessName);

            var value = perfCounter.NextValue();
            if (value == 0.0)
            {
                Thread.Sleep(1000);
                value = perfCounter.NextValue();
            }

            return value;
        }
        public float CollectMetric(PluginResource pluginResource, string option = null)
        {
            var updateSession = (UpdateSession)Activator.CreateInstance(Type.GetTypeFromProgID("Microsoft.Update.Session"));
            var updateSearcher = updateSession.CreateUpdateSearcher();

            switch (pluginResource.ResourceTextKey)
            {
                case ImportantUpdatesCount:
                    return (from IUpdate5 update in updateSearcher.Search(UpdateSearchQuery).Updates
                            where update.BrowseOnly == false
                            select update).Count();

                case OptionalUpdatesCount:
                    return (from IUpdate5 update in updateSearcher.Search(UpdateSearchQuery).Updates
                            where update.BrowseOnly == true
                            select update).Count();

                case LastUpdateDays:
                    var lastUpdateDate = (from IUpdateHistoryEntry entry in updateSearcher.QueryHistory(0, updateSearcher.GetTotalHistoryCount())
                                          orderby entry.Date descending
                                          select entry.Date).First();

                    return (float)(DateTime.UtcNow - lastUpdateDate).Days;
            }

            throw new ArgumentOutOfRangeException(string.Format("Patch resource '{0}' unknown", pluginResource.ResourceTextKey));
        }
        public float CollectMetric(PluginResource pluginResource, string option = null)
        {
            var users = new List<string>();
            var managementScope = new ManagementScope("\\\\localhost", new ConnectionOptions());
            var sessionQuery = new ObjectQuery("Select * from Win32_LogonSession Where LogonType = 2");
            foreach (var session in new ManagementObjectSearcher(managementScope, sessionQuery).Get())
            {
                var associatorsQuery = new ObjectQuery("Associators of {Win32_LogonSession.LogonId=" + session["LogonId"] + "} Where AssocClass=Win32_LoggedOnUser Role=Dependent");
                foreach (var associator in new ManagementObjectSearcher(managementScope, associatorsQuery).Get())
                {
                    users.Add(associator["Domain"].ToString().ToLower() + "\\" + associator["Name"].ToString().ToLower());
                }
            }

            switch (pluginResource.ResourceTextKey)
            {
                case UniqueLogins:
                    return users.Distinct().Count();

                case TotalLogins:
                    return users.Count;
            }

            throw new ArgumentOutOfRangeException(string.Format("Users resource '{0}' unknown", pluginResource.ResourceTextKey));
        }
        public string[] Discover(PluginResource pluginResource)
        {
            if (pluginResource.ResourceTextKey == NamedProcesses || pluginResource.ResourceTextKey == ProcessExists)
            {
                pluginResource.RequiresOptionTextField = true;
            }

            return new string[] { };
        }
 public float CollectMetric(PluginResource pluginResource, string option = null)
 {
     if (!PerformanceCounterCategory.CounterExists(pluginResource.Label, pluginResource.Category))
     {
         return (float)GetPluginResourceDelegateMethod(pluginResource, DelegateMethodType.Metric).Invoke(this, new object[] { pluginResource, option });
     }
     
     return GetCounterValue(pluginResource.Category, pluginResource.Label, option);
 }
        public float CollectMetric(PluginResource pluginResource, string option = null)
        {
            var config = GetConfig(pluginResource);
            if (!config.ContainsKey("username") || !config.ContainsKey("password") || !config.ContainsKey("host") || !config.ContainsKey("port"))
            {
                throw new ArgumentNullException("JMX requires username, password, host, and port");
            }

            if (string.IsNullOrEmpty(option))
            {
                throw new ArgumentNullException("Option value containing the jmx mbean data cannot be empty");
            }

            try
            {
                var parts = option.Split("/".ToCharArray(), 3);
                var obj = parts[0];
                var attribute = parts[1];
                var key = parts.Length == 3 ? parts[2] : null;

                var jar = Path.Combine(Environment.CurrentDirectory, "cmdline-jmxclient-0.10.3.jar");
                var arguments = string.Format("{0}:{1} {2}:{3} {4} {5}", config["username"], config["password"], config["host"], config["port"], obj, attribute);
                var javaBin = System.Environment.GetEnvironmentVariable("PATH").Split(';').Select(p => Path.Combine(p.Trim().Replace(@"\\", @"\"), "java.exe")).Where(j => File.Exists(j)).FirstOrDefault();
                var proc = new Process
                {                    
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = javaBin,
                        Arguments = string.Format("-jar {0} {1}", jar, arguments),
                        UseShellExecute = false,
                        RedirectStandardOutput = true,
                        RedirectStandardError = true,
                        CreateNoWindow = true
                    }
                };
                proc.Start();
                proc.WaitForExit();
                var output = proc.StandardError.ReadToEnd().Trim();
                output = output.Substring(output.IndexOf("org.archive.jmx.Client") + "org.archive.jmx.Client".Length).Trim();

                var value = 0f;
                if (string.IsNullOrWhiteSpace(key))
                {
                    value = float.Parse(output.Split(':')[1].Trim());
                }
                else
                {
                    value = output.Replace("\r", "").Split('\n').Skip(1).ToDictionary(line => line.Split(':')[0].Trim().ToLower(), line => float.Parse(line.Split(':')[1].Trim()))[key.ToLower()];
                }
                return value;
            }
            catch
            {
                throw new ArgumentNullException("JMX server is not running or the mbean does not exist");
            }
        }
 public string[] Discover(PluginResource pluginResource)
 {
     var config = GetConfig(pluginResource);
     if (!config.ContainsKey("username") || !config.ContainsKey("password") || !config.ContainsKey("console_url"))
     {
         throw new ArgumentNullException("Tomcat requires username, password, and console_url");
     }
     else
     {
         return new string[] { };
     }
 }
        public string[] Discover(PluginResource pluginResource)
        {
            var parameters = GetConfig(pluginResource);
            parameters["ResourceTextKey"] = pluginResource.ResourceTextKey;

            var configError = RunScriptCommand(pluginResource.Script, "Get-Config-Errors", parameters);
            if (configError.Length != 0)
            {
                throw new ArgumentNullException(configError[0].ToString());
            }
            else
            {
                return RunScriptCommand(pluginResource.Script, "Discover", parameters);
            }
        }
        public float CollectMetric(PluginResource pluginResource, string option = null)
        {
            var parameters = GetConfig(pluginResource);
            parameters["Option"] = option;
            parameters["ResourceTextKey"] = pluginResource.ResourceTextKey;

            var results = RunScriptCommand(pluginResource.Script, "Collect-Metric", parameters);
            try
            {
                return float.Parse(results[0]);
            }
            catch (Exception)
            {
                throw new ArgumentNullException(results.Length != 0 ? results[0] : "No results found");
            }
        }
        public string[] Discover(PluginResource pluginResource)
        {
            var category = pluginResource.Category;
            var resource = pluginResource.Label;

            if (!PerformanceCounterCategory.CounterExists(resource, category))
            {
                if (GetPluginResourceDelegateMethod(pluginResource, DelegateMethodType.Metric) == null)
                {
                    throw new NotSupportedException(string.Format("Performance Counter \\{0}\\{1} does not exist", category, resource));
                }
            }

            if (PerformanceCounterCategory.GetCategories().Any(c => c.CategoryName == category))
            {
                return PerformanceCounterCategory.GetCategories().FirstOrDefault(c => c.CategoryName == category).GetInstanceNames();
            }

            return (string[])GetPluginResourceDelegateMethod(pluginResource, DelegateMethodType.Discovery).Invoke(this, new object[] { pluginResource });
        }
        public float CollectMetric(PluginResource pluginResource, string option = null)
        {
            if ((pluginResource.ResourceTextKey == NamedProcesses || pluginResource.ResourceTextKey == ProcessExists) & string.IsNullOrEmpty(option))
            {
                throw new ArgumentNullException("Option value containing the process resource name cannot be empty");
            }

            switch (pluginResource.ResourceTextKey)
            {
                case RunningProcesses:
                    return Process.GetProcesses().Length;

                case NamedProcesses:
                    return Process.GetProcessesByName(option).Length;

                case ProcessExists:
                    return Process.GetProcessesByName(option).Length != 0 ? 1 : 0;
            }

            throw new ArgumentOutOfRangeException(string.Format("Process resource '{0}' unknown", pluginResource.ResourceTextKey));
        }
        public float CollectMetric(PluginResource pluginResource, string option = null)
        {
            var config = GetConfig(pluginResource);
            if (!config.ContainsKey("username") || !config.ContainsKey("password") || !config.ContainsKey("console_url"))
            {
                throw new ArgumentNullException("Tomcat requires username, password, and console_url");
            }

            if (metrics.Contains(pluginResource.ResourceTextKey))
            {
                try
                {
                    using (WebClient client = new WebClient())
                    {
                        client.Credentials = new NetworkCredential(config["username"], config["password"]);
                        var output = client.DownloadString(config["console_url"]).ToLower();
                        var pattern = pluginResource.ResourceTextKey.Replace("_", " ").ToLower() + ": (\\d+)";
                        var match = Regex.Match(output, pattern);
                        var value = 0;
                        if (match.Success)
                        {
                            value = int.Parse(match.Groups[1].Value);
                        }
                        return value;
                    }
                }
                catch
                {
                    throw new ArgumentNullException("Tomcat is not installed or running");
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException(string.Format("Tomcat resource '{0}' unknown", pluginResource.ResourceTextKey));
            }            
        }
        public string[] Discover(PluginResource pluginResource)
        {
            pluginResource.RequiresOptionTextField = true;

            var config = GetConfig(pluginResource);
            if (!config.ContainsKey("username") || !config.ContainsKey("password") || !config.ContainsKey("host") || !config.ContainsKey("port"))
            {
                throw new ArgumentNullException("JMX requires username, password, host, and port");
            }
            else
            {
                var javaBin = System.Environment.GetEnvironmentVariable("PATH").Split(';').Select(p => Path.Combine(p.Trim().Replace(@"\\", @"\"), "java.exe")).Where(j => File.Exists(j)).FirstOrDefault();
                try
                {                    
                    Process.Start(javaBin);
                }
                catch(Exception exp)
                {
                    throw new ArgumentNullException(string.Format("Java is either not installed or not put on the path. Bin: {0}; Error details: {1}", javaBin, exp.Message));
                }
            }

            return new string[] { };
        }
 public string[] Discover(PluginResource pluginResource)
 {
     pluginResource.RequiresOptionTextField = true;
     return new string[] { };
 }
 private MethodInfo GetPluginResourceDelegateMethod(PluginResource pluginResource, DelegateMethodType delegateType)
 {
     return GetType().GetMethod(string.Format("Get{0}{1}{2}", pluginResource.Category.Classify(), pluginResource.ResourceTextKey.Classify(), delegateType.ToString()), BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.DeclaredOnly);
 }
 string[] GetAppPoolWasCurrentApplicationPoolStateDiscovery(PluginResource pluginResource)
 {
     throw new NotImplementedException();
 }
 public Dictionary<string, string> GetConfig(PluginResource pluginResource)
 {
     return AgentContext.Current.Config.Value(!string.IsNullOrWhiteSpace(pluginResource.ConfigTextKey) ? pluginResource.ConfigTextKey : pluginResource.CategoryTextKey.Replace("powershell.", "")) ?? new Dictionary<string, string>();            
 }
 float GetLogicalDiskPercentUsedSpaceMetric(PluginResource pluginResource, string option = null)
 {
     var percentSpaceFree = GetCounterValue(pluginResource.Category, "% Free Space", option);
     return 100 - percentSpaceFree;
 }
 public string[] Discover(PluginResource pluginResource)
 {
     return new string[] { };
 }
 float GetMemoryUsedMbytesMetric(PluginResource pluginResource, string option = null)
 {
     return PerformanceInfo.GetTotalMemoryInMB() - PerformanceInfo.GetPhysicalAvailableMemoryInMB();
 }
 public string[] Discover(PluginResource pluginResource)
 {
     return ServiceController.GetServices().Select(s => s.DisplayName).ToArray();
 }
 float GetMemoryPercentUsedMetric(PluginResource pluginResource, string option = null)
 {
     return 100 - GetMemoryPercentFreeMetric(pluginResource, option);
 }
 public Dictionary<string, string> GetConfig(PluginResource pluginResource)
 {
     return new Dictionary<string, string>();
 }
 public void AddPluginResource(PluginResource pluginResource)
 {
     if (_pluginResources.All(r => r.TextKey != pluginResource.TextKey))
     {
         _pluginResources.Add(pluginResource);
     }
 }
 float GetAppPoolWasCurrentApplicationPoolStateMetric(PluginResource pluginResource, string option = null)
 {
     throw new NotImplementedException();
 }
        public float CollectMetric(PluginResource pluginResource, string option = null)
        {
            if (string.IsNullOrEmpty(option))
            {
                throw new ArgumentNullException("Option value containing the filesytem resource cannot be empty");
            }

            foreach (var match in Regex.Matches(option, @"\$.[^$\\]+"))
            {
                var date = match.ToString();
                var dateFormat = date
                                    .Replace("YYYY", "yyyy")
                                    .Replace("YY", "yy")
                                    .Replace("MM", "MM")
                                    .Replace("DD", "dd")    
                                    .Replace("hh", "H")
                                    .Replace("mm", "mm")
                                    .Replace("ss", "ss")
                                    .Replace("Z", "zzz")
                                    .Replace("$", "")
                                    .Replace(":", " ")
                                    .Trim();
                var dateString = DateTime.Now.ToString(dateFormat);
                option = option.Replace(date, dateString);
            }

            switch (pluginResource.ResourceTextKey)
            {
                case FileCreated:
                    if (File.Exists(option))
                    {
                        return (float)(DateTime.UtcNow - File.GetCreationTimeUtc(option)).TotalMinutes;
                    }
                    else if (Directory.Exists(option))
                    {
                        return (float)(DateTime.UtcNow - Directory.GetCreationTimeUtc(option)).TotalMinutes;
                    }
                    throw new FileNotFoundException(option);

                case FileExists:
                    return (File.Exists(option) || Directory.Exists(option)) ? 1 : 0;

                case FileModified:
                    if (File.Exists(option))
                    {
                        return (float)(DateTime.UtcNow - File.GetLastWriteTimeUtc(option)).TotalMinutes;
                    }
                    else if (Directory.Exists(option))
                    {
                        return (float)(DateTime.UtcNow - Directory.GetLastWriteTimeUtc(option)).TotalMinutes;
                    }
                    throw new FileNotFoundException(option);

                case FileSize:
                    if (File.Exists(option))
                    {
                        return (float)(new FileInfo(option).Length / 1024.0);
                    }
                    throw new FileNotFoundException(option);
            }

            throw new ArgumentOutOfRangeException(string.Format("Filesystem resource '{0}' unknown", pluginResource.ResourceTextKey));
        }
 float GetMemoryPercentFreeMetric(PluginResource pluginResource, string option = null)
 {
     return ((float)PerformanceInfo.GetPhysicalAvailableMemoryInMB() / (float)PerformanceInfo.GetTotalMemoryInMB()) * 100;
 }