You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/07/10 12:00:48 UTC

[32/41] ignite git commit: IGNITE-5491 .NET: PersistentStoreMetrics

IGNITE-5491 .NET: PersistentStoreMetrics


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b085fa0d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b085fa0d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b085fa0d

Branch: refs/heads/ignite-5578-1
Commit: b085fa0db67f8cda01e6927715241b10ac43c0f2
Parents: 9790a46
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Mon Jul 10 12:24:54 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Mon Jul 10 12:24:54 2017 +0300

----------------------------------------------------------------------
 .../platform/cluster/PlatformClusterGroup.java  |  39 ++++-
 .../utils/PlatformConfigurationUtils.java       |   8 +-
 .../Cache/PersistentStoreTest.cs                |   9 +-
 .../IgniteConfigurationSerializerTest.cs        |  11 +-
 .../IgniteConfigurationTest.cs                  |  11 +-
 .../Apache.Ignite.Core.csproj                   |   2 +
 .../dotnet/Apache.Ignite.Core/IIgnite.cs        |   9 ++
 .../IgniteConfigurationSection.xsd              |  15 ++
 .../Impl/Cluster/ClusterGroupImpl.cs            |  14 ++
 .../dotnet/Apache.Ignite.Core/Impl/Ignite.cs    |   7 +
 .../PersistentStore/PersistentStoreMetrics.cs   |  88 +++++++++++
 .../PersistentStore/IPersistentStoreMetrics.cs  |  87 +++++++++++
 .../PersistentStoreConfiguration.cs             | 156 ++++++++++++-------
 13 files changed, 392 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cluster/PlatformClusterGroup.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cluster/PlatformClusterGroup.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cluster/PlatformClusterGroup.java
index 3e3aa3a..f6e3d2e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cluster/PlatformClusterGroup.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/cluster/PlatformClusterGroup.java
@@ -25,6 +25,7 @@ import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteCluster;
 import org.apache.ignite.MemoryMetrics;
+import org.apache.ignite.PersistenceMetrics;
 import org.apache.ignite.binary.BinaryRawWriter;
 import org.apache.ignite.cluster.ClusterMetrics;
 import org.apache.ignite.cluster.ClusterNode;
