/// <summary> /// Reports metrics specificed for an application /// </summary> /// <param name="metric"></param> /// <returns>Indicator of success.</returns> internal async Task <bool> ReportPartitionMetricAsync(MetricCheck metric) { ServiceEventSource.Current.ServiceRequestStart(nameof(this.ReportServiceMetricAsync)); try { PartitionLoadInformation loadInfo = await this.Client.QueryManager.GetPartitionLoadInformationAsync(metric.Partition, this._timeout, this._token); foreach (LoadMetricReport item in loadInfo.PrimaryLoadMetricReports) { await this._telemetry.ReportMetricAsync(metric.Service, metric.Partition, item.Name, item.Value, this._token).ConfigureAwait(false); } } catch (FabricElementNotFoundException) { return(false); } catch (TimeoutException ex) { ServiceEventSource.Current.ServiceMessage(this._service.Context, "Timeout in ReportServiceMetric at {0}", ex.StackTrace); } catch (FabricObjectClosedException) { this._service.RefreshFabricClient(); ServiceEventSource.Current.ServiceMessage(this._service.Context, "FabricClient closed"); } ServiceEventSource.Current.ServiceRequestStop(nameof(this.ReportServiceMetricAsync)); return(true); }
/// <summary> /// Called to add a metric to the watchdog. /// </summary> /// <param name="mcm">MetricCheck metric.</param> /// <returns>Task instance.</returns> /// <exception cref="ArgumentException">ServiceName parameter within the HealthCheck instance does not exist.</exception> public async Task <bool> AddMetricAsync(MetricCheck mcm) { // Get the required dictionaries. IReliableDictionary <string, MetricCheck> hcDict = await this.GetMetricCheckDictionaryAsync().ConfigureAwait(false); try { // Create a transaction. using (ITransaction tx = this._service.StateManager.CreateTransaction()) { // Add or update the HealthCheck item in the dictionary. await hcDict.AddOrUpdateAsync(tx, mcm.Key, mcm, (k, v) => { return(mcm); }, this._timeout, this._token).ConfigureAwait(false); await tx.CommitAsync(); Interlocked.Increment(ref this._metricCount); } } catch (FabricObjectClosedException) { this._service.RefreshFabricClient(); return(true); } catch (TimeoutException ex) { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.AddMetricAsync)); } catch (FabricTransientException ex) { ServiceEventSource.Current.Exception(ex.Message, ex.GetType().Name, nameof(this.AddMetricAsync)); } return(false); }
/// <summary> /// Reports metrics specificed for an application /// </summary> /// <param name="metric"></param> /// <returns>Indicator of success.</returns> internal async Task <bool> ReportServiceMetricAsync(MetricCheck metric) { ServiceEventSource.Current.ServiceRequestStart(nameof(this.ReportServiceMetricAsync)); try { Uri serviceUri = new Uri($"fabric:/{metric.Application}/{metric.Service}"); IList <Partition> pList = await this.GetCompletePartitionListAsync(serviceUri).ConfigureAwait(false); foreach (Partition p in pList) { // Check that the partition is ready. if (p.PartitionStatus == ServicePartitionStatus.Ready) { // Get the list of replicas within the partition. IList <Replica> rList = await this.GetCompleteReplicaListAsync(p.PartitionInformation.Id); foreach (Replica r in rList) { // Only query for load information if the replica is ready. if (r.ReplicaStatus == ServiceReplicaStatus.Ready) { // Get the load information from the replica. ReplicaLoadInformation loadInfo = await this.Client.QueryManager.GetReplicaLoadInformationAsync(p.PartitionInformation.Id, r.Id).ConfigureAwait(false); foreach (LoadMetricReport item in loadInfo.LoadMetricReports) { // If it contains one of the names requested, report the load. if (metric.MetricNames.Contains(item.Name)) { //TODO: // await this._telemetry.ReportMetricAsync(metric.Service, r.Id, item.Name, item.Value, this._token).ConfigureAwait(false); } } } } } } } catch (FabricElementNotFoundException) { return(false); } catch (TimeoutException ex) { ServiceEventSource.Current.ServiceMessage(this._service.Context, "Timeout in ReportServiceMetric at {0}", ex.StackTrace); } catch (FabricObjectClosedException) { this._service.RefreshFabricClient(); ServiceEventSource.Current.ServiceMessage(this._service.Context, "FabricClient closed"); } ServiceEventSource.Current.ServiceRequestStop(nameof(this.ReportServiceMetricAsync)); return(true); }
public void MetricCheck_ConstructorTest() { MetricCheck mc1 = new MetricCheck(); Assert.IsNull(mc1.MetricNames); Assert.IsNull(mc1.Application); Assert.IsNull(mc1.Service); Assert.AreEqual(default(Guid), mc1.Partition); // Check this equals the default MetricCheck value. Assert.IsTrue(mc1.Equals(MetricCheck.Default)); // Check the copy constructor. MetricCheck mc2 = new MetricCheck(mc1); Assert.IsTrue(mc1.Equals(mc2)); }
public void MetricCheck_EqualsTest() { string[] metricNames2 = new string[] { "metric4", "metric2", "metric3", "metric1" }; MetricCheck mc1 = new MetricCheck(metricNames, "appName", "svcName", partition1); Assert.IsTrue(mc.Equals(mc1)); mc1 = new MetricCheck(new string[0], "appName", "svcName", partition1); Assert.IsFalse(mc.Equals(mc1)); mc1 = new MetricCheck(metricNames, "app", "svcName", partition1); Assert.IsFalse(mc.Equals(mc1)); mc1 = new MetricCheck(metricNames2, "appName", null, partition1); Assert.IsFalse(mc.Equals(mc1)); mc1 = new MetricCheck(metricNames2, "appName", "svcName", Guid.Empty); Assert.IsFalse(mc.Equals(mc1)); }
/// <summary> /// Enumerates metric requests. /// </summary> internal async Task EnumerateMetricsAsync() { // Check if the partition is readable/writable. if (PartitionAccessStatus.Granted != this._service.ReadStatus || PartitionAccessStatus.Granted != this._service.WriteStatus) { return; } // Get the health check schedule items. IReliableDictionary <string, MetricCheck> mDict = await this.GetMetricCheckDictionaryAsync(); // Create a transaction for the enumeration. using (ITransaction tx = this._service.StateManager.CreateTransaction()) { bool result = false; // Create the AsyncEnumerator. Data.IAsyncEnumerator <KeyValuePair <string, MetricCheck> > ae = (await mDict.CreateEnumerableAsync(tx, EnumerationMode.Ordered)).GetAsyncEnumerator(); while (await ae.MoveNextAsync(this._token)) { MetricCheck mc = ae.Current.Value; if ((false == string.IsNullOrWhiteSpace(mc.Service)) && (default(Guid) != mc.Partition)) { result = await this.ReportPartitionMetricAsync(mc).ConfigureAwait(false); } else if ((false == string.IsNullOrWhiteSpace(mc.Service)) && (default(Guid) == mc.Partition)) { result = await this.ReportServiceMetricAsync(mc).ConfigureAwait(false); } else { result = await this.ReportApplicationMetricAsync(mc).ConfigureAwait(false); } } } this._healthState = HealthState.Ok; }
public void MetricCheck_SerializationTest() { // Serialize to the output buffer as binary. OutputBuffer output = new OutputBuffer(); CompactBinaryWriter <OutputBuffer> writer = new CompactBinaryWriter <OutputBuffer>(output); Serialize.To(writer, mc); // De-serialize from the binary output. InputBuffer input = new InputBuffer(output.Data); CompactBinaryReader <InputBuffer> reader = new CompactBinaryReader <InputBuffer>(input); MetricCheck hc1 = Deserialize <MetricCheck> .From(reader); Assert.IsTrue(mc.Equals(hc1)); // Serialize as JSON using NewtonSoft. string json = JsonConvert.SerializeObject(mc, Formatting.None); hc1 = JsonConvert.DeserializeObject <MetricCheck>(json); Assert.IsTrue(mc.Equals(hc1)); // Using the generic BondCustomSerializer. using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { BondCustomSerializer <MetricCheck> bcs = new BondCustomSerializer <MetricCheck>(); bcs.Write(mc, bw); ms.Position = 0L; using (BinaryReader br = new BinaryReader(ms)) { hc1 = bcs.Read(br); Assert.IsTrue(mc.Equals(hc1)); } } } }