diff options
author | xenoxeno <xeno@ydb.tech> | 2022-09-13 11:36:45 +0300 |
---|---|---|
committer | xenoxeno <xeno@ydb.tech> | 2022-09-13 11:36:45 +0300 |
commit | c92c27d69ad2484e6b0372353da509f8fee13a31 (patch) | |
tree | 7d93c37757b8af7f062b9844a0d1073a90601823 | |
parent | 954648c13ecff2f4f4c1c9673147fcdbcc0cab2f (diff) | |
download | ydb-c92c27d69ad2484e6b0372353da509f8fee13a31.tar.gz |
[viewer] improve nodes handler
-rw-r--r-- | ydb/core/protos/node_whiteboard.proto | 6 | ||||
-rw-r--r-- | ydb/core/tablet/node_whiteboard.cpp | 36 | ||||
-rw-r--r-- | ydb/core/viewer/CMakeLists.txt | 2 | ||||
-rw-r--r-- | ydb/core/viewer/json_nodes.h | 412 | ||||
-rw-r--r-- | ydb/core/viewer/protos/viewer.proto | 1 | ||||
-rw-r--r-- | ydb/core/viewer/wb_merge.h | 7 |
6 files changed, 350 insertions, 114 deletions
diff --git a/ydb/core/protos/node_whiteboard.proto b/ydb/core/protos/node_whiteboard.proto index 13f5cf0bdf..5bd23adec0 100644 --- a/ydb/core/protos/node_whiteboard.proto +++ b/ydb/core/protos/node_whiteboard.proto @@ -68,12 +68,14 @@ message TTabletStateInfo { message TEvTabletStateRequest { optional uint64 ChangedSince = 1; + optional string GroupBy = 20; // it's either empty or "Type,State" for now } message TEvTabletStateResponse { repeated TTabletStateInfo TabletStateInfo = 1; - optional uint64 ResponseTime = 2; - optional uint32 ResponseDuration = 3; // filled during collect + optional uint64 ResponseTime = 2; // ms, filled during processing and merging + optional uint64 ResponseDuration = 3; // us, filled during collect + optional uint64 ProcessDuration = 4; // us, filled during processing } message TNodeStateInfo { diff --git a/ydb/core/tablet/node_whiteboard.cpp b/ydb/core/tablet/node_whiteboard.cpp index 50e1648690..c3f4915265 100644 --- a/ydb/core/tablet/node_whiteboard.cpp +++ b/ydb/core/tablet/node_whiteboard.cpp @@ -616,18 +616,38 @@ protected: } void Handle(TEvWhiteboard::TEvTabletStateRequest::TPtr &ev, const TActorContext &ctx) { + auto now = TMonotonic::Now(); const auto& request = ev->Get()->Record; - ui64 changedSince = request.HasChangedSince() ? request.GetChangedSince() : 0; - TAutoPtr<TEvWhiteboard::TEvTabletStateResponse> response = new TEvWhiteboard::TEvTabletStateResponse(); + std::unique_ptr<TEvWhiteboard::TEvTabletStateResponse> response = std::make_unique<TEvWhiteboard::TEvTabletStateResponse>(); auto& record = response->Record; - for (const auto& pr : TabletStateInfo) { - if (pr.second.GetChangeTime() >= changedSince) { - NKikimrWhiteboard::TTabletStateInfo &tabletStateInfo = *record.AddTabletStateInfo(); - tabletStateInfo.CopyFrom(pr.second); + if (request.groupby().empty()) { + ui64 changedSince = request.has_changedsince() ? request.changedsince() : 0; + for (const auto& pr : TabletStateInfo) { + if (pr.second.changetime() >= changedSince) { + NKikimrWhiteboard::TTabletStateInfo& tabletStateInfo = *record.add_tabletstateinfo(); + tabletStateInfo = pr.second; + } + } + } else if (request.groupby() == "Type,State") { // the only supported group-by for now + std::unordered_map<std::pair<NKikimrTabletBase::TTabletTypes::EType, + NKikimrWhiteboard::TTabletStateInfo::ETabletState>, NKikimrWhiteboard::TTabletStateInfo> stateGroupBy; + for (const auto& [id, stateInfo] : TabletStateInfo) { + NKikimrWhiteboard::TTabletStateInfo& state = stateGroupBy[{stateInfo.type(), stateInfo.state()}]; + auto count = state.count(); + if (count == 0) { + state.set_type(stateInfo.type()); + state.set_state(stateInfo.state()); + } + state.set_count(count + 1); + } + for (auto& pr : stateGroupBy) { + NKikimrWhiteboard::TTabletStateInfo& tabletStateInfo = *record.add_tabletstateinfo(); + tabletStateInfo = std::move(pr.second); } } - response->Record.SetResponseTime(ctx.Now().MilliSeconds()); - ctx.Send(ev->Sender, response.Release(), 0, ev->Cookie); + response->Record.set_responsetime(ctx.Now().MilliSeconds()); + response->Record.set_processduration((TMonotonic::Now() - now).MicroSeconds()); + ctx.Send(ev->Sender, response.release(), 0, ev->Cookie); } void Handle(TEvWhiteboard::TEvNodeStateRequest::TPtr &ev, const TActorContext &ctx) { diff --git a/ydb/core/viewer/CMakeLists.txt b/ydb/core/viewer/CMakeLists.txt index 7b001bd755..5225c9bd5c 100644 --- a/ydb/core/viewer/CMakeLists.txt +++ b/ydb/core/viewer/CMakeLists.txt @@ -32,6 +32,7 @@ target_link_libraries(ydb-core-viewer PUBLIC ydb-core-protos ydb-core-scheme core-tx-schemeshard + core-tx-tx_proxy ydb-core-util core-viewer-json core-viewer-protos @@ -75,6 +76,7 @@ target_link_libraries(ydb-core-viewer.global PUBLIC ydb-core-protos ydb-core-scheme core-tx-schemeshard + core-tx-tx_proxy ydb-core-util core-viewer-json core-viewer-protos diff --git a/ydb/core/viewer/json_nodes.h b/ydb/core/viewer/json_nodes.h index cc58aaec7a..62043bf086 100644 --- a/ydb/core/viewer/json_nodes.h +++ b/ydb/core/viewer/json_nodes.h @@ -7,6 +7,7 @@ #include <ydb/core/viewer/json/json.h> #include <ydb/core/protos/node_whiteboard.pb.h> #include <ydb/core/viewer/protos/viewer.pb.h> +#include <ydb/core/tx/tx_proxy/proxy.h> #include "viewer.h" #include "json_pipe_req.h" #include "json_sysinfo.h" @@ -29,6 +30,7 @@ class TJsonNodes : public TViewerPipeClient<TJsonNodes> { NMon::TEvHttpInfo::TPtr Event; std::unique_ptr<TEvInterconnect::TEvNodesInfo> NodesInfo; std::unordered_map<TNodeId, THolder<TEvWhiteboard::TEvPDiskStateResponse>> PDiskInfo; + std::unordered_map<TNodeId, THolder<TEvWhiteboard::TEvTabletStateResponse>> TabletInfo; std::unordered_map<TNodeId, THolder<TEvWhiteboard::TEvSystemStateResponse>> SysInfo; std::unordered_map<TString, THolder<NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult>> DescribeResult; std::unique_ptr<TEvBlobStorage::TEvControllerConfigResponse> BaseConfig; @@ -39,16 +41,44 @@ class TJsonNodes : public TViewerPipeClient<TJsonNodes> { TString FilterStoragePool; std::unordered_set<TNodeId> FilterNodeIds; std::unordered_set<ui32> FilterGroupIds; - std::unordered_set<TNodeId> NodeIds; + std::unordered_set<TNodeId> PassedNodeIds; + std::vector<TNodeId> NodeIds; + std::optional<ui32> Offset; + std::optional<ui32> MaxCount; enum class EWith { Everything, MissingDisks, SpaceProblems, }; - EWith With = EWith::Everything; + enum class EType { + Any, + Static, + Dynamic, + }; + EType Type = EType::Static; + + enum class ESort { + NodeId, + Host, + DC, + Version, + Uptime, + Memory, + CPU, + LoadAverage, + }; + ESort Sort = ESort::NodeId; + bool ReverseSort = false; + bool SortedNodeList = false; + + bool Storage = true; + bool Tablets = true; + TNodeId MinAllowedNodeId = std::numeric_limits<TNodeId>::min(); + TNodeId MaxAllowedNodeId = std::numeric_limits<TNodeId>::max(); + public: static constexpr NKikimrServices::TActivity::EType ActorActivityType() { return NKikimrServices::TActivity::VIEWER_HANDLER; @@ -69,13 +99,66 @@ public: SplitIds(params.Get("node_id"), ',', FilterNodeIds); if (params.Get("with") == "missing") { With = EWith::MissingDisks; - } if (params.Get("with") == "space") { + } else if (params.Get("with") == "space") { With = EWith::SpaceProblems; } + if (params.Has("offset")) { + Offset = FromStringWithDefault<ui32>(params.Get("offset"), 0); + } + if (params.Has("max_count")) { + MaxCount = FromStringWithDefault<ui32>(params.Get("max_count"), std::numeric_limits<ui32>::max()); + } + if (params.Get("type") == "static") { + Type = EType::Static; + } else if (params.Get("type") == "dynamic") { + Type = EType::Dynamic; + } else if (params.Get("type") == "any") { + Type = EType::Any; + } + Storage = FromStringWithDefault<bool>(params.Get("storage"), Storage); + Tablets = FromStringWithDefault<bool>(params.Get("tablets"), Tablets); + TStringBuf sort = params.Get("sort"); + if (sort) { + if (sort.StartsWith("-") || sort.StartsWith("+")) { + ReverseSort = (sort[0] == '-'); + sort.Skip(1); + } + if (sort == "NodeId") { + Sort = ESort::NodeId; + } else if (sort == "Host") { + Sort = ESort::Host; + } else if (sort == "DC") { + Sort = ESort::DC; + } else if (sort == "Version") { + Sort = ESort::Version; + } else if (sort == "Uptime") { + Sort = ESort::Uptime; + } else if (sort == "Memory") { + Sort = ESort::Memory; + } else if (sort == "CPU") { + Sort = ESort::CPU; + } else if (sort == "LoadAverage") { + Sort = ESort::LoadAverage; + } + } } void Bootstrap() { - RequestBSControllerConfig(); + if (Type != EType::Any) { + TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig; + if (dynamicNameserviceConfig) { + if (Type == EType::Static) { + MaxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId; + } + if (Type == EType::Dynamic) { + MinAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId + 1; + } + } + } + + if (Storage) { + RequestBSControllerConfig(); + } if (!FilterTenant.empty()) { SendNavigate(FilterTenant); } else { @@ -87,7 +170,7 @@ public: if (FilterNodeIds.empty()) { SendRequest(GetNameserviceActorId(), new TEvInterconnect::TEvListNodes()); } else { - for (ui32 nodeId : FilterNodeIds) { + for (TNodeId nodeId : FilterNodeIds) { SendNodeRequest(nodeId); } } @@ -119,11 +202,32 @@ public: TBase::PassAway(); } - void SendNodeRequest(ui32 nodeId) { - if (NodeIds.insert(nodeId).second) { - TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId); - SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvSystemStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId); - SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId); + void SendNodeRequest(TNodeId nodeId) { + if (nodeId >= MinAllowedNodeId && nodeId <= MaxAllowedNodeId) { + if (PassedNodeIds.insert(nodeId).second) { + // optimization for paging with default sort + if (SortedNodeList && Offset.has_value()) { + if (PassedNodeIds.size() <= Offset.value()) { + return; + } + } + if (SortedNodeList && MaxCount.has_value()) { + if (NodeIds.size() >= MaxCount.value()) { + return; + } + } + NodeIds.push_back(nodeId); + TActorId whiteboardServiceId = MakeNodeWhiteboardServiceId(nodeId); + SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvSystemStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId); + if (Storage) { + SendRequest(whiteboardServiceId, new TEvWhiteboard::TEvPDiskStateRequest(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId); + } + if (Tablets) { + auto request = std::make_unique<TEvWhiteboard::TEvTabletStateRequest>(); + request->Record.SetGroupBy("Type,State"); + SendRequest(whiteboardServiceId, request.release(), IEventHandle::FlagTrackDelivery | IEventHandle::FlagSubscribeOnSession, nodeId); + } + } } } @@ -131,7 +235,6 @@ public: auto itBaseConfigGroupIndex = BaseConfigGroupIndex.find(groupId); if (itBaseConfigGroupIndex != BaseConfigGroupIndex.end()) { for (const NKikimrBlobStorage::TVSlotId& vslot : itBaseConfigGroupIndex->second->GetVSlotId()) { - FilterNodeIds.emplace(vslot.GetNodeId()); SendNodeRequest(vslot.GetNodeId()); } } @@ -172,16 +275,43 @@ public: } void Handle(TEvInterconnect::TEvNodesInfo::TPtr& ev) { - ui32 maxAllowedNodeId = std::numeric_limits<ui32>::max(); - TIntrusivePtr<TDynamicNameserviceConfig> dynamicNameserviceConfig = AppData()->DynamicNameserviceConfig; - if (dynamicNameserviceConfig) { - maxAllowedNodeId = dynamicNameserviceConfig->MaxStaticNodeId; - } NodesInfo.reset(ev->Release().Release()); - for (const auto& ni : NodesInfo->Nodes) { - if (ni.NodeId <= maxAllowedNodeId) { - SendNodeRequest(ni.NodeId); + bool reverse = ReverseSort; + std::function<void(TVector<TEvInterconnect::TNodeInfo>&)> sortFunc; + switch (Sort) { + case ESort::NodeId: { + sortFunc = [=](TVector<TEvInterconnect::TNodeInfo>& nodes) { + ::Sort(nodes, [=](const TEvInterconnect::TNodeInfo& a, const TEvInterconnect::TNodeInfo& b) { + return reverse ^ (a.NodeId < b.NodeId); + }); + }; + break; + } + case ESort::Host: { + sortFunc = [=](TVector<TEvInterconnect::TNodeInfo>& nodes) { + ::Sort(nodes, [=](const TEvInterconnect::TNodeInfo& a, const TEvInterconnect::TNodeInfo& b) { + return reverse ^ (a.Host < b.Host); + }); + }; + break; } + case ESort::DC: { + sortFunc = [=](TVector<TEvInterconnect::TNodeInfo>& nodes) { + ::Sort(nodes, [=](const TEvInterconnect::TNodeInfo& a, const TEvInterconnect::TNodeInfo& b) { + return reverse ^ (a.Location.GetDataCenterId() < b.Location.GetDataCenterId()); + }); + }; + break; + } + default: + break; + } + if (sortFunc) { + sortFunc(NodesInfo->Nodes); + SortedNodeList = true; + } + for (const auto& ni : NodesInfo->Nodes) { + SendNodeRequest(ni.NodeId); } RequestDone(); } @@ -189,12 +319,14 @@ public: void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev) { TString path = ev->Get()->GetRecord().GetPath(); const NKikimrSchemeOp::TPathDescription& pathDescription = ev->Get()->GetRecord().GetPathDescription(); - for (const auto& storagePool : pathDescription.GetDomainDescription().GetStoragePools()) { - TString storagePoolName = storagePool.GetName(); - THolder<TEvBlobStorage::TEvControllerSelectGroups> request = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>(); - request->Record.SetReturnAllMatchingGroups(true); - request->Record.AddGroupParameters()->MutableStoragePoolSpecifier()->SetName(storagePoolName); - RequestBSControllerSelectGroups(std::move(request)); + if (Storage) { + for (const auto& storagePool : pathDescription.GetDomainDescription().GetStoragePools()) { + TString storagePoolName = storagePool.GetName(); + THolder<TEvBlobStorage::TEvControllerSelectGroups> request = MakeHolder<TEvBlobStorage::TEvControllerSelectGroups>(); + request->Record.SetReturnAllMatchingGroups(true); + request->Record.AddGroupParameters()->MutableStoragePoolSpecifier()->SetName(storagePoolName); + RequestBSControllerSelectGroups(std::move(request)); + } } DescribeResult[path] = ev->Release(); @@ -214,6 +346,11 @@ public: RequestDone(); } break; + case TEvWhiteboard::EvTabletStateRequest: + if (TabletInfo.emplace(nodeId, nullptr).second) { + RequestDone(); + } + break; } } @@ -222,8 +359,15 @@ public: if (SysInfo.emplace(nodeId, nullptr).second) { RequestDone(); } - if (PDiskInfo.emplace(nodeId, nullptr).second) { - RequestDone(); + if (Storage) { + if (PDiskInfo.emplace(nodeId, nullptr).second) { + RequestDone(); + } + } + if (Tablets) { + if (TabletInfo.emplace(nodeId, nullptr).second) { + RequestDone(); + } } } @@ -239,11 +383,22 @@ public: RequestDone(); } + void Handle(TEvWhiteboard::TEvTabletStateResponse::TPtr& ev) { + ui64 nodeId = ev.Get()->Cookie; + bool needToGroup = ev->Get()->Record.TabletStateInfoSize() > 0 && !ev->Get()->Record.GetTabletStateInfo(0).HasCount(); + TabletInfo[nodeId] = ev->Release(); + if (needToGroup) { // for compatibility with older versions + TabletInfo[nodeId] = GroupWhiteboardResponses(TabletInfo[nodeId], "Type,State", false); + } + RequestDone(); + } + STATEFN(StateWork) { switch (ev->GetTypeRewrite()) { hFunc(TEvInterconnect::TEvNodesInfo, Handle); hFunc(TEvWhiteboard::TEvSystemStateResponse, Handle); hFunc(TEvWhiteboard::TEvPDiskStateResponse, Handle); + hFunc(TEvWhiteboard::TEvTabletStateResponse, Handle); hFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle); hFunc(TEvBlobStorage::TEvControllerSelectGroupsResult, Handle); hFunc(TEvBlobStorage::TEvControllerConfigResponse, Handle); @@ -254,117 +409,168 @@ public: } } - void ReplyAndPassAway() { - NKikimrViewer::TNodesInfo nodesInfo; - std::unordered_map<TNodeId, NKikimrViewer::TNodeInfo*> nodeIndex; - std::unordered_map<TPDiskId, NKikimrWhiteboard::TPDiskStateInfo*> pDiskIndex; - - std::function<NKikimrViewer::TNodeInfo&(TNodeId)> getNode = [&nodesInfo, &nodeIndex](TNodeId nodeId) -> NKikimrViewer::TNodeInfo& { - auto itNode = nodeIndex.find(nodeId); - if (itNode != nodeIndex.end()) { - return *(itNode->second); + NKikimrViewer::TNodesInfo Result; + + NKikimrWhiteboard::TPDiskStateInfo& GetPDisk(TPDiskId pDiskId) { + auto itPDiskInfo = PDiskInfo.find(pDiskId.first); + if (itPDiskInfo == PDiskInfo.end()) { + itPDiskInfo = PDiskInfo.insert({pDiskId.first, MakeHolder<TEvWhiteboard::TEvPDiskStateResponse>()}).first; + } + + for (auto& pDiskInfo : *itPDiskInfo->second->Record.mutable_pdiskstateinfo()) { + if (pDiskInfo.pdiskid() == pDiskId.second) { + return pDiskInfo; } - NKikimrViewer::TNodeInfo& nodeInfo = *nodesInfo.AddNodes(); - nodeInfo.SetNodeId(nodeId); - nodeIndex.emplace(nodeId, &nodeInfo); - return nodeInfo; - }; - - std::function<NKikimrWhiteboard::TPDiskStateInfo&(TPDiskId)> getPDisk = [&getNode, &pDiskIndex](TPDiskId pDiskId) -> NKikimrWhiteboard::TPDiskStateInfo& { - auto itPDisk = pDiskIndex.find(pDiskId); - if (itPDisk != pDiskIndex.end()) { - return *(itPDisk->second); + } + + NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = *itPDiskInfo->second->Record.add_pdiskstateinfo(); + pDiskInfo.SetPDiskId(pDiskId.second); + return pDiskInfo; + } + + static double GetCPU(const NKikimrWhiteboard::TSystemStateInfo& sysInfo) { + double cpu = 0; + if (sysInfo.PoolStatsSize() > 0) { + for (const auto& ps : sysInfo.GetPoolStats()) { + cpu = std::max(cpu, ps.GetUsage()); } - NKikimrViewer::TNodeInfo& nodeInfo = getNode(pDiskId.first); - NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = *nodeInfo.AddPDisks(); - pDiskInfo.SetPDiskId(pDiskId.second); - pDiskIndex.emplace(pDiskId, &pDiskInfo); - return pDiskInfo; - }; - - if (BaseConfig) { + } + return cpu; + } + + static double GetLoadAverage(const NKikimrWhiteboard::TSystemStateInfo& sysInfo) { + if (sysInfo.LoadAverageSize() > 0) { + return sysInfo.GetLoadAverage(0); + } + return 0; + } + + void ReplyAndPassAway() { + if (Storage && BaseConfig) { const NKikimrBlobStorage::TEvControllerConfigResponse& pbRecord(BaseConfig->Record); const NKikimrBlobStorage::TConfigResponse::TStatus& pbStatus(pbRecord.GetResponse().GetStatus(0)); const NKikimrBlobStorage::TBaseConfig& pbConfig(pbStatus.GetBaseConfig()); for (const NKikimrBlobStorage::TBaseConfig::TPDisk& pDisk : pbConfig.GetPDisk()) { + if (!FilterNodeIds.empty() && FilterNodeIds.count(pDisk.GetNodeId()) == 0) { + continue; + } + if (pDisk.GetNodeId() < MinAllowedNodeId || pDisk.GetNodeId() > MaxAllowedNodeId) { + continue; + } TPDiskId pDiskId(pDisk.GetNodeId(), pDisk.GetPDiskId()); - NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = getPDisk(pDiskId); + NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = GetPDisk(pDiskId); pDiskInfo.SetPath(pDisk.GetPath()); pDiskInfo.SetGuid(pDisk.GetGuid()); pDiskInfo.SetCategory(static_cast<ui64>(pDisk.GetType())); - pDiskInfo.SetTotalSize(pDisk.GetPDiskMetrics().GetTotalSize()); - pDiskInfo.SetAvailableSize(pDisk.GetPDiskMetrics().GetAvailableSize()); + if (pDiskInfo.GetTotalSize() == 0) { + pDiskInfo.SetTotalSize(pDisk.GetPDiskMetrics().GetTotalSize()); + } + if (pDiskInfo.GetAvailableSize() == 0) { + pDiskInfo.SetAvailableSize(pDisk.GetPDiskMetrics().GetAvailableSize()); + } } } + ui64 totalNodes = NodeIds.size(); + for (TNodeId nodeId : NodeIds) { - if (!FilterNodeIds.empty() && FilterNodeIds.count(nodeId) == 0) { - continue; + if (Storage) { + if (With == EWith::MissingDisks) { + auto itPDiskState = PDiskInfo.find(nodeId); + if (itPDiskState != PDiskInfo.end() && itPDiskState->second) { + int disksNormal = 0; + for (const auto& protoPDiskInfo : itPDiskState->second->Record.GetPDiskStateInfo()) { + if (protoPDiskInfo.state() == NKikimrBlobStorage::TPDiskState::Normal) { + ++disksNormal; + } + } + if (itPDiskState->second->Record.pdiskstateinfo_size() == disksNormal) { + continue; + } + } + } + if (With == EWith::SpaceProblems) { + auto itSystemState = SysInfo.find(nodeId); + if (itSystemState != SysInfo.end() && itSystemState->second && itSystemState->second->Record.SystemStateInfoSize() > 0) { + if (itSystemState->second->Record.GetSystemStateInfo(0).GetMaxDiskUsage() < 85) { + continue; + } + } + } } - NKikimrViewer::TNodeInfo& nodeInfo = getNode(nodeId); + NKikimrViewer::TNodeInfo& nodeInfo = *Result.add_nodes(); + nodeInfo.set_nodeid(nodeId); auto itSystemState = SysInfo.find(nodeId); if (itSystemState != SysInfo.end() && itSystemState->second) { *nodeInfo.MutableSystemState() = itSystemState->second->Record.GetSystemStateInfo(0); - } else { + } else if (NodesInfo != nullptr) { auto* icNodeInfo = NodesInfo->GetNodeInfo(nodeId); if (icNodeInfo != nullptr) { nodeInfo.MutableSystemState()->SetHost(icNodeInfo->Host); } } - auto itPDiskState = PDiskInfo.find(nodeId); - if (itPDiskState != PDiskInfo.end() && itPDiskState->second) { - for (const auto& protoPDiskInfo : itPDiskState->second->Record.GetPDiskStateInfo()) { - NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = getPDisk({nodeId, protoPDiskInfo.GetPDiskId()}); - pDiskInfo.MergeFrom(protoPDiskInfo); - } - } - } - - ui64 totalNodes = nodesInfo.NodesSize(); - - if (!FilterNodeIds.empty() || !FilterTenant.empty()) { - for (auto itNode = nodesInfo.MutableNodes()->begin(); itNode != nodesInfo.MutableNodes()->end();) { - if (FilterNodeIds.count(itNode->GetNodeId()) == 0) { - itNode = nodesInfo.MutableNodes()->erase(itNode); - } else { - ++itNode; + if (Storage) { + auto itPDiskState = PDiskInfo.find(nodeId); + if (itPDiskState != PDiskInfo.end() && itPDiskState->second) { + for (auto& protoPDiskInfo : *itPDiskState->second->Record.MutablePDiskStateInfo()) { + NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo = *nodeInfo.AddPDisks(); + pDiskInfo = std::move(protoPDiskInfo); + } } } - } - - if (With == EWith::MissingDisks) { - for (auto itNode = nodesInfo.MutableNodes()->begin(); itNode != nodesInfo.MutableNodes()->end();) { - size_t disksNormal = 0; - for (const NKikimrWhiteboard::TPDiskStateInfo& pDiskInfo : itNode->GetPDisks()) { - if (pDiskInfo.GetState() == NKikimrBlobStorage::TPDiskState::Normal) { - ++disksNormal; + if (Tablets) { + auto itTabletState = TabletInfo.find(nodeId); + if (itTabletState != TabletInfo.end() && itTabletState->second) { + for (auto& protoTabletInfo : *itTabletState->second->Record.MutableTabletStateInfo()) { + NKikimrWhiteboard::TTabletStateInfo& tabletInfo = *nodeInfo.AddTablets(); + tabletInfo = std::move(protoTabletInfo); } } - if (itNode->PDisksSize() == disksNormal && disksNormal != 0) { - itNode = nodesInfo.MutableNodes()->erase(itNode); - } else { - ++itNode; - } } } - if (With == EWith::SpaceProblems) { - for (auto itNode = nodesInfo.MutableNodes()->begin(); itNode != nodesInfo.MutableNodes()->end();) { - if (itNode->GetSystemState().GetMaxDiskUsage() < 85) { - itNode = nodesInfo.MutableNodes()->erase(itNode); - } else { - ++itNode; - } - } + bool reverse = ReverseSort; + + switch (Sort) { + case ESort::NodeId: + case ESort::Host: + case ESort::DC: + // already sorted + break; + case ESort::Version: + ::Sort(*Result.MutableNodes(), [reverse](const NKikimrViewer::TNodeInfo& a, const NKikimrViewer::TNodeInfo& b) { + return reverse ^ (a.GetSystemState().GetVersion() < b.GetSystemState().GetVersion()); + }); + break; + case ESort::Uptime: + ::Sort(*Result.MutableNodes(), [reverse](const NKikimrViewer::TNodeInfo& a, const NKikimrViewer::TNodeInfo& b) { + return reverse ^ !(a.GetSystemState().GetStartTime() < b.GetSystemState().GetStartTime()); + }); + break; + case ESort::Memory: + ::Sort(*Result.MutableNodes(), [reverse](const NKikimrViewer::TNodeInfo& a, const NKikimrViewer::TNodeInfo& b) { + return reverse ^ (a.GetSystemState().GetMemoryUsed() < b.GetSystemState().GetMemoryUsed()); + }); + break; + case ESort::CPU: + ::Sort(*Result.MutableNodes(), [reverse](const NKikimrViewer::TNodeInfo& a, const NKikimrViewer::TNodeInfo& b) { + return reverse ^ (GetCPU(a.GetSystemState()) < GetCPU(b.GetSystemState())); + }); + break; + case ESort::LoadAverage: + ::Sort(*Result.MutableNodes(), [reverse](const NKikimrViewer::TNodeInfo& a, const NKikimrViewer::TNodeInfo& b) { + return reverse ^ (GetLoadAverage(a.GetSystemState()) < GetLoadAverage(b.GetSystemState())); + }); + break; } - ui64 foundNodes = nodesInfo.NodesSize(); + ui64 foundNodes = Result.NodesSize(); - nodesInfo.SetTotalNodes(totalNodes); - nodesInfo.SetFoundNodes(foundNodes); + Result.SetTotalNodes(totalNodes); + Result.SetFoundNodes(foundNodes); TStringStream json; - TProtoToJson::ProtoToJson(json, nodesInfo, JsonSettings); + TProtoToJson::ProtoToJson(json, Result, JsonSettings); Send(Initiator, new NMon::TEvHttpInfoRes(Viewer->GetHTTPOKJSON(Event->Get(), std::move(json.Str())), 0, NMon::IEvHttpInfoRes::EContentType::Custom)); PassAway(); } diff --git a/ydb/core/viewer/protos/viewer.proto b/ydb/core/viewer/protos/viewer.proto index ad9e3c94f9..86e4ef9341 100644 --- a/ydb/core/viewer/protos/viewer.proto +++ b/ydb/core/viewer/protos/viewer.proto @@ -395,6 +395,7 @@ message TNodeInfo { uint32 NodeId = 1; NKikimrWhiteboard.TSystemStateInfo SystemState = 2; repeated NKikimrWhiteboard.TPDiskStateInfo PDisks = 3; + repeated NKikimrWhiteboard.TTabletStateInfo Tablets = 5; } message TNodesInfo { diff --git a/ydb/core/viewer/wb_merge.h b/ydb/core/viewer/wb_merge.h index 27fd3c8f67..ca8e269e7c 100644 --- a/ydb/core/viewer/wb_merge.h +++ b/ydb/core/viewer/wb_merge.h @@ -151,7 +151,8 @@ public: static THolder<TResponseType> MergeResponsesBase(TMap<ui32, THolder<TResponseType>>& responses, const MergeKey& mergeKey) { std::unordered_map<typename MergeKey::KeyType, TElementType*> mergedData; ui64 minResponseTime = 0; - ui32 maxResponseDuration = 0; + ui64 maxResponseDuration = 0; + //ui64 sumProcessDuration = 0; TWhiteboardMergerComparator<TElementType> comparator; for (auto it = responses.begin(); it != responses.end(); ++it) { if (it->second != nullptr) { @@ -174,6 +175,7 @@ public: if (maxResponseDuration == 0 || it->second->Record.GetResponseDuration() > maxResponseDuration) { maxResponseDuration = it->second->Record.GetResponseDuration(); } + //sumProcessDuration += it->second->Record.GetProcessDuration(); } } @@ -190,6 +192,9 @@ public: if (maxResponseDuration) { result->Record.SetResponseDuration(maxResponseDuration); } + //if (sumProcessDuration) { + // result->Record.SetProcessDuration(sumProcessDuration); + //} return result; } |