diff --git a/cloud/filestore/libs/diagnostics/user_counter.cpp b/cloud/filestore/libs/diagnostics/user_counter.cpp index 9e2d8dbf711..8f9c87212fd 100644 --- a/cloud/filestore/libs/diagnostics/user_counter.cpp +++ b/cloud/filestore/libs/diagnostics/user_counter.cpp @@ -11,6 +11,7 @@ namespace { //////////////////////////////////////////////////////////////////////////////// +// Read/Write counters constexpr TStringBuf FILESTORE_READ_OPS = "filestore.read_ops"; constexpr TStringBuf FILESTORE_READ_OPS_BURST = "filestore.read_ops_burst"; constexpr TStringBuf FILESTORE_READ_BYTES = "filestore.read_bytes"; @@ -23,8 +24,32 @@ constexpr TStringBuf FILESTORE_WRITE_BYTES = "filestore.write_bytes"; constexpr TStringBuf FILESTORE_WRITE_BYTES_BURST = "filestore.write_bytes_burst"; constexpr TStringBuf FILESTORE_WRITE_LATENCY = "filestore.write_latency"; constexpr TStringBuf FILESTORE_WRITE_ERRORS = "filestore.write_errors"; + +// Index operation counters constexpr TStringBuf FILESTORE_INDEX_OPS = "filestore.index_ops"; +constexpr TStringBuf FILESTORE_INDEX_LATENCY = "filestore.index_latency"; constexpr TStringBuf FILESTORE_INDEX_ERRORS = "filestore.index_errors"; +constexpr TStringBuf FILESTORE_INDEX_CUMULATIVE_TIME = "filestore.index_cumulative_time"; + +const THashMap FILESTORE_INDEX_OPS_NAMES = { + {"AllocateData", "fallocate"}, + {"CreateHandle", "open"}, + {"CreateNode", "createnode"}, + {"DestroyHandle", "release"}, + {"GetNodeAttr", "getattr"}, + {"GetNodeXAttr", "getxattr"}, + {"ListNodeXAttr", "listxattr"}, + {"ListNodes", "readdir"}, + {"RenameNode", "rename"}, + {"SetNodeAttr", "setattr"}, + {"SetNodeXAttr", "setxattr"}, + {"UnlinkNode", "unlink"}, + {"StatFileStore", "statfs"}, + {"ReadLink", "readlink"}, + {"AccessNode", "access"}, + {"RemoveNodeXAttr", "removexattr"}, + {"ReleaseLock", "releaselock"}, + {"AcquireLock", "acquirelock"}}; //////////////////////////////////////////////////////////////////////////////// @@ -214,6 +239,19 @@ TLabels MakeFilestoreLabels( {"instance", instanceId}}; } +TLabels MakeFilestoreLabelsWithRequestName( + const TString& cloudId, + const TString& folderId, + const TString& filestoreId, + const TString& instanceId, + const TString& requestName) +{ + auto labels = + MakeFilestoreLabels(cloudId, folderId, filestoreId, instanceId); + labels.Add("request", requestName); + return labels; +} + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -308,12 +346,45 @@ void RegisterFilestore( request.first.LabelValue != "ReadData" && request.first.LabelValue != "WriteData") { - indexOpsCounters.emplace_back( - src->FindSubgroup("request", request.first.LabelValue), - "Count"); - indexErrorCounters.emplace_back( - src->FindSubgroup("request", request.first.LabelValue), - "Errors/Fatal"); + const auto indexSubgroup = + src->FindSubgroup("request", request.first.LabelValue); + + indexOpsCounters.emplace_back(indexSubgroup, "Count"); + indexErrorCounters.emplace_back(indexSubgroup, "Errors/Fatal"); + + const auto& metricName = + FILESTORE_INDEX_OPS_NAMES.find(request.first.LabelValue); + if (metricName) { + const auto labels = MakeFilestoreLabelsWithRequestName( + cloudId, + folderId, + filestoreId, + instanceId, + metricName->second); + AddUserMetric( + dsc, + labels, + {{indexSubgroup, "Count"}}, + FILESTORE_INDEX_OPS); + AddUserMetric( + dsc, + labels, + { {indexSubgroup, "Time"}}, + FILESTORE_INDEX_CUMULATIVE_TIME + ); + AddHistogramUserMetric( + MS_BUCKETS, + dsc, + labels, + {indexSubgroup, "Time"}, + FILESTORE_INDEX_LATENCY); + AddUserMetric( + dsc, + labels, + { {indexSubgroup, "Errors/Fatal"}}, + FILESTORE_INDEX_ERRORS + ); + } } } @@ -355,6 +426,19 @@ void UnregisterFilestore( dsc.RemoveUserMetric(commonLabels, FILESTORE_INDEX_OPS); dsc.RemoveUserMetric(commonLabels, FILESTORE_INDEX_ERRORS); + + for (const auto& [_, requestName]: FILESTORE_INDEX_OPS_NAMES) { + const auto labels = MakeFilestoreLabelsWithRequestName( + cloudId, + folderId, + filestoreId, + instanceId, + requestName); + dsc.RemoveUserMetric(labels, FILESTORE_INDEX_OPS); + dsc.RemoveUserMetric(labels, FILESTORE_INDEX_CUMULATIVE_TIME); + dsc.RemoveUserMetric(labels, FILESTORE_INDEX_LATENCY); + dsc.RemoveUserMetric(labels, FILESTORE_INDEX_ERRORS); + } } } // NCloud::NFileStore::NUserCounter diff --git a/cloud/filestore/libs/diagnostics/user_counter_ut.cpp b/cloud/filestore/libs/diagnostics/user_counter_ut.cpp index 51c52864cf9..0b49568e01f 100644 --- a/cloud/filestore/libs/diagnostics/user_counter_ut.cpp +++ b/cloud/filestore/libs/diagnostics/user_counter_ut.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace NCloud::NFileStore::NUserCounter { @@ -120,200 +121,7 @@ Y_UNIT_TEST_SUITE(TUserWrapperTest) const TString fsId = "test_fs"; const TString clientId = "test_client"; - const TString testResult = R"--({ - "sensors":[ - { - "kind":"GAUGE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.read_bytes_burst" - }, - "ts":12, - "value":0 - }, - { - "kind":"GAUGE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.read_ops_burst" - }, - "ts":12, - "value":0 - }, - { - "kind":"RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.read_ops" - }, - "ts":12, - "value":0 - }, - { - "kind":"HIST_RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.read_latency" - }, - "ts":12, - "hist":{ - "bounds":[1,2,5,10,20,50,100,200,500,1000,2000,5000,10000,35000], - "buckets":[0,0,0,0,0,0,0,0,0,0,0,0,0,0], - "inf":0 - } - }, - { - "kind":"HIST_RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.write_latency" - }, - "ts":12, - "hist":{ - "bounds":[1,2,5,10,20,50,100,200,500,1000,2000,5000,10000,35000], - "buckets":[0,0,0,0,0,0,0,0,0,0,0,0,0,0], - "inf":0 - } - }, - { - "kind":"RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.index_errors" - }, - "ts":12, - "value":0 - }, - { - "kind":"GAUGE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.write_bytes_burst" - }, - "ts":12, - "value":0 - }, - { - "kind":"GAUGE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.write_ops_burst" - }, - "ts":12, - "value":0 - }, - { - "kind":"RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.read_errors" - }, - "ts":12, - "value":0 - }, - { - "kind":"RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.write_bytes" - }, - "ts":12, - "value":0 - }, - { - "kind":"RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.index_ops" - }, - "ts":12, - "value":0 - }, - { - "kind":"RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.write_ops" - }, - "ts":12, - "value":0 - }, - { - "kind":"RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.write_errors" - }, - "ts":12, - "value":0 - }, - { - "kind":"RATE", - "labels":{ - "service":"compute", - "project":"cloud", - "cluster":"folder", - "filestore":"test_fs", - "instance":"test_client", - "name":"filestore.read_bytes" - }, - "ts":12, - "value":0 - } - ] - })--"; + const TString testResult = NResource::Find("counters.json"); auto testJson = NJson::ReadJsonFastTree(testResult, true); auto emptyJson = NJson::ReadJsonFastTree("{}", true); diff --git a/cloud/filestore/libs/diagnostics/ut/data/counters.json b/cloud/filestore/libs/diagnostics/ut/data/counters.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cloud/filestore/libs/diagnostics/ut/ya.make b/cloud/filestore/libs/diagnostics/ut/ya.make index 8aef226e02b..8626a47a9e2 100644 --- a/cloud/filestore/libs/diagnostics/ut/ya.make +++ b/cloud/filestore/libs/diagnostics/ut/ya.make @@ -13,4 +13,8 @@ PEERDIR( library/cpp/eventlog/dumper ) +RESOURCE( + data/counters.json counters.json +) + END() diff --git a/cloud/storage/core/libs/diagnostics/request_counters.cpp b/cloud/storage/core/libs/diagnostics/request_counters.cpp index ee5997b0286..81a04afd2ab 100644 --- a/cloud/storage/core/libs/diagnostics/request_counters.cpp +++ b/cloud/storage/core/libs/diagnostics/request_counters.cpp @@ -339,6 +339,13 @@ struct TRequestCounters::TStatCounters // initialization is enabled and the values are zeroes Count = counters.GetCounter("Count", true); ErrorsFatal = counters.GetCounter("Errors/Fatal", true); + Time = counters.GetCounter("Time", true); + if (ReportControlPlaneHistogram) { + TimeHist.Register(counters, "Time"); + } else { + TimePercentiles.Register( + *counters.GetSubgroup("percentiles", "Time")); + } } void FullInitIfNeeded() @@ -354,7 +361,6 @@ struct TRequestCounters::TStatCounters auto& counters = *CountersGroup; - Time = counters.GetCounter("Time", true); MaxTime = counters.GetCounter("MaxTime"); MaxTotalTime = counters.GetCounter("MaxTotalTime"); @@ -426,13 +432,6 @@ struct TRequestCounters::TStatCounters counters.GetCounter("PostponedCountGrpc", true); FastPathHits = counters.GetCounter("FastPathHits", true); - } else { - if (ReportControlPlaneHistogram) { - TimeHist.Register(counters, "Time"); - } else { - TimePercentiles.Register( - *counters.GetSubgroup("percentiles", "Time")); - } } AtomicSet(FullyInitialized, true);