diff options
-rw-r--r-- | yt/yt/core/misc/proc.cpp | 37 | ||||
-rw-r--r-- | yt/yt/core/misc/proc.h | 29 | ||||
-rw-r--r-- | yt/yt/core/misc/unittests/proc_ut.cpp | 30 |
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(); |