aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryuryalekseev <yuryalekseev@yandex-team.com>2024-04-28 09:30:35 +0300
committeryuryalekseev <yuryalekseev@yandex-team.com>2024-04-28 09:56:14 +0300
commitf5c2f57f16eea2ec7ec33130b725dbe9a392fa26 (patch)
treeeaa7440fd23c4e74fc0bb407a3e02d1966353da6
parentcb84e961773c15774ce94d1df9ef2fc260c82775 (diff)
downloadydb-f5c2f57f16eea2ec7ec33130b725dbe9a392fa26.tar.gz
YT-21657: Read block device stat through /sys/block/$device/stat.
49101c41a066a40c31c7808a34508059403b299d
-rw-r--r--yt/yt/core/misc/proc.cpp37
-rw-r--r--yt/yt/core/misc/proc.h29
-rw-r--r--yt/yt/core/misc/unittests/proc_ut.cpp30
3 files changed, 96 insertions, 0 deletions
diff --git a/yt/yt/core/misc/proc.cpp b/yt/yt/core/misc/proc.cpp
index e757d73ffd..2518ad1699 100644
--- a/yt/yt/core/misc/proc.cpp
+++ b/yt/yt/core/misc/proc.cpp
@@ -1529,6 +1529,43 @@ THashMap<TString, TDiskStat> GetDiskStats()
#endif
}
+TBlockDeviceStat ParseBlockDeviceStat(const TString& statLine)
+{
+ auto buffer = SplitString(statLine, " ");
+ TBlockDeviceStat result;
+ TryParseField(buffer, 0, result.ReadsCompleted);
+ TryParseField(buffer, 1, result.ReadsMerged);
+ TryParseField(buffer, 2, result.SectorsRead);
+ TryParseField(buffer, 3, result.TimeSpentReading);
+ TryParseField(buffer, 4, result.WritesCompleted);
+ TryParseField(buffer, 5, result.WritesMerged);
+ TryParseField(buffer, 6, result.SectorsWritten);
+ TryParseField(buffer, 7, result.TimeSpentWriting);
+ TryParseField(buffer, 8, result.IOCurrentlyInProgress);
+ TryParseField(buffer, 9, result.TimeSpentDoingIO);
+ TryParseField(buffer, 10, result.WeightedTimeSpentDoingIO);
+ TryParseField(buffer, 11, result.DiscardsCompleted);
+ TryParseField(buffer, 12, result.DiscardsMerged);
+ TryParseField(buffer, 13, result.SectorsDiscarded);
+ TryParseField(buffer, 14, result.TimeSpentDiscarding);
+ TryParseField(buffer, 15, result.FlushesCompleted);
+ TryParseField(buffer, 16, result.TimeSpentFlushing);
+ return result;
+}
+
+std::optional<TBlockDeviceStat> GetBlockDeviceStat(const TString& deviceName)
+{
+#ifdef _linux_
+ const TString path = Format("/sys/block/%v/stat", deviceName);
+ TFileInput diskStatsFile(path);
+ auto data = diskStatsFile.ReadAll();
+ return ParseBlockDeviceStat(Strip(data));
+#else
+ Y_UNUSED(deviceName);
+ return std::nullopt;
+#endif
+}
+
std::vector<TString> ListDisks()
{
#ifdef _linux_
diff --git a/yt/yt/core/misc/proc.h b/yt/yt/core/misc/proc.h
index 1248d66a5c..7eafd72113 100644
--- a/yt/yt/core/misc/proc.h
+++ b/yt/yt/core/misc/proc.h
@@ -343,8 +343,37 @@ struct TDiskStat
TDiskStat ParseDiskStat(const TString& statLine);
+// See https://docs.kernel.org/block/stat.html for more info.
+struct TBlockDeviceStat
+{
+ i64 ReadsCompleted = 0;
+ i64 ReadsMerged = 0;
+ i64 SectorsRead = 0;
+ TDuration TimeSpentReading;
+
+ i64 WritesCompleted = 0;
+ i64 WritesMerged = 0;
+ i64 SectorsWritten = 0;
+ TDuration TimeSpentWriting;
+
+ i64 IOCurrentlyInProgress = 0;
+ TDuration TimeSpentDoingIO;
+ TDuration WeightedTimeSpentDoingIO;
+
+ i64 DiscardsCompleted = 0;
+ i64 DiscardsMerged = 0;
+ i64 SectorsDiscarded = 0;
+ TDuration TimeSpentDiscarding;
+
+ i64 FlushesCompleted = 0;
+ TDuration TimeSpentFlushing;
+};
+
+TBlockDeviceStat ParseBlockDeviceStat(const TString& statLine);
+
//! DeviceName to stat info
THashMap<TString, TDiskStat> GetDiskStats();
+std::optional<TBlockDeviceStat> GetBlockDeviceStat(const TString& deviceName);
std::vector<TString> ListDisks();
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/core/misc/unittests/proc_ut.cpp b/yt/yt/core/misc/unittests/proc_ut.cpp
index f18e462aef..ed8bca5cb5 100644
--- a/yt/yt/core/misc/unittests/proc_ut.cpp
+++ b/yt/yt/core/misc/unittests/proc_ut.cpp
@@ -165,6 +165,36 @@ TEST(TProcTest, DiskStat)
}
}
+TEST(TProcTest, BlockDeviceStat)
+{
+ {
+ auto stat = ParseBlockDeviceStat("509883438 87421933 206345875260 1643399993 1892382802 4495364138 837307482336 2391271400 0 2964131914 3304110410 0 0 0 0 81921472 3564406312");
+ EXPECT_EQ(stat.ReadsCompleted, 509883438ll);
+ EXPECT_EQ(stat.ReadsMerged, 87421933ll);
+ EXPECT_EQ(stat.SectorsRead, 206345875260ll);
+ EXPECT_EQ(stat.TimeSpentReading, TDuration::MilliSeconds(1643399993ul));
+ EXPECT_EQ(stat.WritesCompleted, 1892382802ll);
+ EXPECT_EQ(stat.WritesMerged, 4495364138ll);
+ EXPECT_EQ(stat.SectorsWritten, 837307482336ll);
+ EXPECT_EQ(stat.TimeSpentWriting, TDuration::MilliSeconds(2391271400ul));
+ EXPECT_EQ(stat.IOCurrentlyInProgress, 0ll);
+ EXPECT_EQ(stat.TimeSpentDoingIO, TDuration::MilliSeconds(2964131914ul));
+ EXPECT_EQ(stat.WeightedTimeSpentDoingIO, TDuration::MilliSeconds(3304110410ul));
+ EXPECT_EQ(stat.DiscardsCompleted, 0ll);
+ EXPECT_EQ(stat.DiscardsMerged, 0ll);
+ EXPECT_EQ(stat.SectorsDiscarded, 0ll);
+ EXPECT_EQ(stat.TimeSpentDiscarding, TDuration::MilliSeconds(0ul));
+ EXPECT_EQ(stat.FlushesCompleted, 81921472ll);
+ EXPECT_EQ(stat.TimeSpentFlushing, TDuration::MilliSeconds(3564406312ul));
+ }
+ {
+ for (const TString& disk : ListDisks()) {
+ auto stat = GetBlockDeviceStat(disk);
+ EXPECT_TRUE(stat);
+ }
+ }
+}
+
TEST(TProcTest, FileDescriptorCount)
{
auto initialCount = GetFileDescriptorCount();