/// <summary> /// Parses & loads a set of MBean counters for the given host using the XML tree. /// </summary> /// <param name="root">The root MBean counters config node.</param> /// <param name="host">The host to load counters for.</param> /// <param name="lifeCycleTypeToLoad">A filter that indicates whether ephemeral or persistent counters should be loaded.</param> /// <returns>Collection of MBean counters specified in the root node's config.</returns> public ICollection<ICounter> LoadCounters(XmlNode root, Host host, CounterLifecycleType lifeCycleTypeToLoad) { var counters = new List<ICounter>(); // We currently don't support ephemeral counters for MBeans, so just short circuit out in this case. if (lifeCycleTypeToLoad == CounterLifecycleType.Ephemeral) { return counters; } var sourceNodes = root.SelectNodes("./Source"); if (sourceNodes != null) { foreach (XmlNode sourceNode in sourceNodes) { var startPort = Convert.ToInt32(sourceNode.Attributes["startport"].Value); var endPort = Convert.ToInt32(sourceNode.Attributes["endport"].Value); // Retrieve a collection of all available clients within the specified port range, then new up counters using those. // This way, multiple counters can share a single client & connection. var mbeanClientPool = MBeanClientFactory.CreateClients(host.Name, startPort, endPort); foreach (var mbeanClient in mbeanClientPool) { var countersForSource = BuildCountersForSourceNode(sourceNode, host, mbeanClient, startPort); counters.AddRange(countersForSource); } } } return counters; }
public PerfmonCounter(Host host, string counterCategory, string counterName, string instance, string unit) { Host = host; CounterType = PerfmonCounterType; Source = PerfmonSource; Category = counterCategory; Counter = counterName; Instance = instance; Unit = unit; perfmonCounter = new PerformanceCounter(Category, Counter, Instance, Host.Name); }
/// <summary> /// Parses & loads all Perfmon counters for the given host using the XML tree. /// </summary> /// <param name="root">The root Perfmon counters config node.</param> /// <param name="host">The host to load counters for.</param> /// <param name="lifeCycleTypeToLoad">A filter that indicates whether ephemeral or persistent counters should be loaded.</param> /// <returns>Collection of Perfmon counters specified in the root node's config.</returns> public ICollection<ICounter> LoadCounters(XmlNode root, Host host, CounterLifecycleType lifeCycleTypeToLoad) { var counters = new Collection<ICounter>(); var perfmonCounterNodes = root.SelectNodes("./*/Counter"); foreach (XmlNode counterNode in perfmonCounterNodes) { // Set what we know. var counterName = counterNode.Attributes["name"].Value; var categoryName = counterNode.ParentNode.Attributes["name"].Value; string unitOfMeasurement = null; if (counterNode.Attributes.GetNamedItem("unit") != null) { unitOfMeasurement = counterNode.Attributes["unit"].Value; } // If any instance names are called out, shove them into a list of filters. var instanceFilters = new HashSet<string>(); if (counterNode.HasChildNodes) { var instanceNodes = counterNode.SelectNodes("./Instance"); if (instanceNodes == null) { continue; } foreach (var instanceNode in instanceNodes.Cast<XmlNode>().Where(instanceNode => instanceNode.Attributes.GetNamedItem("name") != null)) { string instanceName = instanceNode.Attributes["name"].Value; CounterLifecycleType configuredCounterLifecycleType = GetConfiguredInstanceLifecycleType(instanceNode); if (configuredCounterLifecycleType == lifeCycleTypeToLoad) { instanceFilters.Add(instanceName); } } } // Load an instance of this perfmon counter for each matching instance name that exists. // If no instance name is specified, just load them all. if (lifeCycleTypeToLoad == CounterLifecycleType.Persistent || instanceFilters.Count > 0) { var counterInstances = PerfmonCounterLoader.LoadInstancesForCounter(host, lifeCycleTypeToLoad, categoryName, counterName, unitOfMeasurement, instanceFilters); foreach (var counterInstance in counterInstances) { counters.Add(counterInstance); } } } return counters; }
public TableauInstrumentationCounter(IMBeanClient mbeanClient, Host host, string sourceName, string subDomain, string path, string categoryName, string counterName, string instanceName, string unit) : base(mbeanClient: mbeanClient, lifecycleType: CounterLifecycleType.Ephemeral, counterType: TableauInstrumentationCounterType, jmxDomain: TableauInstrumentationJmxDomain.JoinIfNotNull(".", subDomain), host: host, source: sourceName, filter: path, category: categoryName, counter: counterName, instance: instanceName, unit: unit) { }
protected AbstractMBeanCounter(IMBeanClient mbeanClient, string counterType, string jmxDomain, Host host, string source, string filter, string category, string counter, string instance, string unit) { Host = host; CounterType = counterType; Source = source; Category = category; Counter = counter; Instance = instance; Unit = unit; MBeanClient = mbeanClient; JmxDomain = jmxDomain; Path = filter; }
/// <summary> /// Builds an ICounter instance from a counter XML node and a set of properties. /// </summary> private static ICounter BuildCounterFromCounterNode(XmlNode counterNode, IMBeanClient mbeanClient, Host host, string sourceName, int startPort) { var counterName = counterNode.Attributes["name"].Value; var categoryName = counterNode.ParentNode.Attributes["name"].Value; var path = counterNode.ParentNode.Attributes["path"].Value; string unitOfMeasurement = null; if (counterNode.Attributes.GetNamedItem("unit") != null) { unitOfMeasurement = counterNode.Attributes["unit"].Value; } var instanceName = BuildInstanceName(sourceName, startPort, mbeanClient.Connector.ConnectionInfo.Port); var rootCounterTypeNode = counterNode.ParentNode.ParentNode; var counterType = rootCounterTypeNode.Name.ToLower(); string subDomain = null; if (rootCounterTypeNode.Attributes != null && rootCounterTypeNode.Attributes["subdomain"] != null) { subDomain = rootCounterTypeNode.Attributes["subdomain"].Value; } // Create the counter. try { var builder = new MBeanBuilder(); return builder.CreateCounter(host) .UsingClient(mbeanClient) .WithSourceName(sourceName) .WithSubDomain(subDomain) .WithPath(path) .WithCategoryName(categoryName) .WithCounterName(counterName) .WithInstanceName(instanceName) .WithUnit(unitOfMeasurement) .Build(counterType); } catch (Exception ex) { Log.DebugFormat(@"Failed to register MBean counter {0}\{1}\{2}\{3}\{4}: {5}", host.Name, sourceName, categoryName, counterName, instanceName, ex.Message); return null; } }
/// <summary> /// Loads all Perfmon counters on the target host matching the given parameters. /// </summary> /// <param name="host">The host to check counters on.</param> /// <param name="lifecycleType">Indicates whether the counters should be loaded as persistent or ephemeral counters.</param> /// <param name="categoryName">The counter category.</param> /// <param name="counterName">The name of the counter.</param> /// <param name="unitOfMeasurement">The unit of measurement that this counter reports in. This is a piece of metadata we add in.</param> /// <param name="instanceFilters">A collection of search terms to use to filter out instances that do not match.</param> /// <returns>List of all matching Perfmon counters.</returns> public static IList<PerfmonCounter> LoadInstancesForCounter(Host host, CounterLifecycleType lifecycleType, string categoryName, string counterName, string unitOfMeasurement, ISet<string> instanceFilters) { IList<PerfmonCounter> counters = new List<PerfmonCounter>(); // If the requested category does not exist, log it and bail out. if (!ExistsCategory(categoryName, host.Name)) { Log.WarnFormat("PerfMon counter category '{0}' on host '{1}' does not exist.", categoryName, host.Name); return counters; } // If the requested counter does not exist, log it and bail out. if (!ExistsCounter(counterName, categoryName, host.Name)) { Log.DebugFormat("PerfMon counter '{0}' in category '{1}' on host '{2}' does not exist.", counterName, categoryName, host.Name); return counters; } var category = new PerformanceCounterCategory(categoryName, host.Name); // Perfmon has both "single-instance" and "multi-instance" counter types -- we need to handle both appropriately. switch (category.CategoryType) { case PerformanceCounterCategoryType.SingleInstance: counters.Add(new PerfmonCounter(host, lifecycleType, categoryName, counterName, instance: null, unit: unitOfMeasurement)); break; case PerformanceCounterCategoryType.MultiInstance: foreach (var instanceName in category.GetInstanceNames()) { if (IsInstanceRequested(instanceName, instanceFilters)) { counters.Add(new PerfmonCounter(host, lifecycleType, categoryName, counterName, instanceName, unitOfMeasurement)); } } break; default: Log.ErrorFormat("Unable to determine category type of PerfMon counter '{0}' in category '{1}' on host '{2}' is unknown; skipping loading it.", counterName, categoryName, host.Name); break; } return counters; }
/// <summary> /// Loads all Perfmon counters on the target host matching the given parameters. /// </summary> /// <param name="host">The host to check counters on.</param> /// <param name="categoryName">The counter category.</param> /// <param name="counterName">The name of the counter.</param> /// <param name="unitOfMeasurement">The unit of measurement that this counter reports in. This is a piece of metadata we add in.</param> /// <param name="instanceFilters">A collection of search terms to use to filter out instances that do not match.</param> /// <returns>List of all matching Perfmon counters.</returns> public static IList<PerfmonCounter> LoadInstancesForCounter(Host host, string categoryName, string counterName, string unitOfMeasurement, IList<string> instanceFilters) { IList<PerfmonCounter> counters = new List<PerfmonCounter>(); // Check if counter exists. var counterExists = false; try { counterExists = PerformanceCounterCategory.CounterExists(counterName, categoryName, host.Name); } catch (UnauthorizedAccessException ex) { Log.Error(String.Format("Error checking for existence of Perfmon counter '{0}' in category '{1}' on host '{2}': {3}", counterName, categoryName, host.Name, ex.Message)); } catch (Win32Exception ex) { Log.Error(String.Format("Could not communicate with Perfmon on target host '{0}': {1}", host.Name, ex.Message)); } // If the requested counter does not exist, log it and bail out. if (!counterExists) { Log.Debug(String.Format("Counter '{0}' in category '{1}' on host '{2}' does not exist.", counterName, categoryName, host.Name)); return counters; } var category = new PerformanceCounterCategory(categoryName, host.Name); // Perfmon has both "single-instance" and "multi-instance" counter types -- we need to handle both appropriately. if (!IsMultiInstance(category)) { // Just create it and add it to the list. var counter = new PerfmonCounter(host, categoryName, counterName, null, unitOfMeasurement); counters.Add(counter); } else { var instanceNames = new List<string>(category.GetInstanceNames()); // If we didn't specify any instance names to filter by, we just grab everything. if (instanceFilters.Count == 0) { foreach (var instanceName in instanceNames) { var builder = new PerfmonCounterBuilder(); var counter = builder.CreateCounter(host) .WithCategoryName(categoryName) .WithCounterName(counterName) .WithInstanceName(instanceName) .WithUnit(unitOfMeasurement); counters.Add(counter); } } // If we did specify instance names to filter by, we loop over instance names, instantiating any counters that match our filters. else { foreach (var instanceFilter in instanceFilters) { var matchingInstances = instanceNames.Where(instanceName => instanceName.Contains(instanceFilter)); foreach (var instanceName in matchingInstances) { var builder = new PerfmonCounterBuilder(); var counter = builder.CreateCounter(host) .WithCategoryName(categoryName) .WithCounterName(counterName) .WithInstanceName(instanceName) .WithUnit(unitOfMeasurement); counters.Add(counter); } } } } return counters; }
public JavaHealthCounter(IMBeanClient mbeanClient, Host host, string sourceName, string path, string categoryName, string counterName, string instanceName, string unit) : base(mbeanClient: mbeanClient, counterType: JavaHealthCounterType, jmxDomain: JavaHealthJmxDomain, host: host, source: sourceName, filter: path, category: categoryName, counter: counterName, instance: instanceName, unit: unit) { }
public PerfmonCounterBuilder CreateCounter(Host host) { Host = host; return this; }
public TableauHealthCounter(IMBeanClient mbeanClient, Host host, string sourceName, string path, string categoryName, string counterName, string instanceName, string unit) : base(mbeanClient: mbeanClient, lifecycleType: CounterLifecycleType.Persistent, counterType: TableauHealthCounterType, jmxDomain: TableauHealthJmxDomain, host: host, source: sourceName, filter: path, category: categoryName, counter: counterName, instance: instanceName, unit: unit) { }
/// <summary> /// Builds a collection of ICounter instances from a source XML node. /// </summary> private List<ICounter> BuildCountersForSourceNode(XmlNode sourceNode, Host host, IMBeanClient mbeanClient, int startPort) { string sourceName = sourceNode.Attributes["name"].Value; var counterNodesForSource = sourceNode.SelectNodes(".//Counter"); var counters = new List<ICounter>(); if (counterNodesForSource != null) { foreach (XmlNode counterNode in counterNodesForSource) { var counter = BuildCounterFromCounterNode(counterNode, mbeanClient, host, sourceName, startPort); if (counter != null) { counters.Add(counter); } } } return counters; }
public MBeanBuilder CreateCounter(Host host) { Host = host; return this; }
/// <summary> /// Parses & loads a set of MBean counters for the given host using the XML tree. /// </summary> /// <param name="root">The root MBean counters config node.</param> /// <param name="host">The host to load counters for.</param> /// <returns>Collection of MBean counters specified in the root node's config.</returns> public ICollection<ICounter> LoadCounters(XmlNode root, Host host) { var counters = new Collection<ICounter>(); var sourceNodes = root.SelectNodes("./Source"); foreach (XmlNode sourceNode in sourceNodes) { var sourceName = sourceNode.Attributes["name"].Value; var startPort = Convert.ToInt32(sourceNode.Attributes["startport"].Value); var endPort = Convert.ToInt32(sourceNode.Attributes["endport"].Value); // Validate port range. if (startPort > endPort || startPort <= 0 || startPort > 65535 || endPort <= 0 || endPort > 65535) { throw new ArgumentException("Invalid port range"); } // Retrieve a collection of all available clients within the specified port range, then new up counters using those. // This way, multiple counters can share a single client & connection. var mbeanClientPool = MBeanClientFactory.CreateClients(host.Name, startPort, endPort); foreach (var mbeanClient in mbeanClientPool) { var counterNodesForSource = sourceNode.SelectNodes(".//Counter"); foreach (XmlNode counterNode in counterNodesForSource) { var counterName = counterNode.Attributes["name"].Value; var categoryName = counterNode.ParentNode.Attributes["name"].Value; var path = counterNode.ParentNode.Attributes["path"].Value; string unitOfMeasurement = null; if (counterNode.Attributes.GetNamedItem("unit") != null) { unitOfMeasurement = counterNode.Attributes["unit"].Value; } var instanceName = sourceName; // Massage the instance name to match what Perfmon does (i.e. a machine with two dataserver processes will have // instance names "dataserver" & "dataserver#1". var processIndex = mbeanClient.Connector.ConnectionInfo.Port - startPort; if (processIndex > 0) { instanceName += "#" + processIndex; } // Create the counter. var counterType = counterNode.ParentNode.ParentNode.Name.ToLower(); try { var builder = new MBeanBuilder(); var counter = builder.CreateCounter(host) .UsingClient(mbeanClient) .WithSourceName(sourceName) .WithPath(path) .WithCategoryName(categoryName) .WithCounterName(counterName) .WithInstanceName(instanceName) .WithUnit(unitOfMeasurement) .Build(counterType); counters.Add(counter); } catch (Exception ex) { Log.Debug(String.Format("Failed to register MBean counter {0}\\{1}\\{2}\\{3}\\{4}: {5}", host.Name, sourceName, categoryName, counterName, instanceName, ex.Message)); } } } } return counters; }