[REEF-1481] Develop basic metrics APIs for REEF.Net This adds the APIs for metrics in Org.Apache.REEF.Common.
JIRA: [REEF-1481](https://issues.apache.org/jira/browse/REEF-1481) Pull Request: This closes #1073 Project: http://git-wip-us.apache.org/repos/asf/reef/repo Commit: http://git-wip-us.apache.org/repos/asf/reef/commit/0b8da4cf Tree: http://git-wip-us.apache.org/repos/asf/reef/tree/0b8da4cf Diff: http://git-wip-us.apache.org/repos/asf/reef/diff/0b8da4cf Branch: refs/heads/master Commit: 0b8da4cfc3761b38339b03870eb4bb75f90811d0 Parents: af63bf6 Author: dhruv <[email protected]> Authored: Fri Jul 8 23:15:38 2016 -0700 Committer: Markus Weimer <[email protected]> Committed: Tue Aug 30 09:37:22 2016 -0700 ---------------------------------------------------------------------- .../Org.Apache.REEF.Common.Tests.csproj | 12 +- .../metrics/DefaultMetricSourceTests.cs | 581 +++++++++++++++++++ .../metrics/ImmutableMetricTest.cs | 189 ++++++ .../metrics/MetricTestUtils.cs | 179 ++++++ .../metrics/MutableMetricTest.cs | 213 +++++++ .../metrics/SnapshotRequestTest.cs | 100 ++++ .../metrics/TestMetricsTag.cs | 82 +++ .../Org.Apache.REEF.Common.csproj | 36 ++ .../metrics/Api/IImmutableMetric.cs | 90 +++ .../metrics/Api/IMetricsCollector.cs | 47 ++ .../metrics/Api/IMetricsFilter.cs | 49 ++ .../metrics/Api/IMetricsInfo.cs | 38 ++ .../metrics/Api/IMetricsRecord.cs | 63 ++ .../metrics/Api/IMetricsRecordBuilder.cs | 104 ++++ .../metrics/Api/IMetricsSource.cs | 42 ++ .../metrics/Api/IMetricsSystem.cs | 77 +++ .../metrics/Api/IMetricsVisitor.cs | 56 ++ .../metrics/Api/ImmutableMetricImpl.cs | 153 +++++ .../metrics/Api/MetricType.cs | 39 ++ .../metrics/Api/MetricsException.cs | 58 ++ .../metrics/Api/MetricsInfoImpl.cs | 58 ++ .../metrics/Api/MetricsTag.cs | 114 ++++ .../metrics/Api/SnapshotRequest.cs | 59 ++ .../DefaultMetricsFactoryImpl.cs | 163 ++++++ .../DefaultMetricsSourceConfiguration.cs | 62 ++ .../DefaultMetricsSourceImpl.cs | 220 +++++++ .../DefaultMetricsSourceParameters.cs | 46 ++ .../metrics/MutableMetricsLayer/ICounter.cs | 40 ++ .../metrics/MutableMetricsLayer/IDoubleGauge.cs | 57 ++ .../IExtendedMutableMetric.cs | 41 ++ .../metrics/MutableMetricsLayer/ILongGauge.cs | 57 ++ .../MutableMetricsLayer/IMetricContainer.cs | 54 ++ .../MutableMetricsLayer/IMetricsFactory.cs | 128 ++++ .../MutableMetricsLayer/IMutableMetric.cs | 41 ++ .../metrics/MutableMetricsLayer/IRate.cs | 30 + .../metrics/MutableMetricsLayer/IStat.cs | 35 ++ .../MutableMetricsLayer/MutableCounter.cs | 103 ++++ .../MutableMetricsLayer/MutableDoubleGauge.cs | 137 +++++ .../MutableMetricsLayer/MutableLongGauge.cs | 136 +++++ .../MutableMetricsLayer/MutableMetricBase.cs | 132 +++++ .../MutableMetricContainer.cs | 111 ++++ .../metrics/MutableMetricsLayer/MutableRate.cs | 50 ++ .../metrics/MutableMetricsLayer/MutableStat.cs | 176 ++++++ .../MutableMetricsLayer/StatsHelperClass.cs | 175 ++++++ 44 files changed, 4432 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common.Tests/Org.Apache.REEF.Common.Tests.csproj ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/Org.Apache.REEF.Common.Tests.csproj b/lang/cs/Org.Apache.REEF.Common.Tests/Org.Apache.REEF.Common.Tests.csproj index dd5e13d..f339a59 100644 --- a/lang/cs/Org.Apache.REEF.Common.Tests/Org.Apache.REEF.Common.Tests.csproj +++ b/lang/cs/Org.Apache.REEF.Common.Tests/Org.Apache.REEF.Common.Tests.csproj @@ -43,6 +43,12 @@ under the License. <Reference Include="System.Xml" /> </ItemGroup> <ItemGroup> + <Compile Include="Metrics\DefaultMetricSourceTests.cs" /> + <Compile Include="Metrics\ImmutableMetricTest.cs" /> + <Compile Include="Metrics\MetricTestUtils.cs" /> + <Compile Include="Metrics\MutableMetricTest.cs" /> + <Compile Include="Metrics\SnapshotRequestTest.cs" /> + <Compile Include="Metrics\TestMetricsTag.cs" /> <Compile Include="TestHttpSerialization.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> @@ -55,6 +61,10 @@ under the License. <Project>{79e7f89a-1dfb-45e1-8d43-d71a954aeb98}</Project> <Name>Org.Apache.REEF.Utilities</Name> </ProjectReference> + <ProjectReference Include="$(SolutionDir)\Org.Apache.REEF.Tang\Org.Apache.REEF.Tang.csproj"> + <Project>{97dbb573-3994-417a-9f69-ffa25f00d2a6}</Project> + <Name>Org.Apache.REEF.Tang</Name> + </ProjectReference> </ItemGroup> <ItemGroup> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> @@ -65,4 +75,4 @@ under the License. <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <Import Project="$(PackagesDir)\StyleCop.MSBuild.$(StyleCopVersion)\build\StyleCop.MSBuild.Targets" Condition="Exists('$(PackagesDir)\StyleCop.MSBuild.$(StyleCopVersion)\build\StyleCop.MSBuild.Targets')" /> -</Project> +</Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common.Tests/metrics/DefaultMetricSourceTests.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/metrics/DefaultMetricSourceTests.cs b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/DefaultMetricSourceTests.cs new file mode 100644 index 0000000..bdf9e21 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/DefaultMetricSourceTests.cs @@ -0,0 +1,581 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using System.Linq; +using Org.Apache.REEF.Common.Metrics.Api; +using Org.Apache.REEF.Common.Metrics.MutableMetricsLayer; +using Org.Apache.REEF.Tang.Implementations.Tang; +using Org.Apache.REEF.Tang.Interface; +using Xunit; + +namespace Org.Apache.REEF.Common.Tests.Metrics +{ + /// <summary> + /// Tests different functionalities of <see cref="DefaultMetricsSourceImpl"/> + /// </summary> + public sealed class DefaultMetricSourceTests + { + /// <summary> + /// Tests <see cref="DefaultMetricsSourceConfiguration"/> + /// </summary> + [Fact] + public void TestMetricsSourceConfiguration() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + Assert.NotNull(metricsSource); + + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + metricsSource.GetMetrics(collector, true); + Assert.Equal(collector.CurrentRecordBuilder.Name, recordName); + Assert.Equal(collector.CurrentRecordBuilder.Context, sourceContext); + collector.CurrentRecordBuilder.Validate("TaskOrContextName", taskId); + collector.CurrentRecordBuilder.Validate("EvaluatorId", evalId); + } + + /// <summary> + /// Tests creating, accessing and updating counters from <see cref="DefaultMetricsSourceImpl"/> + /// </summary> + [Fact] + public void TestDefaultMetricsSourceCounters() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + string[] counterNames = { "cname1", "cname2" }; + const long counterIncr = 2; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + + // Create Counters + foreach (var name in counterNames) + { + metricsSource.Counters.Create(name, name); + } + + // Update counters. + int counter = 1; + foreach (var name in counterNames) + { + metricsSource.Counters[name].Increment(counter * counterIncr); + counter++; + } + + metricsSource.GetMetrics(collector, true); + var rb = collector.CurrentRecordBuilder; + + // Validate counters + counter = 1; + foreach (var name in counterNames) + { + rb.Validate(name, counter * counterIncr); + counter++; + } + } + + /// <summary> + /// Tests creating, accessing and updating long gauge from <see cref="DefaultMetricsSourceImpl"/> + /// </summary> + [Fact] + public void TestDefaultMetricsSourceLongGauges() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + string[] longGaugeNames = { "lname1", "lname2" }; + const long longGaugeIncr = 3; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + + // Create long gauge + foreach (var name in longGaugeNames) + { + metricsSource.LongGauges.Create(name, name); + } + + // Update long gauge + int counter = 1; + foreach (var name in longGaugeNames) + { + metricsSource.LongGauges[name].Increment(counter * longGaugeIncr); + counter++; + } + + metricsSource.GetMetrics(collector, true); + var rb = collector.CurrentRecordBuilder; + + // Validate long gauges + counter = 1; + foreach (var name in longGaugeNames) + { + rb.Validate(name, counter * longGaugeIncr); + counter++; + } + } + + /// <summary> + /// Tests creating, accessing and updating double gauge from <see cref="DefaultMetricsSourceImpl"/> + /// </summary> + [Fact] + public void TestDefaultMetricsSourceDoubleGauges() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + string[] doubleGaugeNames = { "dname1", "dname2" }; + const double doubleGaugeDecr = 1.2; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + + // Create double gauge + foreach (var name in doubleGaugeNames) + { + metricsSource.DoubleGauges.Create(name, name); + } + + // Update double gauge + int counter = 1; + foreach (var name in doubleGaugeNames) + { + metricsSource.DoubleGauges[name].Decrement(counter * doubleGaugeDecr); + counter++; + } + + metricsSource.GetMetrics(collector, true); + var rb = collector.CurrentRecordBuilder; + + // Validate double gauges + counter = 1; + foreach (var name in doubleGaugeNames) + { + rb.Validate(name, -counter * doubleGaugeDecr, 1e-10); + counter++; + } + } + + /// <summary> + /// Tests creating, accessing and updating rate from <see cref="DefaultMetricsSourceImpl"/> + /// </summary> + [Fact] + public void TestDefaultMetricsSourceRate() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + const string rateName = "rname1"; + double[] samples = { 2, 3 }; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + + // Create rate. + metricsSource.Rates.Create(rateName, rateName); + + // Update rate + foreach (var sample in samples) + { + metricsSource.Rates[rateName].Sample(sample); + } + + metricsSource.GetMetrics(collector, true); + var rb = collector.CurrentRecordBuilder; + + // Validate rate + rb.Validate(rateName + "-Num", samples.Length); + rb.Validate(rateName + "-RunningAvg", samples.Sum() / samples.Length, 1e-10); + } + + /// <summary> + /// Tests creating and accessing tags from <see cref="DefaultMetricsSourceImpl"/> + /// </summary> + [Fact] + public void TestDefaultMetricsSourceTags() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + string[] tagNames = { "tname1", "tname2" }; + string[] tagValues = { "tvalue1", "tValue2" }; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + + // Create tags + for (int i = 0; i < tagNames.Length; i++) + { + metricsSource.AddTag(tagNames[i], tagNames[i], tagValues[i]); + } + + metricsSource.GetMetrics(collector, true); + var rb = collector.CurrentRecordBuilder; + + // Validate tags + for (int i = 0; i < tagNames.Length; i++) + { + rb.Validate(tagNames[i], tagValues[i]); + } + + // Verify GetTag functionality + var tag = metricsSource.GetTag(tagNames[0]); + Assert.NotNull(tag); + Assert.Equal(tag.Name, tagNames[0]); + Assert.Equal(tag.Value, tagValues[0]); + + string inValidName = "invalid"; + tag = metricsSource.GetTag(inValidName); + Assert.Null(tag); + } + + /// <summary> + /// Tests whether we can externally subscribe metrics to <see cref="DefaultMetricsSourceImpl"/> + /// and then unsubscribe. + /// </summary> + [Fact] + public void TestDefaultMetricsSourceExternalMetricsSubscription() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + const string subscribedCounterName = "subscribedcounter"; + const long subscribedCounterValue = 1001; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + IMetricsFactory factory = TangFactory.GetTang().NewInjector().GetInstance<IMetricsFactory>(); + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + + var extraCounter = factory.CreateCounter(subscribedCounterName, + subscribedCounterName, + subscribedCounterValue); + extraCounter.Subscribe(metricsSource); + + metricsSource.GetMetrics(collector, true); + var rb = collector.CurrentRecordBuilder; + rb.Validate(subscribedCounterName, subscribedCounterValue); + + extraCounter.Increment(); + extraCounter.OnCompleted(); // This should remove the counter from the metrics source. + metricsSource.GetMetrics(collector, true); + rb = collector.CurrentRecordBuilder; + Assert.False(rb.LongKeyPresent(subscribedCounterName), "The counter should not be present now in the source"); + } + + /// <summary> + /// Tests whether exceptions are thrown while trying to access not created + /// metrics in <see cref="DefaultMetricsSourceImpl"/> + /// </summary> + [Fact] + public void TestDefaultMetricsSourceInvalidAccessExceptions() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + // Checks that exception is thrown while trying to get metrics that are not created. + string inValidName = "invalid"; + Assert.Throws<MetricsException>(() => metricsSource.Counters[inValidName]); + Assert.Throws<MetricsException>(() => metricsSource.DoubleGauges[inValidName]); + Assert.Throws<MetricsException>(() => metricsSource.LongGauges[inValidName]); + Assert.Throws<MetricsException>(() => metricsSource.Rates[inValidName]); + } + + /// <summary> + /// Tests whether exceptions are thrown while trying to recreate already + /// existing metrics in <see cref="DefaultMetricsSourceImpl"/> + /// </summary> + [Fact] + public void TestDefaultMetricsSourceRecreationExceptions() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + string counterName = "cname1"; + string longGaugeName = "lname1"; + string doubleGaugeName = "dname1"; + const string rateName = "rname1"; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + metricsSource.Counters.Create(counterName, counterName); + metricsSource.LongGauges.Create(longGaugeName, longGaugeName); + metricsSource.DoubleGauges.Create(doubleGaugeName, doubleGaugeName); + metricsSource.Rates.Create(rateName, rateName); + + Assert.Throws<MetricsException>(() => metricsSource.Counters.Create(counterName, counterName)); + Assert.Throws<MetricsException>( + () => metricsSource.DoubleGauges.Create(doubleGaugeName, doubleGaugeName)); + Assert.Throws<MetricsException>( + () => metricsSource.LongGauges.Create(longGaugeName, longGaugeName)); + Assert.Throws<MetricsException>(() => metricsSource.Rates.Create(rateName, rateName)); + } + + /// <summary> + /// Tests whether metrics are properly deleted from <see cref="DefaultMetricsSourceImpl"/> + /// </summary> + [Fact] + public void TestDefaultMetricsSourceMetricDeletion() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + string counterName = "cname1"; + string longGaugeName = "lname1"; + string doubleGaugeName = "dname1"; + const string rateName = "rname1"; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + metricsSource.Counters.Create(counterName, counterName); + metricsSource.LongGauges.Create(longGaugeName, longGaugeName); + metricsSource.DoubleGauges.Create(doubleGaugeName, doubleGaugeName); + metricsSource.Rates.Create(rateName, rateName); + + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + + metricsSource.Counters.Delete(counterName); + Assert.Throws<MetricsException>(() => metricsSource.Counters[counterName]); + metricsSource.GetMetrics(collector, true); + var rb = collector.CurrentRecordBuilder; + Assert.False(rb.LongKeyPresent(counterName), "Counter was removed, so it should not be present"); + } + + /// <summary> + /// Verifies that record builder does not get old stats if the flag is set to false. + /// </summary> + [Fact] + public void TestDefaultMetricsSourceGetMetricsFlag() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + string[] counterNames = { "cname1", "cname2" }; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + + // Create Counters + foreach (var name in counterNames) + { + metricsSource.Counters.Create(name, name); + } + + metricsSource.GetMetrics(collector, true); + + // Do not increment second counter. + metricsSource.Counters[counterNames[0]].Increment(); + + // Verifies that record builder does not get old stats if the flag is set to false. + // Only first counter should be present. + metricsSource.GetMetrics(collector, false); + var rb = collector.CurrentRecordBuilder; + Assert.True(rb.LongKeyPresent(counterNames[0]), "Counter was updated, so it should be present"); + Assert.False(rb.LongKeyPresent(counterNames[1]), "Counter was not updated, so it should not be present"); + } + + /// <summary> + /// Tests inserting counters, gauges, rates in one go to <see cref="DefaultMetricsSourceImpl"/> + /// to make sure there are no across container bugs. + /// </summary> + [Fact] + public void TestDefaultMetricsSourceHetergeneousFunctionalities() + { + const string evalId = "evalId"; + const string taskId = "taskId"; + const string sourceContext = "test"; + const string recordName = "testrecord"; + string[] counterNames = { "cname1", "cname2" }; + string[] longGaugeNames = { "lname1", "lname2" }; + string[] doubleGaugeNames = { "dname1", "dname2" }; + const string rateName = "rname1"; + double[] samples = { 2, 3 }; + string[] tagNames = { "tname1", "tname2" }; + string[] tagValues = { "tvalue1", "tValue2" }; + const long counterIncr = 2; + const long longGaugeIncr = 3; + const double doubleGaugeDecr = 1.2; + const string subscribedCounterName = "subscribedcounter"; + const long subscribedCounterValue = 1001; + + DefaultMetricsSourceImpl metricsSource = TangFactory.GetTang().NewInjector( + GenerateMetricsSourceConfiguration(evalId, taskId, sourceContext, recordName)) + .GetInstance<DefaultMetricsSourceImpl>(); + + IMetricsFactory factory = TangFactory.GetTang().NewInjector().GetInstance<IMetricsFactory>(); + + MetricTestUtils.MetricsCollectorTestImpl collector = new MetricTestUtils.MetricsCollectorTestImpl(); + + // Create Counters + foreach (var name in counterNames) + { + metricsSource.Counters.Create(name, name); + } + + // Create long gauge + foreach (var name in longGaugeNames) + { + metricsSource.LongGauges.Create(name, name); + } + + // Create double gauge + foreach (var name in doubleGaugeNames) + { + metricsSource.DoubleGauges.Create(name, name); + } + + // Create rate. + metricsSource.Rates.Create(rateName, rateName); + + // Update counters. + int counter = 1; + foreach (var name in counterNames) + { + metricsSource.Counters[name].Increment(counter * counterIncr); + counter++; + } + + // Update long gauge + counter = 1; + foreach (var name in longGaugeNames) + { + metricsSource.LongGauges[name].Increment(counter * longGaugeIncr); + counter++; + } + + // Update double gauge + counter = 1; + foreach (var name in doubleGaugeNames) + { + metricsSource.DoubleGauges[name].Decrement(counter * doubleGaugeDecr); + counter++; + } + + // Update rate + foreach (var sample in samples) + { + metricsSource.Rates[rateName].Sample(sample); + } + + // Create tags + for (int i = 0; i < tagNames.Length; i++) + { + metricsSource.AddTag(tagNames[i], tagNames[i], tagValues[i]); + } + + var extraCounter = factory.CreateCounter(subscribedCounterName, + subscribedCounterName, + subscribedCounterValue); + extraCounter.Subscribe(metricsSource); + + metricsSource.GetMetrics(collector, true); + var rb = collector.CurrentRecordBuilder; + + // Validate counters + counter = 1; + foreach (var name in counterNames) + { + rb.Validate(name, counter * counterIncr); + counter++; + } + rb.Validate(subscribedCounterName, subscribedCounterValue); + + // Validate long gauges + counter = 1; + foreach (var name in longGaugeNames) + { + rb.Validate(name, counter * longGaugeIncr); + counter++; + } + + // Validate double gauges + counter = 1; + foreach (var name in doubleGaugeNames) + { + rb.Validate(name, -counter * doubleGaugeDecr, 1e-10); + counter++; + } + + // Validate tags + for (int i = 0; i < tagNames.Length; i++) + { + rb.Validate(tagNames[i], tagValues[i]); + } + + // Validate rate + rb.Validate(rateName + "-Num", samples.Length); + rb.Validate(rateName + "-RunningAvg", samples.Sum() / samples.Length, 1e-10); + } + + private static IConfiguration GenerateMetricsSourceConfiguration(string evalId, string taskId, string sourceContext, string recordName) + { + return + DefaultMetricsSourceConfiguration.ConfigurationModule.Set(DefaultMetricsSourceConfiguration.EvaluatorId, + evalId) + .Set(DefaultMetricsSourceConfiguration.TaskOrContextId, taskId) + .Set(DefaultMetricsSourceConfiguration.RecordId, recordName) + .Set(DefaultMetricsSourceConfiguration.SourceContext, sourceContext) + .Build(); + } + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common.Tests/metrics/ImmutableMetricTest.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/metrics/ImmutableMetricTest.cs b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/ImmutableMetricTest.cs new file mode 100644 index 0000000..67ed5b0 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/ImmutableMetricTest.cs @@ -0,0 +1,189 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using Org.Apache.REEF.Common.Metrics.Api; +using Xunit; + +namespace Org.Apache.REEF.Common.Tests.Metrics +{ + /// <summary> + /// Tests various functionalities of <see cref="ImmutableMetricsImpl"/> + /// </summary> + public sealed class ImmutableMetricTest + { + /// <summary> + /// Tests properties for numeric value in <see cref="ImmutableMetricsImpl"/> + /// </summary> + [Fact] + public void TestNumericImmutableMetricProperties() + { + const double dValue = 5.0; + const string name = "testname"; + const string desc = "testdesc"; + IMetricsInfo info = new MetricsInfoImpl(name, desc); + + ImmutableMetricsImpl metric = new ImmutableMetricsImpl(info, + dValue, + MetricType.Counter, + (metricsVisitor) => { }); + Assert.Equal(metric.Info.Name, name); + Assert.Equal(metric.Info.Description, desc); + Assert.False(metric.LongValue != null); + Assert.Equal(metric.NumericValue, dValue); + Assert.Equal(metric.TypeOfMetric, MetricType.Counter); + } + + /// <summary> + /// Tests properties for long value in <see cref="ImmutableMetricsImpl"/> + /// </summary> + [Fact] + public void TestLongImmutableMetricProperties() + { + const long lValue = 6; + const string name = "testname"; + const string desc = "testdesc"; + IMetricsInfo info = new MetricsInfoImpl(name, desc); + + var metric = new ImmutableMetricsImpl(info, lValue, MetricType.Counter, (metricsVisitor) => { }); + Assert.Equal(metric.Info.Name, name); + Assert.Equal(metric.Info.Description, desc); + Assert.False(metric.NumericValue != null); + Assert.Equal(metric.LongValue, lValue); + Assert.Equal(metric.TypeOfMetric, MetricType.Counter); + } + + /// <summary> + /// Tests Equality function for numeric value in <see cref="ImmutableMetricsImpl"/> + /// </summary> + [Fact] + public void TestNumericImmutableMetricEqualityFunction() + { + const double dValue = 5.0; + const long lValue = 6; + const string name = "testname"; + const string desc = "testdesc"; + IMetricsInfo info = new MetricsInfoImpl(name, desc); + + ImmutableMetricsImpl metric = new ImmutableMetricsImpl(info, + dValue, + MetricType.Counter, + (metricsVisitor) => { }); + + ImmutableMetricsImpl otherMetric = new ImmutableMetricsImpl(info, + dValue, + MetricType.Counter, + (metricsVisitor) => { }); + Assert.True(metric.Equals(otherMetric)); + otherMetric = new ImmutableMetricsImpl(info, lValue, MetricType.Counter, (metricsVisitor) => { }); + Assert.False(metric.Equals(otherMetric)); + otherMetric = new ImmutableMetricsImpl(new MetricsInfoImpl("wrongname", desc), + dValue, + MetricType.Counter, + (metricsVisitor) => { }); + Assert.False(metric.Equals(otherMetric)); + otherMetric = new ImmutableMetricsImpl(new MetricsInfoImpl(name, "wrongdesc"), + dValue, + MetricType.Counter, + (metricsVisitor) => { }); + Assert.False(metric.Equals(otherMetric)); + otherMetric = new ImmutableMetricsImpl(info, dValue, MetricType.Gauge, (metricsVisitor) => { }); + Assert.False(metric.Equals(otherMetric)); + } + + /// <summary> + /// Tests Equality function for long value in <see cref="ImmutableMetricsImpl"/> + /// </summary> + [Fact] + public void TestLongImmutableMetricEqualityFunction() + { + const double dValue = 5.0; + const long lValue = 6; + const string name = "testname"; + const string desc = "testdesc"; + IMetricsInfo info = new MetricsInfoImpl(name, desc); + + ImmutableMetricsImpl metric = new ImmutableMetricsImpl(info, + lValue, + MetricType.Counter, + (metricsVisitor) => { }); + + var otherMetric = new ImmutableMetricsImpl(info, lValue, MetricType.Counter, (metricsVisitor) => { }); + otherMetric = new ImmutableMetricsImpl(info, dValue, MetricType.Counter, (metricsVisitor) => { }); + Assert.False(metric.Equals(otherMetric)); + + otherMetric = new ImmutableMetricsImpl(new MetricsInfoImpl("wrongname", desc), + lValue, + MetricType.Counter, + (metricsVisitor) => { }); + Assert.False(metric.Equals(otherMetric)); + + otherMetric = new ImmutableMetricsImpl(new MetricsInfoImpl(name, "wrongdesc"), + lValue, + MetricType.Counter, + (metricsVisitor) => { }); + Assert.False(metric.Equals(otherMetric)); + + otherMetric = new ImmutableMetricsImpl(info, lValue, MetricType.Gauge, (metricsVisitor) => { }); + Assert.False(metric.Equals(otherMetric)); + } + + /// <summary> + /// Tests ToString function for numeric value in <see cref="ImmutableMetricsImpl"/> + /// </summary> + [Fact] + public void TestNumericImmutableMetricToStringFunction() + { + const double dValue = 5.0; + const string name = "testname"; + const string desc = "testdesc"; + IMetricsInfo info = new MetricsInfoImpl(name, desc); + string expectedDoubleString = string.Format("Metric Type: {0}, Metric Information: {1}, Metric Value: {2}", + MetricType.Counter, + info, + dValue); + + ImmutableMetricsImpl metric = new ImmutableMetricsImpl(info, + dValue, + MetricType.Counter, + (metricsVisitor) => { }); + Assert.Equal(metric.ToString(), expectedDoubleString); + } + + /// <summary> + /// Tests ToString function for long value in <see cref="ImmutableMetricsImpl"/> + /// </summary> + [Fact] + public void TestLongImmutableMetricToStringFunction() + { + const long lValue = 6; + const string name = "testname"; + const string desc = "testdesc"; + IMetricsInfo info = new MetricsInfoImpl(name, desc); + + string expectedLongString = string.Format("Metric Type: {0}, Metric Information: {1}, Metric Value: {2}", + MetricType.Counter, + info, + lValue); + + ImmutableMetricsImpl metric = new ImmutableMetricsImpl(info, + lValue, + MetricType.Counter, + (metricsVisitor) => { }); + Assert.Equal(metric.ToString(), expectedLongString); + } + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common.Tests/metrics/MetricTestUtils.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/metrics/MetricTestUtils.cs b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/MetricTestUtils.cs new file mode 100644 index 0000000..357e8a5 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/MetricTestUtils.cs @@ -0,0 +1,179 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using System; +using System.Collections.Generic; +using Org.Apache.REEF.Common.Metrics.Api; +using Xunit; + +namespace Org.Apache.REEF.Common.Tests.Metrics +{ + internal static class MetricTestUtils + { + /// <summary> + /// Implementation of <see cref="IMetricsRecordBuilder"/> to test Snapshot functions of + /// different Mutable metrics. + /// </summary> + internal sealed class RecordBuilderForTests : IMetricsRecordBuilder + { + private readonly Dictionary<string, long> _longMetricVals = new Dictionary<string, long>(); + private readonly Dictionary<string, double> _doubleMetricVals = new Dictionary<string, double>(); + private readonly Dictionary<string, string> _tagVals = new Dictionary<string, string>(); + + public RecordBuilderForTests() + { + } + + public RecordBuilderForTests(string name) + { + Name = name; + } + + public string Name { get; private set; } + + public string Context { get; private set; } + + public IMetricsRecordBuilder AddTag(string name, string value) + { + _tagVals[name] = value; + return this; + } + + public IMetricsRecordBuilder AddTag(IMetricsInfo info, string value) + { + _tagVals[info.Name] = value; + return this; + } + + public IMetricsRecordBuilder Add(MetricsTag tag) + { + _tagVals[tag.Name] = tag.Value; + return this; + } + + public IMetricsRecordBuilder Add(IImmutableMetric metric) + { + throw new NotImplementedException(); + } + + public IMetricsRecordBuilder SetContext(string value) + { + Context = value; + return this; + } + + public IMetricsRecordBuilder AddCounter(IMetricsInfo info, long value) + { + _longMetricVals[info.Name] = value; + return this; + } + + public IMetricsRecordBuilder AddGauge(IMetricsInfo info, double value) + { + _doubleMetricVals[info.Name] = value; + return this; + } + + public IMetricsRecordBuilder AddGauge(IMetricsInfo info, long value) + { + _longMetricVals[info.Name] = value; + return this; + } + + public IMetricsCollector ParentCollector() + { + throw new NotImplementedException(); + } + + public IMetricsCollector EndRecord() + { + throw new NotImplementedException(); + } + + public void Validate(string name, long expected) + { + if (!_longMetricVals.ContainsKey(name)) + { + Assert.True(false, "Metric name not present"); + } + Assert.Equal(expected, _longMetricVals[name]); + } + + public void Validate(string name, double expected, double delta) + { + if (!_doubleMetricVals.ContainsKey(name)) + { + Assert.True(false, "Metric name not present"); + } + Assert.True(Math.Abs(expected - _doubleMetricVals[name]) < delta); + } + + public void Validate(string tagName, string expectedTagVal) + { + if (!_tagVals.ContainsKey(tagName)) + { + Assert.True(false, "Tag name not present"); + } + Assert.Equal(expectedTagVal, _tagVals[tagName]); + } + + public bool LongKeyPresent(string name) + { + return _longMetricVals.ContainsKey(name); + } + + public bool DoubleKeyPresent(string name) + { + return _doubleMetricVals.ContainsKey(name); + } + + public bool MetricsEmpty() + { + return _doubleMetricVals.Count == 0 && _longMetricVals.Count == 0; + } + + public void Reset() + { + _longMetricVals.Clear(); + _doubleMetricVals.Clear(); + _tagVals.Clear(); + } + } + + /// <summary> + /// <see cref="IMetricsCollector"/> implementation for test purposes. + /// </summary> + internal sealed class MetricsCollectorTestImpl : IMetricsCollector + { + public RecordBuilderForTests CurrentRecordBuilder + { + get; + private set; + } + public IMetricsRecordBuilder CreateRecord(string name) + { + CurrentRecordBuilder = new RecordBuilderForTests(name); + return CurrentRecordBuilder; + } + + public IMetricsRecordBuilder CreateRecord(IMetricsInfo info) + { + throw new System.NotImplementedException(); + } + } + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common.Tests/metrics/MutableMetricTest.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/metrics/MutableMetricTest.cs b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/MutableMetricTest.cs new file mode 100644 index 0000000..5a74aa3 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/MutableMetricTest.cs @@ -0,0 +1,213 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using System; +using System.Linq; +using Org.Apache.REEF.Common.Metrics.Api; +using Org.Apache.REEF.Common.Metrics.MutableMetricsLayer; +using Org.Apache.REEF.Tang.Implementations.Tang; +using Xunit; + +namespace Org.Apache.REEF.Common.Tests.Metrics +{ + /// <summary> + /// Tests various classes in REEF.Common.metrics.MutableMetricsLib. + /// </summary> + public sealed class TestMutableMetrics + { + /// <summary> + /// Tests various functions of <see cref="MutableCounter"/> + /// </summary> + [Fact] + public void TestCounterMetrics() + { + const string name = "countertest"; + const string desc = "countertestdesc"; + IMetricsFactory factory = TangFactory.GetTang().NewInjector().GetInstance<IMetricsFactory>(); + + var longCounter = factory.CreateCounter(name, desc, 5); + Assert.Equal(name, longCounter.Info.Name); + Assert.Equal(desc, longCounter.Info.Description); + + MetricTestUtils.RecordBuilderForTests recordBuilder = new MetricTestUtils.RecordBuilderForTests(); + SnapshotRequest request = new SnapshotRequest(recordBuilder, false); + + longCounter.OnNext(request); + recordBuilder.Validate(name, 5); + recordBuilder.Reset(); + + longCounter.Increment(); + longCounter.OnNext(request); + recordBuilder.Validate(name, 6); + recordBuilder.Reset(); + + longCounter.OnNext(request); + Assert.False(recordBuilder.LongKeyPresent(name), "Metric is not supposed to be recorded."); + + request = new SnapshotRequest(recordBuilder, true); + longCounter.OnNext(request); + recordBuilder.Validate(name, 6); + recordBuilder.Reset(); + } + + /// <summary> + /// Tests various functions of <see cref="MutableDoubleGauge"/> and <see cref="MutableLongGauge"/>. + /// </summary> + [Fact] + public void TestGaugeMetrics() + { + const string name = "gaugetest"; + const string desc = "guagetestdesc"; + IMetricsFactory factory = TangFactory.GetTang().NewInjector().GetInstance<IMetricsFactory>(); + + var doubleGauge = factory.CreateDoubleGauge(name, desc, 5); + Assert.Equal(name, doubleGauge.Info.Name); + Assert.Equal(desc, doubleGauge.Info.Description); + + MetricTestUtils.RecordBuilderForTests recordBuilder = new MetricTestUtils.RecordBuilderForTests(); + SnapshotRequest request = new SnapshotRequest(recordBuilder, false); + + doubleGauge.OnNext(request); + recordBuilder.Validate(name, 5.0, 1e-10); + recordBuilder.Reset(); + + doubleGauge.Increment(2.2); + doubleGauge.OnNext(request); + recordBuilder.Validate(name, 7.2, 1e-10); + recordBuilder.Reset(); + + doubleGauge.Decrement(1); + doubleGauge.OnNext(request); + recordBuilder.Validate(name, 6.2, 1e-10); + recordBuilder.Reset(); + + doubleGauge.OnNext(request); + Assert.False(recordBuilder.DoubleKeyPresent(name), "Metric is not supposed to be recorded."); + + request = new SnapshotRequest(recordBuilder, true); + doubleGauge.OnNext(request); + recordBuilder.Validate(name, 6.2, 1e-10); + recordBuilder.Reset(); + + request = new SnapshotRequest(recordBuilder, false); + var longGauge = factory.CreateLongGauge(name, desc, 5); + Assert.Equal(name, longGauge.Info.Name); + Assert.Equal(desc, longGauge.Info.Description); + + longGauge.OnNext(request); + recordBuilder.Validate(name, (long)5); + recordBuilder.Reset(); + + longGauge.Increment(2); + longGauge.OnNext(request); + recordBuilder.Validate(name, (long)7); + recordBuilder.Reset(); + + longGauge.Decrement(1); + longGauge.OnNext(request); + recordBuilder.Validate(name, (long)6); + recordBuilder.Reset(); + + longGauge.OnNext(request); + Assert.False(recordBuilder.LongKeyPresent(name), "Metric is not supposed to be recorded."); + + request = new SnapshotRequest(recordBuilder, true); + longGauge.OnNext(request); + recordBuilder.Validate(name, (long)6); + recordBuilder.Reset(); + } + + /// <summary> + /// Tests various functions of <see cref="MutableStat"/>. + /// </summary> + [Fact] + public void TestStatMetrics() + { + const string name = "stattest"; + const string desc = "stattestdesc"; + const string valueName = "statValName"; + const double delta = 1e-10; + IMetricsFactory factory = TangFactory.GetTang().NewInjector().GetInstance<IMetricsFactory>(); + + double[] array1 = new double[3]; + double[] array2 = new double[3]; + Random randGen = new Random(); + + array1 = array1.Select(x => randGen.NextDouble()).ToArray(); + array2 = array2.Select(x => randGen.NextDouble()).ToArray(); + + var stat = factory.CreateStatMetric(name, desc, valueName); + MetricTestUtils.RecordBuilderForTests recordBuilder = new MetricTestUtils.RecordBuilderForTests(); + var request = new SnapshotRequest(recordBuilder, false); + + foreach (var entry in array1) + { + stat.Sample(entry); + } + + double expectedMean = array1.Sum() / 3; + double expectedStd = Math.Sqrt(array1.Select(x => Math.Pow(x - expectedMean, 2)).Sum() / 2); + + stat.OnNext(request); + recordBuilder.Validate(name + "-Num", (long)3); + recordBuilder.Validate(name + "-RunningAvg", expectedMean, delta); + recordBuilder.Validate(name + "-RunningStdev", expectedStd, delta); + recordBuilder.Validate(name + "-IntervalAvg", expectedMean, delta); + recordBuilder.Validate(name + "-IntervalStdev", expectedStd, delta); + recordBuilder.Validate(name + "-RunningMin", array1.Min(), delta); + recordBuilder.Validate(name + "-IntervalMin", array1.Min(), delta); + recordBuilder.Validate(name + "-RunningMax", array1.Max(), delta); + recordBuilder.Validate(name + "-IntervalMax", array1.Max(), delta); + + recordBuilder.Reset(); + foreach (var entry in array2) + { + stat.Sample(entry); + } + + double expectedIntervalMean = array2.Sum() / 3; + double expectedIntervalStd = Math.Sqrt(array2.Select(x => Math.Pow(x - expectedIntervalMean, 2)).Sum() / 2); + double expectedIntervalMin = array2.Min(); + double expectedIntervalMax = array2.Max(); + double expectedRunningMean = (array1.Sum() + array2.Sum()) / 6; + double expectedRunningStd = + Math.Sqrt((array1.Select(x => Math.Pow(x - expectedRunningMean, 2)).Sum() + + array2.Select(x => Math.Pow(x - expectedRunningMean, 2)).Sum()) / 5); + double expectedRunningMin = Math.Min(array1.Min(), array2.Min()); + double expectedRunningMax = Math.Max(array1.Max(), array2.Max()); + + stat.OnNext(request); + recordBuilder.Validate(name + "-Num", (long)6); + recordBuilder.Validate(name + "-RunningAvg", expectedRunningMean, delta); + recordBuilder.Validate(name + "-RunningStdev", expectedRunningStd, delta); + recordBuilder.Validate(name + "-IntervalAvg", expectedIntervalMean, delta); + recordBuilder.Validate(name + "-IntervalStdev", expectedIntervalStd, delta); + recordBuilder.Validate(name + "-RunningMin", expectedRunningMin, delta); + recordBuilder.Validate(name + "-IntervalMin", expectedIntervalMin, delta); + recordBuilder.Validate(name + "-RunningMax", expectedRunningMax, delta); + recordBuilder.Validate(name + "-IntervalMax", expectedIntervalMax, delta); + + recordBuilder.Reset(); + stat.OnNext(request); + Assert.False(recordBuilder.LongKeyPresent(name + "-Num"), "Metric is not supposed to be recorded."); + + request = new SnapshotRequest(recordBuilder, true); + stat.OnNext(request); + Assert.True(recordBuilder.LongKeyPresent(name + "-Num"), "Metric is supposed to be recorded."); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common.Tests/metrics/SnapshotRequestTest.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/metrics/SnapshotRequestTest.cs b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/SnapshotRequestTest.cs new file mode 100644 index 0000000..05b1aa1 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/SnapshotRequestTest.cs @@ -0,0 +1,100 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using Org.Apache.REEF.Common.Metrics.Api; +using Xunit; + +namespace Org.Apache.REEF.Common.Tests.Metrics +{ + /// <summary> + /// Contains functions to test <see cref="SnapshotRequest"/> clkass. + /// </summary> + public sealed class SnapshotRequestTest + { + /// <summary> + /// Tests <see cref="SnapshotRequest"/>. + /// </summary> + [Fact] + public void TestSnapshotRequest() + { + var request = new SnapshotRequest(new MetricsRecordBuilderTestImpl(), true); + Assert.NotNull(request.Builder); + Assert.Equal(request.FullSnapshot, true); + + request = new SnapshotRequest(new MetricsRecordBuilderTestImpl(), false); + Assert.NotNull(request.Builder); + Assert.Equal(request.FullSnapshot, false); + + request = new SnapshotRequest(new MetricsRecordBuilderTestImpl()); + Assert.NotNull(request.Builder); + Assert.Equal(request.FullSnapshot, false); + } + + private class MetricsRecordBuilderTestImpl : IMetricsRecordBuilder + { + public IMetricsRecordBuilder AddTag(string name, string value) + { + throw new System.NotImplementedException(); + } + + public IMetricsRecordBuilder AddTag(IMetricsInfo info, string value) + { + throw new System.NotImplementedException(); + } + + public IMetricsRecordBuilder Add(MetricsTag tag) + { + throw new System.NotImplementedException(); + } + + public IMetricsRecordBuilder Add(IImmutableMetric metric) + { + throw new System.NotImplementedException(); + } + + public IMetricsRecordBuilder SetContext(string value) + { + throw new System.NotImplementedException(); + } + + public IMetricsRecordBuilder AddCounter(IMetricsInfo info, long value) + { + throw new System.NotImplementedException(); + } + + public IMetricsRecordBuilder AddGauge(IMetricsInfo info, long value) + { + throw new System.NotImplementedException(); + } + + public IMetricsRecordBuilder AddGauge(IMetricsInfo info, double value) + { + throw new System.NotImplementedException(); + } + + public IMetricsCollector ParentCollector() + { + throw new System.NotImplementedException(); + } + + public IMetricsCollector EndRecord() + { + throw new System.NotImplementedException(); + } + } + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common.Tests/metrics/TestMetricsTag.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common.Tests/metrics/TestMetricsTag.cs b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/TestMetricsTag.cs new file mode 100644 index 0000000..fb0908e --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common.Tests/metrics/TestMetricsTag.cs @@ -0,0 +1,82 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using Org.Apache.REEF.Common.Metrics.Api; +using Org.Apache.REEF.Common.Metrics.MutableMetricsLayer; +using Org.Apache.REEF.Tang.Implementations.Tang; +using Xunit; + +namespace Org.Apache.REEF.Common.Tests.Metrics +{ + /// <summary> + /// Contains functions to test <see cref="MetricsTag"/> clkass. + /// </summary> + public sealed class TestMetricsTag + { + /// <summary> + /// Tests <see cref="MetricsInfoImpl"/>. + /// </summary> + [Fact] + public void TestMetricsInfoImpl() + { + const string name = "testname"; + const string desc = "testdesc"; + + MetricsInfoImpl impl = new MetricsInfoImpl(name, desc); + Assert.Equal(name, impl.Name); + Assert.Equal(desc, impl.Description); + } + + /// <summary> + /// Tests different functions of <see cref="MetricsTag"/> + /// </summary> + [Fact] + public void TestMetricsTagClass() + { + const string name = "tagtest"; + const string otherName = "othertagtest"; + const string desc = "tagtestdesc"; + const string otherDesc = "othertagtestdesc"; + const string tagValue = "tagvalue"; + const string otherTagValue = "othertagvalue"; + IMetricsFactory factory = TangFactory.GetTang().NewInjector().GetInstance<IMetricsFactory>(); + + IMetricsInfo info = new MetricsInfoImpl(name, desc); + MetricsTag tag = factory.CreateTag(info, tagValue); + + Assert.Equal(name, tag.Name); + Assert.Equal(desc, tag.Description); + Assert.Equal(tagValue, tag.Value); + + MetricsTag sameTag = factory.CreateTag(info, tagValue); + Assert.True(tag.Equals(sameTag)); + + MetricsTag otherTag = factory.CreateTag(info, otherTagValue); + Assert.False(tag.Equals(otherTag)); + + otherTag = factory.CreateTag(new MetricsInfoImpl(otherName, desc), tagValue); + Assert.False(tag.Equals(otherTag)); + + otherTag = factory.CreateTag(new MetricsInfoImpl(name, otherDesc), otherTagValue); + Assert.False(tag.Equals(otherTag)); + + string expectedToString = "Tag Information: " + "Name: " + info.Name + ", Description: " + info.Description + + ", Tag Value: " + tagValue; + Assert.Equal(expectedToString, tag.ToString()); + } + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj b/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj index cc14799..492ab5c 100644 --- a/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj +++ b/lang/cs/Org.Apache.REEF.Common/Org.Apache.REEF.Common.csproj @@ -119,6 +119,42 @@ under the License. <Compile Include="Jar\ResourceHelper.cs" /> <Compile Include="ITaskSubmittable.cs" /> <Compile Include="Client\Parameters\DriverConfigurationProviders.cs" /> + <Compile Include="Metrics\Api\ImmutableMetricImpl.cs" /> + <Compile Include="Metrics\Api\IImmutableMetric.cs" /> + <Compile Include="Metrics\Api\IMetricsCollector.cs" /> + <Compile Include="Metrics\Api\IMetricsFilter.cs" /> + <Compile Include="Metrics\Api\IMetricsInfo.cs" /> + <Compile Include="Metrics\Api\IMetricsRecord.cs" /> + <Compile Include="Metrics\Api\IMetricsRecordBuilder.cs" /> + <Compile Include="Metrics\Api\IMetricsSource.cs" /> + <Compile Include="Metrics\Api\IMetricsSystem.cs" /> + <Compile Include="Metrics\Api\IMetricsVisitor.cs" /> + <Compile Include="Metrics\Api\MetricsInfoImpl.cs" /> + <Compile Include="Metrics\Api\MetricsException.cs" /> + <Compile Include="Metrics\Api\MetricsTag.cs" /> + <Compile Include="Metrics\Api\MetricType.cs" /> + <Compile Include="Metrics\Api\SnapshotRequest.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\DefaultMetricsFactoryImpl.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\DefaultMetricsSourceConfiguration.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\DefaultMetricsSourceImpl.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\ICounter.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\IDoubleGauge.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\IExtendedMutableMetric.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\ILongGauge.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\IMetricsFactory.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\IMutableMetric.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\IRate.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\IStat.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\MutableCounter.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\MutableDoubleGauge.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\MutableLongGauge.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\MutableMetricBase.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\IMetricContainer.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\MutableMetricContainer.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\MutableRate.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\MutableStat.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\DefaultMetricsSourceParameters.cs" /> + <Compile Include="Metrics\MutableMetricsLayer\StatsHelperClass.cs" /> <Compile Include="Poison\PoisonedEventHandler.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Protobuf\ReefProtocol\ClientRuntime.pb.cs"> http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common/metrics/Api/IImmutableMetric.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/metrics/Api/IImmutableMetric.cs b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IImmutableMetric.cs new file mode 100644 index 0000000..0241ee5 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IImmutableMetric.cs @@ -0,0 +1,90 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using Org.Apache.REEF.Utilities.Attributes; + +namespace Org.Apache.REEF.Common.Metrics.Api +{ + /// <summary> + /// Immutable metric interface. All the metrics put in the <see cref="IMetricsRecord"/> + /// by <see cref="IMetricsSource"/> are kept as <see cref="IImmutableMetric"/>. + /// </summary> + [Unstable("0.16", "Contract may change.")] + public interface IImmutableMetric + { + /// <summary> + /// Long Value of the metric. Immutable metrics of + /// type integrals, byte, bool are all type casted to long before storing + /// them as immutable metrics. For a given instance of this interface, either this property + /// or <see cref="NumericValue"/> returns a valid value. + /// </summary> + long? LongValue { get; } + + /// <summary> + /// Numeric Value of the metric. Immutable metrics of + /// non integral numerical types are all type casted to double before storing + /// them as immutable metrics. For a given instance of this interface, either this property + /// or <see cref="LongValue"/> returns a valid value. + /// </summary> + double? NumericValue { get; } + + /// <summary> + /// Meta-data of the metric. + /// </summary> + IMetricsInfo Info { get; } + + /// <summary> + /// String representation of a metric for display. + /// </summary> + /// <returns>The string representation of the metric.</returns> + string ToString(); + + /// <summary> + /// Checks whether two metrics are equal. Relies on Equals + /// function of <see cref="IMetricsInfo"/> implementations. + /// </summary> + /// <param name="obj">Object to compare against.</param> + /// <returns>True if both represent the same metric.</returns> + bool Equals(object obj); + + /// <summary> + /// Return hash code of the metric object. Simply uses the hash of ToString() method. + /// </summary> + /// <returns>Hash code.</returns> + int GetHashCode(); + + /// <summary> + /// Type of metric - counter or gauge. Filled in by exact + /// metric type. It is assumed that converting complex + /// metrics like Stats and Rates in to immutable ones require + /// their decomposition in to multiple instances of <see cref="IImmutableMetric"/>, + /// for example: number of samples will be of type counter, mean, variance etc. + /// will be of type gauge, etc. + /// </summary> + MetricType TypeOfMetric { get; } + + /// <summary> + /// Accepts a visitor interface. This function is used to get exact + /// metric specfic information (for example, if visitor implementation + /// wants to determine whether it is a counter or gauge, etc., by making + /// the exact implementation of <see cref="IImmutableMetric"/> call the + /// appropriate function in <see cref="IMetricsVisitor"/>. + /// </summary> + /// <param name="visitor">Metrics visitor interface.</param> + void Visit(IMetricsVisitor visitor); + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsCollector.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsCollector.cs b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsCollector.cs new file mode 100644 index 0000000..c9b51c5 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsCollector.cs @@ -0,0 +1,47 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using Org.Apache.REEF.Utilities.Attributes; + +namespace Org.Apache.REEF.Common.Metrics.Api +{ + /// <summary> + /// Interface for collecting the metrics. This interface is passed to + /// the <see cref="IMetricsSource"/> to add and fill in the records. + /// </summary> + [Unstable("0.16", "Contract may change.")] + public interface IMetricsCollector + { + /// <summary> + /// Creates a metric record by name. The exact semantics of what to do if another + /// record of same name exists - (create another with same name, return existing one, + /// or throw exception) is left to the implementation. + /// </summary> + /// <param name="name">Name of the record.</param> + /// <returns>Record builder for the record.</returns> + IMetricsRecordBuilder CreateRecord(string name); + + /// <summary> + /// Creates a metric record by meta-data info. The exact semantics of what to do if another + /// record of same name exists - (create another with same name, return existing one, + /// or throw exception) is left to the implementation. + /// </summary> + /// <param name="info">Meta-data info of the record.</param> + /// <returns>Record builder for the record.</returns> + IMetricsRecordBuilder CreateRecord(IMetricsInfo info); + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsFilter.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsFilter.cs b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsFilter.cs new file mode 100644 index 0000000..3ef811b --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsFilter.cs @@ -0,0 +1,49 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using System; +using Org.Apache.REEF.Utilities.Attributes; + +namespace Org.Apache.REEF.Common.Metrics.Api +{ + /// <summary> + /// Metrics filter interface used to filter metrics at different levels - + /// source and sink names, record, individual tag, individual metric. + /// </summary> + [Unstable("0.16", "Contract may change.")] + public interface IMetricsFilter + { + /// <summary> + /// Returns a function indicating whether to accept the name string + /// (can be from metric, source, sink, record etc.). Returns True if accepted, + /// false otherwise. + /// </summary> + Func<string, bool> AcceptsName { get; } + + /// <summary> + /// Returns a function indicating whether to accept the tag. Returns True if accepted, + /// false otherwise. + /// </summary> + Func<MetricsTag, bool> AcceptsTag { get; } + + /// <summary> + /// Returns a function indicating whether to accept the record. Returns True if accepted, + /// false otherwise. + /// </summary> + Func<IMetricsRecord, bool> AcceptsRecord { get; } + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsInfo.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsInfo.cs b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsInfo.cs new file mode 100644 index 0000000..2389dc3 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsInfo.cs @@ -0,0 +1,38 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using Org.Apache.REEF.Utilities.Attributes; + +namespace Org.Apache.REEF.Common.Metrics.Api +{ + /// <summary> + /// Interface to provide immutable meta info. for metrics + /// </summary> + [Unstable("0.16", "Contract may change.")] + public interface IMetricsInfo + { + /// <summary> + /// The name of the metric or tag. + /// </summary> + string Name { get; } + + /// <summary> + /// Description of the metric or tag. + /// </summary> + string Description { get; } + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsRecord.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsRecord.cs b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsRecord.cs new file mode 100644 index 0000000..71cb138 --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsRecord.cs @@ -0,0 +1,63 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using System.Collections.Generic; +using Org.Apache.REEF.Utilities.Attributes; + +namespace Org.Apache.REEF.Common.Metrics.Api +{ + /// <summary> + /// Immutable record of the metric. Represents snapshot of set of metrics + /// with a timestamp. + /// </summary> + [Unstable("0.16", "Contract may change.")] + public interface IMetricsRecord + { + /// <summary> + /// Gets the timestamp of the metric in seconds. + /// Exact semantics is left to the default implementation. + /// One option is to create the seconds-since-the-UNIX-epoch mentioned at this page. + /// https://blogs.msdn.microsoft.com/brada/2004/03/20/seconds-since-the-unix-epoch-in-c/ + /// </summary> + long Timestamp { get; } + + /// <summary> + /// Name of the record. + /// </summary> + string Name { get; } + + /// <summary> + /// Description of the record. + /// </summary> + string Description { get; } + + /// <summary> + /// Context name of the record. + /// </summary> + string Context { get; } + + /// <summary> + /// Get the tags of the record. + /// </summary> + IEnumerable<MetricsTag> Tags { get; } + + /// <summary> + /// Get the metrics of the record. + /// </summary> + IEnumerable<IImmutableMetric> Metrics { get; } + } +} http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsRecordBuilder.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsRecordBuilder.cs b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsRecordBuilder.cs new file mode 100644 index 0000000..36f6d0e --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsRecordBuilder.cs @@ -0,0 +1,104 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using Org.Apache.REEF.Utilities.Attributes; + +namespace Org.Apache.REEF.Common.Metrics.Api +{ + /// <summary> + /// Builder used to build a metrics record. Used by <see cref="IMetricsCollector"/> to + /// add a record, typically in <see cref="IMetricsSource"/>. Note that this interface will + /// be used to take Mutable metrics and convert them to immutable ones (<see cref="IImmutableMetric"/> + /// so that they can be consumed possibly at some later time also. + /// </summary> + [Unstable("0.16", "Contract may change.")] + public interface IMetricsRecordBuilder + { + /// <summary> + /// Adds metrics tag (<see cref="MetricsTag"/>) to the record + /// </summary> + /// <param name="name">Name of the tag.</param> + /// <param name="value">Value of the tag.</param> + /// <returns>Self to add more metrics/tags.</returns> + IMetricsRecordBuilder AddTag(string name, string value); + + /// <summary> + /// Adds metrics tag (<see cref="MetricsTag"/>) to the record + /// </summary> + /// <param name="info">Meta data for the tag.</param> + /// <param name="value">Value of the tag.</param> + /// <returns>Self to add more metrics/tags.</returns> + IMetricsRecordBuilder AddTag(IMetricsInfo info, string value); + + /// <summary> + /// Adds an immutable metrics tag(<see cref="MetricsTag"/>) object. Avoids making a copy. + /// </summary> + /// <param name="tag">A pre-made tags object.</param> + /// <returns>Self to add more metrics/tags.</returns> + IMetricsRecordBuilder Add(MetricsTag tag); + + /// <summary> + /// Adds an immutable metric to the record. Saves making a new metric object. + /// </summary> + /// <param name="metric">A pre-made metric object.</param> + /// <returns>Self to add more metrics/tags.</returns> + IMetricsRecordBuilder Add(IImmutableMetric metric); + + /// <summary> + /// Sets the special context tag of the record. + /// </summary> + /// <param name="value">Value of the context</param> + /// <returns>Self to add more metrics/tags.</returns> + IMetricsRecordBuilder SetContext(string value); + + /// <summary> + /// Adds counter metric + /// </summary> + /// <param name="info">Meta data of the metric</param> + /// <param name="value">Value of the metric</param> + /// <returns></returns> + IMetricsRecordBuilder AddCounter(IMetricsInfo info, long value); + + /// <summary> + /// Adds long gauge metric + /// </summary> + /// <param name="info">Meta data of the metric</param> + /// <param name="value">Value of the metric</param> + /// <returns></returns> + IMetricsRecordBuilder AddGauge(IMetricsInfo info, long value); + + /// <summary> + /// Adds double gauge metric + /// </summary> + /// <param name="info">Meta data of the metric</param> + /// <param name="value">Value of the metric</param> + /// <returns></returns> + IMetricsRecordBuilder AddGauge(IMetricsInfo info, double value); + + /// <summary> + /// Returns the parent <see cref="IMetricsCollector"/> object. + /// </summary> + /// <returns>Parent <see cref="IMetricsCollector"/> object</returns> + IMetricsCollector ParentCollector(); + + /// <summary> + /// Finalizes the record and enables adding multiple records in one line. + /// </summary> + /// <returns>Parent <see cref="IMetricsCollector"/> object</returns> + IMetricsCollector EndRecord(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/reef/blob/0b8da4cf/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsSource.cs ---------------------------------------------------------------------- diff --git a/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsSource.cs b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsSource.cs new file mode 100644 index 0000000..a705b7e --- /dev/null +++ b/lang/cs/Org.Apache.REEF.Common/metrics/Api/IMetricsSource.cs @@ -0,0 +1,42 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +using System; +using Org.Apache.REEF.Common.Metrics.MutableMetricsLayer; +using Org.Apache.REEF.Tang.Annotations; +using Org.Apache.REEF.Utilities.Attributes; + +namespace Org.Apache.REEF.Common.Metrics.Api +{ + /// <summary> + /// Metrics source interface. The current snapshot of metrics is taken via this + /// interface which are then later on pushed to sink. Derived from <see cref="IObservable{IMetricsRecordBuilder}"/>. + /// <see cref="GetMetrics"/> will call OnNext() of different mutable metrics that implement + /// <see cref="IObserver{IMetricsRecordBuilder}"/> + /// </summary> + [DefaultImplementation(typeof(DefaultMetricsSourceImpl))] + [Unstable("0.16", "Contract may change.")] + public interface IMetricsSource : IObservable<SnapshotRequest> + { + /// <summary> + /// Gets metrics from the source. + /// </summary> + /// <param name="collector">Collector that stores the resulting metrics snapshot as records.</param> + /// <param name="all">If true, gets metric values even if they are unchanged.</param> + void GetMetrics(IMetricsCollector collector, bool all); + } +} \ No newline at end of file
