diff options
| author | Alexey Efimov <[email protected]> | 2024-09-30 15:42:26 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-09-30 13:42:26 +0000 |
| commit | 500c5c729df156228582b92fd1bda37d5911496d (patch) | |
| tree | 94469e1e2c2d94c174aa9cbdf524027a305ebf68 | |
| parent | 463bc9788fc7f832294f3a3eff2208b5a2b68c8e (diff) | |
Fix group sorting (#9892)
| -rw-r--r-- | ydb/core/viewer/json_handlers_storage.cpp | 2 | ||||
| -rw-r--r-- | ydb/core/viewer/json_handlers_viewer.cpp | 2 | ||||
| -rw-r--r-- | ydb/core/viewer/protos/viewer.proto | 10 | ||||
| -rw-r--r-- | ydb/core/viewer/storage_groups.h | 101 | ||||
| -rw-r--r-- | ydb/core/viewer/viewer_nodes.h | 37 |
5 files changed, 138 insertions, 14 deletions
diff --git a/ydb/core/viewer/json_handlers_storage.cpp b/ydb/core/viewer/json_handlers_storage.cpp index fa99923cea3..750da437452 100644 --- a/ydb/core/viewer/json_handlers_storage.cpp +++ b/ydb/core/viewer/json_handlers_storage.cpp @@ -4,7 +4,7 @@ namespace NKikimr::NViewer { void InitStorageGroupsJsonHandler(TJsonHandlers& jsonHandlers) { - jsonHandlers.AddHandler("/storage/groups", new TJsonHandler<TStorageGroups>(TStorageGroups::GetSwagger()), 5); + jsonHandlers.AddHandler("/storage/groups", new TJsonHandler<TStorageGroups>(TStorageGroups::GetSwagger()), 6); } void InitStorageJsonHandlers(TJsonHandlers& jsonHandlers) { diff --git a/ydb/core/viewer/json_handlers_viewer.cpp b/ydb/core/viewer/json_handlers_viewer.cpp index 9e4ae55f211..3971bfc0345 100644 --- a/ydb/core/viewer/json_handlers_viewer.cpp +++ b/ydb/core/viewer/json_handlers_viewer.cpp @@ -243,7 +243,7 @@ void InitViewerHealthCheckJsonHandler(TJsonHandlers& handlers) { } void InitViewerNodesJsonHandler(TJsonHandlers& handlers) { - handlers.AddHandler("/viewer/nodes", new TJsonHandler<TJsonNodes>(TJsonNodes::GetSwagger()), 7); + handlers.AddHandler("/viewer/nodes", new TJsonHandler<TJsonNodes>(TJsonNodes::GetSwagger()), 8); } void InitViewerACLJsonHandler(TJsonHandlers &jsonHandlers) { diff --git a/ydb/core/viewer/protos/viewer.proto b/ydb/core/viewer/protos/viewer.proto index 80a5ddd8ec7..0330e1ef5f8 100644 --- a/ydb/core/viewer/protos/viewer.proto +++ b/ydb/core/viewer/protos/viewer.proto @@ -461,6 +461,16 @@ message TStorageGroupInfo { message TStorageGroupGroup { string GroupName = 1; uint64 GroupCount = 2; + optional uint64 Used = 13; + optional uint64 Limit = 14; + optional uint64 Available = 15; + optional float Usage = 16; + optional uint64 Read = 17; + optional uint64 Write = 18; + optional float DiskSpaceUsage = 19; + optional uint64 LatencyPutTabletLog = 20; + optional uint64 LatencyPutUserData = 21; + optional uint64 LatencyGetFast = 22; } message TStoragePoolInfo { diff --git a/ydb/core/viewer/storage_groups.h b/ydb/core/viewer/storage_groups.h index 026ed293805..e18a86a680b 100644 --- a/ydb/core/viewer/storage_groups.h +++ b/ydb/core/viewer/storage_groups.h @@ -174,6 +174,8 @@ public: std::optional<std::size_t> Limit; ui32 SpaceUsageProblem = 90; // % + using TGroupSortKey = std::variant<TString, ui64, float, bool>; + struct TPDisk { ui32 PDiskId = 0; TNodeId NodeId = 0; @@ -273,7 +275,7 @@ public: ui64 Available = 0; ui64 Read = 0; ui64 Write = 0; - ui32 MissingDisks = 0; + ui64 MissingDisks = 0; ui64 PutTabletLogLatency = 0; ui64 PutUserDataLatency = 0; ui64 GetFastLatency = 0; @@ -523,6 +525,30 @@ public: } return groupName; } + + TGroupSortKey GetSortKey(EGroupFields groupBy) const { + switch (groupBy) { + case EGroupFields::GroupId: + case EGroupFields::Erasure: + case EGroupFields::PoolName: + case EGroupFields::Kind: + case EGroupFields::MediaType: + case EGroupFields::State: + return GetGroupName(groupBy); + case EGroupFields::Usage: + return Usage; + case EGroupFields::DiskSpaceUsage: + return DiskSpaceUsage; + case EGroupFields::Encryption: + return EncryptionMode; + case EGroupFields::MissingDisks: + return MissingDisks; + case EGroupFields::Latency: + return PutTabletLogLatency; + default: + return TString(); + } + } }; using TGroupData = std::vector<TGroup>; @@ -530,7 +556,42 @@ public: struct TGroupGroup { TString Name; + TGroupSortKey SortKey; TGroupView Groups; + + // stats + float Usage = 0; // avg + ui64 Used = 0; // sum + ui64 Limit = 0; // sum + ui64 Available = 0; // sum + ui64 Read = 0; // sum + ui64 Write = 0; // sum + ui64 PutTabletLogLatency = 0; // max + ui64 PutUserDataLatency = 0; // max + ui64 GetFastLatency = 0; // max + float DiskSpaceUsage = 0; // max + + void CalcStats() { + for (TGroup* group : Groups) { + Usage += group->Usage; + Used += group->Used; + Limit += group->Limit; + Read += group->Read; + Write += group->Write; + if (Available) { + Available = std::min(Available, group->Available); + } else { + Available = group->Available; + } + PutTabletLogLatency = std::max(PutTabletLogLatency, group->PutTabletLogLatency); + PutUserDataLatency = std::max(PutUserDataLatency, group->PutUserDataLatency); + GetFastLatency = std::max(GetFastLatency, group->GetFastLatency); + DiskSpaceUsage = std::max(DiskSpaceUsage, group->DiskSpaceUsage); + } + if (!Groups.empty()) { + Usage /= Groups.size(); + } + } }; TGroupData GroupData; @@ -547,8 +608,6 @@ public: const TFieldsType FieldsAll = TFieldsType().set(); const TFieldsType FieldsBsGroups = TFieldsType().set(+EGroupFields::GroupId) .set(+EGroupFields::Erasure) - .set(+EGroupFields::Used) - .set(+EGroupFields::Limit) .set(+EGroupFields::Latency); const TFieldsType FieldsBsPools = TFieldsType().set(+EGroupFields::PoolName) .set(+EGroupFields::Kind) @@ -655,6 +714,8 @@ public: result = EGroupFields::PDiskId; } else if (field == "Latency") { result = EGroupFields::Latency; + } else if (field == "Available") { + result = EGroupFields::Available; } return result; } @@ -1013,6 +1074,7 @@ public: groupGroups.emplace(gb, GroupGroups.size()); groupGroup = &GroupGroups.emplace_back(); groupGroup->Name = gb; + groupGroup->SortKey = group->GetSortKey(GroupBy); } else { groupGroup = &GroupGroups[it->second]; } @@ -1031,7 +1093,7 @@ public: case EGroupFields::MediaType: case EGroupFields::State: GroupCollection(); - SortCollection(GroupGroups, [](const TGroupGroup& groupGroup) { return groupGroup.Name; }); + SortCollection(GroupGroups, [](const TGroupGroup& groupGroup) { return groupGroup.SortKey; }); NeedGroup = false; break; case EGroupFields::Usage: @@ -1039,7 +1101,7 @@ public: case EGroupFields::MissingDisks: case EGroupFields::Latency: GroupCollection(); - SortCollection(GroupGroups, [](const TGroupGroup& groupGroup) { return groupGroup.Name; }, true); + SortCollection(GroupGroups, [](const TGroupGroup& groupGroup) { return groupGroup.SortKey; }, true); NeedGroup = false; break; case EGroupFields::Read: @@ -2072,10 +2134,37 @@ public: } } } else { - for (const TGroupGroup& groupGroup : GroupGroups) { + for (TGroupGroup& groupGroup : GroupGroups) { NKikimrViewer::TStorageGroupGroup& jsonGroupGroup = *json.AddStorageGroupGroups(); jsonGroupGroup.SetGroupName(groupGroup.Name); jsonGroupGroup.SetGroupCount(groupGroup.Groups.size()); + groupGroup.CalcStats(); + if (FieldsAvailable.test(+EGroupFields::Used)) { + jsonGroupGroup.SetUsed(groupGroup.Used); + } + if (FieldsAvailable.test(+EGroupFields::Limit)) { + jsonGroupGroup.SetLimit(groupGroup.Limit); + } + if (FieldsAvailable.test(+EGroupFields::Read)) { + jsonGroupGroup.SetRead(groupGroup.Read); + } + if (FieldsAvailable.test(+EGroupFields::Write)) { + jsonGroupGroup.SetWrite(groupGroup.Write); + } + if (FieldsAvailable.test(+EGroupFields::Usage)) { + jsonGroupGroup.SetUsage(groupGroup.Usage); + } + if (FieldsAvailable.test(+EGroupFields::Available)) { + jsonGroupGroup.SetAvailable(groupGroup.Available); + } + if (FieldsAvailable.test(+EGroupFields::DiskSpaceUsage)) { + jsonGroupGroup.SetDiskSpaceUsage(groupGroup.DiskSpaceUsage); + } + if (FieldsAvailable.test(+EGroupFields::Latency)) { + jsonGroupGroup.SetLatencyPutTabletLog(groupGroup.PutTabletLogLatency); + jsonGroupGroup.SetLatencyPutUserData(groupGroup.PutUserDataLatency); + jsonGroupGroup.SetLatencyGetFast(groupGroup.GetFastLatency); + } } } AddEvent("RenderingResult"); diff --git a/ydb/core/viewer/viewer_nodes.h b/ydb/core/viewer/viewer_nodes.h index f51d4f6484a..acbf7bfa26f 100644 --- a/ydb/core/viewer/viewer_nodes.h +++ b/ydb/core/viewer/viewer_nodes.h @@ -145,6 +145,8 @@ class TJsonNodes : public TViewerPipeClient { bool OffloadMerge = true; size_t OffloadMergeAttempts = 2; + using TGroupSortKey = std::variant<TString, ui64, float>; + struct TNode { TEvInterconnect::TNodeInfo NodeInfo; NKikimrWhiteboard::TSystemStateInfo SystemState; @@ -470,6 +472,27 @@ class TJsonNodes : public TViewerPipeClient { return groupName; } + TGroupSortKey GetGroupSortKey(ENodeFields groupBy, TInstant now) const { + switch (groupBy) { + case ENodeFields::NodeId: + case ENodeFields::HostName: + case ENodeFields::NodeName: + case ENodeFields::Database: + case ENodeFields::DC: + case ENodeFields::Rack: + case ENodeFields::Version: + return GetGroupName(groupBy, now); + case ENodeFields::DiskSpaceUsage: + return DiskSpaceUsage; + case ENodeFields::Missing: + return MissingDisks; + case ENodeFields::Uptime: + return static_cast<ui64>(now.Seconds()) - (Disconnected ? SystemState.GetDisconnectTime() : SystemState.GetStartTime()); + default: + return TString(); + } + } + void MergeFrom(const NKikimrWhiteboard::TSystemStateInfo& systemState) { SystemState.MergeFrom(systemState); Cleanup(); @@ -479,11 +502,6 @@ class TJsonNodes : public TViewerPipeClient { } }; - struct TNodeGroup { - TString Name; - std::vector<TNode*> Nodes; - }; - struct TNodeBatch { std::vector<TNode*> NodesToAskFor; std::vector<TNode*> NodesToAskAbout; @@ -501,6 +519,12 @@ class TJsonNodes : public TViewerPipeClient { using TNodeData = std::vector<TNode>; using TNodeView = std::deque<TNode*>; + struct TNodeGroup { + TString Name; + TGroupSortKey SortKey; + TNodeView Nodes; + }; + TNodeData NodeData; TNodeView NodeView; std::vector<TNodeGroup> NodeGroups; @@ -1031,6 +1055,7 @@ public: nodeGroups.emplace(gb, NodeGroups.size()); nodeGroup = &NodeGroups.emplace_back(); nodeGroup->Name = gb; + nodeGroup->SortKey = node->GetGroupSortKey(GroupBy, now); } else { nodeGroup = &NodeGroups[it->second]; } @@ -1052,7 +1077,7 @@ public: case ENodeFields::Uptime: case ENodeFields::Version: GroupCollection(); - SortCollection(NodeGroups, [](const TNodeGroup& nodeGroup) { return nodeGroup.Name; }); + SortCollection(NodeGroups, [](const TNodeGroup& nodeGroup) { return nodeGroup.SortKey; }); NeedGroup = false; break; case ENodeFields::NodeInfo: |