@@ -122,6 +123,9 @@ public class PlatformClusterGroup extends PlatformAbstractTarget {
     /** */
     private static final int OP_IS_ACTIVE = 29;
 
+    /** */
+    private static final int OP_PERSISTENT_STORE_METRICS = 30;
+
     /** Projection. */
     private final ClusterGroupEx prj;
 
@@ -146,7 +150,7 @@ public class PlatformClusterGroup extends PlatformAbstractTarget {
 
                 break;
 
-            case OP_MEMORY_METRICS:
+            case OP_MEMORY_METRICS: {
                 Collection<MemoryMetrics> metrics = prj.ignite().memoryMetrics();
 
                 writer.writeInt(metrics.size());
@@ -156,6 +160,15 @@ public class PlatformClusterGroup extends PlatformAbstractTarget {
                 }
 
                 break;
+            }
+
+            case OP_PERSISTENT_STORE_METRICS: {
+                PersistenceMetrics metrics = prj.ignite().persistentStoreMetrics();
+
+                writePersistentStoreMetrics(writer, metrics);
+
+                break;
+            }
 
             default:
                 super.processOutStream(type, writer);
@@ -448,4 +461,28 @@ public class PlatformClusterGroup extends PlatformAbstractTarget {
         writer.writeFloat(metrics.getLargeEntriesPagesPercentage());
         writer.writeFloat(metrics.getPagesFillFactor());
     }
+
+    /**
+     * Writes persistent store metrics.
+     *
+     * @param writer Writer.
+     * @param metrics Metrics
+     */
+    private void writePersistentStoreMetrics(BinaryRawWriter writer, PersistenceMetrics metrics) {
+        assert writer != null;
+        assert metrics != null;
+
+        writer.writeFloat(metrics.getWalLoggingRate());
+        writer.writeFloat(metrics.getWalWritingRate());
+        writer.writeInt(metrics.getWalArchiveSegments());
+        writer.writeFloat(metrics.getWalFsyncTimeAverage());
+        writer.writeLong(metrics.getLastCheckpointingDuration());
+        writer.writeLong(metrics.getLastCheckpointLockWaitDuration());
+        writer.writeLong(metrics.getLastCheckpointMarkDuration());
+        writer.writeLong(metrics.getLastCheckpointPagesWriteDuration());
+        writer.writeLong(metrics.getLastCheckpointFsyncDuration());
+        writer.writeLong(metrics.getLastCheckpointTotalPagesNumber());
+        writer.writeLong(metrics.getLastCheckpointDataPagesNumber());
+        writer.writeLong(metrics.getLastCheckpointCopiedOnWritePagesNumber());
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
index 92db41a..d513071 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/utils/PlatformConfigurationUtils.java
@@ -1505,7 +1505,10 @@ public class PlatformConfigurationUtils {
                 .setWalFlushFrequency((int) in.readLong())
                 .setWalFsyncDelay(in.readInt())
                 .setWalRecordIteratorBufferSize(in.readInt())
-                .setAlwaysWriteFullPages(in.readBoolean());
+                .setAlwaysWriteFullPages(in.readBoolean())
+                .setMetricsEnabled(in.readBoolean())
+                .setSubIntervals(in.readInt())
+                .setRateTimeInterval(in.readLong());
     }
 
     /**
@@ -1535,6 +1538,9 @@ public class PlatformConfigurationUtils {
             w.writeInt(cfg.getWalFsyncDelay());
             w.writeInt(cfg.getWalRecordIteratorBufferSize());
             w.writeBoolean(cfg.isAlwaysWriteFullPages());
+            w.writeBoolean(cfg.isMetricsEnabled());
+            w.writeInt(cfg.getSubIntervals());
+            w.writeLong(cfg.getRateTimeInterval());
 
         } else {
             w.writeBoolean(false);

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs
index e9cbce8..3320dd7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/PersistentStoreTest.cs
@@ -58,7 +58,8 @@ namespace Apache.Ignite.Core.Tests.Cache
                 {
                     PersistentStorePath = Path.Combine(_tempDir, "Store"),
                     WalStorePath = Path.Combine(_tempDir, "WalStore"),
-                    WalArchivePath = Path.Combine(_tempDir, "WalArchive")
+                    WalArchivePath = Path.Combine(_tempDir, "WalArchive"),
+                    MetricsEnabled = true
                 }
             };
 
@@ -72,6 +73,12 @@ namespace Apache.Ignite.Core.Tests.Cache
                 var cache = ignite.CreateCache<int, int>(cacheName);
 
                 cache[1] = 1;
+
+                // Check some metrics.
+                var metrics = ignite.GetPersistentStoreMetrics();
+                Assert.Greater(metrics.WalLoggingRate, 0);
+                Assert.Greater(metrics.WalWritingRate, 0);
+                Assert.Greater(metrics.WalFsyncTimeAverage, 0);
             }
 
             // Verify directories.

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
index 3d0bb56..7e0d941 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationSerializerTest.cs
@@ -143,7 +143,7 @@ namespace Apache.Ignite.Core.Tests
                                 </memoryPolicies>
                             </memoryConfiguration>
                             <sqlConnectorConfiguration host='bar' port='10' portRange='11' socketSendBufferSize='12' socketReceiveBufferSize='13' tcpNoDelay='true' maxOpenCursorsPerConnection='14' threadPoolSize='15' />
-                            <persistentStoreConfiguration alwaysWriteFullPages='true' checkpointingFrequency='00:00:1' checkpointingPageBufferSize='2' checkpointingThreads='3' lockWaitTime='00:00:04' persistentStorePath='foo' tlbSize='5' walArchivePath='bar' walFlushFrequency='00:00:06' walFsyncDelayNanos='7' walHistorySize='8' walMode='None' walRecordIteratorBufferSize='9' walSegments='10' walSegmentSize='11' walStorePath='baz' />
+                            <persistentStoreConfiguration alwaysWriteFullPages='true' checkpointingFrequency='00:00:1' checkpointingPageBufferSize='2' checkpointingThreads='3' lockWaitTime='00:00:04' persistentStorePath='foo' tlbSize='5' walArchivePath='bar' walFlushFrequency='00:00:06' walFsyncDelayNanos='7' walHistorySize='8' walMode='None' walRecordIteratorBufferSize='9' walSegments='10' walSegmentSize='11' walStorePath='baz' metricsEnabled='true' rateTimeInterval='0:0:6' subIntervals='3' />
                         </igniteConfig>";
 
             var cfg = IgniteConfiguration.FromXml(xml);
@@ -315,7 +315,9 @@ namespace Apache.Ignite.Core.Tests
             Assert.AreEqual(10, pers.WalSegments);
             Assert.AreEqual(11, pers.WalSegmentSize);
             Assert.AreEqual("baz", pers.WalStorePath);
-
+            Assert.IsTrue(pers.MetricsEnabled);
+            Assert.AreEqual(3, pers.SubIntervals);
+            Assert.AreEqual(TimeSpan.FromSeconds(6), pers.RateTimeInterval);
         }
 
         /// <summary>
@@ -907,7 +909,10 @@ namespace Apache.Ignite.Core.Tests
                     WalRecordIteratorBufferSize = 32 * 1024 * 1024,
                     WalSegments = 6,
                     WalSegmentSize = 5 * 1024 * 1024,
-                    WalStorePath = Path.GetTempPath()
+                    WalStorePath = Path.GetTempPath(),
+                    SubIntervals = 25,
+                    MetricsEnabled = true,
+                    RateTimeInterval = TimeSpan.FromDays(1)
                 },
                 IsActiveOnStart = false
             };

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
index 5e5cb1c..4902118 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteConfigurationTest.cs
@@ -266,6 +266,9 @@ namespace Apache.Ignite.Core.Tests
                 Assert.AreEqual(pers.WalSegments, resPers.WalSegments);
                 Assert.AreEqual(pers.WalSegmentSize, resPers.WalSegmentSize);
                 Assert.AreEqual(pers.WalStorePath, resPers.WalStorePath);
+                Assert.AreEqual(pers.MetricsEnabled, resPers.MetricsEnabled);
+                Assert.AreEqual(pers.RateTimeInterval, resPers.RateTimeInterval);
+                Assert.AreEqual(pers.SubIntervals, resPers.SubIntervals);
             }
         }
 
@@ -539,6 +542,9 @@ namespace Apache.Ignite.Core.Tests
             Assert.AreEqual(PersistentStoreConfiguration.DefaultWalSegmentSize, cfg.WalSegmentSize);
             Assert.AreEqual(PersistentStoreConfiguration.DefaultWalSegments, cfg.WalSegments);
             Assert.AreEqual(WalMode.Default, cfg.WalMode);
+            Assert.IsFalse(cfg.MetricsEnabled);
+            Assert.AreEqual(PersistentStoreConfiguration.DefaultSubIntervals, cfg.SubIntervals);
+            Assert.AreEqual(PersistentStoreConfiguration.DefaultRateTimeInterval, cfg.RateTimeInterval);
         }
 
         /// <summary>
@@ -741,7 +747,10 @@ namespace Apache.Ignite.Core.Tests
                     WalRecordIteratorBufferSize = 32 * 1024 * 1024,
                     WalSegments = 6,
                     WalSegmentSize = 5 * 1024 * 1024,
-                    WalStorePath = Path.GetTempPath()
+                    WalStorePath = Path.GetTempPath(),
+                    MetricsEnabled = true,
+                    SubIntervals = 7,
+                    RateTimeInterval = TimeSpan.FromSeconds(9)
                 }
             };
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index 9df2889..76132c3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -99,6 +99,8 @@
     <Compile Include="Cache\IMemoryMetrics.cs" />
     <Compile Include="Common\ExceptionFactory.cs" />
     <Compile Include="Configuration\Package-Info.cs" />
+    <Compile Include="Impl\PersistentStore\PersistentStoreMetrics.cs" />
+    <Compile Include="PersistentStore\IPersistentStoreMetrics.cs" />
     <Compile Include="PersistentStore\Package-Info.cs" />
     <Compile Include="PersistentStore\PersistentStoreConfiguration.cs" />
     <Compile Include="Configuration\SqlConnectorConfiguration.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
index 8c4bee2..bf061db 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs
@@ -32,6 +32,7 @@ namespace Apache.Ignite.Core
     using Apache.Ignite.Core.Log;
     using Apache.Ignite.Core.Lifecycle;
     using Apache.Ignite.Core.Messaging;
+    using Apache.Ignite.Core.PersistentStore;
     using Apache.Ignite.Core.Plugin;
     using Apache.Ignite.Core.Services;
     using Apache.Ignite.Core.Transactions;
@@ -359,5 +360,13 @@ namespace Apache.Ignite.Core
         ///   <c>true</c> if the grid is active; otherwise, <c>false</c>.
         /// </returns>
         bool IsActive();
+
+        /// <summary>
+        /// Gets the persistent store metrics.
+        /// <para />
+        /// To enable metrics set <see cref="PersistentStoreConfiguration.MetricsEnabled"/> property
+        /// in <see cref="IgniteConfiguration.PersistentStoreConfiguration"/>.
+        /// </summary>
+        IPersistentStoreMetrics GetPersistentStoreMetrics();
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
index 919f303..d7fd5ac 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/IgniteConfigurationSection.xsd
@@ -1394,6 +1394,21 @@
                                 <xs:documentation>Whether full pages should always be written.</xs:documentation>
                             </xs:annotation>
                         </xs:attribute>
+                        <xs:attribute name="metricsEnabled" type="xs:boolean">
+                            <xs:annotation>
+                                <xs:documentation>Enable persistent store metrics.</xs:documentation>
+                            </xs:annotation>
+                        </xs:attribute>
+                        <xs:attribute name="subIntervals" type="xs:int">
+                            <xs:annotation>
+                                <xs:documentation>Number of sub intervals to split RateTimeInterval into.</xs:documentation>
+                            </xs:annotation>
+                        </xs:attribute>
+                        <xs:attribute name="rateTimeInterval" type="xs:string">
+                            <xs:annotation>
+                                <xs:documentation>Rate time interval.</xs:documentation>
+                            </xs:annotation>
+                        </xs:attribute>
                     </xs:complexType>
                 </xs:element>
                 <xs:element name="pluginConfigurations" minOccurs="0">

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs
index 37b4e79..6e07b78 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Cluster/ClusterGroupImpl.cs
@@ -35,9 +35,11 @@ namespace Apache.Ignite.Core.Impl.Cluster
     using Apache.Ignite.Core.Impl.Compute;
     using Apache.Ignite.Core.Impl.Events;
     using Apache.Ignite.Core.Impl.Messaging;
+    using Apache.Ignite.Core.Impl.PersistentStore;
     using Apache.Ignite.Core.Impl.Services;
     using Apache.Ignite.Core.Impl.Unmanaged;
     using Apache.Ignite.Core.Messaging;
+    using Apache.Ignite.Core.PersistentStore;
     using Apache.Ignite.Core.Services;
     using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils;
 
@@ -130,6 +132,9 @@ namespace Apache.Ignite.Core.Impl.Cluster
         /** */
         private const int OpIsActive = 29;
 
+        /** */
+        private const int OpGetPersistentStoreMetrics = 30;
+
         /** Initial Ignite instance. */
         private readonly Ignite _ignite;
         
@@ -615,6 +620,15 @@ namespace Apache.Ignite.Core.Impl.Cluster
         }
 
         /// <summary>
+        /// Gets the persistent store metrics.
+        /// </summary>
+        public IPersistentStoreMetrics GetPersistentStoreMetrics()
+        {
+            return DoInOp(OpGetPersistentStoreMetrics, stream =>
+                new PersistentStoreMetrics(Marshaller.StartUnmarshal(stream, false)));
+        }
+
+        /// <summary>
         /// Creates new Cluster Group from given native projection.
         /// </summary>
         /// <param name="prj">Native projection.</param>

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs
index fc7894a..205f6e2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs
@@ -45,6 +45,7 @@ namespace Apache.Ignite.Core.Impl
     using Apache.Ignite.Core.Lifecycle;
     using Apache.Ignite.Core.Log;
     using Apache.Ignite.Core.Messaging;
+    using Apache.Ignite.Core.PersistentStore;
     using Apache.Ignite.Core.Services;
     using Apache.Ignite.Core.Transactions;
     using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils;
@@ -757,6 +758,12 @@ namespace Apache.Ignite.Core.Impl
             return _prj.IsActive();
         }
 
+        /** <inheritdoc /> */
+        public IPersistentStoreMetrics GetPersistentStoreMetrics()
+        {
+            return _prj.GetPersistentStoreMetrics();
+        }
+
         /// <summary>
         /// Gets or creates near cache.
         /// </summary>

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PersistentStore/PersistentStoreMetrics.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PersistentStore/PersistentStoreMetrics.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PersistentStore/PersistentStoreMetrics.cs
new file mode 100644
index 0000000..85a4fdf
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PersistentStore/PersistentStoreMetrics.cs
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.Impl.PersistentStore
+{
+    using System;
+    using System.Diagnostics;
+    using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Impl.Binary;
+    using Apache.Ignite.Core.PersistentStore;
+    
+    /// <summary>
+    /// Persistent store metrics.
+    /// </summary>
+    internal class PersistentStoreMetrics : IPersistentStoreMetrics
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PersistentStoreMetrics"/> class.
+        /// </summary>
+        public PersistentStoreMetrics(IBinaryRawReader reader)
+        {
+            Debug.Assert(reader != null);
+
+            WalLoggingRate = reader.ReadFloat();
+            WalWritingRate = reader.ReadFloat();
+            WalArchiveSegments = reader.ReadInt();
+            WalFsyncTimeAverage = reader.ReadFloat();
+            LastCheckpointingDuration = reader.ReadLongAsTimespan();
+            LastCheckpointLockWaitDuration = reader.ReadLongAsTimespan();
+            LastCheckpointMarkDuration = reader.ReadLongAsTimespan();
+            LastCheckpointPagesWriteDuration = reader.ReadLongAsTimespan();
+            LastCheckpointFsyncDuration = reader.ReadLongAsTimespan();
+            LastCheckpointTotalPagesNumber = reader.ReadLong();
+            LastCheckpointDataPagesNumber = reader.ReadLong();
+            LastCheckpointCopiedOnWritePagesNumber = reader.ReadLong();
+        }
+
+        /** <inheritdoc /> */
+        public float WalLoggingRate { get; private set; }
+
+        /** <inheritdoc /> */
+        public float WalWritingRate { get; private set; }
+
+        /** <inheritdoc /> */
+        public int WalArchiveSegments { get; private set; }
+
+        /** <inheritdoc /> */
+        public float WalFsyncTimeAverage { get; private set; }
+
+        /** <inheritdoc /> */
+        public TimeSpan LastCheckpointingDuration { get; private set; }
+
+        /** <inheritdoc /> */
+        public TimeSpan LastCheckpointLockWaitDuration { get; private set; }
+
+        /** <inheritdoc /> */
+        public TimeSpan LastCheckpointMarkDuration { get; private set; }
+
+        /** <inheritdoc /> */
+        public TimeSpan LastCheckpointPagesWriteDuration { get; private set; }
+
+        /** <inheritdoc /> */
+        public TimeSpan LastCheckpointFsyncDuration { get; private set; }
+
+        /** <inheritdoc /> */
+        public long LastCheckpointTotalPagesNumber { get; private set; }
+
+        /** <inheritdoc /> */
+        public long LastCheckpointDataPagesNumber { get; private set; }
+
+        /** <inheritdoc /> */
+        public long LastCheckpointCopiedOnWritePagesNumber { get; private set; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core/PersistentStore/IPersistentStoreMetrics.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/PersistentStore/IPersistentStoreMetrics.cs b/modules/platforms/dotnet/Apache.Ignite.Core/PersistentStore/IPersistentStoreMetrics.cs
new file mode 100644
index 0000000..e7e8481
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/PersistentStore/IPersistentStoreMetrics.cs
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+namespace Apache.Ignite.Core.PersistentStore
+{
+    using System;
+
+    /// <summary>
+    /// Persistent store metrics.
+    /// </summary>
+    public interface IPersistentStoreMetrics
+    {
+        /// <summary>
+        /// Gets the average number of WAL records per second written during the last time interval. 
+        /// </summary>
+        float WalLoggingRate { get; }
+
+        /// <summary>
+        /// Gets the average number of bytes per second written during the last time interval.
+        /// </summary>
+        float WalWritingRate { get; }
+
+        /// <summary>
+        /// Gets the current number of WAL segments in the WAL archive.
+        /// </summary>
+        int WalArchiveSegments { get; }
+
+        /// <summary>
+        /// Gets the average WAL fsync duration in microseconds over the last time interval.
+        /// </summary>
+        float WalFsyncTimeAverage { get; }
+
+        /// <summary>
+        /// Gets the duration of the last checkpoint.
+        /// </summary>
+        TimeSpan LastCheckpointingDuration { get; }
+
+        /// <summary>
+        /// Gets the duration of last checkpoint lock wait.
+        /// </summary>
+        TimeSpan LastCheckpointLockWaitDuration { get; }
+
+        /// <summary>
+        /// Gets the duration of last checkpoint mark phase.
+        /// </summary>
+        TimeSpan LastCheckpointMarkDuration { get; }
+
+        /// <summary>
+        /// Gets the duration of last checkpoint pages write phase.
+        /// </summary>
+        TimeSpan LastCheckpointPagesWriteDuration { get; }
+
+        /// <summary>
+        /// Gets the duration of the sync phase of the last checkpoint.
+        /// </summary>
+        TimeSpan LastCheckpointFsyncDuration { get; }
+
+        /// <summary>
+        /// Gets the total number of pages written during the last checkpoint.
+        /// </summary>
+        long LastCheckpointTotalPagesNumber { get; }
+
+        /// <summary>
+        /// Gets the number of data pages written during the last checkpoint.
+        /// </summary>
+        long LastCheckpointDataPagesNumber { get; }
+
+        /// <summary>
+        /// Gets the number of pages copied to a temporary checkpoint buffer during the last checkpoint.
+        /// </summary>
+        long LastCheckpointCopiedOnWritePagesNumber { get; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/b085fa0d/modules/platforms/dotnet/Apache.Ignite.Core/PersistentStore/PersistentStoreConfiguration.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/PersistentStore/PersistentStoreConfiguration.cs b/modules/platforms/dotnet/Apache.Ignite.Core/PersistentStore/PersistentStoreConfiguration.cs
index c998ab3..43b17ac 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/PersistentStore/PersistentStoreConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/PersistentStore/PersistentStoreConfiguration.cs
@@ -20,6 +20,7 @@ namespace Apache.Ignite.Core.PersistentStore
     using System;
     using System.ComponentModel;
     using System.Diagnostics;
+    using System.Diagnostics.CodeAnalysis;
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Impl.Binary;
 
@@ -29,6 +30,73 @@ namespace Apache.Ignite.Core.PersistentStore
     public class PersistentStoreConfiguration
     {
         /// <summary>
+        /// Default value for <see cref="CheckpointingPageBufferSize"/>.
+        /// </summary>
+        public const long DefaultCheckpointingPageBufferSize = 256L * 1024 * 1024;
+
+        /// <summary>
+        /// Default value for <see cref="CheckpointingThreads"/>.
+        /// </summary>
+        public const int DefaultCheckpointingThreads = 1;
+
+        /// <summary>
+        /// Default value for <see cref="CheckpointingFrequency"/>.
+        /// </summary>
+        public static readonly TimeSpan DefaultCheckpointingFrequency = TimeSpan.FromSeconds(180);
+
+        /// <summary>
+        /// Default value for <see cref="LockWaitTime"/>.
+        /// </summary>
+        public static readonly TimeSpan DefaultLockWaitTime = TimeSpan.FromSeconds(10);
+
+        /// <summary>
+        /// Default value for <see cref="WalHistorySize"/>.
+        /// </summary>
+        public const int DefaultWalHistorySize = 20;
+
+        /// <summary>
+        /// Default value for <see cref="WalSegments"/>.
+        /// </summary>
+        public const int DefaultWalSegments = 10;
+
+        /// <summary>
+        /// Default value for <see cref="WalSegmentSize"/>.
+        /// </summary>
+        public const int DefaultWalSegmentSize = 64 * 1024 * 1024;
+
+        /// <summary>
+        /// Default value for <see cref="TlbSize"/>.
+        /// </summary>
+        public const int DefaultTlbSize = 128 * 1024;
+
+        /// <summary>
+        /// Default value for <see cref="WalFlushFrequency"/>.
+        /// </summary>
+        public static readonly TimeSpan DefaultWalFlushFrequency = TimeSpan.FromSeconds(2);
+
+        /// <summary>
+        /// Default value for <see cref="WalRecordIteratorBufferSize"/>.
+        /// </summary>
+        public const int DefaultWalRecordIteratorBufferSize = 64 * 1024 * 1024;
+
+        /// <summary>
+        /// Default value for <see cref="WalFsyncDelayNanos"/>.
+        /// </summary>
+        public const int DefaultWalFsyncDelayNanos = 1;
+
+        /// <summary>
+        /// The default sub intervals.
+        /// </summary>
+        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
+            Justification = "Consistency with Java config")]
+        public const int DefaultSubIntervals = 5;
+
+        /// <summary>
+        /// The default rate time interval.
+        /// </summary>
+        public static readonly TimeSpan DefaultRateTimeInterval = TimeSpan.FromSeconds(60);
+
+        /// <summary>
         /// Initializes a new instance of the <see cref="PersistentStoreConfiguration"/> class.
         /// </summary>
         public PersistentStoreConfiguration()
@@ -44,6 +112,8 @@ namespace Apache.Ignite.Core.PersistentStore
             WalFlushFrequency = DefaultWalFlushFrequency;
             WalRecordIteratorBufferSize = DefaultWalRecordIteratorBufferSize;
             WalFsyncDelayNanos = DefaultWalFsyncDelayNanos;
+            RateTimeInterval = DefaultRateTimeInterval;
+            SubIntervals = DefaultSubIntervals;
         }
 
         /// <summary>
@@ -64,12 +134,15 @@ namespace Apache.Ignite.Core.PersistentStore
             WalSegmentSize = reader.ReadInt();
             WalStorePath = reader.ReadString();
             WalArchivePath = reader.ReadString();
-            WalMode = (WalMode) reader.ReadInt();
+            WalMode = (WalMode)reader.ReadInt();
             TlbSize = reader.ReadInt();
             WalFlushFrequency = reader.ReadLongAsTimespan();
             WalFsyncDelayNanos = reader.ReadInt();
             WalRecordIteratorBufferSize = reader.ReadInt();
             AlwaysWriteFullPages = reader.ReadBoolean();
+            MetricsEnabled = reader.ReadBoolean();
+            SubIntervals = reader.ReadInt();
+            RateTimeInterval = reader.ReadLongAsTimespan();
         }
 
         /// <summary>
@@ -90,70 +163,18 @@ namespace Apache.Ignite.Core.PersistentStore
             writer.WriteInt(WalSegmentSize);
             writer.WriteString(WalStorePath);
             writer.WriteString(WalArchivePath);
-            writer.WriteInt((int) WalMode);
+            writer.WriteInt((int)WalMode);
             writer.WriteInt(TlbSize);
             writer.WriteTimeSpanAsLong(WalFlushFrequency);
             writer.WriteInt(WalFsyncDelayNanos);
             writer.WriteInt(WalRecordIteratorBufferSize);
             writer.WriteBoolean(AlwaysWriteFullPages);
+            writer.WriteBoolean(MetricsEnabled);
+            writer.WriteInt(SubIntervals);
+            writer.WriteTimeSpanAsLong(RateTimeInterval);
         }
 
         /// <summary>
-        /// Default value for <see cref="CheckpointingPageBufferSize"/>.
-        /// </summary>
-        public const long DefaultCheckpointingPageBufferSize = 256L * 1024 * 1024;
-
-        /// <summary>
-        /// Default value for <see cref="CheckpointingThreads"/>.
-        /// </summary>
-        public const int DefaultCheckpointingThreads = 1;
-
-        /// <summary>
-        /// Default value for <see cref="CheckpointingFrequency"/>.
-        /// </summary>
-        public static readonly TimeSpan DefaultCheckpointingFrequency = TimeSpan.FromSeconds(180);
-
-        /// <summary>
-        /// Default value for <see cref="LockWaitTime"/>.
-        /// </summary>
-        public static readonly TimeSpan DefaultLockWaitTime = TimeSpan.FromSeconds(10);
-
-        /// <summary>
-        /// Default value for <see cref="WalHistorySize"/>.
-        /// </summary>
-        public const int DefaultWalHistorySize = 20;
-
-        /// <summary>
-        /// Default value for <see cref="WalSegments"/>.
-        /// </summary>
-        public const int DefaultWalSegments = 10;
-
-        /// <summary>
-        /// Default value for <see cref="WalSegmentSize"/>.
-        /// </summary>
-        public const int DefaultWalSegmentSize = 64 * 1024 * 1024;
-
-        /// <summary>
-        /// Default value for <see cref="TlbSize"/>.
-        /// </summary>
-        public const int DefaultTlbSize = 128 * 1024;
-
-        /// <summary>
-        /// Default value for <see cref="WalFlushFrequency"/>.
-        /// </summary>
-        public static readonly TimeSpan DefaultWalFlushFrequency = TimeSpan.FromSeconds(2);
-
-        /// <summary>
-        /// Default value for <see cref="WalRecordIteratorBufferSize"/>.
-        /// </summary>
-        public const int DefaultWalRecordIteratorBufferSize = 64 * 1024 * 1024;
-
-        /// <summary>
-        /// Default value for <see cref="WalFsyncDelayNanos"/>.
-        /// </summary>
-        public const int DefaultWalFsyncDelayNanos = 1;
-
-        /// <summary>
         /// Gets or sets the path where data and indexes will be persisted.
         /// </summary>
         public string PersistentStorePath { get; set; }
@@ -247,5 +268,26 @@ namespace Apache.Ignite.Core.PersistentStore
         /// Gets or sets a value indicating whether full pages should always be written.
         /// </summary>
         public bool AlwaysWriteFullPages { get; set; }
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to enable persistent store metrics.
+        /// See <see cref="IIgnite.GetPersistentStoreMetrics"/>.
+        /// </summary>
+        public bool MetricsEnabled { get; set; }
+
+        /// <summary>
+        /// Gets or sets the length of the time interval for rate-based metrics.
+        /// This interval defines a window over which hits will be tracked.
+        /// </summary>
+        [DefaultValue(typeof(TimeSpan), "00:01:00")]
+        public TimeSpan RateTimeInterval { get; set; }
+
+        /// <summary>
+        /// Number of sub-intervals to split the <see cref="RateTimeInterval"/> into to track the update history.
+        /// </summary>
+        [DefaultValue(DefaultSubIntervals)]
+        [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly",
+            Justification = "Consistency with Java config")]
+        public int SubIntervals { get; set; }
     }
 }