diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/monlib/dynamic_counters/page.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/monlib/dynamic_counters/page.cpp')
-rw-r--r-- | library/cpp/monlib/dynamic_counters/page.cpp | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/library/cpp/monlib/dynamic_counters/page.cpp b/library/cpp/monlib/dynamic_counters/page.cpp new file mode 100644 index 0000000000..5124a47bb3 --- /dev/null +++ b/library/cpp/monlib/dynamic_counters/page.cpp @@ -0,0 +1,141 @@ +#include "page.h" +#include "encode.h" + +#include <library/cpp/monlib/service/pages/templates.h> +#include <library/cpp/string_utils/quote/quote.h> + +#include <util/string/split.h> +#include <util/system/tls.h> + +using namespace NMonitoring; + +namespace { + Y_POD_STATIC_THREAD(TDynamicCounters*) + currentCounters(nullptr); +} + +TMaybe<EFormat> ParseFormat(TStringBuf str) { + if (str == TStringBuf("json")) { + return EFormat::JSON; + } else if (str == TStringBuf("spack")) { + return EFormat::SPACK; + } else if (str == TStringBuf("prometheus")) { + return EFormat::PROMETHEUS; + } else { + return Nothing(); + } +} + +void TDynamicCountersPage::Output(NMonitoring::IMonHttpRequest& request) { + if (OutputCallback) { + OutputCallback(); + } + + TCountableBase::EVisibility visibility{ + TCountableBase::EVisibility::Public + }; + + TVector<TStringBuf> parts; + StringSplitter(request.GetPathInfo()) + .Split('/') + .SkipEmpty() + .Collect(&parts); + + TMaybe<EFormat> format = !parts.empty() ? ParseFormat(parts.back()) : Nothing(); + if (format) { + parts.pop_back(); + } + + if (!parts.empty() && parts.back() == TStringBuf("private")) { + visibility = TCountableBase::EVisibility::Private; + parts.pop_back(); + } + + auto counters = Counters; + + for (const auto& escaped : parts) { + const auto part = CGIUnescapeRet(escaped); + + TVector<TString> labels; + StringSplitter(part).Split('=').SkipEmpty().Collect(&labels); + + if (labels.size() != 2U) + return NotFound(request); + + if (const auto child = counters->FindSubgroup( + labels.front(), + labels.back())) { + + counters = child; + } else { + return HandleAbsentSubgroup(request); + } + } + + if (!format) { + currentCounters = counters.Get(); + THtmlMonPage::Output(request); + currentCounters = nullptr; + return; + } + + IOutputStream& out = request.Output(); + if (*format == EFormat::JSON) { + out << HTTPOKJSON; + } else if (*format == EFormat::SPACK) { + out << HTTPOKSPACK; + } else if (*format == EFormat::PROMETHEUS) { + out << HTTPOKPROMETHEUS; + } else { + ythrow yexception() << "unsupported metric encoding format: " << *format; + } + + auto encoder = CreateEncoder(&out, *format, visibility); + counters->Accept(TString(), TString(), *encoder); + out.Flush(); +} + +void TDynamicCountersPage::HandleAbsentSubgroup(IMonHttpRequest& request) { + if (UnknownGroupPolicy == EUnknownGroupPolicy::Error) { + NotFound(request); + } else if (UnknownGroupPolicy == EUnknownGroupPolicy::Ignore) { + NoContent(request); + } else { + Y_FAIL("Unsupported policy set"); + } +} + +void TDynamicCountersPage::BeforePre(IMonHttpRequest& request) { + IOutputStream& out = request.Output(); + HTML(out) { + DIV() { + out << "<a href='" << request.GetPath() << "/json'>Counters as JSON</a>"; + out << " for <a href='https://wiki.yandex-team.ru/solomon/'>Solomon</a>"; + } + + H5() { + out << "Counters subgroups"; + } + UL() { + currentCounters->EnumerateSubgroups([&](const TString& name, const TString& value) { + LI() { + TString pathPart = name + "=" + value; + Quote(pathPart, ""); + out << "\n<a href='" << request.GetPath() << "/" << pathPart << "'>" << name << " " << value << "</a>"; + } + }); + } + + H4() { + out << "Counters as text"; + } + } +} + +void TDynamicCountersPage::OutputText(IOutputStream& out, IMonHttpRequest&) { + currentCounters->OutputPlainText(out); +} + +void TDynamicCountersPage::SetUnknownGroupPolicy(EUnknownGroupPolicy value) { + UnknownGroupPolicy = value; +} |