/// <summary> /// Create a new metric instance for the provided performance counter object /// </summary> /// <remarks>This will create a new performance counter metric object, add it to this collection, and return it in one call.</remarks> /// <param name="newPerfCounter">The windows performance counter to add</param> /// <returns>The newly created performance counter metric packet object</returns> public PerfCounterMetric Add(PerformanceCounter newPerfCounter) { //just do the null check - everything else we do in the base object add if (newPerfCounter == null) { throw new ArgumentNullException(nameof(newPerfCounter), "A performance counter object must be provided to add it to the collection."); } //we first need to go waltz off and find the definition for this guy string key = PerfCounterMetricDefinition.GetKey(newPerfCounter); //if this key doesn't match our key then we have a problem - it isn't for our collection if (base.Definition.Name != key) { throw new ArgumentOutOfRangeException(nameof(newPerfCounter)); } //New object - go ahead and create it for us. PerfCounterMetric newPerfCounterMetric = new PerfCounterMetric((PerfCounterMetricDefinition)base.Definition, newPerfCounter); //we do NOT add it to our collection - it JUST DID THAT in the constructor. If we do it again, we'll get an exception //finally, return the performance counter packet object to our caller so they can find it easily. return(newPerfCounterMetric); }
/// <summary>Creates a new performance counter metric instance or returns an existing one from the provided definition information, or returns any existing instance if found.</summary> /// <remarks>If the metric definition doesn't exist, it will be created. If the metric doesn't exist, it will be created. /// If the metric definition does exist, but is not a Performance Counter Metric (or a derived class) an exception will be thrown.</remarks> /// <param name="newPerformanceCounter">The windows performance counter to add a definition for</param> /// <param name="alias">An alias to use to determine the instance name instead of the instance of the supplied counter.</param> /// <returns>The Performance Counter Metric object for the specified instance.</returns> public static PerfCounterMetric AddOrGet(PerformanceCounter newPerformanceCounter, PerfCounterInstanceAlias alias) { //we need to find the definition, adding it if necessary string definitionKey = PerfCounterMetricDefinition.GetKey(newPerformanceCounter); IMetricDefinition definition; if (Log.Metrics.TryGetValue(definitionKey, out definition)) { //if the metric definition exists, but is of the wrong type we have a problem. if ((definition is PerfCounterMetricDefinition) == false) { throw new ArgumentException("A metric already exists with the provided type, category, and counter name but it is not compatible with being a performance counter metric. This indicates a programming error in a client application or Gibraltar."); } } else { //we didn't find one, make a new one definition = new PerfCounterMetricDefinition(Log.Metrics, newPerformanceCounter); } //now we have our definition, proceed to create a new metric if it doesn't exist //Interesting note: here is where we basically lock in an alias to be its initial value. string metricKey = GetKey(newPerformanceCounter); IMetric metric; //see if we can get the metric already. If not, we'll create it lock (((MetricCollection)definition.Metrics).Lock) //make sure the get & add are atomic { if (definition.Metrics.TryGetValue(metricKey, out metric) == false) { metric = new PerfCounterMetric((PerfCounterMetricDefinition)definition, newPerformanceCounter, alias); } } return((PerfCounterMetric)metric); }