diff options
author | Sergey Polovko <sergey@polovko.me> | 2022-02-10 16:47:03 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:03 +0300 |
commit | 2e714b5ebd40a1f4cc31c27f1ad6e49ca6d895f5 (patch) | |
tree | b83306b6e37edeea782e9eed673d89286c4fef35 /library/cpp | |
parent | 3e0b762a82514bac89c1dd6ea7211e381d8aa248 (diff) | |
download | ydb-2e714b5ebd40a1f4cc31c27f1ad6e49ca6d895f5.tar.gz |
Restoring authorship annotation for Sergey Polovko <sergey@polovko.me>. Commit 2 of 2.
Diffstat (limited to 'library/cpp')
353 files changed, 13918 insertions, 13918 deletions
diff --git a/library/cpp/actors/core/actor.cpp b/library/cpp/actors/core/actor.cpp index c84b8d7e2f..6f9ba6a42b 100644 --- a/library/cpp/actors/core/actor.cpp +++ b/library/cpp/actors/core/actor.cpp @@ -7,7 +7,7 @@ namespace NActors { Y_POD_THREAD(TActivationContext*) TlsActivationContext((TActivationContext*)nullptr); - bool TActorContext::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { + bool TActorContext::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { return Send(new IEventHandle(recipient, SelfID, ev, flags, cookie, nullptr, std::move(traceId))); } @@ -15,7 +15,7 @@ namespace NActors { return ExecutorThread.Send(ev); } - void IActor::Registered(TActorSystem* sys, const TActorId& owner) { + void IActor::Registered(TActorSystem* sys, const TActorId& owner) { // fallback to legacy method, do not use it anymore if (auto eh = AfterRegister(SelfId(), owner)) sys->Send(eh); @@ -25,7 +25,7 @@ namespace NActors { SelfActorId.Out(out); } - bool IActor::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const noexcept { + bool IActor::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const noexcept { return SelfActorId.Send(recipient, ev, flags, cookie, std::move(traceId)); } @@ -33,19 +33,19 @@ namespace NActors { return TlsActivationContext->ExecutorThread.Send(ev); } - void TActivationContext::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { - TlsActivationContext->ExecutorThread.Schedule(deadline, ev, cookie); - } - + void TActivationContext::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { + TlsActivationContext->ExecutorThread.Schedule(deadline, ev, cookie); + } + void TActivationContext::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { TlsActivationContext->ExecutorThread.Schedule(deadline, ev, cookie); } void TActivationContext::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { - TlsActivationContext->ExecutorThread.Schedule(delta, ev, cookie); + TlsActivationContext->ExecutorThread.Schedule(delta, ev, cookie); } - bool TActorIdentity::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { + bool TActorIdentity::Send(const TActorId& recipient, IEventBase* ev, ui32 flags, ui64 cookie, NWilson::TTraceId traceId) const { return TActivationContext::Send(new IEventHandle(recipient, *this, ev, flags, cookie, nullptr, std::move(traceId))); } @@ -75,11 +75,11 @@ namespace NActors { return TlsActivationContext->ExecutorThread.RegisterActor(actor, &TlsActivationContext->Mailbox, SelfActorId.Hint(), SelfActorId); } - TActorId TActivationContext::Register(IActor* actor, TActorId parentId, TMailboxType::EType mailboxType, ui32 poolId) { + TActorId TActivationContext::Register(IActor* actor, TActorId parentId, TMailboxType::EType mailboxType, ui32 poolId) { return TlsActivationContext->ExecutorThread.RegisterActor(actor, mailboxType, poolId, parentId); } - TActorId TActivationContext::InterconnectProxy(ui32 destinationNodeId) { + TActorId TActivationContext::InterconnectProxy(ui32 destinationNodeId) { return TlsActivationContext->ExecutorThread.ActorSystem->InterconnectProxy(destinationNodeId); } @@ -95,36 +95,36 @@ namespace NActors { return NHPTimer::GetSeconds(GetCurrentEventTicks()); } - TActorId TActorContext::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const { + TActorId TActorContext::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const { return ExecutorThread.RegisterActor(actor, mailboxType, poolId, SelfID); } - TActorId IActor::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const noexcept { + TActorId IActor::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId) const noexcept { return TlsActivationContext->ExecutorThread.RegisterActor(actor, mailboxType, poolId, SelfActorId); } - void TActorContext::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const { - ExecutorThread.Schedule(deadline, new IEventHandle(SelfID, TActorId(), ev), cookie); - } - + void TActorContext::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const { + ExecutorThread.Schedule(deadline, new IEventHandle(SelfID, TActorId(), ev), cookie); + } + void TActorContext::Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie) const { ExecutorThread.Schedule(deadline, new IEventHandle(SelfID, TActorId(), ev), cookie); } void TActorContext::Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie) const { - ExecutorThread.Schedule(delta, new IEventHandle(SelfID, TActorId(), ev), cookie); + ExecutorThread.Schedule(delta, new IEventHandle(SelfID, TActorId(), ev), cookie); + } + + void IActor::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const noexcept { + TlsActivationContext->ExecutorThread.Schedule(deadline, new IEventHandle(SelfActorId, TActorId(), ev), cookie); } - void IActor::Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie) const noexcept { - TlsActivationContext->ExecutorThread.Schedule(deadline, new IEventHandle(SelfActorId, TActorId(), ev), cookie); - } - void IActor::Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie) const noexcept { TlsActivationContext->ExecutorThread.Schedule(deadline, new IEventHandle(SelfActorId, TActorId(), ev), cookie); } void IActor::Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie) const noexcept { - TlsActivationContext->ExecutorThread.Schedule(delta, new IEventHandle(SelfActorId, TActorId(), ev), cookie); + TlsActivationContext->ExecutorThread.Schedule(delta, new IEventHandle(SelfActorId, TActorId(), ev), cookie); } TInstant TActivationContext::Now() { diff --git a/library/cpp/actors/core/actor.h b/library/cpp/actors/core/actor.h index 8bfef6b5bd..ed29bd14b9 100644 --- a/library/cpp/actors/core/actor.h +++ b/library/cpp/actors/core/actor.h @@ -36,17 +36,17 @@ namespace NActors { public: static bool Send(TAutoPtr<IEventHandle> ev); - - /** - * Schedule one-shot event that will be send at given time point in the future. - * + + /** + * Schedule one-shot event that will be send at given time point in the future. + * * @param deadline the wallclock time point in future when event must be send - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event - */ - static void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); - - /** + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event + */ + static void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); + + /** * Schedule one-shot event that will be send at given time point in the future. * * @param deadline the monotonic time point in future when event must be send @@ -56,12 +56,12 @@ namespace NActors { static void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); /** - * Schedule one-shot event that will be send after given delay. - * - * @param delta the time from now to delay event sending - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event - */ + * Schedule one-shot event that will be send after given delay. + * + * @param delta the time from now to delay event sending + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event + */ static void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); static TInstant Now(); @@ -79,9 +79,9 @@ namespace NActors { static TActorId RegisterWithSameMailbox(IActor* actor, TActorId parentId); static const TActorContext& AsActorContext(); - static TActorContext ActorContextFor(TActorId id); + static TActorContext ActorContextFor(TActorId id); - static TActorId InterconnectProxy(ui32 nodeid); + static TActorId InterconnectProxy(ui32 nodeid); static TActorSystem* ActorSystem(); static i64 GetCurrentEventTicks(); @@ -89,34 +89,34 @@ namespace NActors { }; struct TActorContext: public TActivationContext { - const TActorId SelfID; + const TActorId SelfID; - explicit TActorContext(TMailboxHeader& mailbox, TExecutorThread& executorThread, NHPTimer::STime eventStart, const TActorId& selfID) + explicit TActorContext(TMailboxHeader& mailbox, TExecutorThread& executorThread, NHPTimer::STime eventStart, const TActorId& selfID) : TActivationContext(mailbox, executorThread, eventStart) , SelfID(selfID) { } - bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const; + bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const; template <typename TEvent> - bool Send(const TActorId& recipient, THolder<TEvent> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const { + bool Send(const TActorId& recipient, THolder<TEvent> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const { return Send(recipient, static_cast<IEventBase*>(ev.Release()), flags, cookie, std::move(traceId)); } bool Send(TAutoPtr<IEventHandle> ev) const; - + TInstant Now() const; TMonotonic Monotonic() const; - /** - * Schedule one-shot event that will be send at given time point in the future. - * + /** + * Schedule one-shot event that will be send at given time point in the future. + * * @param deadline the wallclock time point in future when event must be send - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event - */ - void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; - - /** + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event + */ + void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; + + /** * Schedule one-shot event that will be send at given time point in the future. * * @param deadline the monotonic time point in future when event must be send @@ -126,20 +126,20 @@ namespace NActors { void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; /** - * Schedule one-shot event that will be send after given delay. - * - * @param delta the time from now to delay event sending - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event - */ + * Schedule one-shot event that will be send after given delay. + * + * @param delta the time from now to delay event sending + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event + */ void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; - - TActorContext MakeFor(const TActorId& otherId) const { + + TActorContext MakeFor(const TActorId& otherId) const { return TActorContext(Mailbox, ExecutorThread, EventStart, otherId); } // register new actor in ActorSystem on new fresh mailbox. - TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const; + TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const; // Register new actor in ActorSystem on same _mailbox_ as current actor. // There is one thread per mailbox to execute actor, which mean @@ -153,17 +153,17 @@ namespace NActors { extern Y_POD_THREAD(TActivationContext*) TlsActivationContext; - struct TActorIdentity: public TActorId { - explicit TActorIdentity(TActorId actorId) - : TActorId(actorId) + struct TActorIdentity: public TActorId { + explicit TActorIdentity(TActorId actorId) + : TActorId(actorId) { } - void operator=(TActorId actorId) { + void operator=(TActorId actorId) { *this = TActorIdentity(actorId); } - bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const; + bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const; void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const; @@ -174,18 +174,18 @@ namespace NActors { class IActorOps : TNonCopyable { public: virtual void Describe(IOutputStream&) const noexcept = 0; - virtual bool Send(const TActorId& recipient, IEventBase*, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const noexcept = 0; - - /** - * Schedule one-shot event that will be send at given time point in the future. - * + virtual bool Send(const TActorId& recipient, IEventBase*, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const noexcept = 0; + + /** + * Schedule one-shot event that will be send at given time point in the future. + * * @param deadline the wallclock time point in future when event must be send - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event - */ - virtual void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept = 0; - - /** + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event + */ + virtual void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept = 0; + + /** * Schedule one-shot event that will be send at given time point in the future. * * @param deadline the monotonic time point in future when event must be send @@ -195,15 +195,15 @@ namespace NActors { virtual void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept = 0; /** - * Schedule one-shot event that will be send after given delay. - * - * @param delta the time from now to delay event sending - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event - */ - virtual void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept = 0; - - virtual TActorId Register(IActor*, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const noexcept = 0; + * Schedule one-shot event that will be send after given delay. + * + * @param delta the time from now to delay event sending + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event + */ + virtual void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept = 0; + + virtual TActorId Register(IActor*, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const noexcept = 0; virtual TActorId RegisterWithSameMailbox(IActor*) const noexcept = 0; }; @@ -219,7 +219,7 @@ namespace NActors { i64 ElapsedTicks; ui64 HandledEvents; - friend void DoActorInit(TActorSystem*, IActor*, const TActorId&, const TActorId&); + friend void DoActorInit(TActorSystem*, IActor*, const TActorId&, const TActorId&); friend class TDecorator; public: @@ -254,7 +254,7 @@ namespace NActors { protected: IActor(TReceiveFunc stateFunc, ui32 activityType = OTHER) : StateFunc(stateFunc) - , SelfActorId(TActorId()) + , SelfActorId(TActorId()) , ElapsedTicks(0) , HandledEvents(0) , ActivityType(activityType) @@ -310,7 +310,7 @@ namespace NActors { InvokeOtherActor(TActor& actor, TMethod&& method, TArgs&&... args) { struct TRecurseContext : TActorContext { TActivationContext *Prev; - TRecurseContext(const TActorId& actorId) + TRecurseContext(const TActorId& actorId) : TActorContext(TActivationContext::ActorContextFor(actorId)) , Prev(TlsActivationContext) { @@ -323,9 +323,9 @@ namespace NActors { return (actor.*method)(std::forward<TArgs>(args)...); } - virtual void Registered(TActorSystem* sys, const TActorId& owner); + virtual void Registered(TActorSystem* sys, const TActorId& owner); - virtual TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) { + virtual TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) { Y_UNUSED(self); Y_UNUSED(parentId); return TAutoPtr<IEventHandle>(); @@ -350,23 +350,23 @@ namespace NActors { protected: void Describe(IOutputStream&) const noexcept override; - bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const noexcept final; + bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const noexcept final; template <typename TEvent> - bool Send(const TActorId& recipient, THolder<TEvent> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const{ + bool Send(const TActorId& recipient, THolder<TEvent> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) const{ return Send(recipient, static_cast<IEventBase*>(ev.Release()), flags, cookie, std::move(traceId)); } - + template <class TEvent, class ... TEventArgs> bool Send(TActorId recipient, TEventArgs&& ... args) const { return Send(recipient, MakeHolder<TEvent>(std::forward<TEventArgs>(args)...)); } - void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final; + void Schedule(TInstant deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final; void Schedule(TMonotonic deadline, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final; void Schedule(TDuration delta, IEventBase* ev, ISchedulerCookie* cookie = nullptr) const noexcept final; // register new actor in ActorSystem on new fresh mailbox. - TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const noexcept final; + TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) const noexcept final; // Register new actor in ActorSystem on same _mailbox_ as current actor. // There is one thread per mailbox to execute actor, which mean @@ -454,7 +454,7 @@ namespace NActors { return *static_cast<TActorContext*>(tls); } - inline TActorContext TActivationContext::ActorContextFor(TActorId id) { + inline TActorContext TActivationContext::ActorContextFor(TActorId id) { auto& tls = *TlsActivationContext; return TActorContext(tls.Mailbox, tls.ExecutorThread, tls.EventStart, id); } diff --git a/library/cpp/actors/core/actor_bootstrapped.h b/library/cpp/actors/core/actor_bootstrapped.h index 25e6b3fbe2..a37887c939 100644 --- a/library/cpp/actors/core/actor_bootstrapped.h +++ b/library/cpp/actors/core/actor_bootstrapped.h @@ -9,7 +9,7 @@ namespace NActors { template<typename TDerived> class TActorBootstrapped : public TActor<TDerived> { protected: - TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override { + TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override { return new IEventHandle(TEvents::TSystem::Bootstrap, 0, self, parentId, {}, 0); } @@ -19,11 +19,11 @@ namespace NActors { TDerived& self = static_cast<TDerived&>(*this); if constexpr (std::is_invocable_v<T, TDerived, const TActorContext&>) { self.Bootstrap(ctx); - } else if constexpr (std::is_invocable_v<T, TDerived, const TActorId&, const TActorContext&>) { + } else if constexpr (std::is_invocable_v<T, TDerived, const TActorId&, const TActorContext&>) { self.Bootstrap(ev->Sender, ctx); } else if constexpr (std::is_invocable_v<T, TDerived>) { self.Bootstrap(); - } else if constexpr (std::is_invocable_v<T, TDerived, const TActorId&>) { + } else if constexpr (std::is_invocable_v<T, TDerived, const TActorId&>) { self.Bootstrap(ev->Sender); } else { static_assert(dependent_false<TDerived>::value, "No correct Bootstrap() signature"); diff --git a/library/cpp/actors/core/actor_coroutine.h b/library/cpp/actors/core/actor_coroutine.h index af7328d3a1..6bcb768eaf 100644 --- a/library/cpp/actors/core/actor_coroutine.h +++ b/library/cpp/actors/core/actor_coroutine.h @@ -24,8 +24,8 @@ namespace NActors { TActorContext *ActorContext = nullptr; protected: - TActorIdentity SelfActorId = TActorIdentity(TActorId()); - TActorId ParentActorId; + TActorIdentity SelfActorId = TActorIdentity(TActorId()); + TActorId ParentActorId; private: template <typename TFirstEvent, typename... TOtherEvents> @@ -107,12 +107,12 @@ namespace NActors { TActorSystem *GetActorSystem() const { return GetActorContext().ExecutorThread.ActorSystem; } TInstant Now() const { return GetActorContext().Now(); } - bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) { + bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) { return GetActorContext().Send(recipient, ev, flags, cookie, std::move(traceId)); } template <typename TEvent> - bool Send(const TActorId& recipient, THolder<TEvent> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) { + bool Send(const TActorId& recipient, THolder<TEvent> ev, ui32 flags = 0, ui64 cookie = 0, NWilson::TTraceId traceId = {}) { return GetActorContext().Send(recipient, ev.Release(), flags, cookie, std::move(traceId)); } @@ -130,7 +130,7 @@ namespace NActors { return GetActorContext().Schedule(deadline, ev, cookie); } - TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) { + TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>()) { return GetActorContext().Register(actor, mailboxType, poolId); } @@ -159,7 +159,7 @@ namespace NActors { , Impl(std::move(impl)) {} - TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parent) override { + TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parent) override { return new IEventHandle(TEvents::TSystem::Bootstrap, 0, self, parent, {}, 0); } diff --git a/library/cpp/actors/core/actor_coroutine_ut.cpp b/library/cpp/actors/core/actor_coroutine_ut.cpp index 13bfdcc2bf..951512b877 100644 --- a/library/cpp/actors/core/actor_coroutine_ut.cpp +++ b/library/cpp/actors/core/actor_coroutine_ut.cpp @@ -29,7 +29,7 @@ Y_UNIT_TEST_SUITE(ActorCoro) { }; class TBasicResponderActor: public TActorBootstrapped<TBasicResponderActor> { - TDeque<TActorId> RespondTo; + TDeque<TActorId> RespondTo; public: TBasicResponderActor() { @@ -77,7 +77,7 @@ Y_UNIT_TEST_SUITE(ActorCoro) { } void Run() override { - TActorId child = GetActorContext().Register(new TBasicResponderActor); + TActorId child = GetActorContext().Register(new TBasicResponderActor); ui32 itemsProcessed = 0; try { while (!Finish) { diff --git a/library/cpp/actors/core/actorid.cpp b/library/cpp/actors/core/actorid.cpp index 3330cd0ab3..ccda035eac 100644 --- a/library/cpp/actors/core/actorid.cpp +++ b/library/cpp/actors/core/actorid.cpp @@ -3,18 +3,18 @@ #include <util/string/cast.h> namespace NActors { - void TActorId::Out(IOutputStream& o) const { + void TActorId::Out(IOutputStream& o) const { o << "[" << NodeId() << ":" << LocalId() << ":" << Hint() << "]"; } - TString TActorId::ToString() const { + TString TActorId::ToString() const { TString x; TStringOutput o(x); Out(o); return x; } - bool TActorId::Parse(const char* buf, ui32 sz) { + bool TActorId::Parse(const char* buf, ui32 sz) { if (sz < 4 || buf[0] != '[' || buf[sz - 1] != ']') return false; diff --git a/library/cpp/actors/core/actorid.h b/library/cpp/actors/core/actorid.h index c631ef3a72..d972b1a0ff 100644 --- a/library/cpp/actors/core/actorid.h +++ b/library/cpp/actors/core/actorid.h @@ -11,7 +11,7 @@ namespace NActors { // next 11 bits of node-id - pool id // next 20 bits - node id itself - struct TActorId { + struct TActorId { static constexpr ui32 MaxServiceIDLength = 12; static constexpr ui32 MaxPoolID = 0x000007FF; static constexpr ui32 MaxNodeId = 0x000FFFFF; @@ -37,19 +37,19 @@ namespace NActors { } Raw; public: - TActorId() noexcept { + TActorId() noexcept { Raw.X.X1 = 0; Raw.X.X2 = 0; } - explicit TActorId(ui32 nodeId, ui32 poolId, ui64 localId, ui32 hint) noexcept { + explicit TActorId(ui32 nodeId, ui32 poolId, ui64 localId, ui32 hint) noexcept { Y_VERIFY_DEBUG(poolId <= MaxPoolID); Raw.N.LocalId = localId; Raw.N.Hint = hint; Raw.N.NodeId = nodeId | (poolId << PoolIndexShift); } - explicit TActorId(ui32 nodeId, const TStringBuf& x) noexcept { + explicit TActorId(ui32 nodeId, const TStringBuf& x) noexcept { Y_VERIFY(x.size() <= MaxServiceIDLength, "service id is too long"); Raw.N.LocalId = 0; Raw.N.Hint = 0; @@ -57,7 +57,7 @@ namespace NActors { memcpy(Raw.Buf, x.data(), x.size()); } - explicit TActorId(ui64 x1, ui64 x2) noexcept { + explicit TActorId(ui64 x1, ui64 x2) noexcept { Raw.X.X1 = x1; Raw.X.X2 = x2; } @@ -103,7 +103,7 @@ namespace NActors { return Raw.X.X2; } - bool operator<(const TActorId& x) const noexcept { + bool operator<(const TActorId& x) const noexcept { const ui64 s1 = Raw.X.X1; const ui64 s2 = Raw.X.X2; const ui64 x1 = x.Raw.X.X1; @@ -112,11 +112,11 @@ namespace NActors { return (s1 != x1) ? (s1 < x1) : (s2 < x2); } - bool operator!=(const TActorId& x) const noexcept { + bool operator!=(const TActorId& x) const noexcept { return Raw.X.X1 != x.Raw.X.X1 || Raw.X.X2 != x.Raw.X.X2; } - bool operator==(const TActorId& x) const noexcept { + bool operator==(const TActorId& x) const noexcept { return !(x != *this); } @@ -153,19 +153,19 @@ namespace NActors { } struct THash { - ui64 operator()(const TActorId& actorId) const noexcept { - return actorId.Hash(); + ui64 operator()(const TActorId& actorId) const noexcept { + return actorId.Hash(); } }; struct THash32 { - ui64 operator()(const TActorId& actorId) const noexcept { - return actorId.Hash(); + ui64 operator()(const TActorId& actorId) const noexcept { + return actorId.Hash(); } }; struct TOrderedCmp { - bool operator()(const TActorId &left, const TActorId &right) const noexcept { + bool operator()(const TActorId &left, const TActorId &right) const noexcept { Y_VERIFY_DEBUG(!left.IsService() && !right.IsService(), "ordered compare works for plain actorids only"); const ui32 n1 = left.NodeId(); const ui32 n2 = right.NodeId(); @@ -179,18 +179,18 @@ namespace NActors { bool Parse(const char* buf, ui32 sz); }; - static_assert(sizeof(TActorId) == 16, "expect sizeof(TActorId) == 16"); + static_assert(sizeof(TActorId) == 16, "expect sizeof(TActorId) == 16"); static_assert(MaxPools < TActorId::MaxPoolID); // current implementation of united pool has limit MaxPools on pool id } template <> -inline void Out<NActors::TActorId>(IOutputStream& o, const NActors::TActorId& x) { +inline void Out<NActors::TActorId>(IOutputStream& o, const NActors::TActorId& x) { return x.Out(o); } template <> -struct THash<NActors::TActorId> { - inline ui64 operator()(const NActors::TActorId& x) const { +struct THash<NActors::TActorId> { + inline ui64 operator()(const NActors::TActorId& x) const { return x.Hash(); } }; diff --git a/library/cpp/actors/core/actorsystem.cpp b/library/cpp/actors/core/actorsystem.cpp index 488abd2963..c58698a206 100644 --- a/library/cpp/actors/core/actorsystem.cpp +++ b/library/cpp/actors/core/actorsystem.cpp @@ -21,16 +21,16 @@ namespace NActors { LWTRACE_USING(ACTORLIB_PROVIDER); struct TActorSystem::TServiceMap : TNonCopyable { - NActors::TServiceMap<TActorId, TActorId, TActorId::THash> LocalMap; + NActors::TServiceMap<TActorId, TActorId, TActorId::THash> LocalMap; TTicketLock Lock; - TActorId RegisterLocalService(const TActorId& serviceId, const TActorId& actorId) { + TActorId RegisterLocalService(const TActorId& serviceId, const TActorId& actorId) { TTicketLock::TGuard guard(&Lock); - const TActorId old = LocalMap.Update(serviceId, actorId); + const TActorId old = LocalMap.Update(serviceId, actorId); return old; } - TActorId LookupLocal(const TActorId& x) { + TActorId LookupLocal(const TActorId& x) { return LocalMap.Find(x); } }; @@ -68,7 +68,7 @@ namespace NActors { ev->Callstack.TraceIfEmpty(); #endif - TActorId recipient = ev->GetRecipientRewrite(); + TActorId recipient = ev->GetRecipientRewrite(); const ui32 recpNodeId = recipient.NodeId(); if (recpNodeId != NodeId && recpNodeId != 0) { @@ -114,13 +114,13 @@ namespace NActors { return false; } - bool TActorSystem::Send(const TActorId& recipient, IEventBase* ev, ui32 flags) const { + bool TActorSystem::Send(const TActorId& recipient, IEventBase* ev, ui32 flags) const { return this->Send(new IEventHandle(recipient, DefSelfID, ev, flags)); } - void TActorSystem::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) const { + void TActorSystem::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) const { Schedule(deadline - Timestamp(), ev, cookie); - } + } void TActorSystem::Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) const { const auto current = Monotonic(); @@ -131,22 +131,22 @@ namespace NActors { ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie); } - void TActorSystem::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) const { + void TActorSystem::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) const { const auto deadline = Monotonic() + delta; - - TTicketLock::TGuard guard(&ScheduleLock); - ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie); + + TTicketLock::TGuard guard(&ScheduleLock); + ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie); } - TActorId TActorSystem::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 executorPool, ui64 revolvingCounter, - const TActorId& parentId) { + TActorId TActorSystem::Register(IActor* actor, TMailboxType::EType mailboxType, ui32 executorPool, ui64 revolvingCounter, + const TActorId& parentId) { Y_VERIFY(executorPool < ExecutorPoolCount, "executorPool# %" PRIu32 ", ExecutorPoolCount# %" PRIu32, (ui32)executorPool, (ui32)ExecutorPoolCount); return CpuManager->GetExecutorPool(executorPool)->Register(actor, mailboxType, revolvingCounter, parentId); } NThreading::TFuture<THolder<IEventBase>> TActorSystem::AskGeneric(TMaybe<ui32> expectedEventType, - TActorId recipient, THolder<IEventBase> event, + TActorId recipient, THolder<IEventBase> event, TDuration timeout) { auto promise = NThreading::NewPromise<THolder<IEventBase>>(); Register(MakeAskActor(expectedEventType, recipient, std::move(event), timeout, promise).Release()); @@ -173,16 +173,16 @@ namespace NActors { return ret; } - TActorId TActorSystem::InterconnectProxy(ui32 destinationNode) const { + TActorId TActorSystem::InterconnectProxy(ui32 destinationNode) const { if (destinationNode < InterconnectCount) return Interconnect[destinationNode]; else if (destinationNode != NodeId) return MakeInterconnectProxyId(destinationNode); else - return TActorId(); + return TActorId(); } - ui32 TActorSystem::BroadcastToProxies(const std::function<IEventHandle*(const TActorId&)>& eventFabric) { + ui32 TActorSystem::BroadcastToProxies(const std::function<IEventHandle*(const TActorId&)>& eventFabric) { // TODO: get rid of this method for (ui32 i = 0; i < InterconnectCount; ++i) { Send(eventFabric(Interconnect[i])); @@ -194,9 +194,9 @@ namespace NActors { return ServiceMap->LookupLocal(x); } - TActorId TActorSystem::RegisterLocalService(const TActorId& serviceId, const TActorId& actorId) { - // TODO: notify old actor about demotion - return ServiceMap->RegisterLocalService(serviceId, actorId); + TActorId TActorSystem::RegisterLocalService(const TActorId& serviceId, const TActorId& actorId) { + // TODO: notify old actor about demotion + return ServiceMap->RegisterLocalService(serviceId, actorId); } void TActorSystem::GetPoolStats(ui32 poolId, TExecutorPoolStats& poolStats, TVector<TExecutorThreadStats>& statsCopy) const { @@ -217,7 +217,7 @@ namespace NActors { // setup interconnect proxies { const TInterconnectSetup& setup = SystemSetup->Interconnect; - Interconnect.Reset(new TActorId[InterconnectCount + 1]); + Interconnect.Reset(new TActorId[InterconnectCount + 1]); for (ui32 i = 0, e = InterconnectCount; i != e; ++i) { const TActorSetupCmd& x = setup.ProxyActors[i]; if (x.Actor) { @@ -231,8 +231,8 @@ namespace NActors { // setup local services { for (ui32 i = 0, e = (ui32)SystemSetup->LocalServices.size(); i != e; ++i) { - const std::pair<TActorId, TActorSetupCmd>& x = SystemSetup->LocalServices[i]; - const TActorId xid = Register(x.second.Actor, x.second.MailboxType, x.second.PoolId, i); + const std::pair<TActorId, TActorSetupCmd>& x = SystemSetup->LocalServices[i]; + const TActorId xid = Register(x.second.Actor, x.second.MailboxType, x.second.PoolId, i); Y_VERIFY(!!xid); if (!!x.first) RegisterLocalService(x.first, xid); diff --git a/library/cpp/actors/core/actorsystem.h b/library/cpp/actors/core/actorsystem.h index c2c88ed2ec..40499d7586 100644 --- a/library/cpp/actors/core/actorsystem.h +++ b/library/cpp/actors/core/actorsystem.h @@ -66,17 +66,17 @@ namespace NActors { virtual ui32 GetReadyActivation(TWorkerContext& wctx, ui64 revolvingCounter) = 0; virtual void ReclaimMailbox(TMailboxType::EType mailboxType, ui32 hint, TWorkerId workerId, ui64 revolvingCounter) = 0; - /** - * Schedule one-shot event that will be send at given time point in the future. - * + /** + * Schedule one-shot event that will be send at given time point in the future. + * * @param deadline the wallclock time point in future when event must be send - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event * @param workerId index of thread which will perform event dispatching - */ + */ virtual void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) = 0; - - /** + + /** * Schedule one-shot event that will be send at given time point in the future. * * @param deadline the monotonic time point in future when event must be send @@ -87,21 +87,21 @@ namespace NActors { virtual void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) = 0; /** - * Schedule one-shot event that will be send after given delay. - * - * @param delta the time from now to delay event sending - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event + * Schedule one-shot event that will be send after given delay. + * + * @param delta the time from now to delay event sending + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event * @param workerId index of thread which will perform event dispatching - */ + */ virtual void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) = 0; - + // for actorsystem virtual bool Send(TAutoPtr<IEventHandle>& ev) = 0; virtual void ScheduleActivation(ui32 activation) = 0; virtual void ScheduleActivationEx(ui32 activation, ui64 revolvingCounter) = 0; - virtual TActorId Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingCounter, const TActorId& parentId) = 0; - virtual TActorId Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) = 0; + virtual TActorId Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingCounter, const TActorId& parentId) = 0; + virtual TActorId Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) = 0; // lifecycle stuff virtual void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) = 0; @@ -223,7 +223,7 @@ namespace NActors { THolder<TServiceMap> ServiceMap; const ui32 InterconnectCount; - TArrayHolder<TActorId> Interconnect; + TArrayHolder<TActorId> Interconnect; volatile ui64 CurrentTimestamp; volatile ui64 CurrentMonotonic; @@ -235,7 +235,7 @@ namespace NActors { friend class TExecutorThread; THolder<TActorSystemSetup> SystemSetup; - TActorId DefSelfID; + TActorId DefSelfID; void* AppData0; TIntrusivePtr<NLog::TSettings> LoggerSettings0; TProxyWrapperFactory ProxyWrapperFactory; @@ -255,22 +255,22 @@ namespace NActors { void Stop(); void Cleanup(); - TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 executorPool = 0, - ui64 revolvingCounter = 0, const TActorId& parentId = TActorId()); + TActorId Register(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 executorPool = 0, + ui64 revolvingCounter = 0, const TActorId& parentId = TActorId()); bool Send(TAutoPtr<IEventHandle> ev) const; - bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0) const; + bool Send(const TActorId& recipient, IEventBase* ev, ui32 flags = 0) const; /** - * Schedule one-shot event that will be send at given time point in the future. - * + * Schedule one-shot event that will be send at given time point in the future. + * * @param deadline the wallclock time point in future when event must be send - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event - */ - void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) const; - - /** + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event + */ + void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) const; + + /** * Schedule one-shot event that will be send at given time point in the future. * * @param deadline the monotonic time point in future when event must be send @@ -280,15 +280,15 @@ namespace NActors { void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) const; /** - * Schedule one-shot event that will be send after given delay. - * - * @param delta the time from now to delay event sending - * @param ev the event to send - * @param cookie cookie that will be piggybacked with event - */ - void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) const; - - /** + * Schedule one-shot event that will be send after given delay. + * + * @param delta the time from now to delay event sending + * @param ev the event to send + * @param cookie cookie that will be piggybacked with event + */ + void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr) const; + + /** * A way to interact with actors from non-actor context. * * This method will send the `event` to the `recipient` and then will wait for a response. When response arrives, @@ -303,7 +303,7 @@ namespace NActors { */ template <typename T> [[nodiscard]] - NThreading::TFuture<THolder<T>> Ask(TActorId recipient, THolder<IEventBase> event, TDuration timeout = TDuration::Max()) { + NThreading::TFuture<THolder<T>> Ask(TActorId recipient, THolder<IEventBase> event, TDuration timeout = TDuration::Max()) { if constexpr (std::is_same_v<T, IEventBase>) { return AskGeneric(Nothing(), recipient, std::move(event), timeout); } else { @@ -317,20 +317,20 @@ namespace NActors { [[nodiscard]] NThreading::TFuture<THolder<IEventBase>> AskGeneric( TMaybe<ui32> expectedEventType, - TActorId recipient, + TActorId recipient, THolder<IEventBase> event, TDuration timeout); ui64 AllocateIDSpace(ui64 count); - TActorId InterconnectProxy(ui32 destinationNode) const; - ui32 BroadcastToProxies(const std::function<IEventHandle*(const TActorId&)>&); + TActorId InterconnectProxy(ui32 destinationNode) const; + ui32 BroadcastToProxies(const std::function<IEventHandle*(const TActorId&)>&); void UpdateLinkStatus(ui8 status, ui32 destinationNode); ui8 LinkStatus(ui32 destinationNode); TActorId LookupLocalService(const TActorId& x) const; - TActorId RegisterLocalService(const TActorId& serviceId, const TActorId& actorId); + TActorId RegisterLocalService(const TActorId& serviceId, const TActorId& actorId); ui32 GetMaxActivityType() const { return SystemSetup ? SystemSetup->MaxActivityType : 1; diff --git a/library/cpp/actors/core/actorsystem_ut.cpp b/library/cpp/actors/core/actorsystem_ut.cpp index 2c93b12dcd..231d6f0ca1 100644 --- a/library/cpp/actors/core/actorsystem_ut.cpp +++ b/library/cpp/actors/core/actorsystem_ut.cpp @@ -1,45 +1,45 @@ -#include "actorsystem.h" - -#include <library/cpp/actors/testlib/test_runtime.h> -#include <library/cpp/testing/unittest/registar.h> - -using namespace NActors; - -Y_UNIT_TEST_SUITE(TActorSystemTest) { - - class TTestActor: public TActor<TTestActor> { - public: - TTestActor() - : TActor{&TThis::Main} - { - } - - STATEFN(Main) { - Y_UNUSED(ev); - } - }; - - THolder<TTestActorRuntimeBase> CreateRuntime() { - auto runtime = MakeHolder<TTestActorRuntimeBase>(); - runtime->SetScheduledEventFilter([](auto&&, auto&&, auto&&, auto&&) { return false; }); - runtime->Initialize(); - return runtime; - } - - Y_UNIT_TEST(LocalService) { - THolder<TTestActorRuntimeBase> runtime = CreateRuntime(); - auto actorA = runtime->Register(new TTestActor); - auto actorB = runtime->Register(new TTestActor); - - TActorId myServiceId{0, TStringBuf{"my-service"}}; - - auto prevActorId = runtime->RegisterService(myServiceId, actorA); - UNIT_ASSERT(!prevActorId); - UNIT_ASSERT_EQUAL(runtime->GetLocalServiceId(myServiceId), actorA); - - prevActorId = runtime->RegisterService(myServiceId, actorB); - UNIT_ASSERT(prevActorId); - UNIT_ASSERT_EQUAL(prevActorId, actorA); - UNIT_ASSERT_EQUAL(runtime->GetLocalServiceId(myServiceId), actorB); - } -} +#include "actorsystem.h" + +#include <library/cpp/actors/testlib/test_runtime.h> +#include <library/cpp/testing/unittest/registar.h> + +using namespace NActors; + +Y_UNIT_TEST_SUITE(TActorSystemTest) { + + class TTestActor: public TActor<TTestActor> { + public: + TTestActor() + : TActor{&TThis::Main} + { + } + + STATEFN(Main) { + Y_UNUSED(ev); + } + }; + + THolder<TTestActorRuntimeBase> CreateRuntime() { + auto runtime = MakeHolder<TTestActorRuntimeBase>(); + runtime->SetScheduledEventFilter([](auto&&, auto&&, auto&&, auto&&) { return false; }); + runtime->Initialize(); + return runtime; + } + + Y_UNIT_TEST(LocalService) { + THolder<TTestActorRuntimeBase> runtime = CreateRuntime(); + auto actorA = runtime->Register(new TTestActor); + auto actorB = runtime->Register(new TTestActor); + + TActorId myServiceId{0, TStringBuf{"my-service"}}; + + auto prevActorId = runtime->RegisterService(myServiceId, actorA); + UNIT_ASSERT(!prevActorId); + UNIT_ASSERT_EQUAL(runtime->GetLocalServiceId(myServiceId), actorA); + + prevActorId = runtime->RegisterService(myServiceId, actorB); + UNIT_ASSERT(prevActorId); + UNIT_ASSERT_EQUAL(prevActorId, actorA); + UNIT_ASSERT_EQUAL(runtime->GetLocalServiceId(myServiceId), actorB); + } +} diff --git a/library/cpp/actors/core/ask.cpp b/library/cpp/actors/core/ask.cpp index 4e4d6a1a2b..0054c9a906 100644 --- a/library/cpp/actors/core/ask.cpp +++ b/library/cpp/actors/core/ask.cpp @@ -19,7 +19,7 @@ namespace NActors { public: TAskActor( TMaybe<ui32> expectedEventType, - TActorId recipient, + TActorId recipient, THolder<IEventBase> event, TDuration timeout, const NThreading::TPromise<THolder<IEventBase>>& promise) @@ -55,7 +55,7 @@ namespace NActors { public: TMaybe<ui32> ExpectedEventType_; - TActorId Recipient_; + TActorId Recipient_; THolder<IEventBase> Event_; TDuration Timeout_; NThreading::TPromise<THolder<IEventBase>> Promise_; @@ -64,7 +64,7 @@ namespace NActors { THolder<IActor> MakeAskActor( TMaybe<ui32> expectedEventType, - TActorId recipient, + TActorId recipient, THolder<IEventBase> event, TDuration timeout, const NThreading::TPromise<THolder<IEventBase>>& promise) diff --git a/library/cpp/actors/core/ask.h b/library/cpp/actors/core/ask.h index b935fac564..036f1833a4 100644 --- a/library/cpp/actors/core/ask.h +++ b/library/cpp/actors/core/ask.h @@ -11,7 +11,7 @@ namespace NActors { */ THolder<IActor> MakeAskActor( TMaybe<ui32> expectedEventType, - TActorId recipient, + TActorId recipient, THolder<IEventBase> event, TDuration timeout, const NThreading::TPromise<THolder<IEventBase>>& promise); diff --git a/library/cpp/actors/core/event.h b/library/cpp/actors/core/event.h index 9519978bc1..6ff02aaf94 100644 --- a/library/cpp/actors/core/event.h +++ b/library/cpp/actors/core/event.h @@ -48,9 +48,9 @@ namespace NActors { // fat handle class IEventHandle : TNonCopyable { struct TOnNondelivery { - TActorId Recipient; + TActorId Recipient; - TOnNondelivery(const TActorId& recipient) + TOnNondelivery(const TActorId& recipient) : Recipient(recipient) { } @@ -99,8 +99,8 @@ namespace NActors { const ui32 Type; const ui32 Flags; - const TActorId Recipient; - const TActorId Sender; + const TActorId Recipient; + const TActorId Sender; const ui64 Cookie; const TScopeId OriginScopeId = TScopeId::LocallyGenerated; // filled in when the message is received from Interconnect @@ -108,7 +108,7 @@ namespace NActors { NWilson::TTraceId TraceId; // filled if feeded by interconnect session - const TActorId InterconnectSession; + const TActorId InterconnectSession; #ifdef ACTORSLIB_COLLECT_EXEC_STATS ::NHPTimer::STime SendTime; @@ -138,13 +138,13 @@ namespace NActors { THolder<IEventBase> Event; TIntrusivePtr<TEventSerializedData> Buffer; - TActorId RewriteRecipient; + TActorId RewriteRecipient; ui32 RewriteType; THolder<TOnNondelivery> OnNondeliveryHolder; // only for local events public: - void Rewrite(ui32 typeRewrite, TActorId recipientRewrite) { + void Rewrite(ui32 typeRewrite, TActorId recipientRewrite) { RewriteRecipient = recipientRewrite; RewriteType = typeRewrite; } @@ -154,7 +154,7 @@ namespace NActors { RewriteType = Type; } - const TActorId& GetRecipientRewrite() const { + const TActorId& GetRecipientRewrite() const { return RewriteRecipient; } @@ -162,12 +162,12 @@ namespace NActors { return RewriteType; } - TActorId GetForwardOnNondeliveryRecipient() const { - return OnNondeliveryHolder.Get() ? OnNondeliveryHolder->Recipient : TActorId(); + TActorId GetForwardOnNondeliveryRecipient() const { + return OnNondeliveryHolder.Get() ? OnNondeliveryHolder->Recipient : TActorId(); } - IEventHandle(const TActorId& recipient, const TActorId& sender, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, - const TActorId* forwardOnNondelivery = nullptr, NWilson::TTraceId traceId = {}) + IEventHandle(const TActorId& recipient, const TActorId& sender, IEventBase* ev, ui32 flags = 0, ui64 cookie = 0, + const TActorId* forwardOnNondelivery = nullptr, NWilson::TTraceId traceId = {}) : Type(ev->Type()) , Flags(flags) , Recipient(recipient) @@ -187,11 +187,11 @@ namespace NActors { IEventHandle(ui32 type, ui32 flags, - const TActorId& recipient, - const TActorId& sender, + const TActorId& recipient, + const TActorId& sender, TIntrusivePtr<TEventSerializedData> buffer, ui64 cookie, - const TActorId* forwardOnNondelivery = nullptr, + const TActorId* forwardOnNondelivery = nullptr, NWilson::TTraceId traceId = {}) : Type(type) , Flags(flags) @@ -211,11 +211,11 @@ namespace NActors { } // Special ctor for events from interconnect. - IEventHandle(const TActorId& session, + IEventHandle(const TActorId& session, ui32 type, ui32 flags, - const TActorId& recipient, - const TActorId& sender, + const TActorId& recipient, + const TActorId& sender, TIntrusivePtr<TEventSerializedData> buffer, ui64 cookie, TScopeId originScopeId, @@ -276,7 +276,7 @@ namespace NActors { return x; } - TAutoPtr<IEventHandle> Forward(const TActorId& dest) { + TAutoPtr<IEventHandle> Forward(const TActorId& dest) { if (Event) return new IEventHandle(dest, Sender, Event.Release(), Flags, Cookie, nullptr, std::move(TraceId)); else diff --git a/library/cpp/actors/core/event_pb.h b/library/cpp/actors/core/event_pb.h index baaf333ca9..d7546b901a 100644 --- a/library/cpp/actors/core/event_pb.h +++ b/library/cpp/actors/core/event_pb.h @@ -488,11 +488,11 @@ namespace NActors { } }; - inline TActorId ActorIdFromProto(const NActorsProto::TActorId& actorId) { - return TActorId(actorId.GetRawX1(), actorId.GetRawX2()); + inline TActorId ActorIdFromProto(const NActorsProto::TActorId& actorId) { + return TActorId(actorId.GetRawX1(), actorId.GetRawX2()); } - inline void ActorIdToProto(const TActorId& src, NActorsProto::TActorId* dest) { + inline void ActorIdToProto(const TActorId& src, NActorsProto::TActorId* dest) { Y_VERIFY_DEBUG(dest); dest->SetRawX1(src.RawX1()); dest->SetRawX2(src.RawX2()); diff --git a/library/cpp/actors/core/events.h b/library/cpp/actors/core/events.h index b5b9d7c9fa..702cf50fad 100644 --- a/library/cpp/actors/core/events.h +++ b/library/cpp/actors/core/events.h @@ -20,7 +20,7 @@ namespace NActors { ES_INTERCONNECT_TCP = 8, ES_PROFILER = 9, ES_YF = 10, - ES_HTTP = 11, + ES_HTTP = 11, ES_USERSPACE = 4096, @@ -99,7 +99,7 @@ namespace NActors { InvokeQuery, End, - // Compatibility section + // Compatibility section PoisonPill = Poison, ActorDied = Gone, }; @@ -191,17 +191,17 @@ namespace NActors { struct TEvCallbackException: public TEventPB<TEvCallbackException, NActorsProto::TCallbackException, TSystem::CallbackException> { - TEvCallbackException(const TActorId& id, const TString& msg) { - ActorIdToProto(id, Record.MutableActorId()); + TEvCallbackException(const TActorId& id, const TString& msg) { + ActorIdToProto(id, Record.MutableActorId()); Record.SetExceptionMessage(msg); } }; struct TEvCallbackCompletion: public TEventPB<TEvCallbackCompletion, - NActorsProto::TActorId, + NActorsProto::TActorId, TSystem::CallbackCompletion> { - TEvCallbackCompletion(const TActorId& id) { - ActorIdToProto(id, &Record); + TEvCallbackCompletion(const TActorId& id) { + ActorIdToProto(id, &Record); } }; diff --git a/library/cpp/actors/core/events_undelivered.cpp b/library/cpp/actors/core/events_undelivered.cpp index 2a5a0b1cc6..23deaffd10 100644 --- a/library/cpp/actors/core/events_undelivered.cpp +++ b/library/cpp/actors/core/events_undelivered.cpp @@ -41,7 +41,7 @@ namespace NActors { TAutoPtr<IEventHandle> IEventHandle::ForwardOnNondelivery(ui32 reason, bool unsure) { if (Flags & FlagForwardOnNondelivery) { const ui32 updatedFlags = Flags & ~(FlagForwardOnNondelivery | FlagSubscribeOnSession); - const TActorId recp = OnNondeliveryHolder ? OnNondeliveryHolder->Recipient : TActorId(); + const TActorId recp = OnNondeliveryHolder ? OnNondeliveryHolder->Recipient : TActorId(); if (Event) return new IEventHandle(recp, Sender, Event.Release(), updatedFlags, Cookie, &Recipient, TraceId.Clone()); diff --git a/library/cpp/actors/core/executelater.h b/library/cpp/actors/core/executelater.h index ec55c43b40..e7a13c1005 100644 --- a/library/cpp/actors/core/executelater.h +++ b/library/cpp/actors/core/executelater.h @@ -17,8 +17,8 @@ namespace NActors { IActor::EActivityType activityType, ui32 channel = 0, ui64 cookie = 0, - const TActorId& reportCompletionTo = TActorId(), - const TActorId& reportExceptionTo = TActorId()) noexcept + const TActorId& reportCompletionTo = TActorId(), + const TActorId& reportExceptionTo = TActorId()) noexcept : Callback(std::move(callback)) , Channel(channel) , Cookie(cookie) @@ -65,8 +65,8 @@ namespace NActors { TCallback Callback; const ui32 Channel; const ui64 Cookie; - const TActorId ReportCompletionTo; - const TActorId ReportExceptionTo; + const TActorId ReportCompletionTo; + const TActorId ReportExceptionTo; }; template <typename T> @@ -75,8 +75,8 @@ namespace NActors { IActor::EActivityType activityType, ui32 channel = 0, ui64 cookie = 0, - const TActorId& reportCompletionTo = TActorId(), - const TActorId& reportExceptionTo = TActorId()) noexcept { + const TActorId& reportCompletionTo = TActorId(), + const TActorId& reportExceptionTo = TActorId()) noexcept { return new TExecuteLater<T>(std::forward<T>(func), activityType, channel, diff --git a/library/cpp/actors/core/executor_pool_base.cpp b/library/cpp/actors/core/executor_pool_base.cpp index 860496f108..c3b9999168 100644 --- a/library/cpp/actors/core/executor_pool_base.cpp +++ b/library/cpp/actors/core/executor_pool_base.cpp @@ -7,7 +7,7 @@ namespace NActors { LWTRACE_USING(ACTORLIB_PROVIDER); - void DoActorInit(TActorSystem* sys, IActor* actor, const TActorId& self, const TActorId& owner) { + void DoActorInit(TActorSystem* sys, IActor* actor, const TActorId& self, const TActorId& owner) { actor->SelfActorId = self; actor->Registered(sys, owner); } @@ -97,7 +97,7 @@ namespace NActors { mailbox->AttachActor(localActorId, actor); // do init - const TActorId actorId(ActorSystem->NodeId, PoolId, localActorId, hint); + const TActorId actorId(ActorSystem->NodeId, PoolId, localActorId, hint); DoActorInit(ActorSystem, actor, actorId, parentId); // Once we unlock the mailbox the actor starts running and we cannot use the pointer any more @@ -144,7 +144,7 @@ namespace NActors { const ui64 localActorId = AllocateID(); mailbox->AttachActor(localActorId, actor); - const TActorId actorId(ActorSystem->NodeId, PoolId, localActorId, hint); + const TActorId actorId(ActorSystem->NodeId, PoolId, localActorId, hint); DoActorInit(ActorSystem, actor, actorId, parentId); NHPTimer::STime elapsed = GetCycleCountFast() - hpstart; if (elapsed > 1000000) { diff --git a/library/cpp/actors/core/executor_pool_base.h b/library/cpp/actors/core/executor_pool_base.h index d52a242fc6..c84ce1af77 100644 --- a/library/cpp/actors/core/executor_pool_base.h +++ b/library/cpp/actors/core/executor_pool_base.h @@ -24,8 +24,8 @@ namespace NActors { ~TExecutorPoolBaseMailboxed(); void ReclaimMailbox(TMailboxType::EType mailboxType, ui32 hint, TWorkerId workerId, ui64 revolvingWriteCounter) override; bool Send(TAutoPtr<IEventHandle>& ev) override; - TActorId Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingWriteCounter, const TActorId& parentId) override; - TActorId Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) override; + TActorId Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingWriteCounter, const TActorId& parentId) override; + TActorId Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) override; bool Cleanup() override; }; diff --git a/library/cpp/actors/core/executor_pool_basic.cpp b/library/cpp/actors/core/executor_pool_basic.cpp index 936d2e94a7..4dce16939a 100644 --- a/library/cpp/actors/core/executor_pool_basic.cpp +++ b/library/cpp/actors/core/executor_pool_basic.cpp @@ -315,11 +315,11 @@ namespace NActors { void TBasicExecutorPool::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) { Y_VERIFY_DEBUG(workerId < PoolThreads); - + const auto deadline = ActorSystem->Monotonic() + delta; ScheduleWriters[workerId].Push(deadline.MicroSeconds(), ev.Release(), cookie); - } - + } + void TBasicExecutorPool::SetRealTimeMode() const { // TODO: musl-libc version of `sched_param` struct is for some reason different from pthread // version in Ubuntu 12.04 diff --git a/library/cpp/actors/core/executor_pool_basic.h b/library/cpp/actors/core/executor_pool_basic.h index dd83c85c74..023190f7fe 100644 --- a/library/cpp/actors/core/executor_pool_basic.h +++ b/library/cpp/actors/core/executor_pool_basic.h @@ -6,7 +6,7 @@ #include "executor_pool_base.h" #include <library/cpp/actors/util/unordered_cache.h> #include <library/cpp/actors/util/threadparkpad.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <util/system/mutex.h> @@ -87,7 +87,7 @@ namespace NActors { void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; - + void ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) override; void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) override; diff --git a/library/cpp/actors/core/executor_pool_basic_ut.cpp b/library/cpp/actors/core/executor_pool_basic_ut.cpp index 8c170c2d84..76dff693af 100644 --- a/library/cpp/actors/core/executor_pool_basic_ut.cpp +++ b/library/cpp/actors/core/executor_pool_basic_ut.cpp @@ -25,7 +25,7 @@ private: private: TAtomic Counter; - TActorId Receiver; + TActorId Receiver; std::function<void(void)> Action; @@ -36,7 +36,7 @@ public: , Action(action) {} - void Start(TActorId receiver, size_t count) + void Start(TActorId receiver, size_t count) { AtomicSet(Counter, count); Receiver = receiver; @@ -102,7 +102,7 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { executorPool->SetThreadCount(halfSize); TTestSenderActor* actors[size]; - TActorId actorIds[size]; + TActorId actorIds[size]; for (size_t i = 0; i < size; ++i) { actors[i] = new TTestSenderActor(); actorIds[i] = actorSystem.Register(actors[i]); @@ -176,7 +176,7 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { executorPool->SetThreadCount(halfSize); TTestSenderActor* actors[size]; - TActorId actorIds[size]; + TActorId actorIds[size]; for (size_t i = 0; i < size; ++i) { actors[i] = new TTestSenderActor(); actorIds[i] = actorSystem.Register(actors[i]); @@ -201,7 +201,7 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { counter = 0; } }); - TActorId changerActorId = actorSystem.Register(changerActor); + TActorId changerActorId = actorSystem.Register(changerActor); changerActor->Start(changerActorId, msgCount); actorSystem.Send(changerActorId, new TEvMsg()); @@ -260,7 +260,7 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { auto begin = TInstant::Now(); TTestSenderActor* actors[size]; - TActorId actorIds[size]; + TActorId actorIds[size]; for (size_t i = 0; i < size; ++i) { actors[i] = new TTestSenderActor(); @@ -304,7 +304,7 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { auto begin = TInstant::Now(); TTestSenderActor* actors[actorsCount]; - TActorId actorIds[actorsCount]; + TActorId actorIds[actorsCount]; for (size_t i = 0; i < actorsCount; ++i) { actors[i] = new TTestSenderActor(); @@ -348,7 +348,7 @@ Y_UNIT_TEST_SUITE(BasicExecutorPool) { auto begin = TInstant::Now(); TTestSenderActor* actors[actorsCount]; - TActorId actorIds[actorsCount]; + TActorId actorIds[actorsCount]; for (size_t i = 0; i < actorsCount; ++i) { actors[i] = new TTestSenderActor(); diff --git a/library/cpp/actors/core/executor_pool_io.cpp b/library/cpp/actors/core/executor_pool_io.cpp index 025b5a22c2..fb557ae6b0 100644 --- a/library/cpp/actors/core/executor_pool_io.cpp +++ b/library/cpp/actors/core/executor_pool_io.cpp @@ -81,11 +81,11 @@ namespace NActors { void TIOExecutorPool::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) { Y_UNUSED(workerId); const auto deadline = ActorSystem->Monotonic() + delta; - - TTicketLock::TGuard guard(&ScheduleLock); - ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie); - } - + + TTicketLock::TGuard guard(&ScheduleLock); + ScheduleQueue->Writer.Push(deadline.MicroSeconds(), ev.Release(), cookie); + } + void TIOExecutorPool::ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) { Activations.Push(activation, revolvingWriteCounter); const TAtomic x = AtomicIncrement(Semaphore); diff --git a/library/cpp/actors/core/executor_pool_io.h b/library/cpp/actors/core/executor_pool_io.h index a1359ba4ab..e576d642a1 100644 --- a/library/cpp/actors/core/executor_pool_io.h +++ b/library/cpp/actors/core/executor_pool_io.h @@ -35,7 +35,7 @@ namespace NActors { void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie, TWorkerId workerId) override; - + void ScheduleActivationEx(ui32 activation, ui64 revolvingWriteCounter) override; void Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) override; diff --git a/library/cpp/actors/core/executor_pool_united.cpp b/library/cpp/actors/core/executor_pool_united.cpp index da4934eccd..dac6245635 100644 --- a/library/cpp/actors/core/executor_pool_united.cpp +++ b/library/cpp/actors/core/executor_pool_united.cpp @@ -1255,13 +1255,13 @@ namespace NActors { inline bool TUnitedWorkers::NextExecution(TPoolId pool, ui32& activation, ui64 revolvingCounter) { return Pools[pool].NextExecution(activation, revolvingCounter); } - + inline void TUnitedWorkers::StopExecution(TPoolId pool) { if (Pools[pool].StopExecution()) { // pending token TryWake(pool); } - } - + } + inline void TUnitedWorkers::Balance() { ui64 ts = GetCycleCountFast(); if (Balancer->TryLock(ts)) { diff --git a/library/cpp/actors/core/executor_pool_united.h b/library/cpp/actors/core/executor_pool_united.h index b1af850312..a090ba2466 100644 --- a/library/cpp/actors/core/executor_pool_united.h +++ b/library/cpp/actors/core/executor_pool_united.h @@ -7,7 +7,7 @@ #include <library/cpp/actors/util/unordered_cache.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <library/cpp/actors/util/unordered_cache.h> #include <library/cpp/containers/stack_vector/stack_vec.h> @@ -79,7 +79,7 @@ namespace NActors { // Stop currently active execution and start new one if token is available // NOTE: Reuses token if it's not destroyed bool NextExecution(TPoolId pool, ui32& activation, ui64 revolvingCounter); - + // Stop active execution void StopExecution(TPoolId pool); diff --git a/library/cpp/actors/core/executor_pool_united_ut.cpp b/library/cpp/actors/core/executor_pool_united_ut.cpp index be92b9352a..d4df17f1b8 100644 --- a/library/cpp/actors/core/executor_pool_united_ut.cpp +++ b/library/cpp/actors/core/executor_pool_united_ut.cpp @@ -37,7 +37,7 @@ private: private: TAtomic Counter; - TActorId Receiver; + TActorId Receiver; std::function<void(void)> Action; diff --git a/library/cpp/actors/core/executor_thread.cpp b/library/cpp/actors/core/executor_thread.cpp index 03ef88ea51..446b651efd 100644 --- a/library/cpp/actors/core/executor_thread.cpp +++ b/library/cpp/actors/core/executor_thread.cpp @@ -50,14 +50,14 @@ namespace NActors { &Ctx.WorkerStats); } - TActorId TExecutorThread::RegisterActor(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId, const TActorId& parentId) { + TActorId TExecutorThread::RegisterActor(IActor* actor, TMailboxType::EType mailboxType, ui32 poolId, const TActorId& parentId) { if (poolId == Max<ui32>()) return Ctx.Executor->Register(actor, mailboxType, ++RevolvingWriteCounter, parentId ? parentId : CurrentRecipient); else return ActorSystem->Register(actor, mailboxType, poolId, ++RevolvingWriteCounter, parentId ? parentId : CurrentRecipient); } - TActorId TExecutorThread::RegisterActor(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) { + TActorId TExecutorThread::RegisterActor(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) { return Ctx.Executor->Register(actor, mailbox, hint, parentId ? parentId : CurrentRecipient); } @@ -71,7 +71,7 @@ namespace NActors { DyingActors.clear(); // here is actual destruction of actors } - void TExecutorThread::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { + void TExecutorThread::Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { ++CurrentActorScheduledEventsCounter; Ctx.Executor->Schedule(deadline, ev, cookie, Ctx.WorkerId); } @@ -81,11 +81,11 @@ namespace NActors { Ctx.Executor->Schedule(deadline, ev, cookie, Ctx.WorkerId); } - void TExecutorThread::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { - ++CurrentActorScheduledEventsCounter; + void TExecutorThread::Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie) { + ++CurrentActorScheduledEventsCounter; Ctx.Executor->Schedule(delta, ev, cookie, Ctx.WorkerId); - } - + } + template <class T> inline TString SafeTypeName(T* t) { if (t == nullptr) { @@ -102,7 +102,7 @@ namespace NActors { return actor ? SafeTypeName(actor) : ("activityType_" + ToString(activityType) + " (destroyed)"); } - inline void LwTraceSlowDelivery(IEventHandle* ev, const IActor* actor, ui32 poolId, const TActorId& currentRecipient, + inline void LwTraceSlowDelivery(IEventHandle* ev, const IActor* actor, ui32 poolId, const TActorId& currentRecipient, double delivMs, double sinceActivationMs, ui32 eventsExecutedBefore) { const auto baseEv = (ev && ev->HasEvent()) ? ev->GetBase() : nullptr; LWPROBE(EventSlowDelivery, @@ -116,7 +116,7 @@ namespace NActors { } inline void LwTraceSlowEvent(IEventHandle* ev, ui32 evTypeForTracing, const IActor* actor, ui32 poolId, ui32 activityType, - const TActorId& currentRecipient, double eventMs) { + const TActorId& currentRecipient, double eventMs) { // Event could have been destroyed by actor->Receive(); const auto baseEv = (ev && ev->HasEvent()) ? ev->GetBase() : nullptr; LWPROBE(SlowEvent, @@ -198,7 +198,7 @@ namespace NActors { if (actor) actor->AddElapsedTicks(elapsed); - CurrentRecipient = TActorId(); + CurrentRecipient = TActorId(); } else { TAutoPtr<IEventHandle> nonDelivered = ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown); if (nonDelivered.Get()) { diff --git a/library/cpp/actors/core/executor_thread.h b/library/cpp/actors/core/executor_thread.h index f3f1d527d6..9d3c573f0d 100644 --- a/library/cpp/actors/core/executor_thread.h +++ b/library/cpp/actors/core/executor_thread.h @@ -39,17 +39,17 @@ namespace NActors { : TExecutorThread(workerId, 0, actorSystem, executorPool, mailboxTable, threadName, timePerMailbox, eventsPerMailbox) {} - TActorId RegisterActor(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>(), - const TActorId& parentId = TActorId()); - TActorId RegisterActor(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId = TActorId()); + TActorId RegisterActor(IActor* actor, TMailboxType::EType mailboxType = TMailboxType::HTSwap, ui32 poolId = Max<ui32>(), + const TActorId& parentId = TActorId()); + TActorId RegisterActor(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId = TActorId()); void UnregisterActor(TMailboxHeader* mailbox, ui64 localActorId); void DropUnregistered(); const std::vector<THolder<IActor>>& GetUnregistered() const { return DyingActors; } - void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); + void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); - void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); - + void Schedule(TDuration delta, TAutoPtr<IEventHandle> ev, ISchedulerCookie* cookie = nullptr); + bool Send(TAutoPtr<IEventHandle> ev) { #ifdef USE_ACTOR_CALLSTACK ev->Callstack = TCallstack::GetTlsCallstack(); @@ -81,7 +81,7 @@ namespace NActors { // Event-specific (currently executing) TVector<THolder<IActor>> DyingActors; - TActorId CurrentRecipient; + TActorId CurrentRecipient; ui64 CurrentActorScheduledEventsCounter = 0; // Thread-specific diff --git a/library/cpp/actors/core/invoke.h b/library/cpp/actors/core/invoke.h index 26de350a95..931a9767dd 100644 --- a/library/cpp/actors/core/invoke.h +++ b/library/cpp/actors/core/invoke.h @@ -92,7 +92,7 @@ namespace NActors { , Complete(std::move(complete)) {} - void Bootstrap(const TActorId& parentId, const TActorContext& ctx) { + void Bootstrap(const TActorId& parentId, const TActorContext& ctx) { auto process = [complete = std::move(Complete)](TEvents::TEvInvokeResult& res, const TActorContext& ctx) { complete([&] { return res.GetResult<TCallback>(); }, ctx); }; diff --git a/library/cpp/actors/core/log.cpp b/library/cpp/actors/core/log.cpp index 88e24f4c01..5f63b5af58 100644 --- a/library/cpp/actors/core/log.cpp +++ b/library/cpp/actors/core/log.cpp @@ -1,7 +1,7 @@ #include "log.h" #include "log_settings.h" -#include <library/cpp/monlib/service/pages/templates.h> +#include <library/cpp/monlib/service/pages/templates.h> static_assert(int(NActors::NLog::PRI_EMERG) == int(::TLOG_EMERG), "expect int(NActors::NLog::PRI_EMERG) == int(::TLOG_EMERG)"); static_assert(int(NActors::NLog::PRI_ALERT) == int(::TLOG_ALERT), "expect int(NActors::NLog::PRI_ALERT) == int(::TLOG_ALERT)"); diff --git a/library/cpp/actors/core/log.h b/library/cpp/actors/core/log.h index c7b6e85bef..c11a7cf3c1 100644 --- a/library/cpp/actors/core/log.h +++ b/library/cpp/actors/core/log.h @@ -14,7 +14,7 @@ #include <util/string/printf.h> #include <util/string/builder.h> #include <library/cpp/logger/all.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <library/cpp/monlib/metrics/metric_registry.h> #include <library/cpp/json/writer/json.h> #include <library/cpp/svnversion/svnversion.h> @@ -323,7 +323,7 @@ namespace NActors { { const NLog::TSettings *mSettings = ctx.LoggerSettings(); TLoggerActor::Throttle(*mSettings); - ctx.Send(new IEventHandle(mSettings->LoggerActorId, TActorId(), new NLog::TEvLog(mPriority, mComponent, std::move(str)))); + ctx.Send(new IEventHandle(mSettings->LoggerActorId, TActorId(), new NLog::TEvLog(mPriority, mComponent, std::move(str)))); } template <typename TCtx, typename... TArgs> diff --git a/library/cpp/actors/core/log_settings.cpp b/library/cpp/actors/core/log_settings.cpp index de2a3a9a68..f52f2fc5d2 100644 --- a/library/cpp/actors/core/log_settings.cpp +++ b/library/cpp/actors/core/log_settings.cpp @@ -4,7 +4,7 @@ namespace NActors { namespace NLog { - TSettings::TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, + TSettings::TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, EComponent minVal, EComponent maxVal, EComponentToStringFunc func, EPriority defPriority, EPriority defSamplingPriority, ui32 defSamplingRate, ui64 timeThresholdMs) @@ -27,7 +27,7 @@ namespace NActors { Append(minVal, maxVal, func); } - TSettings::TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, + TSettings::TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, EPriority defPriority, EPriority defSamplingPriority, ui32 defSamplingRate, ui64 timeThresholdMs) : LoggerActorId(loggerActorId) diff --git a/library/cpp/actors/core/log_settings.h b/library/cpp/actors/core/log_settings.h index 564d2db73e..7fe4504edd 100644 --- a/library/cpp/actors/core/log_settings.h +++ b/library/cpp/actors/core/log_settings.h @@ -69,7 +69,7 @@ namespace NActors { struct TSettings: public TThrRefBase { public: - TActorId LoggerActorId; + TActorId LoggerActorId; EComponent LoggerComponent; ui64 TimeThresholdMs; bool AllowDrop; @@ -98,12 +98,12 @@ namespace NActors { // protobuf enumeration of components. In this case protoc // automatically generates YOURTYPE_MIN, YOURTYPE_MAX and // YOURTYPE_Name for you. - TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, + TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, EComponent minVal, EComponent maxVal, EComponentToStringFunc func, EPriority defPriority, EPriority defSamplingPriority = PRI_DEBUG, ui32 defSamplingRate = 0, ui64 timeThresholdMs = 1000); - TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, + TSettings(const TActorId& loggerActorId, const EComponent loggerComponent, EPriority defPriority, EPriority defSamplingPriority = PRI_DEBUG, ui32 defSamplingRate = 0, ui64 timeThresholdMs = 1000); diff --git a/library/cpp/actors/core/log_ut.cpp b/library/cpp/actors/core/log_ut.cpp index 2a65e270de..09b5f88ea2 100644 --- a/library/cpp/actors/core/log_ut.cpp +++ b/library/cpp/actors/core/log_ut.cpp @@ -15,7 +15,7 @@ namespace { } TIntrusivePtr<TSettings> DefaultSettings() { - auto loggerId = TActorId{0, "Logger"}; + auto loggerId = TActorId{0, "Logger"}; auto s = MakeIntrusive<TSettings>(loggerId, 0, EPriority::PRI_TRACE); s->SetAllowDrop(false); s->Append(0, 1, ServiceToString); @@ -98,7 +98,7 @@ namespace { TIntrusivePtr<TDynamicCounters> Counters{MakeIntrusive<TDynamicCounters>()}; std::shared_ptr<TMockBackend> LogBackend; - TActorId LoggerActor; + TActorId LoggerActor; TTestActorRuntimeBase Runtime; }; } diff --git a/library/cpp/actors/core/mailbox.cpp b/library/cpp/actors/core/mailbox.cpp index 40fcebaa72..d84b4f9e46 100644 --- a/library/cpp/actors/core/mailbox.cpp +++ b/library/cpp/actors/core/mailbox.cpp @@ -163,7 +163,7 @@ namespace NActors { } bool TMailboxTable::SendTo(TAutoPtr<IEventHandle>& ev, IExecutorPool* executorPool) { - const TActorId& recipient = ev->GetRecipientRewrite(); + const TActorId& recipient = ev->GetRecipientRewrite(); const ui32 hint = recipient.Hint(); // copy-paste from Get to avoid duplicated type-switches diff --git a/library/cpp/actors/core/mailbox.h b/library/cpp/actors/core/mailbox.h index 38a03af42d..0bd9c4d314 100644 --- a/library/cpp/actors/core/mailbox.h +++ b/library/cpp/actors/core/mailbox.h @@ -305,14 +305,14 @@ namespace NActors { static const ui32 LineIndexShift = 12; static const ui32 LineIndexMask = 0x1FFFFu << LineIndexShift; static const ui32 LineHintMask = 0xFFFu; - static const ui32 PoolIndexShift = TActorId::PoolIndexShift; - static const ui32 PoolIndexMask = TActorId::PoolIndexMask; + static const ui32 PoolIndexShift = TActorId::PoolIndexShift; + static const ui32 PoolIndexMask = TActorId::PoolIndexMask; static ui32 LineIndex(ui32 hint) { return ((hint & LineIndexMask) >> LineIndexShift); } static ui32 PoolIndex(ui32 hint) { - return TActorId::PoolIndex(hint); + return TActorId::PoolIndex(hint); } TMailboxHeader* Get(ui32 hint); diff --git a/library/cpp/actors/core/mon.h b/library/cpp/actors/core/mon.h index 45e0e7ff65..c450f2338e 100644 --- a/library/cpp/actors/core/mon.h +++ b/library/cpp/actors/core/mon.h @@ -2,8 +2,8 @@ #include "events.h" #include "event_local.h" -#include <library/cpp/monlib/service/monservice.h> -#include <library/cpp/monlib/service/pages/mon_page.h> +#include <library/cpp/monlib/service/monservice.h> +#include <library/cpp/monlib/service/pages/mon_page.h> namespace NActors { namespace NMon { diff --git a/library/cpp/actors/core/process_stats.cpp b/library/cpp/actors/core/process_stats.cpp index 61bf7452a7..0e1dbd0031 100644 --- a/library/cpp/actors/core/process_stats.cpp +++ b/library/cpp/actors/core/process_stats.cpp @@ -3,8 +3,8 @@ #include "hfunc.h" #include "process_stats.h" -#include <library/cpp/monlib/dynamic_counters/counters.h> -#include <library/cpp/monlib/metrics/metric_registry.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/metrics/metric_registry.h> #include <util/datetime/uptime.h> #include <util/system/defaults.h> @@ -197,7 +197,7 @@ namespace { MinorPageFaults = ProcStatGroup->GetCounter("Process/MinorPageFaults", true); MajorPageFaults = ProcStatGroup->GetCounter("Process/MajorPageFaults", true); UptimeSeconds = ProcStatGroup->GetCounter("Process/UptimeSeconds", false); - NumThreads = ProcStatGroup->GetCounter("Process/NumThreads", false); + NumThreads = ProcStatGroup->GetCounter("Process/NumThreads", false); SystemUptimeSeconds = ProcStatGroup->GetCounter("System/UptimeSeconds", false); } @@ -213,7 +213,7 @@ namespace { *MinorPageFaults = procStat.MinFlt; *MajorPageFaults = procStat.MajFlt; *UptimeSeconds = procStat.Uptime.Seconds(); - *NumThreads = procStat.NumThreads; + *NumThreads = procStat.NumThreads; *SystemUptimeSeconds = procStat.Uptime.Seconds(); } @@ -228,7 +228,7 @@ namespace { NMonitoring::TDynamicCounters::TCounterPtr MinorPageFaults; NMonitoring::TDynamicCounters::TCounterPtr MajorPageFaults; NMonitoring::TDynamicCounters::TCounterPtr UptimeSeconds; - NMonitoring::TDynamicCounters::TCounterPtr NumThreads; + NMonitoring::TDynamicCounters::TCounterPtr NumThreads; NMonitoring::TDynamicCounters::TCounterPtr SystemUptimeSeconds; }; @@ -236,7 +236,7 @@ namespace { class TRegistryCollector: public TProcStatCollectingActor<TRegistryCollector> { using TBase = TProcStatCollectingActor<TRegistryCollector>; public: - TRegistryCollector(TDuration interval, NMonitoring::TMetricRegistry& registry) + TRegistryCollector(TDuration interval, NMonitoring::TMetricRegistry& registry) : TBase{interval} { VmSize = registry.IntGauge({{"sensor", "process.VmSize"}}); @@ -244,13 +244,13 @@ namespace { FileRssSize = registry.IntGauge({{"sensor", "process.FileRssSize"}}); CGroupMemLimit = registry.IntGauge({{"sensor", "process.CGroupMemLimit"}}); UptimeSeconds = registry.IntGauge({{"sensor", "process.UptimeSeconds"}}); - NumThreads = registry.IntGauge({{"sensor", "process.NumThreads"}}); + NumThreads = registry.IntGauge({{"sensor", "process.NumThreads"}}); SystemUptimeSeconds = registry.IntGauge({{"sensor", "system.UptimeSeconds"}}); - - UserTime = registry.Rate({{"sensor", "process.UserTime"}}); - SysTime = registry.Rate({{"sensor", "process.SystemTime"}}); - MinorPageFaults = registry.Rate({{"sensor", "process.MinorPageFaults"}}); - MajorPageFaults = registry.Rate({{"sensor", "process.MajorPageFaults"}}); + + UserTime = registry.Rate({{"sensor", "process.UserTime"}}); + SysTime = registry.Rate({{"sensor", "process.SystemTime"}}); + MinorPageFaults = registry.Rate({{"sensor", "process.MinorPageFaults"}}); + MajorPageFaults = registry.Rate({{"sensor", "process.MajorPageFaults"}}); } void UpdateCounters(const TProcStat& procStat) { @@ -259,23 +259,23 @@ namespace { FileRssSize->Set(procStat.FileRss); CGroupMemLimit->Set(procStat.CGroupMemLim); UptimeSeconds->Set(procStat.Uptime.Seconds()); - NumThreads->Set(procStat.NumThreads); + NumThreads->Set(procStat.NumThreads); SystemUptimeSeconds->Set(procStat.SystemUptime.Seconds()); - - // it is ok here to reset and add metric value, because mutation - // is performed in siglethreaded context - - UserTime->Reset(); - UserTime->Add(procStat.Utime); - - SysTime->Reset(); - SysTime->Add(procStat.Stime); - - MinorPageFaults->Reset(); - MinorPageFaults->Add(procStat.MinFlt); - - MajorPageFaults->Reset(); - MajorPageFaults->Add(procStat.MajFlt); + + // it is ok here to reset and add metric value, because mutation + // is performed in siglethreaded context + + UserTime->Reset(); + UserTime->Add(procStat.Utime); + + SysTime->Reset(); + SysTime->Add(procStat.Stime); + + MinorPageFaults->Reset(); + MinorPageFaults->Add(procStat.MinFlt); + + MajorPageFaults->Reset(); + MajorPageFaults->Add(procStat.MajFlt); } private: @@ -283,12 +283,12 @@ namespace { NMonitoring::TIntGauge* AnonRssSize; NMonitoring::TIntGauge* FileRssSize; NMonitoring::TIntGauge* CGroupMemLimit; - NMonitoring::TRate* UserTime; - NMonitoring::TRate* SysTime; - NMonitoring::TRate* MinorPageFaults; - NMonitoring::TRate* MajorPageFaults; + NMonitoring::TRate* UserTime; + NMonitoring::TRate* SysTime; + NMonitoring::TRate* MinorPageFaults; + NMonitoring::TRate* MajorPageFaults; NMonitoring::TIntGauge* UptimeSeconds; - NMonitoring::TIntGauge* NumThreads; + NMonitoring::TIntGauge* NumThreads; NMonitoring::TIntGauge* SystemUptimeSeconds; }; } // namespace @@ -297,7 +297,7 @@ namespace { return new TDynamicCounterCollector(intervalSec, counters); } - IActor* CreateProcStatCollector(TDuration interval, NMonitoring::TMetricRegistry& registry) { + IActor* CreateProcStatCollector(TDuration interval, NMonitoring::TMetricRegistry& registry) { return new TRegistryCollector(interval, registry); } } diff --git a/library/cpp/actors/core/process_stats.h b/library/cpp/actors/core/process_stats.h index 4e6bb31090..66346d0b5a 100644 --- a/library/cpp/actors/core/process_stats.h +++ b/library/cpp/actors/core/process_stats.h @@ -3,10 +3,10 @@ #include "defs.h" #include "actor.h" -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> namespace NMonitoring { - class TMetricRegistry; + class TMetricRegistry; } namespace NActors { @@ -62,5 +62,5 @@ namespace NActors { }; IActor* CreateProcStatCollector(ui32 intervalSec, NMonitoring::TDynamicCounterPtr counters); - IActor* CreateProcStatCollector(TDuration interval, NMonitoring::TMetricRegistry& registry); + IActor* CreateProcStatCollector(TDuration interval, NMonitoring::TMetricRegistry& registry); } diff --git a/library/cpp/actors/core/scheduler_actor.cpp b/library/cpp/actors/core/scheduler_actor.cpp index d1e6501fd1..febc5e40dd 100644 --- a/library/cpp/actors/core/scheduler_actor.cpp +++ b/library/cpp/actors/core/scheduler_actor.cpp @@ -39,7 +39,7 @@ namespace NActors { TVector<NSchedulerQueue::TReader*> Readers; - TActorId PollerActor; + TActorId PollerActor; TPollerToken::TPtr PollerToken; ui64 RealTime; @@ -68,7 +68,7 @@ namespace NActors { : TActor(&TSchedulerActor::StateFunc) , Cfg(cfg) , TimerDescriptor(new TTimerDescriptor()) - , PollerActor(MakePollerActorId()) + , PollerActor(MakePollerActorId()) { Y_ASSERT(Cfg.ResolutionMicroseconds != 0); Y_ASSERT(Cfg.ProgressThreshold != 0); diff --git a/library/cpp/actors/core/scheduler_actor.h b/library/cpp/actors/core/scheduler_actor.h index 600f8d98ff..c2c561b43d 100644 --- a/library/cpp/actors/core/scheduler_actor.h +++ b/library/cpp/actors/core/scheduler_actor.h @@ -21,9 +21,9 @@ namespace NActors { IActor* CreateSchedulerActor(const TSchedulerConfig& cfg); - inline TActorId MakeSchedulerActorId() { + inline TActorId MakeSchedulerActorId() { char x[12] = {'s', 'c', 'h', 'e', 'd', 'u', 'l', 'e', 'r', 's', 'e', 'r'}; - return TActorId(0, TStringBuf(x, 12)); + return TActorId(0, TStringBuf(x, 12)); } } diff --git a/library/cpp/actors/core/scheduler_actor_ut.cpp b/library/cpp/actors/core/scheduler_actor_ut.cpp index dae14cbe67..09b7369d36 100644 --- a/library/cpp/actors/core/scheduler_actor_ut.cpp +++ b/library/cpp/actors/core/scheduler_actor_ut.cpp @@ -60,14 +60,14 @@ Y_UNIT_TEST_SUITE(SchedulerActor) { setup->Executors[i] = new TBasicExecutorPool(i, 5, 10, "basic"); } // create poller actor (whether platform supports it) - TActorId pollerActorId; + TActorId pollerActorId; if (IActor* poller = CreatePollerActor()) { - pollerActorId = MakePollerActorId(); + pollerActorId = MakePollerActorId(); setup->LocalServices.emplace_back(pollerActorId, TActorSetupCmd(poller, TMailboxType::ReadAsFilled, 0)); } - TActorId schedulerActorId; + TActorId schedulerActorId; if (IActor* schedulerActor = CreateSchedulerActor(TSchedulerConfig())) { - schedulerActorId = MakeSchedulerActorId(); + schedulerActorId = MakeSchedulerActorId(); setup->LocalServices.emplace_back(schedulerActorId, TActorSetupCmd(schedulerActor, TMailboxType::ReadAsFilled, 0)); } setup->Scheduler = CreateSchedulerThread(TSchedulerConfig()); diff --git a/library/cpp/actors/core/ut/ya.make b/library/cpp/actors/core/ut/ya.make index 11b2ea3eb7..3ee28d5850 100644 --- a/library/cpp/actors/core/ut/ya.make +++ b/library/cpp/actors/core/ut/ya.make @@ -29,18 +29,18 @@ PEERDIR( ) SRCS( - actor_coroutine_ut.cpp - actor_ut.cpp - actorsystem_ut.cpp + actor_coroutine_ut.cpp + actor_ut.cpp + actorsystem_ut.cpp ask_ut.cpp balancer_ut.cpp - event_pb_payload_ut.cpp + event_pb_payload_ut.cpp event_pb_ut.cpp executor_pool_basic_ut.cpp executor_pool_united_ut.cpp log_ut.cpp memory_tracker_ut.cpp - scheduler_actor_ut.cpp + scheduler_actor_ut.cpp ) END() diff --git a/library/cpp/actors/core/ya.make b/library/cpp/actors/core/ya.make index 40f27456c8..880a9d00db 100644 --- a/library/cpp/actors/core/ya.make +++ b/library/cpp/actors/core/ya.make @@ -111,7 +111,7 @@ PEERDIR( library/cpp/json/writer library/cpp/logger library/cpp/lwtrace - library/cpp/monlib/dynamic_counters + library/cpp/monlib/dynamic_counters library/cpp/svnversion library/cpp/threading/future ) diff --git a/library/cpp/actors/helpers/activeactors.h b/library/cpp/actors/helpers/activeactors.h index b0e4f5cc99..0fdb0fab10 100644 --- a/library/cpp/actors/helpers/activeactors.h +++ b/library/cpp/actors/helpers/activeactors.h @@ -10,9 +10,9 @@ namespace NActors { // TActiveActors // This class helps manage created actors and kill them all on PoisonPill. //////////////////////////////////////////////////////////////////////////// - class TActiveActors : public THashSet<TActorId> { + class TActiveActors : public THashSet<TActorId> { public: - void Insert(const TActorId &aid) { + void Insert(const TActorId &aid) { bool inserted = insert(aid).second; Y_VERIFY(inserted); } @@ -23,7 +23,7 @@ namespace NActors { } } - void Erase(const TActorId &aid) { + void Erase(const TActorId &aid) { auto num = erase(aid); Y_VERIFY(num == 1); } diff --git a/library/cpp/actors/helpers/flow_controlled_queue.cpp b/library/cpp/actors/helpers/flow_controlled_queue.cpp index 61610ec3d3..d75cc54023 100644 --- a/library/cpp/actors/helpers/flow_controlled_queue.cpp +++ b/library/cpp/actors/helpers/flow_controlled_queue.cpp @@ -18,12 +18,12 @@ class TFlowControlledRequestActor : public IActor { void HandleReply(TAutoPtr<IEventHandle> &ev); void HandleUndelivered(TEvents::TEvUndelivered::TPtr &ev); public: - const TActorId Source; + const TActorId Source; const ui64 Cookie; const ui32 Flags; const ui64 StartCounter; - TFlowControlledRequestActor(ui32 activity, TFlowControlledRequestQueue *queue, TActorId source, ui64 cookie, ui32 flags) + TFlowControlledRequestActor(ui32 activity, TFlowControlledRequestQueue *queue, TActorId source, ui64 cookie, ui32 flags) : IActor(static_cast<TReceiveFunc>(&TFlowControlledRequestActor::StateWait), activity) , QueueActor(queue) , Source(source) @@ -49,7 +49,7 @@ public: }; class TFlowControlledRequestQueue : public IActor { - const TActorId Target; + const TActorId Target; const TFlowControlledQueueConfig Config; TDeque<THolder<IEventHandle>> UnhandledRequests; @@ -123,7 +123,7 @@ class TFlowControlledRequestQueue : public IActor { if (reqActor) { if (reqActor->Flags & IEventHandle::FlagSubscribeOnSession) { TActivationContext::Send( - new IEventHandle(reqActor->Source, TActorId(), new TEvInterconnect::TEvNodeDisconnected(nodeid), 0, reqActor->Cookie) + new IEventHandle(reqActor->Source, TActorId(), new TEvInterconnect::TEvNodeDisconnected(nodeid), 0, reqActor->Cookie) ); } reqActor->PassAway(); @@ -153,7 +153,7 @@ class TFlowControlledRequestQueue : public IActor { PassAway(); } public: - TFlowControlledRequestQueue(TActorId target, ui32 activity, const TFlowControlledQueueConfig &config) + TFlowControlledRequestQueue(TActorId target, ui32 activity, const TFlowControlledQueueConfig &config) : IActor(static_cast<TReceiveFunc>(&TFlowControlledRequestQueue::StateWork), activity) , Target(target) , Config(config) @@ -208,7 +208,7 @@ void TFlowControlledRequestActor::HandleUndelivered(TEvents::TEvUndelivered::TPt } -IActor* CreateFlowControlledRequestQueue(TActorId targetId, ui32 activity, const TFlowControlledQueueConfig &config) { +IActor* CreateFlowControlledRequestQueue(TActorId targetId, ui32 activity, const TFlowControlledQueueConfig &config) { return new TFlowControlledRequestQueue(targetId, activity, config); } diff --git a/library/cpp/actors/helpers/flow_controlled_queue.h b/library/cpp/actors/helpers/flow_controlled_queue.h index 1d03226103..d250405304 100644 --- a/library/cpp/actors/helpers/flow_controlled_queue.h +++ b/library/cpp/actors/helpers/flow_controlled_queue.h @@ -13,6 +13,6 @@ namespace NActors { ui32 LatencyFactor = 4; }; - IActor* CreateFlowControlledRequestQueue(TActorId targetId, ui32 activity = IActor::ACTORLIB_COMMON, const TFlowControlledQueueConfig &config = TFlowControlledQueueConfig()); + IActor* CreateFlowControlledRequestQueue(TActorId targetId, ui32 activity = IActor::ACTORLIB_COMMON, const TFlowControlledQueueConfig &config = TFlowControlledQueueConfig()); } diff --git a/library/cpp/actors/helpers/mon_histogram_helper.h b/library/cpp/actors/helpers/mon_histogram_helper.h index 80b9690a75..a9a57e3823 100644 --- a/library/cpp/actors/helpers/mon_histogram_helper.h +++ b/library/cpp/actors/helpers/mon_histogram_helper.h @@ -1,9 +1,9 @@ #pragma once -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> + +#include <util/string/cast.h> -#include <util/string/cast.h> - namespace NActors { namespace NMon { class THistogramCounterHelper { @@ -79,7 +79,7 @@ namespace NActors { ui64 FirstBucketVal; ui64 BucketCount; TVector<NMonitoring::TDynamicCounters::TCounterPtr> BucketsHolder; - TVector<NMonitoring::TDeprecatedCounter*> Buckets; + TVector<NMonitoring::TDeprecatedCounter*> Buckets; }; } diff --git a/library/cpp/actors/helpers/selfping_actor.h b/library/cpp/actors/helpers/selfping_actor.h index d1f320509e..d7d07f9fa8 100644 --- a/library/cpp/actors/helpers/selfping_actor.h +++ b/library/cpp/actors/helpers/selfping_actor.h @@ -1,7 +1,7 @@ #pragma once #include <library/cpp/actors/core/actor.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> namespace NActors { diff --git a/library/cpp/actors/helpers/ya.make b/library/cpp/actors/helpers/ya.make index 0169a2c727..d8771179de 100644 --- a/library/cpp/actors/helpers/ya.make +++ b/library/cpp/actors/helpers/ya.make @@ -14,7 +14,7 @@ SRCS( PEERDIR( library/cpp/actors/core - library/cpp/monlib/dynamic_counters + library/cpp/monlib/dynamic_counters ) END() diff --git a/library/cpp/actors/http/http_cache.cpp b/library/cpp/actors/http/http_cache.cpp index 834fe47b73..27c4eeb6f3 100644 --- a/library/cpp/actors/http/http_cache.cpp +++ b/library/cpp/actors/http/http_cache.cpp @@ -16,7 +16,7 @@ namespace NHttp { class THttpOutgoingCacheActor : public NActors::TActorBootstrapped<THttpOutgoingCacheActor>, THttpConfig { public: using TBase = NActors::TActorBootstrapped<THttpOutgoingCacheActor>; - NActors::TActorId HttpProxyId; + NActors::TActorId HttpProxyId; TGetCachePolicy GetCachePolicy; static constexpr TDuration RefreshTimeout = TDuration::Seconds(1); @@ -584,7 +584,7 @@ TCachePolicy GetDefaultCachePolicy(const THttpRequest* request, const TCachePoli return policy; } -NActors::IActor* CreateHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) { +NActors::IActor* CreateHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy) { return new THttpOutgoingCacheActor(httpProxyId, std::move(cachePolicy)); } diff --git a/library/cpp/actors/http/http_cache.h b/library/cpp/actors/http/http_cache.h index 313c7bd266..ac38bdcac8 100644 --- a/library/cpp/actors/http/http_cache.h +++ b/library/cpp/actors/http/http_cache.h @@ -19,7 +19,7 @@ struct TCachePolicy { using TGetCachePolicy = std::function<TCachePolicy(const THttpRequest*)>; -NActors::IActor* CreateHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy); +NActors::IActor* CreateHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy); NActors::IActor* CreateOutgoingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy); NActors::IActor* CreateIncomingHttpCache(const NActors::TActorId& httpProxyId, TGetCachePolicy cachePolicy); TCachePolicy GetDefaultCachePolicy(const THttpRequest* request, const TCachePolicy& policy = TCachePolicy()); diff --git a/library/cpp/actors/http/http_proxy.cpp b/library/cpp/actors/http/http_proxy.cpp index 3a466006cd..36c6855d93 100644 --- a/library/cpp/actors/http/http_proxy.cpp +++ b/library/cpp/actors/http/http_proxy.cpp @@ -1,5 +1,5 @@ #include <library/cpp/actors/core/events.h> -#include <library/cpp/monlib/metrics/metric_registry.h> +#include <library/cpp/monlib/metrics/metric_registry.h> #include "http_proxy.h" namespace NHttp { @@ -8,7 +8,7 @@ class THttpProxy : public NActors::TActorBootstrapped<THttpProxy>, public THttpC public: IActor* AddListeningPort(TEvHttpProxy::TEvAddListeningPort::TPtr event, const NActors::TActorContext& ctx) { IActor* listeningSocket = CreateHttpAcceptorActor(ctx.SelfID, Poller); - TActorId acceptorId = ctx.Register(listeningSocket); + TActorId acceptorId = ctx.Register(listeningSocket); ctx.Send(event->Forward(acceptorId)); Acceptors.emplace_back(acceptorId); return listeningSocket; @@ -16,7 +16,7 @@ public: IActor* AddOutgoingConnection(const TString& address, bool secure, const NActors::TActorContext& ctx) { IActor* connectionSocket = CreateOutgoingConnectionActor(ctx.SelfID, address, secure, Poller); - TActorId connectionId = ctx.Register(connectionSocket); + TActorId connectionId = ctx.Register(connectionSocket); Connections.emplace(connectionId); return connectionSocket; } @@ -26,7 +26,7 @@ public: Become(&THttpProxy::StateWork); } - THttpProxy(NMonitoring::TMetricRegistry& sensors) + THttpProxy(NMonitoring::TMetricRegistry& sensors) : Sensors(sensors) {} @@ -49,10 +49,10 @@ protected: void PassAway() override { Send(Poller, new NActors::TEvents::TEvPoisonPill()); - for (const NActors::TActorId& connection : Connections) { + for (const NActors::TActorId& connection : Connections) { Send(connection, new NActors::TEvents::TEvPoisonPill()); } - for (const NActors::TActorId& acceptor : Acceptors) { + for (const NActors::TActorId& acceptor : Acceptors) { Send(acceptor, new NActors::TEvents::TEvPoisonPill()); } NActors::TActorBootstrapped<THttpProxy>::PassAway(); @@ -60,7 +60,7 @@ protected: void Handle(TEvHttpProxy::TEvHttpIncomingRequest::TPtr event, const NActors::TActorContext& ctx) { TStringBuf url = event->Get()->Request->URL.Before('?'); - THashMap<TString, TActorId>::iterator it; + THashMap<TString, TActorId>::iterator it; while (!url.empty()) { it = Handlers.find(url); if (it != Handlers.end()) { @@ -204,8 +204,8 @@ protected: PassAway(); } - NActors::TActorId Poller; - TVector<TActorId> Acceptors; + NActors::TActorId Poller; + TVector<TActorId> Acceptors; struct THostEntry { TSockAddrInet6 Address; @@ -215,9 +215,9 @@ protected: static constexpr TDuration HostsTimeToLive = TDuration::Seconds(60); THashMap<TString, THostEntry> Hosts; - THashMap<TString, TActorId> Handlers; - THashSet<TActorId> Connections; // outgoing - NMonitoring::TMetricRegistry& Sensors; + THashMap<TString, TActorId> Handlers; + THashSet<TActorId> Connections; // outgoing + NMonitoring::TMetricRegistry& Sensors; }; TEvHttpProxy::TEvReportSensors* BuildOutgoingRequestSensors(const THttpOutgoingRequestPtr& request, const THttpIncomingResponsePtr& response) { @@ -240,7 +240,7 @@ TEvHttpProxy::TEvReportSensors* BuildIncomingRequestSensors(const THttpIncomingR ); } -NActors::IActor* CreateHttpProxy(NMonitoring::TMetricRegistry& sensors) { +NActors::IActor* CreateHttpProxy(NMonitoring::TMetricRegistry& sensors) { return new THttpProxy(sensors); } diff --git a/library/cpp/actors/http/http_proxy.h b/library/cpp/actors/http/http_proxy.h index 97ea6fbd44..afd0170997 100644 --- a/library/cpp/actors/http/http_proxy.h +++ b/library/cpp/actors/http/http_proxy.h @@ -8,7 +8,7 @@ #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/interconnect/poller_actor.h> #include <library/cpp/dns/cache.h> -#include <library/cpp/monlib/metrics/metric_registry.h> +#include <library/cpp/monlib/metrics/metric_registry.h> #include <util/generic/variant.h> #include "http.h" #include "http_proxy_ssl.h" @@ -25,7 +25,7 @@ struct TSocketDescriptor : NActors::TSharedDescriptor, THttpConfig { struct TEvHttpProxy { enum EEv { - EvAddListeningPort = EventSpaceBegin(NActors::TEvents::ES_HTTP), + EvAddListeningPort = EventSpaceBegin(NActors::TEvents::ES_HTTP), EvConfirmListen, EvRegisterHandler, EvHttpIncomingRequest, @@ -41,7 +41,7 @@ struct TEvHttpProxy { EvEnd }; - static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_HTTP), "ES_HTTP event space is too small."); + static_assert(EvEnd < EventSpaceEnd(NActors::TEvents::ES_HTTP), "ES_HTTP event space is too small."); struct TEvAddListeningPort : NActors::TEventLocal<TEvAddListeningPort, EvAddListeningPort> { TIpPort Port; @@ -71,9 +71,9 @@ struct TEvHttpProxy { struct TEvRegisterHandler : NActors::TEventLocal<TEvRegisterHandler, EvRegisterHandler> { TString Path; - TActorId Handler; + TActorId Handler; - TEvRegisterHandler(const TString& path, const TActorId& handler) + TEvRegisterHandler(const TString& path, const TActorId& handler) : Path(path) , Handler(handler) {} @@ -142,32 +142,32 @@ struct TEvHttpProxy { struct TEvHttpConnectionOpened : NActors::TEventLocal<TEvHttpConnectionOpened, EvHttpConnectionOpened> { TString PeerAddress; - TActorId ConnectionID; + TActorId ConnectionID; - TEvHttpConnectionOpened(const TString& peerAddress, const TActorId& connectionID) + TEvHttpConnectionOpened(const TString& peerAddress, const TActorId& connectionID) : PeerAddress(peerAddress) , ConnectionID(connectionID) {} }; struct TEvHttpConnectionClosed : NActors::TEventLocal<TEvHttpConnectionClosed, EvHttpConnectionClosed> { - TActorId ConnectionID; + TActorId ConnectionID; TDeque<THttpIncomingRequestPtr> RecycledRequests; - TEvHttpConnectionClosed(const TActorId& connectionID) + TEvHttpConnectionClosed(const TActorId& connectionID) : ConnectionID(connectionID) {} - TEvHttpConnectionClosed(const TActorId& connectionID, TDeque<THttpIncomingRequestPtr> recycledRequests) + TEvHttpConnectionClosed(const TActorId& connectionID, TDeque<THttpIncomingRequestPtr> recycledRequests) : ConnectionID(connectionID) , RecycledRequests(std::move(recycledRequests)) {} }; struct TEvHttpAcceptorClosed : NActors::TEventLocal<TEvHttpAcceptorClosed, EvHttpAcceptorClosed> { - TActorId ConnectionID; + TActorId ConnectionID; - TEvHttpAcceptorClosed(const TActorId& connectionID) + TEvHttpAcceptorClosed(const TActorId& connectionID) : ConnectionID(connectionID) {} }; @@ -218,16 +218,16 @@ struct TEvHttpProxy { }; struct TEndpointInfo { - TActorId Proxy; - TActorId Owner; + TActorId Proxy; + TActorId Owner; TString WorkerName; bool Secure; TSslHelpers::TSslHolder<SSL_CTX> SecureContext; }; -NActors::IActor* CreateHttpProxy(NMonitoring::TMetricRegistry& sensors); -NActors::IActor* CreateHttpAcceptorActor(const TActorId& owner, const TActorId& poller); -NActors::IActor* CreateOutgoingConnectionActor(const TActorId& owner, const TString& host, bool secure, const TActorId& poller); +NActors::IActor* CreateHttpProxy(NMonitoring::TMetricRegistry& sensors); +NActors::IActor* CreateHttpAcceptorActor(const TActorId& owner, const TActorId& poller); +NActors::IActor* CreateOutgoingConnectionActor(const TActorId& owner, const TString& host, bool secure, const TActorId& poller); NActors::IActor* CreateIncomingConnectionActor( const TEndpointInfo& endpoint, TIntrusivePtr<TSocketDescriptor> socket, diff --git a/library/cpp/actors/http/http_proxy_acceptor.cpp b/library/cpp/actors/http/http_proxy_acceptor.cpp index 95b07ffa84..9780541b71 100644 --- a/library/cpp/actors/http/http_proxy_acceptor.cpp +++ b/library/cpp/actors/http/http_proxy_acceptor.cpp @@ -7,15 +7,15 @@ namespace NHttp { class TAcceptorActor : public NActors::TActor<TAcceptorActor>, public THttpConfig { public: using TBase = NActors::TActor<TAcceptorActor>; - const TActorId Owner; - const TActorId Poller; + const TActorId Owner; + const TActorId Poller; TIntrusivePtr<TSocketDescriptor> Socket; NActors::TPollerToken::TPtr PollerToken; - THashSet<TActorId> Connections; + THashSet<TActorId> Connections; TDeque<THttpIncomingRequestPtr> RecycledRequests; TEndpointInfo Endpoint; - TAcceptorActor(const TActorId& owner, const TActorId& poller) + TAcceptorActor(const TActorId& owner, const TActorId& poller) : NActors::TActor<TAcceptorActor>(&TAcceptorActor::StateInit) , Owner(owner) , Poller(poller) @@ -77,12 +77,12 @@ protected: } } LOG_WARN_S(ctx, HttpLog, "Failed to listen on " << bindAddress.ToString() << " - retrying..."); - ctx.ExecutorThread.Schedule(TDuration::Seconds(1), event.Release()); + ctx.ExecutorThread.Schedule(TDuration::Seconds(1), event.Release()); } void Die(const NActors::TActorContext& ctx) override { ctx.Send(Owner, new TEvHttpProxy::TEvHttpAcceptorClosed(ctx.SelfID)); - for (const NActors::TActorId& connection : Connections) { + for (const NActors::TActorId& connection : Connections) { ctx.Send(connection, new NActors::TEvents::TEvPoisonPill()); } } @@ -104,7 +104,7 @@ protected: connectionSocket = CreateIncomingConnectionActor(Endpoint, socket, addr, std::move(RecycledRequests.front())); RecycledRequests.pop_front(); } - NActors::TActorId connectionId = ctx.Register(connectionSocket); + NActors::TActorId connectionId = ctx.Register(connectionSocket); ctx.Send(Poller, new NActors::TEvPollerRegister(socket, connectionId, connectionId)); Connections.emplace(connectionId); socket = new TSocketDescriptor(); @@ -128,7 +128,7 @@ protected: } }; -NActors::IActor* CreateHttpAcceptorActor(const TActorId& owner, const TActorId& poller) { +NActors::IActor* CreateHttpAcceptorActor(const TActorId& owner, const TActorId& poller) { return new TAcceptorActor(owner, poller); } diff --git a/library/cpp/actors/http/http_proxy_outgoing.cpp b/library/cpp/actors/http/http_proxy_outgoing.cpp index 5bd4dd74b0..d9189dba8a 100644 --- a/library/cpp/actors/http/http_proxy_outgoing.cpp +++ b/library/cpp/actors/http/http_proxy_outgoing.cpp @@ -8,18 +8,18 @@ class TOutgoingConnectionActor : public NActors::TActor<TOutgoingConnectionActor public: using TBase = NActors::TActor<TOutgoingConnectionActor<TSocketImpl>>; using TSelf = TOutgoingConnectionActor<TSocketImpl>; - const TActorId Owner; - const TActorId Poller; + const TActorId Owner; + const TActorId Poller; SocketAddressType Address; TString Host; - TActorId RequestOwner; + TActorId RequestOwner; THttpOutgoingRequestPtr Request; THttpIncomingResponsePtr Response; TInstant LastActivity; TDuration ConnectionTimeout = CONNECTION_TIMEOUT; NActors::TPollerToken::TPtr PollerToken; - TOutgoingConnectionActor(const TActorId& owner, const TString& host, const TActorId& poller) + TOutgoingConnectionActor(const TActorId& owner, const TString& host, const TActorId& poller) : TBase(&TSelf::StateWaiting) , Owner(owner) , Poller(poller) @@ -38,7 +38,7 @@ public: void ReplyAndDie(const NActors::TActorContext& ctx) { LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") -> (" << Response->Status << " " << Response->Message << ")"); ctx.Send(RequestOwner, new TEvHttpProxy::TEvHttpIncomingResponse(Request, Response)); - RequestOwner = TActorId(); + RequestOwner = TActorId(); THolder<TEvHttpProxy::TEvReportSensors> sensors(BuildOutgoingRequestSensors(Request, Response)); ctx.Send(Owner, sensors.Release()); LOG_DEBUG_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed"); @@ -49,7 +49,7 @@ public: LOG_ERROR_S(ctx, HttpLog, "(#" << TSocketImpl::GetRawSocket() << "," << Address << ") connection closed with error: " << error); if (RequestOwner) { ctx.Send(RequestOwner, new TEvHttpProxy::TEvHttpIncomingResponse(Request, Response, error)); - RequestOwner = TActorId(); + RequestOwner = TActorId(); THolder<TEvHttpProxy::TEvReportSensors> sensors(BuildOutgoingRequestSensors(Request, Response)); ctx.Send(Owner, sensors.Release()); Die(ctx); @@ -287,7 +287,7 @@ protected: } }; -NActors::IActor* CreateOutgoingConnectionActor(const TActorId& owner, const TString& host, bool secure, const TActorId& poller) { +NActors::IActor* CreateOutgoingConnectionActor(const TActorId& owner, const TString& host, bool secure, const TActorId& poller) { if (secure) { return new TOutgoingConnectionActor<TSecureSocketImpl>(owner, host, poller); } else { diff --git a/library/cpp/actors/http/http_ut.cpp b/library/cpp/actors/http/http_ut.cpp index b21ceb550f..4c922f8d0f 100644 --- a/library/cpp/actors/http/http_ut.cpp +++ b/library/cpp/actors/http/http_ut.cpp @@ -180,17 +180,17 @@ Y_UNIT_TEST_SUITE(HttpProxy) { TIpPort port = portManager.GetTcpPort(); TAutoPtr<NActors::IEventHandle> handle; actorSystem.Initialize(); - NMonitoring::TMetricRegistry sensors; + NMonitoring::TMetricRegistry sensors; NActors::IActor* proxy = NHttp::CreateHttpProxy(sensors); - NActors::TActorId proxyId = actorSystem.Register(proxy); - actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), new NHttp::TEvHttpProxy::TEvAddListeningPort(port)), 0, true); + NActors::TActorId proxyId = actorSystem.Register(proxy); + actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), new NHttp::TEvHttpProxy::TEvAddListeningPort(port)), 0, true); actorSystem.DispatchEvents(); - NActors::TActorId serverId = actorSystem.AllocateEdgeActor(); + NActors::TActorId serverId = actorSystem.AllocateEdgeActor(); actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true); - NActors::TActorId clientId = actorSystem.AllocateEdgeActor(); + NActors::TActorId clientId = actorSystem.AllocateEdgeActor(); NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("http://[::1]:" + ToString(port) + "/test"); actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true); @@ -213,7 +213,7 @@ Y_UNIT_TEST_SUITE(HttpProxy) { TIpPort port = portManager.GetTcpPort(); TAutoPtr<NActors::IEventHandle> handle; actorSystem.Initialize(); - NMonitoring::TMetricRegistry sensors; + NMonitoring::TMetricRegistry sensors; TString certificateContent = R"___(-----BEGIN PRIVATE KEY----- MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCzRZjodO7Aqe1w @@ -273,7 +273,7 @@ CRA/5XcX13GJwHHj6LCoc3sL7mt8qV9HKY2AOZ88mpObzISZxgPpdKCfjsrdm63V certificateFile.Write(certificateContent.data(), certificateContent.size()); NActors::IActor* proxy = NHttp::CreateHttpProxy(sensors); - NActors::TActorId proxyId = actorSystem.Register(proxy); + NActors::TActorId proxyId = actorSystem.Register(proxy); THolder<NHttp::TEvHttpProxy::TEvAddListeningPort> add = MakeHolder<NHttp::TEvHttpProxy::TEvAddListeningPort>(port); ///////// https configuration @@ -281,13 +281,13 @@ CRA/5XcX13GJwHHj6LCoc3sL7mt8qV9HKY2AOZ88mpObzISZxgPpdKCfjsrdm63V add->CertificateFile = certificateFile.Name(); add->PrivateKeyFile = certificateFile.Name(); ///////// - actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), add.Release()), 0, true); + actorSystem.Send(new NActors::IEventHandle(proxyId, TActorId(), add.Release()), 0, true); actorSystem.DispatchEvents(); - NActors::TActorId serverId = actorSystem.AllocateEdgeActor(); + NActors::TActorId serverId = actorSystem.AllocateEdgeActor(); actorSystem.Send(new NActors::IEventHandle(proxyId, serverId, new NHttp::TEvHttpProxy::TEvRegisterHandler("/test", serverId)), 0, true); - NActors::TActorId clientId = actorSystem.AllocateEdgeActor(); + NActors::TActorId clientId = actorSystem.AllocateEdgeActor(); NHttp::THttpOutgoingRequestPtr httpRequest = NHttp::THttpOutgoingRequest::CreateRequestGet("https://[::1]:" + ToString(port) + "/test"); actorSystem.Send(new NActors::IEventHandle(proxyId, clientId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest(httpRequest)), 0, true); @@ -314,11 +314,11 @@ CRA/5XcX13GJwHHj6LCoc3sL7mt8qV9HKY2AOZ88mpObzISZxgPpdKCfjsrdm63V NActors::TActorSystem actorSystem(setup); actorSystem.Start(); NHttp::THttpProxy* incomingProxy = new NHttp::THttpProxy(); - NActors::TActorId incomingProxyId = actorSystem.Register(incomingProxy); + NActors::TActorId incomingProxyId = actorSystem.Register(incomingProxy); actorSystem.Send(incomingProxyId, new NHttp::TEvHttpProxy::TEvAddListeningPort(13337)); NHttp::THttpProxy* outgoingProxy = new NHttp::THttpProxy(); - NActors::TActorId outgoingProxyId = actorSystem.Register(outgoingProxy); + NActors::TActorId outgoingProxyId = actorSystem.Register(outgoingProxy); THolder<NHttp::THttpStaticStringRequest> httpRequest = MakeHolder<NHttp::THttpStaticStringRequest>("GET /test HTTP/1.1\r\n\r\n"); actorSystem.Send(outgoingProxyId, new NHttp::TEvHttpProxy::TEvHttpOutgoingRequest("[::]:13337", std::move(httpRequest))); diff --git a/library/cpp/actors/http/ya.make b/library/cpp/actors/http/ya.make index ade447be3f..7ce68b7a75 100644 --- a/library/cpp/actors/http/ya.make +++ b/library/cpp/actors/http/ya.make @@ -26,7 +26,7 @@ PEERDIR( library/cpp/actors/core library/cpp/actors/interconnect library/cpp/dns - library/cpp/monlib/metrics + library/cpp/monlib/metrics library/cpp/string_utils/quote ) diff --git a/library/cpp/actors/interconnect/events_local.h b/library/cpp/actors/interconnect/events_local.h index a7da62c3d7..8a46ffd535 100644 --- a/library/cpp/actors/interconnect/events_local.h +++ b/library/cpp/actors/interconnect/events_local.h @@ -107,29 +107,29 @@ namespace NActors { struct TEvHandshakeAsk: public TEventLocal<TEvHandshakeAsk, ui32(ENetwork::HandshakeAsk)> { DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeAsk, "Network: TEvHandshakeAsk") - TEvHandshakeAsk(const TActorId& self, - const TActorId& peer, + TEvHandshakeAsk(const TActorId& self, + const TActorId& peer, ui64 counter) : Self(self) , Peer(peer) , Counter(counter) { } - const TActorId Self; - const TActorId Peer; + const TActorId Self; + const TActorId Peer; const ui64 Counter; }; struct TEvHandshakeAck: public TEventLocal<TEvHandshakeAck, ui32(ENetwork::HandshakeAck)> { DEFINE_SIMPLE_LOCAL_EVENT(TEvHandshakeAck, "Network: TEvHandshakeAck") - TEvHandshakeAck(const TActorId& self, ui64 nextPacket, TSessionParams params) + TEvHandshakeAck(const TActorId& self, ui64 nextPacket, TSessionParams params) : Self(self) , NextPacket(nextPacket) , Params(std::move(params)) {} - const TActorId Self; + const TActorId Self; const ui64 NextPacket; const TSessionParams Params; }; @@ -185,8 +185,8 @@ namespace NActors { TEvHandshakeDone( TIntrusivePtr<NInterconnect::TStreamSocket> socket, - const TActorId& peer, - const TActorId& self, + const TActorId& peer, + const TActorId& self, ui64 nextPacket, TAutoPtr<TProgramInfo>&& programInfo, TSessionParams params) @@ -200,8 +200,8 @@ namespace NActors { } TIntrusivePtr<NInterconnect::TStreamSocket> Socket; - const TActorId Peer; - const TActorId Self; + const TActorId Peer; + const TActorId Self; const ui64 NextPacket; TAutoPtr<TProgramInfo> ProgramInfo; const TSessionParams Params; @@ -319,10 +319,10 @@ namespace NActors { template <typename TContainer> TEvLoadMessage(const TContainer& route, const TString& id, const TString* payload) { - for (const TActorId& actorId : route) { + for (const TActorId& actorId : route) { auto* hop = Record.AddHops(); if (actorId) { - ActorIdToProto(actorId, hop->MutableNextHop()); + ActorIdToProto(actorId, hop->MutableNextHop()); } } Record.SetId(id); @@ -366,13 +366,13 @@ namespace NActors { }; struct TEvSessionBufferSizeResponse : TEventLocal<TEvSessionBufferSizeResponse, static_cast<ui32>(ENetwork::EvSessionBufferSizeResponse)> { - TEvSessionBufferSizeResponse(const TActorId& sessionId, ui64 outputBufferSize) + TEvSessionBufferSizeResponse(const TActorId& sessionId, ui64 outputBufferSize) : SessionID(sessionId) , BufferSize(outputBufferSize) { } - TActorId SessionID; + TActorId SessionID; ui64 BufferSize; }; diff --git a/library/cpp/actors/interconnect/interconnect.h b/library/cpp/actors/interconnect/interconnect.h index f052a6e92e..225a5243fd 100644 --- a/library/cpp/actors/interconnect/interconnect.h +++ b/library/cpp/actors/interconnect/interconnect.h @@ -10,7 +10,7 @@ namespace NActors { TString SelfAddress; ui32 SelfPort; - TVector<TActorId> GlobalNameservers; // todo: add some info about (like expected reply time) + TVector<TActorId> GlobalNameservers; // todo: add some info about (like expected reply time) }; struct TInterconnectProxySetup: public TThrRefBase { @@ -41,12 +41,12 @@ namespace NActors { TIntrusivePtr<TInterconnectGlobalState> GlobalState; - virtual IActor* CreateSession(const TActorId& ownerId, IProxy* owner) = 0; // returned actor is session and would be attached to same mailbox as proxy to allow sync calls + virtual IActor* CreateSession(const TActorId& ownerId, IProxy* owner) = 0; // returned actor is session and would be attached to same mailbox as proxy to allow sync calls virtual TActorSetupCmd CreateAcceptor() = 0; }; struct TNameserverSetup { - TActorId ServiceID; + TActorId ServiceID; TIntrusivePtr<TInterconnectGlobalState> GlobalState; }; @@ -118,12 +118,12 @@ namespace NActors { }; struct TNodeRegistrarSetup { - TActorId ServiceID; + TActorId ServiceID; TIntrusivePtr<TInterconnectGlobalState> GlobalState; }; - TActorId GetNameserviceActorId(); + TActorId GetNameserviceActorId(); /** * Const table-lookup based name service diff --git a/library/cpp/actors/interconnect/interconnect_channel.h b/library/cpp/actors/interconnect/interconnect_channel.h index 659a6a9e5c..e4a0ae3cda 100644 --- a/library/cpp/actors/interconnect/interconnect_channel.h +++ b/library/cpp/actors/interconnect/interconnect_channel.h @@ -1,6 +1,6 @@ #pragma once -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <library/cpp/actors/core/actorsystem.h> #include <library/cpp/actors/core/event_load.h> #include <library/cpp/actors/util/rope.h> diff --git a/library/cpp/actors/interconnect/interconnect_common.h b/library/cpp/actors/interconnect/interconnect_common.h index 81e0694da1..285709a00c 100644 --- a/library/cpp/actors/interconnect/interconnect_common.h +++ b/library/cpp/actors/interconnect/interconnect_common.h @@ -3,7 +3,7 @@ #include <library/cpp/actors/core/actorid.h> #include <library/cpp/actors/core/actorsystem.h> #include <library/cpp/actors/util/datetime.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <library/cpp/monlib/metrics/metric_registry.h> #include <util/generic/map.h> #include <util/generic/set.h> @@ -63,7 +63,7 @@ namespace NActors { typedef TMap<ui16, TChannelSettings> TChannelsConfig; using TRegisterMonPageCallback = std::function<void(const TString& path, const TString& title, - TActorSystem* actorSystem, const TActorId& actorId)>; + TActorSystem* actorSystem, const TActorId& actorId)>; using TInitWhiteboardCallback = std::function<void(ui16 icPort, TActorSystem* actorSystem)>; @@ -71,13 +71,13 @@ namespace NActors { bool orange, bool red, TActorSystem* actorSystem)>; struct TInterconnectProxyCommon : TAtomicRefCount<TInterconnectProxyCommon> { - TActorId NameserviceId; + TActorId NameserviceId; NMonitoring::TDynamicCounterPtr MonCounters; std::shared_ptr<NMonitoring::IMetricRegistry> Metrics; TChannelsConfig ChannelsConfig; TInterconnectSettings Settings; TRegisterMonPageCallback RegisterMonPage; - TActorId DestructorId; + TActorId DestructorId; std::shared_ptr<std::atomic<TAtomicBase>> DestructorQueueSize; TAtomicBase MaxDestructorQueueSize = 1024 * 1024 * 1024; TString ClusterUUID; diff --git a/library/cpp/actors/interconnect/interconnect_counters.cpp b/library/cpp/actors/interconnect/interconnect_counters.cpp index e389e93688..224160d4b4 100644 --- a/library/cpp/actors/interconnect/interconnect_counters.cpp +++ b/library/cpp/actors/interconnect/interconnect_counters.cpp @@ -619,11 +619,11 @@ namespace { TotalBytesRead_ = createRate(Metrics_, "interconnect.total_bytes_read"); for (const char *reason : TDisconnectReason::Reasons) { - DisconnectByReason_[reason] = Metrics_->Rate( - NMonitoring::MakeLabels({ - {"sensor", "interconnect.disconnect_reason"}, - {"reason", reason}, - })); + DisconnectByReason_[reason] = Metrics_->Rate( + NMonitoring::MakeLabels({ + {"sensor", "interconnect.disconnect_reason"}, + {"reason", reason}, + })); } } diff --git a/library/cpp/actors/interconnect/interconnect_handshake.cpp b/library/cpp/actors/interconnect/interconnect_handshake.cpp index 51d1e607bc..9ede998d8e 100644 --- a/library/cpp/actors/interconnect/interconnect_handshake.cpp +++ b/library/cpp/actors/interconnect/interconnect_handshake.cpp @@ -25,8 +25,8 @@ namespace NActors { struct TInitialPacket { struct { - TActorId SelfVirtualId; - TActorId PeerVirtualId; + TActorId SelfVirtualId; + TActorId PeerVirtualId; ui64 NextPacket; ui64 Version; } Header; @@ -34,7 +34,7 @@ namespace NActors { TInitialPacket() = default; - TInitialPacket(const TActorId& self, const TActorId& peer, ui64 nextPacket, ui64 version) { + TInitialPacket(const TActorId& self, const TActorId& peer, ui64 nextPacket, ui64 version) { Header.SelfVirtualId = self; Header.PeerVirtualId = peer; Header.NextPacket = nextPacket; @@ -79,8 +79,8 @@ namespace NActors { private: TInterconnectProxyCommon::TPtr Common; - TActorId SelfVirtualId; - TActorId PeerVirtualId; + TActorId SelfVirtualId; + TActorId PeerVirtualId; ui32 PeerNodeId = 0; ui64 NextPacketToPeer = 0; TMaybe<ui64> NextPacketFromPeer; // will be obtained from incoming initial packet @@ -102,7 +102,7 @@ namespace NActors { return IActor::INTERCONNECT_HANDSHAKE; } - THandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self, const TActorId& peer, + THandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self, const TActorId& peer, ui32 nodeId, ui64 nextPacket, TString peerHostName, TSessionParams params) : TActorCoroImpl(StackSize, true, true) // allow unhandled poison pills and dtors , Common(std::move(common)) @@ -377,7 +377,7 @@ namespace NActors { // set up virtual self id to ensure peer will not drop our connection char buf[12] = {'c', 'o', 'o', 'k', 'i', 'e', ' ', 'c', 'h', 'e', 'c', 'k'}; - SelfVirtualId = TActorId(SelfActorId.NodeId(), TStringBuf(buf, 12)); + SelfVirtualId = TActorId(SelfActorId.NodeId(), TStringBuf(buf, 12)); bool success = true; try { @@ -401,7 +401,7 @@ namespace NActors { request.SetProgramStartTime(0); request.SetSerial(0); request.SetReceiverNodeId(0); - request.SetSenderActorId(TString()); + request.SetSenderActorId(TString()); request.SetCookie(cookie); request.SetDoCheckCookie(true); SendExBlock(request, "SendExBlockDoCheckCookie"); @@ -419,7 +419,7 @@ namespace NActors { } // restore state - SelfVirtualId = TActorId(); + SelfVirtualId = TActorId(); std::swap(tempSocket, Socket); std::swap(tempPollerToken, PollerToken); return success; @@ -455,7 +455,7 @@ namespace NActors { request.SetProgramStartTime(Common->StartTime); request.SetSerial(SelfVirtualId.LocalId()); request.SetReceiverNodeId(PeerNodeId); - request.SetSenderActorId(SelfVirtualId.ToString()); + request.SetSenderActorId(SelfVirtualId.ToString()); request.SetSenderHostName(Common->TechnicalSelfHostName); request.SetReceiverHostName(PeerHostName); @@ -519,7 +519,7 @@ namespace NActors { ValidateClusterUUID(success, generateError); ValidateVersionTag(success, generateError); - const auto& s = success.GetSenderActorId(); + const auto& s = success.GetSenderActorId(); PeerVirtualId.Parse(s.data(), s.size()); // recover flags @@ -599,8 +599,8 @@ namespace NActors { SendInitialPacket(); } else { // peer wants a new session, clear fields and send initial packet - SelfVirtualId = TActorId(); - PeerVirtualId = TActorId(); + SelfVirtualId = TActorId(); + PeerVirtualId = TActorId(); NextPacketToPeer = 0; SendInitialPacket(); @@ -637,7 +637,7 @@ namespace NActors { PeerHostName = request.GetSenderHostName(); // parse peer virtual id - const auto& str = request.GetSenderActorId(); + const auto& str = request.GetSenderActorId(); PeerVirtualId.Parse(str.data(), str.size()); // validate request @@ -709,7 +709,7 @@ namespace NActors { SendExBlock(record, "ExReply"); // extract sender actor id (self virtual id) - const auto& str = success.GetSenderActorId(); + const auto& str = success.GetSenderActorId(); SelfVirtualId.Parse(str.data(), str.size()); } else if (auto ev = reply->CastAsLocal<TEvHandshakeReplyError>()) { // in case of error just send reply to the peer and terminate handshake @@ -981,8 +981,8 @@ namespace NActors { } }; - IActor* CreateOutgoingHandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self, - const TActorId& peer, ui32 nodeId, ui64 nextPacket, TString peerHostName, + IActor* CreateOutgoingHandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self, + const TActorId& peer, ui32 nodeId, ui64 nextPacket, TString peerHostName, TSessionParams params) { return new TActorCoro(MakeHolder<THandshakeActor>(std::move(common), self, peer, nodeId, nextPacket, std::move(peerHostName), std::move(params))); diff --git a/library/cpp/actors/interconnect/interconnect_handshake.h b/library/cpp/actors/interconnect/interconnect_handshake.h index 7c5c25c3b8..b3c0db6c5d 100644 --- a/library/cpp/actors/interconnect/interconnect_handshake.h +++ b/library/cpp/actors/interconnect/interconnect_handshake.h @@ -15,8 +15,8 @@ namespace NActors { using TSocketPtr = TIntrusivePtr<NInterconnect::TStreamSocket>; - IActor* CreateOutgoingHandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self, - const TActorId& peer, ui32 nodeId, ui64 nextPacket, TString peerHostName, + IActor* CreateOutgoingHandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self, + const TActorId& peer, ui32 nodeId, ui64 nextPacket, TString peerHostName, TSessionParams params); IActor* CreateIncomingHandshakeActor(TInterconnectProxyCommon::TPtr common, TSocketPtr socket); diff --git a/library/cpp/actors/interconnect/interconnect_impl.h b/library/cpp/actors/interconnect/interconnect_impl.h index 2ca0db8763..ee29e4d397 100644 --- a/library/cpp/actors/interconnect/interconnect_impl.h +++ b/library/cpp/actors/interconnect/interconnect_impl.h @@ -4,7 +4,7 @@ #include <library/cpp/actors/protos/interconnect.pb.h> #include <library/cpp/actors/core/event_pb.h> #include <library/cpp/actors/helpers/mon_histogram_helper.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> namespace NActors { // resolve node info diff --git a/library/cpp/actors/interconnect/interconnect_mon.cpp b/library/cpp/actors/interconnect/interconnect_mon.cpp index 48823c5b0e..cf924ccbf9 100644 --- a/library/cpp/actors/interconnect/interconnect_mon.cpp +++ b/library/cpp/actors/interconnect/interconnect_mon.cpp @@ -1,9 +1,9 @@ #include "interconnect_mon.h" #include "interconnect_tcp_proxy.h" - -#include <library/cpp/json/json_value.h> -#include <library/cpp/json/json_writer.h> -#include <library/cpp/monlib/service/pages/templates.h> + +#include <library/cpp/json/json_value.h> +#include <library/cpp/json/json_writer.h> +#include <library/cpp/monlib/service/pages/templates.h> #include <openssl/ssl.h> #include <openssl/pem.h> @@ -14,7 +14,7 @@ namespace NInterconnect { class TInterconnectMonActor : public TActor<TInterconnectMonActor> { class TQueryProcessor : public TActorBootstrapped<TQueryProcessor> { - const TActorId Sender; + const TActorId Sender; const bool Json; TMap<ui32, TInterconnectProxyTCP::TProxyStats> Stats; ui32 PendingReplies = 0; @@ -24,7 +24,7 @@ namespace NInterconnect { return INTERCONNECT_MONACTOR; } - TQueryProcessor(const TActorId& sender, bool json) + TQueryProcessor(const TActorId& sender, bool json) : Sender(sender) , Json(json) {} diff --git a/library/cpp/actors/interconnect/interconnect_mon.h b/library/cpp/actors/interconnect/interconnect_mon.h index e78229a2c4..3fb26053fb 100644 --- a/library/cpp/actors/interconnect/interconnect_mon.h +++ b/library/cpp/actors/interconnect/interconnect_mon.h @@ -7,9 +7,9 @@ namespace NInterconnect { NActors::IActor *CreateInterconnectMonActor(TIntrusivePtr<NActors::TInterconnectProxyCommon> common = nullptr); - static inline NActors::TActorId MakeInterconnectMonActorId(ui32 nodeId) { + static inline NActors::TActorId MakeInterconnectMonActorId(ui32 nodeId) { char s[12] = {'I', 'C', 'O', 'v', 'e', 'r', 'v', 'i', 'e', 'w', 0, 0}; - return NActors::TActorId(nodeId, TStringBuf(s, 12)); + return NActors::TActorId(nodeId, TStringBuf(s, 12)); } } // NInterconnect diff --git a/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp b/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp index c9f6f8b5dc..43419bf70d 100644 --- a/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp +++ b/library/cpp/actors/interconnect/interconnect_nameserver_table.cpp @@ -79,8 +79,8 @@ namespace NActors { return true; } - TActorId GetNameserviceActorId() { - return TActorId(0, "namesvc"); + TActorId GetNameserviceActorId() { + return TActorId(0, "namesvc"); } } diff --git a/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp b/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp index b42ae8dffd..0abe9fe659 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp +++ b/library/cpp/actors/interconnect/interconnect_tcp_input_session.cpp @@ -6,7 +6,7 @@ namespace NActors { LWTRACE_USING(ACTORLIB_PROVIDER); - TInputSessionTCP::TInputSessionTCP(const TActorId& sessionId, TIntrusivePtr<NInterconnect::TStreamSocket> socket, + TInputSessionTCP::TInputSessionTCP(const TActorId& sessionId, TIntrusivePtr<NInterconnect::TStreamSocket> socket, TIntrusivePtr<TReceiveContext> context, TInterconnectProxyCommon::TPtr common, std::shared_ptr<IInterconnectMetrics> metrics, ui32 nodeId, ui64 lastConfirmed, TDuration deadPeerTimeout, TSessionParams params) diff --git a/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp b/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp index 4191951abd..7e2d8ccb94 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp +++ b/library/cpp/actors/interconnect/interconnect_tcp_proxy.cpp @@ -3,7 +3,7 @@ #include "interconnect_tcp_session.h" #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/protos/services_common.pb.h> -#include <library/cpp/monlib/service/pages/templates.h> +#include <library/cpp/monlib/service/pages/templates.h> #include <util/system/getpid.h> namespace NActors { @@ -45,7 +45,7 @@ namespace NActors { LOG_INFO_IC("ICP01", "ready to work"); } - void TInterconnectProxyTCP::Registered(TActorSystem* sys, const TActorId& owner) { + void TInterconnectProxyTCP::Registered(TActorSystem* sys, const TActorId& owner) { if (!DynamicPtr) { // perform usual bootstrap for static nodes sys->Send(new IEventHandle(TEvents::TSystem::Bootstrap, 0, SelfId(), owner, nullptr, 0)); @@ -311,9 +311,9 @@ namespace NActors { auto event = MakeHolder<TEvHandshakeReplyOK>(); auto* pb = event->Record.MutableSuccess(); - const TActorId virtualId = GenerateSessionVirtualId(); + const TActorId virtualId = GenerateSessionVirtualId(); pb->SetProtocol(INTERCONNECT_PROTOCOL_VERSION); - pb->SetSenderActorId(virtualId.ToString()); + pb->SetSenderActorId(virtualId.ToString()); pb->SetProgramPID(GetPID()); pb->SetProgramStartTime(Common->StartTime); pb->SetSerial(virtualId.LocalId()); @@ -536,14 +536,14 @@ namespace NActors { SessionVirtualId.ToString().data()); Session = nullptr; - SessionID = TActorId(); + SessionID = TActorId(); // drop all pending events as we are closed ProcessPendingSessionEvents(); // reset virtual ids as this session is terminated - SessionVirtualId = TActorId(); - RemoteSessionVirtualId = TActorId(); + SessionVirtualId = TActorId(); + RemoteSessionVirtualId = TActorId(); if (Metrics) { Metrics->IncSessionDeaths(); diff --git a/library/cpp/actors/interconnect/interconnect_tcp_proxy.h b/library/cpp/actors/interconnect/interconnect_tcp_proxy.h index e5921134ed..023e5bd1ee 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_proxy.h +++ b/library/cpp/actors/interconnect/interconnect_tcp_proxy.h @@ -4,7 +4,7 @@ #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/event_pb.h> #include <library/cpp/actors/core/events.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include "interconnect_common.h" #include "interconnect_counters.h" @@ -70,7 +70,7 @@ namespace NActors { } void Bootstrap(); - void Registered(TActorSystem* sys, const TActorId& owner) override; + void Registered(TActorSystem* sys, const TActorId& owner) override; private: friend class TInterconnectSessionTCP; @@ -366,7 +366,7 @@ namespace NActors { // read only TInterconnectProxyCommon::TPtr const Common; - const TActorId& GetNameserviceId() const { + const TActorId& GetNameserviceId() const { return Common->NameserviceId; } @@ -403,24 +403,24 @@ namespace NActors { void DropSessionEvent(STATEFN_SIG); TInterconnectSessionTCP* Session = nullptr; - TActorId SessionID; + TActorId SessionID; // virtual ids used during handshake to check if it is the connection // for the same session or to find out the latest shandshake // it's virtual because session actor apears after successfull handshake - TActorId SessionVirtualId; - TActorId RemoteSessionVirtualId; + TActorId SessionVirtualId; + TActorId RemoteSessionVirtualId; - TActorId GenerateSessionVirtualId() { + TActorId GenerateSessionVirtualId() { ICPROXY_PROFILED; const ui64 localId = TlsActivationContext->ExecutorThread.ActorSystem->AllocateIDSpace(1); - return NActors::TActorId(SelfId().NodeId(), 0, localId, 0); + return NActors::TActorId(SelfId().NodeId(), 0, localId, 0); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TActorId IncomingHandshakeActor; + TActorId IncomingHandshakeActor; TInstant IncomingHandshakeActorFilledIn; TInstant IncomingHandshakeActorReset; TMaybe<ui64> LastSerialFromIncomingHandshake; @@ -429,7 +429,7 @@ namespace NActors { void DropIncomingHandshake(bool poison = true) { ICPROXY_PROFILED; - if (const TActorId& actorId = std::exchange(IncomingHandshakeActor, TActorId())) { + if (const TActorId& actorId = std::exchange(IncomingHandshakeActor, TActorId())) { LOG_DEBUG_IC("ICP111", "dropped incoming handshake: %s poison: %s", actorId.ToString().data(), poison ? "true" : "false"); if (poison) { @@ -444,7 +444,7 @@ namespace NActors { void DropOutgoingHandshake(bool poison = true) { ICPROXY_PROFILED; - if (const TActorId& actorId = std::exchange(OutgoingHandshakeActor, TActorId())) { + if (const TActorId& actorId = std::exchange(OutgoingHandshakeActor, TActorId())) { LOG_DEBUG_IC("ICP112", "dropped outgoing handshake: %s poison: %s", actorId.ToString().data(), poison ? "true" : "false"); if (poison) { @@ -477,12 +477,12 @@ namespace NActors { SwitchToState(__LINE__, "PendingConnection", &TThis::PendingConnection); } - void IssueIncomingHandshakeReply(const TActorId& handshakeId, ui64 peerLocalId, + void IssueIncomingHandshakeReply(const TActorId& handshakeId, ui64 peerLocalId, THolder<IEventBase> event); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TActorId OutgoingHandshakeActor; + TActorId OutgoingHandshakeActor; TInstant OutgoingHandshakeActorCreated; TInstant OutgoingHandshakeActorReset; diff --git a/library/cpp/actors/interconnect/interconnect_tcp_server.cpp b/library/cpp/actors/interconnect/interconnect_tcp_server.cpp index 2c025dc389..b95c994598 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_server.cpp +++ b/library/cpp/actors/interconnect/interconnect_tcp_server.cpp @@ -23,7 +23,7 @@ namespace NActors { } } - TAutoPtr<IEventHandle> TInterconnectListenerTCP::AfterRegister(const TActorId& self, const TActorId& parentId) { + TAutoPtr<IEventHandle> TInterconnectListenerTCP::AfterRegister(const TActorId& self, const TActorId& parentId) { return new IEventHandle(self, parentId, new TEvents::TEvBootstrap, 0); } diff --git a/library/cpp/actors/interconnect/interconnect_tcp_server.h b/library/cpp/actors/interconnect/interconnect_tcp_server.h index 086fe26ab3..fc71073c2d 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_server.h +++ b/library/cpp/actors/interconnect/interconnect_tcp_server.h @@ -34,7 +34,7 @@ namespace NActors { } } - TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override; + TAutoPtr<IEventHandle> AfterRegister(const TActorId& self, const TActorId& parentId) override; void Die(const TActorContext& ctx) override; @@ -50,8 +50,8 @@ namespace NActors { TInterconnectProxyCommon::TPtr const ProxyCommonCtx; }; - static inline TActorId MakeInterconnectListenerActorId(bool dynamic) { + static inline TActorId MakeInterconnectListenerActorId(bool dynamic) { char x[12] = {'I', 'C', 'L', 'i', 's', 't', 'e', 'n', 'e', 'r', '/', dynamic ? 'D' : 'S'}; - return TActorId(0, TStringBuf(x, 12)); + return TActorId(0, TStringBuf(x, 12)); } } diff --git a/library/cpp/actors/interconnect/interconnect_tcp_session.cpp b/library/cpp/actors/interconnect/interconnect_tcp_session.cpp index 468e8bdd64..2ded7f9f53 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_session.cpp +++ b/library/cpp/actors/interconnect/interconnect_tcp_session.cpp @@ -7,7 +7,7 @@ #include <library/cpp/actors/core/interconnect.h> #include <library/cpp/actors/util/datetime.h> #include <library/cpp/actors/protos/services_common.pb.h> -#include <library/cpp/monlib/service/pages/templates.h> +#include <library/cpp/monlib/service/pages/templates.h> namespace NActors { LWTRACE_USING(ACTORLIB_PROVIDER); @@ -474,7 +474,7 @@ namespace NActors { if (ev->Sender == ReceiverId) { const bool wasConnected(Socket); LOG_INFO_IC_SESSION("ICS07", "socket disconnect %" PRIi64 " reason# %s", Socket ? i64(*Socket) : -1, ev->Get()->Reason.ToString().data()); - ReceiverId = TActorId(); // reset receiver actor id as we have no more receiver yet + ReceiverId = TActorId(); // reset receiver actor id as we have no more receiver yet if (wasConnected) { // we were sucessfully connected and did not expect failure, so it arrived from the input side; we should // restart handshake process, closing our part of socket first diff --git a/library/cpp/actors/interconnect/interconnect_tcp_session.h b/library/cpp/actors/interconnect/interconnect_tcp_session.h index dfab4065c0..7fc00dbcc5 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_session.h +++ b/library/cpp/actors/interconnect/interconnect_tcp_session.h @@ -10,7 +10,7 @@ #include <library/cpp/actors/util/rope.h> #include <library/cpp/actors/util/funnel_queue.h> #include <library/cpp/actors/util/recentwnd.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <library/cpp/actors/core/actor_bootstrapped.h> #include <util/generic/queue.h> @@ -179,7 +179,7 @@ namespace NActors { return INTERCONNECT_SESSION_TCP; } - TInputSessionTCP(const TActorId& sessionId, + TInputSessionTCP(const TActorId& sessionId, TIntrusivePtr<NInterconnect::TStreamSocket> socket, TIntrusivePtr<TReceiveContext> context, TInterconnectProxyCommon::TPtr common, @@ -495,7 +495,7 @@ namespace NActors { void GenerateHttpInfo(TStringStream& str); TIntrusivePtr<TReceiveContext> ReceiveContext; - TActorId ReceiverId; + TActorId ReceiverId; TDuration Ping; ui64 ConfirmPacketsForcedBySize = 0; @@ -513,7 +513,7 @@ namespace NActors { : public TActorBootstrapped<TInterconnectSessionKiller> { ui32 RepliesReceived = 0; ui32 RepliesNumber = 0; - TActorId LargestSession = TActorId(); + TActorId LargestSession = TActorId(); ui64 MaxBufferSize = 0; TInterconnectProxyCommon::TPtr Common; @@ -529,7 +529,7 @@ namespace NActors { void Bootstrap() { auto sender = SelfId(); - const auto eventFabric = [&sender](const TActorId& recp) -> IEventHandle* { + const auto eventFabric = [&sender](const TActorId& recp) -> IEventHandle* { auto ev = new TEvSessionBufferSizeRequest(); return new IEventHandle(recp, sender, ev, IEventHandle::FlagTrackDelivery); }; diff --git a/library/cpp/actors/interconnect/load.cpp b/library/cpp/actors/interconnect/load.cpp index 22850b3126..2a8443da71 100644 --- a/library/cpp/actors/interconnect/load.cpp +++ b/library/cpp/actors/interconnect/load.cpp @@ -72,7 +72,7 @@ namespace NInterconnect { }; class TLoadResponderMasterActor : public TActorBootstrapped<TLoadResponderMasterActor> { - TVector<TActorId> Slaves; + TVector<TActorId> Slaves; ui32 SlaveIndex = 0; STRICT_STFUNC(StateFunc, @@ -93,7 +93,7 @@ namespace NInterconnect { } void Die(const TActorContext& ctx) override { - for (const TActorId& actorId : Slaves) { + for (const TActorId& actorId : Slaves) { ctx.Send(actorId, new TEvents::TEvPoisonPill); } TActorBootstrapped::Die(ctx); @@ -122,9 +122,9 @@ namespace NInterconnect { return new TLoadResponderMasterActor(); } - TActorId MakeLoadResponderActorId(ui32 nodeId) { + TActorId MakeLoadResponderActorId(ui32 nodeId) { char x[12] = {'I', 'C', 'L', 'o', 'a', 'd', 'R', 'e', 's', 'p', 'A', 'c'}; - return TActorId(nodeId, TStringBuf(x, 12)); + return TActorId(nodeId, TStringBuf(x, 12)); } class TLoadActor: public TActorBootstrapped<TLoadActor> { @@ -144,8 +144,8 @@ namespace NInterconnect { TInstant NextMessageTimestamp; THashMap<TString, TMessageInfo> InFly; ui64 NextId = 1; - TVector<TActorId> Hops; - TActorId FirstHop; + TVector<TActorId> Hops; + TActorId FirstHop; ui64 NumDropped = 0; std::shared_ptr<std::atomic_uint64_t> Traffic; @@ -167,7 +167,7 @@ namespace NInterconnect { Traffic = std::move(ev->Get()->Traffic); for (const ui32 nodeId : Params.NodeHops) { - const TActorId& actorId = nodeId ? MakeLoadResponderActorId(nodeId) : TActorId(); + const TActorId& actorId = nodeId ? MakeLoadResponderActorId(nodeId) : TActorId(); if (!FirstHop) { FirstHop = actorId; } else { diff --git a/library/cpp/actors/interconnect/load.h b/library/cpp/actors/interconnect/load.h index 060fa7641b..0a01a0dc04 100644 --- a/library/cpp/actors/interconnect/load.h +++ b/library/cpp/actors/interconnect/load.h @@ -5,7 +5,7 @@ namespace NInterconnect { // load responder -- lives on every node as a service actor NActors::IActor* CreateLoadResponderActor(); - NActors::TActorId MakeLoadResponderActorId(ui32 node); + NActors::TActorId MakeLoadResponderActorId(ui32 node); // load actor -- generates load with specific parameters struct TLoadParams { diff --git a/library/cpp/actors/interconnect/mock/ic_mock.cpp b/library/cpp/actors/interconnect/mock/ic_mock.cpp index 1267920559..884503e602 100644 --- a/library/cpp/actors/interconnect/mock/ic_mock.cpp +++ b/library/cpp/actors/interconnect/mock/ic_mock.cpp @@ -42,7 +42,7 @@ namespace NActors { : Key(key) {} - void Attach(ui32 nodeId, TActorSystem *as, const TActorId& actorId) { + void Attach(ui32 nodeId, TActorSystem *as, const TActorId& actorId) { TPeerInfo *peer = GetPeer(nodeId); auto guard = TWriteGuard(peer->Mutex); Y_VERIFY(!peer->ActorSystem); @@ -188,7 +188,7 @@ namespace NActors { , Common(std::move(common)) {} - void Registered(TActorSystem *as, const TActorId& parent) override { + void Registered(TActorSystem *as, const TActorId& parent) override { TActor::Registered(as, parent); State.Attach(NodeId, as, SelfId()); } diff --git a/library/cpp/actors/interconnect/packet.h b/library/cpp/actors/interconnect/packet.h index 187d0b6bdf..4ba50a2b5f 100644 --- a/library/cpp/actors/interconnect/packet.h +++ b/library/cpp/actors/interconnect/packet.h @@ -18,7 +18,7 @@ using NActors::IEventBase; using NActors::IEventHandle; -using NActors::TActorId; +using NActors::TActorId; using NActors::TConstIoVec; using NActors::TEventSerializedData; @@ -91,8 +91,8 @@ union TTcpPacketBuf { struct TEventDescr { ui32 Type; ui32 Flags; - TActorId Recipient; - TActorId Sender; + TActorId Recipient; + TActorId Sender; ui64 Cookie; // wilson trace id is stored as a serialized entity to avoid using complex object with prohibited copy ctor NWilson::TTraceId::TSerializedTraceId TraceId; @@ -102,7 +102,7 @@ struct TEventDescr { struct TEventHolder : TNonCopyable { TEventDescr Descr; - TActorId ForwardRecipient; + TActorId ForwardRecipient; THolder<IEventBase> Event; TIntrusivePtr<TEventSerializedData> Buffer; ui64 Serial; diff --git a/library/cpp/actors/interconnect/poller_actor.cpp b/library/cpp/actors/interconnect/poller_actor.cpp index 8c7b61a7a7..e75cbcaef4 100644 --- a/library/cpp/actors/interconnect/poller_actor.cpp +++ b/library/cpp/actors/interconnect/poller_actor.cpp @@ -1,35 +1,35 @@ #include "poller_actor.h" #include "interconnect_common.h" -#include <library/cpp/actors/core/actor_bootstrapped.h> +#include <library/cpp/actors/core/actor_bootstrapped.h> #include <library/cpp/actors/core/actorsystem.h> #include <library/cpp/actors/core/hfunc.h> #include <library/cpp/actors/core/log.h> #include <library/cpp/actors/core/probes.h> -#include <library/cpp/actors/protos/services_common.pb.h> +#include <library/cpp/actors/protos/services_common.pb.h> #include <library/cpp/actors/util/funnel_queue.h> - + #include <util/generic/intrlist.h> #include <util/system/thread.h> #include <util/system/event.h> #include <util/system/pipe.h> #include <variant> - + namespace NActors { LWTRACE_USING(ACTORLIB_PROVIDER); - namespace { + namespace { int LastSocketError() { #if defined(_win_) return WSAGetLastError(); #else return errno; #endif - } - } - + } + } + struct TSocketRecord : TThrRefBase { const TIntrusivePtr<TSharedDescriptor> Socket; const TActorId ReadActorId; @@ -57,7 +57,7 @@ namespace NActors { : Socket(std::move(socket)) {} }; - + using TPollerSyncOperation = std::variant<TPollerExitThread, TPollerWakeup, TPollerUnregisterSocket>; struct TPollerSyncOperationWrapper { @@ -149,7 +149,7 @@ namespace NActors { bool DrainReadEnd() { size_t totalRead = 0; char buffer[4096]; - for (;;) { + for (;;) { ssize_t n = ReadEnd.Read(buffer, sizeof(buffer)); if (n < 0) { const int error = LastSocketError(); @@ -157,17 +157,17 @@ namespace NActors { continue; } else if (error == EAGAIN || error == EWOULDBLOCK) { break; - } else { + } else { Y_FAIL("read() failed with %s", strerror(errno)); - } + } } else { Y_VERIFY(n); totalRead += n; - } + } } return totalRead; } - + bool ProcessSyncOpQueue() { if (DrainReadEnd()) { Y_VERIFY(!SyncOperationsQ.IsEmpty()); @@ -181,25 +181,25 @@ namespace NActors { return false; // terminate the thread } else if (std::get_if<TPollerWakeup>(&op->Operation)) { op->SignalDone(); - } else { + } else { Y_FAIL(); - } + } } while (SyncOperationsQ.Pop()); - } + } return true; - } - + } + void *ThreadProc() override { SetCurrentThreadName("network poller"); while (ProcessSyncOpQueue()) { static_cast<TDerived&>(*this).ProcessEventsInLoop(); - } + } return nullptr; - } + } }; - + } // namespace NActors - + #if defined(_linux_) # include "poller_actor_linux.h" #elif defined(_darwin_) @@ -209,38 +209,38 @@ namespace NActors { #else # error "Unsupported platform" #endif - + namespace NActors { - + class TPollerToken::TImpl { std::weak_ptr<TPollerThread> Thread; TIntrusivePtr<TSocketRecord> Record; // valid only when Thread is held locked - - public: + + public: TImpl(std::shared_ptr<TPollerThread> thread, TIntrusivePtr<TSocketRecord> record) : Thread(thread) , Record(std::move(record)) - { + { thread->RegisterSocket(Record); } - + ~TImpl() { if (auto thread = Thread.lock()) { thread->UnregisterSocket(Record); - } - } - + } + } + void Request(bool read, bool write) { if (auto thread = Thread.lock()) { thread->Request(Record, read, write); - } - } + } + } const TIntrusivePtr<TSharedDescriptor>& Socket() const { return Record->Socket; } - }; - + }; + class TPollerActor: public TActorBootstrapped<TPollerActor> { // poller thread std::shared_ptr<TPollerThread> PollerThread; diff --git a/library/cpp/actors/interconnect/poller_actor.h b/library/cpp/actors/interconnect/poller_actor.h index 5bd4f50704..f927b82089 100644 --- a/library/cpp/actors/interconnect/poller_actor.h +++ b/library/cpp/actors/interconnect/poller_actor.h @@ -55,9 +55,9 @@ namespace NActors { IActor* CreatePollerActor(); - inline TActorId MakePollerActorId() { + inline TActorId MakePollerActorId() { char x[12] = {'I', 'C', 'P', 'o', 'l', 'l', 'e', 'r', '\xDE', '\xAD', '\xBE', '\xEF'}; - return TActorId(0, TStringBuf(std::begin(x), std::end(x))); + return TActorId(0, TStringBuf(std::begin(x), std::end(x))); } } diff --git a/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp b/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp index bbdabbd339..565a511859 100644 --- a/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp +++ b/library/cpp/actors/interconnect/ut/channel_scheduler_ut.cpp @@ -20,7 +20,7 @@ Y_UNIT_TEST_SUITE(ChannelScheduler) { auto pushEvent = [&](size_t size, int channel) { TString payload(size, 'X'); - auto ev = MakeHolder<IEventHandle>(1, 0, TActorId(), TActorId(), MakeIntrusive<TEventSerializedData>(payload, false), 0); + auto ev = MakeHolder<IEventHandle>(1, 0, TActorId(), TActorId(), MakeIntrusive<TEventSerializedData>(payload, false), 0); auto& ch = scheduler.GetOutputChannel(channel); const bool wasWorking = ch.IsWorking(); ch.Push(*ev); diff --git a/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp b/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp index 334859882f..e6b2bd4e4c 100644 --- a/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp +++ b/library/cpp/actors/interconnect/ut/event_holder_pool_ut.cpp @@ -2,7 +2,7 @@ #include <library/cpp/actors/core/events.h> #include <library/cpp/actors/core/event_local.h> #include <library/cpp/actors/interconnect/interconnect_common.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <library/cpp/actors/interconnect/event_holder_pool.h> #include <atomic> diff --git a/library/cpp/actors/interconnect/ut/large.cpp b/library/cpp/actors/interconnect/ut/large.cpp index d67509f058..ba2a50c6f6 100644 --- a/library/cpp/actors/interconnect/ut/large.cpp +++ b/library/cpp/actors/interconnect/ut/large.cpp @@ -14,10 +14,10 @@ Y_UNIT_TEST_SUITE(LargeMessage) { using namespace NActors; class TProducer: public TActorBootstrapped<TProducer> { - const TActorId RecipientActorId; + const TActorId RecipientActorId; public: - TProducer(const TActorId& recipientActorId) + TProducer(const TActorId& recipientActorId) : RecipientActorId(recipientActorId) {} @@ -41,7 +41,7 @@ Y_UNIT_TEST_SUITE(LargeMessage) { class TConsumer : public TActorBootstrapped<TConsumer> { TManualEvent& Done; - TActorId SessionId; + TActorId SessionId; public: TConsumer(TManualEvent& done) @@ -77,7 +77,7 @@ Y_UNIT_TEST_SUITE(LargeMessage) { TManualEvent done; TConsumer* consumer = new TConsumer(done); - const TActorId recp = testCluster.RegisterActor(consumer, 1); + const TActorId recp = testCluster.RegisterActor(consumer, 1); testCluster.RegisterActor(new TProducer(recp), 2); done.WaitI(); } diff --git a/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h b/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h index ac46180804..2b6d27cd3f 100644 --- a/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h +++ b/library/cpp/actors/interconnect/ut/lib/ic_test_cluster.h @@ -70,7 +70,7 @@ public: ~TTestICCluster() { } - TActorId RegisterActor(NActors::IActor* actor, ui32 nodeId) { + TActorId RegisterActor(NActors::IActor* actor, ui32 nodeId) { return Nodes[nodeId]->RegisterActor(actor); } @@ -78,7 +78,7 @@ public: return Nodes[nodeId]->InterconnectProxy(peerNodeId); } - void KillActor(ui32 nodeId, const TActorId& id) { + void KillActor(ui32 nodeId, const TActorId& id) { Nodes[nodeId]->Send(id, new NActors::TEvents::TEvPoisonPill); } }; diff --git a/library/cpp/actors/interconnect/ut/lib/node.h b/library/cpp/actors/interconnect/ut/lib/node.h index 59dd2554c8..ff30b1445e 100644 --- a/library/cpp/actors/interconnect/ut/lib/node.h +++ b/library/cpp/actors/interconnect/ut/lib/node.h @@ -62,7 +62,7 @@ public: setup.LocalServices.emplace_back(MakePollerActorId(), TActorSetupCmd(CreatePollerActor(), TMailboxType::ReadAsFilled, 0)); - const TActorId loggerActorId(0, "logger"); + const TActorId loggerActorId(0, "logger"); constexpr ui32 LoggerComponentId = 410; // NKikimrServices::LOGGER auto loggerSettings = MakeIntrusive<NLog::TSettings>( @@ -114,7 +114,7 @@ public: ActorSystem->Stop(); } - bool Send(const TActorId& recipient, IEventBase* ev) { + bool Send(const TActorId& recipient, IEventBase* ev) { return ActorSystem->Send(recipient, ev); } @@ -127,7 +127,7 @@ public: } void RegisterServiceActor(const TActorId& serviceId, IActor* actor) { - const TActorId actorId = ActorSystem->Register(actor); + const TActorId actorId = ActorSystem->Register(actor); ActorSystem->RegisterLocalService(serviceId, actorId); } diff --git a/library/cpp/actors/interconnect/ut/lib/test_actors.h b/library/cpp/actors/interconnect/ut/lib/test_actors.h index 07fe10d93a..7591200471 100644 --- a/library/cpp/actors/interconnect/ut/lib/test_actors.h +++ b/library/cpp/actors/interconnect/ut/lib/test_actors.h @@ -3,13 +3,13 @@ namespace NActors { class TSenderBaseActor: public TActorBootstrapped<TSenderBaseActor> { protected: - const TActorId RecipientActorId; + const TActorId RecipientActorId; const ui32 Preload; ui64 SequenceNumber = 0; ui32 InFlySize = 0; public: - TSenderBaseActor(const TActorId& recipientActorId, ui32 preload = 1) + TSenderBaseActor(const TActorId& recipientActorId, ui32 preload = 1) : RecipientActorId(recipientActorId) , Preload(preload) { diff --git a/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp b/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp index dbd05ce746..23d846a2fd 100644 --- a/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp +++ b/library/cpp/actors/interconnect/ut/poller_actor_ut.cpp @@ -1,38 +1,38 @@ -#include <library/cpp/actors/interconnect/poller_actor.h> -#include <library/cpp/actors/testlib/test_runtime.h> - +#include <library/cpp/actors/interconnect/poller_actor.h> +#include <library/cpp/actors/testlib/test_runtime.h> + #include <library/cpp/testing/unittest/registar.h> - -#include <util/network/pair.h> -#include <util/network/socket.h> - -using namespace NActors; - -class TTestSocket: public TSharedDescriptor { -public: - explicit TTestSocket(SOCKET fd) - : Fd_(fd) - { - } - - int GetDescriptor() override { - return Fd_; - } - -private: - SOCKET Fd_; -}; -using TTestSocketPtr = TIntrusivePtr<TTestSocket>; - -// create pair of connected, non-blocking sockets -std::pair<TTestSocketPtr, TTestSocketPtr> NonBlockSockets() { - SOCKET fds[2]; - SocketPair(fds); - SetNonBlock(fds[0]); - SetNonBlock(fds[1]); - return {MakeIntrusive<TTestSocket>(fds[0]), MakeIntrusive<TTestSocket>(fds[1])}; -} - + +#include <util/network/pair.h> +#include <util/network/socket.h> + +using namespace NActors; + +class TTestSocket: public TSharedDescriptor { +public: + explicit TTestSocket(SOCKET fd) + : Fd_(fd) + { + } + + int GetDescriptor() override { + return Fd_; + } + +private: + SOCKET Fd_; +}; +using TTestSocketPtr = TIntrusivePtr<TTestSocket>; + +// create pair of connected, non-blocking sockets +std::pair<TTestSocketPtr, TTestSocketPtr> NonBlockSockets() { + SOCKET fds[2]; + SocketPair(fds); + SetNonBlock(fds[0]); + SetNonBlock(fds[1]); + return {MakeIntrusive<TTestSocket>(fds[0]), MakeIntrusive<TTestSocket>(fds[1])}; +} + std::pair<TTestSocketPtr, TTestSocketPtr> TcpSockets() { // create server (listening) socket SOCKET server = socket(AF_INET, SOCK_STREAM, 0); @@ -74,101 +74,101 @@ std::pair<TTestSocketPtr, TTestSocketPtr> TcpSockets() { return std::make_pair(MakeIntrusive<TTestSocket>(client), MakeIntrusive<TTestSocket>(accepted)); } -class TPollerActorTest: public TTestBase { - UNIT_TEST_SUITE(TPollerActorTest); - UNIT_TEST(Registration) - UNIT_TEST(ReadNotification) - UNIT_TEST(WriteNotification) - UNIT_TEST(HangupNotification) - UNIT_TEST_SUITE_END(); - -public: - void SetUp() override { - ActorSystem_ = MakeHolder<TTestActorRuntimeBase>(); - ActorSystem_->Initialize(); - - PollerId_ = ActorSystem_->Register(CreatePollerActor()); - - TDispatchOptions opts; - opts.FinalEvents.emplace_back(TEvents::TSystem::Bootstrap, 1); - ActorSystem_->DispatchEvents(opts); - } - - void Registration() { - auto [s1, s2] = NonBlockSockets(); - auto readerId = ActorSystem_->AllocateEdgeActor(); - auto writerId = ActorSystem_->AllocateEdgeActor(); - +class TPollerActorTest: public TTestBase { + UNIT_TEST_SUITE(TPollerActorTest); + UNIT_TEST(Registration) + UNIT_TEST(ReadNotification) + UNIT_TEST(WriteNotification) + UNIT_TEST(HangupNotification) + UNIT_TEST_SUITE_END(); + +public: + void SetUp() override { + ActorSystem_ = MakeHolder<TTestActorRuntimeBase>(); + ActorSystem_->Initialize(); + + PollerId_ = ActorSystem_->Register(CreatePollerActor()); + + TDispatchOptions opts; + opts.FinalEvents.emplace_back(TEvents::TSystem::Bootstrap, 1); + ActorSystem_->DispatchEvents(opts); + } + + void Registration() { + auto [s1, s2] = NonBlockSockets(); + auto readerId = ActorSystem_->AllocateEdgeActor(); + auto writerId = ActorSystem_->AllocateEdgeActor(); + RegisterSocket(s1, readerId, writerId); - - // reader should receive event after socket registration + + // reader should receive event after socket registration TPollerToken::TPtr token; - { + { auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(readerId); token = ev->Get()->PollerToken; - } - - // writer should receive event after socket registration - { + } + + // writer should receive event after socket registration + { auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(writerId); UNIT_ASSERT_EQUAL(token, ev->Get()->PollerToken); - } - } - - void ReadNotification() { - auto [r, w] = NonBlockSockets(); - auto clientId = ActorSystem_->AllocateEdgeActor(); + } + } + + void ReadNotification() { + auto [r, w] = NonBlockSockets(); + auto clientId = ActorSystem_->AllocateEdgeActor(); RegisterSocket(r, clientId, {}); - - // notification after registration + + // notification after registration TPollerToken::TPtr token; - { + { auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId); token = ev->Get()->PollerToken; - } - - char buf; - - // data not ready yet for read - UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == -1); - UNIT_ASSERT(errno == EWOULDBLOCK); - + } + + char buf; + + // data not ready yet for read + UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == -1); + UNIT_ASSERT(errno == EWOULDBLOCK); + // request read poll token->Request(true, false); - // write data - UNIT_ASSERT(write(w->GetDescriptor(), "x", 1) == 1); - - // notification after socket become readable - { + // write data + UNIT_ASSERT(write(w->GetDescriptor(), "x", 1) == 1); + + // notification after socket become readable + { auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerReady>(clientId); UNIT_ASSERT_EQUAL(ev->Get()->Socket, r); UNIT_ASSERT(ev->Get()->Read); UNIT_ASSERT(!ev->Get()->Write); - } - - // read data - UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == 1); - UNIT_ASSERT_EQUAL('x', buf); - - // no more data to read - UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == -1); - UNIT_ASSERT(errno == EWOULDBLOCK); - } - - void WriteNotification() { + } + + // read data + UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == 1); + UNIT_ASSERT_EQUAL('x', buf); + + // no more data to read + UNIT_ASSERT(read(r->GetDescriptor(), &buf, sizeof(buf)) == -1); + UNIT_ASSERT(errno == EWOULDBLOCK); + } + + void WriteNotification() { auto [r, w] = TcpSockets(); - auto clientId = ActorSystem_->AllocateEdgeActor(); + auto clientId = ActorSystem_->AllocateEdgeActor(); SetNonBlock(w->GetDescriptor()); RegisterSocket(w, TActorId{}, clientId); - - // notification after registration + + // notification after registration TPollerToken::TPtr token; { auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId); token = ev->Get()->PollerToken; - } - + } + char buffer[4096]; memset(buffer, 'x', sizeof(buffer)); @@ -181,7 +181,7 @@ public: written += res; } else if (res == 0) { UNIT_FAIL("unexpected zero return from send()"); - } else { + } else { UNIT_ASSERT(res == -1); if (errno == EINTR) { continue; @@ -191,10 +191,10 @@ public: } else { UNIT_FAIL("unexpected error from send()"); } - } - } + } + } Cerr << "written " << written << " bytes" << Endl; - + // read all written data from the read end for (;;) { char buffer[4096]; @@ -216,7 +216,7 @@ public: } } } - + // wait for notification after socket becomes writable again { auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerReady>(clientId); @@ -224,41 +224,41 @@ public: UNIT_ASSERT(!ev->Get()->Read); UNIT_ASSERT(ev->Get()->Write); } - } - } - - void HangupNotification() { - auto [r, w] = NonBlockSockets(); - auto clientId = ActorSystem_->AllocateEdgeActor(); + } + } + + void HangupNotification() { + auto [r, w] = NonBlockSockets(); + auto clientId = ActorSystem_->AllocateEdgeActor(); RegisterSocket(r, clientId, TActorId{}); - - // notification after registration + + // notification after registration TPollerToken::TPtr token; - { + { auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerRegisterResult>(clientId); token = ev->Get()->PollerToken; - } - + } + token->Request(true, false); ShutDown(w->GetDescriptor(), SHUT_RDWR); - + // notification after peer shuts down its socket - { + { auto ev = ActorSystem_->GrabEdgeEvent<TEvPollerReady>(clientId); UNIT_ASSERT_EQUAL(ev->Get()->Socket, r); UNIT_ASSERT(ev->Get()->Read); - } - } - -private: + } + } + +private: void RegisterSocket(TTestSocketPtr socket, TActorId readActorId, TActorId writeActorId) { auto ev = new TEvPollerRegister{socket, readActorId, writeActorId}; - ActorSystem_->Send(new IEventHandle(PollerId_, TActorId{}, ev)); - } - -private: - THolder<TTestActorRuntimeBase> ActorSystem_; - TActorId PollerId_; -}; - -UNIT_TEST_SUITE_REGISTRATION(TPollerActorTest); + ActorSystem_->Send(new IEventHandle(PollerId_, TActorId{}, ev)); + } + +private: + THolder<TTestActorRuntimeBase> ActorSystem_; + TActorId PollerId_; +}; + +UNIT_TEST_SUITE_REGISTRATION(TPollerActorTest); diff --git a/library/cpp/actors/interconnect/ut/ya.make b/library/cpp/actors/interconnect/ut/ya.make index ec19f1a64a..2f5b13352e 100644 --- a/library/cpp/actors/interconnect/ut/ya.make +++ b/library/cpp/actors/interconnect/ut/ya.make @@ -15,11 +15,11 @@ ELSE() ENDIF() SRCS( - channel_scheduler_ut.cpp + channel_scheduler_ut.cpp event_holder_pool_ut.cpp interconnect_ut.cpp large.cpp - poller_actor_ut.cpp + poller_actor_ut.cpp dynamic_proxy_ut.cpp ) @@ -28,7 +28,7 @@ PEERDIR( library/cpp/actors/interconnect library/cpp/actors/interconnect/ut/lib library/cpp/actors/interconnect/ut/protos - library/cpp/actors/testlib + library/cpp/actors/testlib library/cpp/digest/md5 library/cpp/testing/unittest ) diff --git a/library/cpp/actors/interconnect/ut_fat/main.cpp b/library/cpp/actors/interconnect/ut_fat/main.cpp index 69374cd080..5d19bc3003 100644 --- a/library/cpp/actors/interconnect/ut_fat/main.cpp +++ b/library/cpp/actors/interconnect/ut_fat/main.cpp @@ -23,7 +23,7 @@ Y_UNIT_TEST_SUITE(InterconnectUnstableConnection) { ui16 SendFlags; public: - TSenderActor(const TActorId& recipientActorId, ui16 sendFlags) + TSenderActor(const TActorId& recipientActorId, ui16 sendFlags) : TSenderBaseActor(recipientActorId, 32) , SendFlags(sendFlags) { @@ -108,7 +108,7 @@ Y_UNIT_TEST_SUITE(InterconnectUnstableConnection) { TTestICCluster testCluster(numNodes, TChannelsConfig(), &interrupterSettings); TReceiverActor* receiverActor = new TReceiverActor(testCluster.GetNode(1)); - const TActorId recipient = testCluster.RegisterActor(receiverActor, 2); + const TActorId recipient = testCluster.RegisterActor(receiverActor, 2); TSenderActor* senderActor = new TSenderActor(recipient, flags); testCluster.RegisterActor(senderActor, 1); @@ -124,7 +124,7 @@ Y_UNIT_TEST_SUITE(InterconnectUnstableConnection) { TTestICCluster testCluster(numNodes, TChannelsConfig(), &interrupterSettings); TReceiverActor* receiverActor = new TReceiverActor(testCluster.GetNode(1)); - const TActorId recipient = testCluster.RegisterActor(receiverActor, 2); + const TActorId recipient = testCluster.RegisterActor(receiverActor, 2); TSenderActor* senderActor = new TSenderActor(recipient, flags); testCluster.RegisterActor(senderActor, 1); diff --git a/library/cpp/actors/interconnect/ya.make b/library/cpp/actors/interconnect/ya.make index 9e4fb46fdb..60d29b0fc0 100644 --- a/library/cpp/actors/interconnect/ya.make +++ b/library/cpp/actors/interconnect/ya.make @@ -75,18 +75,18 @@ PEERDIR( contrib/libs/libc_compat contrib/libs/openssl library/cpp/actors/core - library/cpp/actors/dnscachelib + library/cpp/actors/dnscachelib library/cpp/actors/dnsresolver library/cpp/actors/helpers library/cpp/actors/prof library/cpp/actors/protos library/cpp/actors/util library/cpp/digest/crc32c - library/cpp/json + library/cpp/json library/cpp/lwtrace - library/cpp/monlib/dynamic_counters + library/cpp/monlib/dynamic_counters library/cpp/monlib/metrics - library/cpp/monlib/service/pages/tablesorter + library/cpp/monlib/service/pages/tablesorter library/cpp/openssl/init library/cpp/packedtypes ) diff --git a/library/cpp/actors/protos/actors.proto b/library/cpp/actors/protos/actors.proto index 8155535f1f..5fbd6d44ee 100644 --- a/library/cpp/actors/protos/actors.proto +++ b/library/cpp/actors/protos/actors.proto @@ -2,12 +2,12 @@ package NActorsProto; option java_package = "ru.yandex.kikimr.proto"; option java_outer_classname = "NActorsBaseProto"; -message TActorId { +message TActorId { required fixed64 RawX1 = 1; required fixed64 RawX2 = 2; } message TCallbackException { - required TActorId ActorId = 1; + required TActorId ActorId = 1; required string ExceptionMessage = 2; } diff --git a/library/cpp/actors/protos/interconnect.proto b/library/cpp/actors/protos/interconnect.proto index 8656c8ea1f..2e3b0d0d15 100644 --- a/library/cpp/actors/protos/interconnect.proto +++ b/library/cpp/actors/protos/interconnect.proto @@ -51,7 +51,7 @@ message THandshakeRequest { required uint64 Serial = 4; required uint32 ReceiverNodeId = 5; - required string SenderActorId = 6; + required string SenderActorId = 6; optional string SenderHostName = 7; optional string ReceiverHostName = 8; @@ -81,7 +81,7 @@ message THandshakeSuccess { required uint64 ProgramStartTime = 3; required uint64 Serial = 4; - required string SenderActorId = 5; + required string SenderActorId = 5; optional string VersionTag = 6; repeated string AcceptedVersionTags = 7; @@ -104,7 +104,7 @@ message THandshakeReply { message TEvLoadMessage { message THop { - optional NActorsProto.TActorId NextHop = 1; // if zero, then the payload is trimmed out of the message + optional NActorsProto.TActorId NextHop = 1; // if zero, then the payload is trimmed out of the message } repeated THop Hops = 1; // the route for the message diff --git a/library/cpp/actors/testlib/test_runtime.cpp b/library/cpp/actors/testlib/test_runtime.cpp index cda6980b1e..6fa25b9965 100644 --- a/library/cpp/actors/testlib/test_runtime.cpp +++ b/library/cpp/actors/testlib/test_runtime.cpp @@ -295,17 +295,17 @@ namespace NActors { void Schedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, TWorkerId workerId) override { DoSchedule(deadline, ev, cookie, workerId); - } - + } + void Schedule(TMonotonic deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, TWorkerId workerId) override { DoSchedule(TInstant::FromValue(deadline.GetValue()), ev, cookie, workerId); } void Schedule(TDuration delay, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, TWorkerId workerId) override { - TInstant deadline = Runtime->GetTimeProvider()->Now() + delay; + TInstant deadline = Runtime->GetTimeProvider()->Now() + delay; DoSchedule(deadline, ev, cookie, workerId); - } - + } + void DoSchedule(TInstant deadline, TAutoPtr<IEventHandle> ev, ISchedulerCookie *cookie, TWorkerId workerId) { Y_UNUSED(workerId); @@ -319,13 +319,13 @@ namespace NActors { Cerr << "Got scheduled event at " << TInstant::MicroSeconds(Runtime->CurrentTimestamp) << ", "; PrintEvent(ev, Runtime); } - - auto now = Runtime->GetTimeProvider()->Now(); - if (deadline < now) { - deadline = now; // avoid going backwards in time - } - TDuration delay = (deadline - now); - + + auto now = Runtime->GetTimeProvider()->Now(); + if (deadline < now) { + deadline = now; // avoid going backwards in time + } + TDuration delay = (deadline - now); + if (Runtime->SingleSysEnv || !Runtime->ScheduledEventFilterFunc(*Runtime, ev, delay, deadline)) { ui32 mailboxHint = ev->GetRecipientRewrite().Hint(); Runtime->GetMailbox(Runtime->FirstNodeId + NodeIndex, mailboxHint).Schedule(TScheduledEventQueueItem(deadline, ev, cookie)); @@ -336,9 +336,9 @@ namespace NActors { if (cookie) { cookie->Detach(); } - if (verbose) { + if (verbose) { Cerr << "Scheduled event for " << ev->GetRecipientRewrite().ToString() << " was dropped\n"; - } + } } } @@ -366,8 +366,8 @@ namespace NActors { ui32 mailboxHint = ev->GetRecipientRewrite().Hint(); if (ev->GetTypeRewrite() == ui32(NActors::NLog::EEv::Log)) { - const NActors::TActorId loggerActorId = NActors::TActorId(nodeId, "logger"); - TActorId logger = node->ActorSystem->LookupLocalService(loggerActorId); + const NActors::TActorId loggerActorId = NActors::TActorId(nodeId, "logger"); + TActorId logger = node->ActorSystem->LookupLocalService(loggerActorId); if (ev->GetRecipientRewrite() == logger) { TMailboxHeader* mailbox = node->MailboxTable->Get(mailboxHint); IActor* recipientActor = mailbox->FindActor(ev->GetRecipientRewrite().LocalId()); @@ -403,7 +403,7 @@ namespace NActors { } TActorId Register(IActor *actor, TMailboxType::EType mailboxType, ui64 revolvingCounter, - const TActorId& parentId) override { + const TActorId& parentId) override { return Runtime->Register(actor, NodeIndex, PoolId, mailboxType, revolvingCounter, parentId); } @@ -486,7 +486,7 @@ namespace NActors { } void TTestActorRuntimeBase::InitNode(TNodeDataBase* node, size_t nodeIndex) { - const NActors::TActorId loggerActorId = NActors::TActorId(FirstNodeId + nodeIndex, "logger"); + const NActors::TActorId loggerActorId = NActors::TActorId(FirstNodeId + nodeIndex, "logger"); node->LogSettings = new NActors::NLog::TSettings(loggerActorId, 410 /* NKikimrServices::LOGGER */, NActors::NLog::PRI_WARN, NActors::NLog::PRI_WARN, 0); node->LogSettings->SetAllowDrop(false); @@ -579,7 +579,7 @@ namespace NActors { } - void TTestActorRuntimeBase::DefaultRegistrationObserver(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId) { + void TTestActorRuntimeBase::DefaultRegistrationObserver(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId) { if (runtime.ScheduleWhiteList.find(parentId) != runtime.ScheduleWhiteList.end()) { runtime.ScheduleWhiteList.insert(actorId); runtime.ScheduleWhiteListParent[actorId] = parentId; @@ -640,7 +640,7 @@ namespace NActors { TInstant time = scheduledEvents.begin()->Deadline; while (!scheduledEvents.empty() && scheduledEvents.begin()->Deadline == time) { - static THashMap<std::pair<TActorId, TString>, ui64> eventTypes; + static THashMap<std::pair<TActorId, TString>, ui64> eventTypes; auto& item = *scheduledEvents.begin(); TString name = item.Event->GetBase() ? TypeName(*item.Event->GetBase()) : Sprintf("%08" PRIx32, item.Event->Type); eventTypes[std::make_pair(item.Event->Recipient, name)]++; @@ -725,7 +725,7 @@ namespace NActors { VERBOSE = verbose; } - void TTestActorRuntimeBase::AddLocalService(const TActorId& actorId, const TActorSetupCmd& cmd, ui32 nodeIndex) { + void TTestActorRuntimeBase::AddLocalService(const TActorId& actorId, const TActorSetupCmd& cmd, ui32 nodeIndex) { Y_VERIFY(!IsInitialized); Y_VERIFY(nodeIndex < NodeCount); auto node = Nodes[nodeIndex + FirstNodeId]; @@ -857,8 +857,8 @@ namespace NActors { return (*TmpDir)(); } - TActorId TTestActorRuntimeBase::Register(IActor* actor, ui32 nodeIndex, ui32 poolId, TMailboxType::EType mailboxType, - ui64 revolvingCounter, const TActorId& parentId) { + TActorId TTestActorRuntimeBase::Register(IActor* actor, ui32 nodeIndex, ui32 poolId, TMailboxType::EType mailboxType, + ui64 revolvingCounter, const TActorId& parentId) { Y_VERIFY(nodeIndex < NodeCount); TGuard<TMutex> guard(Mutex); TNodeDataBase* node = Nodes[FirstNodeId + nodeIndex].Get(); @@ -897,7 +897,7 @@ namespace NActors { mailbox->AttachActor(localActorId, actor); // do init - const TActorId actorId(FirstNodeId + nodeIndex, poolId, localActorId, hint); + const TActorId actorId(FirstNodeId + nodeIndex, poolId, localActorId, hint); ActorNames[actorId] = TypeName(*actor); RegistrationObserver(*this, parentId ? parentId : CurrentRecipient, actorId); DoActorInit(node->ActorSystem.Get(), actor, actorId, parentId ? parentId : CurrentRecipient); @@ -925,8 +925,8 @@ namespace NActors { return actorId; } - TActorId TTestActorRuntimeBase::Register(IActor *actor, ui32 nodeIndex, ui32 poolId, TMailboxHeader *mailbox, ui32 hint, - const TActorId& parentId) { + TActorId TTestActorRuntimeBase::Register(IActor *actor, ui32 nodeIndex, ui32 poolId, TMailboxHeader *mailbox, ui32 hint, + const TActorId& parentId) { Y_VERIFY(nodeIndex < NodeCount); TGuard<TMutex> guard(Mutex); TNodeDataBase* node = Nodes[FirstNodeId + nodeIndex].Get(); @@ -941,7 +941,7 @@ namespace NActors { } mailbox->AttachActor(localActorId, actor); - const TActorId actorId(FirstNodeId + nodeIndex, poolId, localActorId, hint); + const TActorId actorId(FirstNodeId + nodeIndex, poolId, localActorId, hint); ActorNames[actorId] = TypeName(*actor); RegistrationObserver(*this, parentId ? parentId : CurrentRecipient, actorId); DoActorInit(node->ActorSystem.Get(), actor, actorId, parentId ? parentId : CurrentRecipient); @@ -949,7 +949,7 @@ namespace NActors { return actorId; } - TActorId TTestActorRuntimeBase::RegisterService(const TActorId& serviceId, const TActorId& actorId, ui32 nodeIndex) { + TActorId TTestActorRuntimeBase::RegisterService(const TActorId& serviceId, const TActorId& actorId, ui32 nodeIndex) { TGuard<TMutex> guard(Mutex); Y_VERIFY(nodeIndex < NodeCount); TNodeDataBase* node = Nodes[FirstNodeId + nodeIndex].Get(); @@ -959,13 +959,13 @@ namespace NActors { node->ActorToActorId[actor] = actorId; } - return node->ActorSystem->RegisterLocalService(serviceId, actorId); + return node->ActorSystem->RegisterLocalService(serviceId, actorId); } - TActorId TTestActorRuntimeBase::AllocateEdgeActor(ui32 nodeIndex) { + TActorId TTestActorRuntimeBase::AllocateEdgeActor(ui32 nodeIndex) { TGuard<TMutex> guard(Mutex); Y_VERIFY(nodeIndex < NodeCount); - TActorId edgeActor = Register(new TEdgeActor(this), nodeIndex); + TActorId edgeActor = Register(new TEdgeActor(this), nodeIndex); EdgeActors.insert(edgeActor); EdgeActorByMailbox[TEventMailboxId(edgeActor.NodeId(), edgeActor.Hint())] = edgeActor; return edgeActor; @@ -1414,14 +1414,14 @@ namespace NActors { return it->second; } - TActorId TTestActorRuntimeBase::GetLocalServiceId(const TActorId& serviceId, ui32 nodeIndex) { + TActorId TTestActorRuntimeBase::GetLocalServiceId(const TActorId& serviceId, ui32 nodeIndex) { TGuard<TMutex> guard(Mutex); Y_VERIFY(nodeIndex < NodeCount); TNodeDataBase* node = Nodes[FirstNodeId + nodeIndex].Get(); return node->ActorSystem->LookupLocalService(serviceId); } - void TTestActorRuntimeBase::WaitForEdgeEvents(TEventFilter filter, const TSet<TActorId>& edgeFilter, TDuration simTimeout) { + void TTestActorRuntimeBase::WaitForEdgeEvents(TEventFilter filter, const TSet<TActorId>& edgeFilter, TDuration simTimeout) { TGuard<TMutex> guard(Mutex); ui32 dispatchCount = 0; if (!edgeFilter.empty()) { @@ -1429,7 +1429,7 @@ namespace NActors { Y_VERIFY(EdgeActors.contains(edgeActor), "%s is not an edge actor", ToString(edgeActor).data()); } } - const TSet<TActorId>& edgeActors = edgeFilter.empty() ? EdgeActors : edgeFilter; + const TSet<TActorId>& edgeActors = edgeFilter.empty() ? EdgeActors : edgeFilter; TInstant deadline = TInstant::MicroSeconds(CurrentTimestamp) + simTimeout; for (;;) { for (auto edgeActor : edgeActors) { @@ -1460,7 +1460,7 @@ namespace NActors { } } - TActorId TTestActorRuntimeBase::GetInterconnectProxy(ui32 nodeIndexFrom, ui32 nodeIndexTo) { + TActorId TTestActorRuntimeBase::GetInterconnectProxy(ui32 nodeIndexFrom, ui32 nodeIndexTo) { TGuard<TMutex> guard(Mutex); Y_VERIFY(nodeIndexFrom < NodeCount); Y_VERIFY(nodeIndexTo < NodeCount); @@ -1469,7 +1469,7 @@ namespace NActors { return node->ActorSystem->InterconnectProxy(FirstNodeId + nodeIndexTo); } - void TTestActorRuntimeBase::BlockOutputForActor(const TActorId& actorId) { + void TTestActorRuntimeBase::BlockOutputForActor(const TActorId& actorId) { TGuard<TMutex> guard(Mutex); BlockedOutput.insert(actorId); } @@ -1480,7 +1480,7 @@ namespace NActors { DispatcherRandomProvider = CreateDeterministicRandomProvider(DispatcherRandomSeed); } - IActor* TTestActorRuntimeBase::FindActor(const TActorId& actorId, ui32 nodeIndex) const { + IActor* TTestActorRuntimeBase::FindActor(const TActorId& actorId, ui32 nodeIndex) const { TGuard<TMutex> guard(Mutex); if (nodeIndex == Max<ui32>()) { Y_VERIFY(actorId.NodeId()); @@ -1494,7 +1494,7 @@ namespace NActors { return FindActor(actorId, node); } - void TTestActorRuntimeBase::EnableScheduleForActor(const TActorId& actorId, bool allow) { + void TTestActorRuntimeBase::EnableScheduleForActor(const TActorId& actorId, bool allow) { TGuard<TMutex> guard(Mutex); if (allow) { if (VERBOSE) { @@ -1509,7 +1509,7 @@ namespace NActors { } } - bool TTestActorRuntimeBase::IsScheduleForActorEnabled(const TActorId& actorId) const { + bool TTestActorRuntimeBase::IsScheduleForActorEnabled(const TActorId& actorId) const { TGuard<TMutex> guard(Mutex); return ScheduleWhiteList.find(actorId) != ScheduleWhiteList.end(); } @@ -1570,7 +1570,7 @@ namespace NActors { IActor* recipientActor = mailbox->FindActor(recipientLocalId); if (recipientActor) { // Save actorId by value in order to prevent ctx from being invalidated during another Send call. - TActorId actorId = ev->GetRecipientRewrite(); + TActorId actorId = ev->GetRecipientRewrite(); node->ActorToActorId[recipientActor] = ev->GetRecipientRewrite(); TActorContext ctx(*mailbox, *node->ExecutorThread, GetCycleCountFast(), actorId); TActivationContext *prevTlsActivationContext = TlsActivationContext; @@ -1585,7 +1585,7 @@ namespace NActors { recipientActor->Receive(evHolder, ctx); node->ExecutorThread->DropUnregistered(); } - CurrentRecipient = TActorId(); + CurrentRecipient = TActorId(); TlsActivationContext = prevTlsActivationContext; } else { if (VERBOSE) { @@ -1599,7 +1599,7 @@ namespace NActors { } } - IActor* TTestActorRuntimeBase::FindActor(const TActorId& actorId, TNodeDataBase* node) const { + IActor* TTestActorRuntimeBase::FindActor(const TActorId& actorId, TNodeDataBase* node) const { ui32 mailboxHint = actorId.Hint(); ui64 localId = actorId.LocalId(); TMailboxHeader* mailbox = node->MailboxTable->Get(mailboxHint); @@ -1644,7 +1644,7 @@ namespace NActors { setup->LocalServices = node->LocalServices; setup->Interconnect.ProxyActors.resize(FirstNodeId + NodeCount); - const TActorId nameserviceId = GetNameserviceActorId(); + const TActorId nameserviceId = GetNameserviceActorId(); TIntrusivePtr<TInterconnectProxyCommon> common; common.Reset(new TInterconnectProxyCommon); @@ -1688,7 +1688,7 @@ namespace NActors { NActors::TLoggerActor *loggerActor = new NActors::TLoggerActor(node->LogSettings, logBackend, GetCountersForComponent(node->DynamicCounters, "utils")); NActors::TActorSetupCmd loggerActorCmd(loggerActor, NActors::TMailboxType::Simple, node->GetLoggerPoolId()); - std::pair<NActors::TActorId, NActors::TActorSetupCmd> loggerActorPair(node->LogSettings->LoggerActorId, loggerActorCmd); + std::pair<NActors::TActorId, NActors::TActorSetupCmd> loggerActorPair(node->LogSettings->LoggerActorId, loggerActorCmd); setup->LocalServices.push_back(loggerActorPair); } @@ -1732,7 +1732,7 @@ namespace NActors { Mailboxes.erase(mboxId); } - TString TTestActorRuntimeBase::GetActorName(const TActorId& actorId) const { + TString TTestActorRuntimeBase::GetActorName(const TActorId& actorId) const { auto it = ActorNames.find(actorId); if (it != ActorNames.end()) return it->second; @@ -1773,7 +1773,7 @@ namespace NActors { return TEST_ACTOR_RUNTIME; } - TStrandingActorDecorator(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors, + TStrandingActorDecorator(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors, TSimpleSharedPtr<TStrandingActorDecoratorContext> context, TTestActorRuntimeBase* runtime, TReplyCheckerCreator createReplyChecker) : Delegatee(delegatee) @@ -1813,7 +1813,7 @@ namespace NActors { STFUNC(Reply) { Y_VERIFY(!HasReply); IEventHandle *requestEv = Context->Queue->Head(); - TActorId originalSender = requestEv->Sender; + TActorId originalSender = requestEv->Sender; HasReply = !ReplyChecker->IsWaitingForMoreResponses(ev.Get()); if (HasReply) { delete Context->Queue->Pop(); @@ -1857,11 +1857,11 @@ namespace NActors { return forwardedEv; } private: - const TActorId Delegatee; + const TActorId Delegatee; const bool IsSync; - const TVector<TActorId> AdditionalActors; + const TVector<TActorId> AdditionalActors; TSimpleSharedPtr<TStrandingActorDecoratorContext> Context; - TActorId ReplyId; + TActorId ReplyId; bool HasReply; TDispatchOptions DelegateeOptions; TTestActorRuntimeBase* Runtime; @@ -1882,7 +1882,7 @@ namespace NActors { { } - IActor* Wrap(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors) override { + IActor* Wrap(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors) override { return new TStrandingActorDecorator(delegatee, isSync, additionalActors, Context, Runtime, CreateReplyChecker); } diff --git a/library/cpp/actors/testlib/test_runtime.h b/library/cpp/actors/testlib/test_runtime.h index b7e8edd1c5..26e3b45c98 100644 --- a/library/cpp/actors/testlib/test_runtime.h +++ b/library/cpp/actors/testlib/test_runtime.h @@ -199,7 +199,7 @@ namespace NActors { typedef std::function<void(TTestActorRuntimeBase& runtime, TScheduledEventsList& scheduledEvents, TEventsList& queue)> TScheduledEventsSelector; typedef std::function<bool(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event)> TEventFilter; typedef std::function<bool(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event, TDuration delay, TInstant& deadline)> TScheduledEventFilter; - typedef std::function<void(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId)> TRegistrationObserver; + typedef std::function<void(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId)> TRegistrationObserver; TTestActorRuntimeBase(THeSingleSystemEnv); @@ -213,7 +213,7 @@ namespace NActors { static void CollapsedTimeScheduledEventsSelector(TTestActorRuntimeBase& runtime, TScheduledEventsList& scheduledEvents, TEventsList& queue); static bool DefaultFilterFunc(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event); static bool NopFilterFunc(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event, TDuration delay, TInstant& deadline); - static void DefaultRegistrationObserver(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId); + static void DefaultRegistrationObserver(TTestActorRuntimeBase& runtime, const TActorId& parentId, const TActorId& actorId); TEventObserver SetObserverFunc(TEventObserver observerFunc); TScheduledEventsSelector SetScheduledEventsSelectorFunc(TScheduledEventsSelector scheduledEventsSelectorFunc); TEventFilter SetEventFilter(TEventFilter filterFunc); @@ -232,20 +232,20 @@ namespace NActors { TInstant GetCurrentTime() const; void UpdateCurrentTime(TInstant newTime); void AdvanceCurrentTime(TDuration duration); - void AddLocalService(const TActorId& actorId, const TActorSetupCmd& cmd, ui32 nodeIndex = 0); + void AddLocalService(const TActorId& actorId, const TActorSetupCmd& cmd, ui32 nodeIndex = 0); virtual void Initialize(); ui32 GetNodeId(ui32 index = 0) const; ui32 GetNodeCount() const; ui64 AllocateLocalId(); ui32 InterconnectPoolId() const; TString GetTempDir(); - TActorId Register(IActor* actor, ui32 nodeIndex = 0, ui32 poolId = 0, + TActorId Register(IActor* actor, ui32 nodeIndex = 0, ui32 poolId = 0, TMailboxType::EType mailboxType = TMailboxType::Simple, ui64 revolvingCounter = 0, - const TActorId& parentid = TActorId()); - TActorId Register(IActor *actor, ui32 nodeIndex, ui32 poolId, TMailboxHeader *mailbox, ui32 hint, - const TActorId& parentid = TActorId()); - TActorId RegisterService(const TActorId& serviceId, const TActorId& actorId, ui32 nodeIndex = 0); - TActorId AllocateEdgeActor(ui32 nodeIndex = 0); + const TActorId& parentid = TActorId()); + TActorId Register(IActor *actor, ui32 nodeIndex, ui32 poolId, TMailboxHeader *mailbox, ui32 hint, + const TActorId& parentid = TActorId()); + TActorId RegisterService(const TActorId& serviceId, const TActorId& actorId, ui32 nodeIndex = 0); + TActorId AllocateEdgeActor(ui32 nodeIndex = 0); TEventsList CaptureEvents(); TEventsList CaptureMailboxEvents(ui32 hint, ui32 nodeId); TScheduledEventsList CaptureScheduledEvents(); @@ -260,13 +260,13 @@ namespace NActors { void Schedule(IEventHandle* ev, const TDuration& duration, ui32 nodeIndex = 0); void ClearCounters(); ui64 GetCounter(ui32 evType) const; - TActorId GetLocalServiceId(const TActorId& serviceId, ui32 nodeIndex = 0); - void WaitForEdgeEvents(TEventFilter filter, const TSet<TActorId>& edgeFilter = {}, TDuration simTimeout = TDuration::Max()); - TActorId GetInterconnectProxy(ui32 nodeIndexFrom, ui32 nodeIndexTo); - void BlockOutputForActor(const TActorId& actorId); - IActor* FindActor(const TActorId& actorId, ui32 nodeIndex = Max<ui32>()) const; - void EnableScheduleForActor(const TActorId& actorId, bool allow = true); - bool IsScheduleForActorEnabled(const TActorId& actorId) const; + TActorId GetLocalServiceId(const TActorId& serviceId, ui32 nodeIndex = 0); + void WaitForEdgeEvents(TEventFilter filter, const TSet<TActorId>& edgeFilter = {}, TDuration simTimeout = TDuration::Max()); + TActorId GetInterconnectProxy(ui32 nodeIndexFrom, ui32 nodeIndexTo); + void BlockOutputForActor(const TActorId& actorId); + IActor* FindActor(const TActorId& actorId, ui32 nodeIndex = Max<ui32>()) const; + void EnableScheduleForActor(const TActorId& actorId, bool allow = true); + bool IsScheduleForActorEnabled(const TActorId& actorId) const; TIntrusivePtr<NMonitoring::TDynamicCounters> GetDynamicCounters(ui32 nodeIndex = 0); void SetupMonitoring(); @@ -317,7 +317,7 @@ namespace NActors { template<class TEvent> typename TEvent::TPtr GrabEdgeEventIf( - const TSet<TActorId>& edgeFilter, + const TSet<TActorId>& edgeFilter, const std::function<bool(const typename TEvent::TPtr&)>& predicate, TDuration simTimeout = TDuration::Max()) { @@ -345,11 +345,11 @@ namespace NActors { template<class TEvent> typename TEvent::TPtr GrabEdgeEventIf( - const TActorId& edgeActor, + const TActorId& edgeActor, const std::function<bool(const typename TEvent::TPtr&)>& predicate, TDuration simTimeout = TDuration::Max()) { - TSet<TActorId> edgeFilter{edgeActor}; + TSet<TActorId> edgeFilter{edgeActor}; return GrabEdgeEventIf<TEvent>(edgeFilter, predicate, simTimeout); } @@ -368,13 +368,13 @@ namespace NActors { } template<class TEvent> - typename TEvent::TPtr GrabEdgeEvent(const TSet<TActorId>& edgeFilter, TDuration simTimeout = TDuration::Max()) { + typename TEvent::TPtr GrabEdgeEvent(const TSet<TActorId>& edgeFilter, TDuration simTimeout = TDuration::Max()) { return GrabEdgeEventIf<TEvent>(edgeFilter, [](const typename TEvent::TPtr&) { return true; }, simTimeout); } template<class TEvent> - typename TEvent::TPtr GrabEdgeEvent(const TActorId& edgeActor, TDuration simTimeout = TDuration::Max()) { - TSet<TActorId> edgeFilter{edgeActor}; + typename TEvent::TPtr GrabEdgeEvent(const TActorId& edgeActor, TDuration simTimeout = TDuration::Max()) { + TSet<TActorId> edgeFilter{edgeActor}; return GrabEdgeEvent<TEvent>(edgeFilter, simTimeout); } @@ -409,7 +409,7 @@ namespace NActors { } template<class TEvent> - typename TEvent::TPtr GrabEdgeEventRethrow(const TSet<TActorId>& edgeFilter, TDuration simTimeout = TDuration::Max()) { + typename TEvent::TPtr GrabEdgeEventRethrow(const TSet<TActorId>& edgeFilter, TDuration simTimeout = TDuration::Max()) { try { return GrabEdgeEvent<TEvent>(edgeFilter, simTimeout); } catch (...) { @@ -418,7 +418,7 @@ namespace NActors { } template<class TEvent> - typename TEvent::TPtr GrabEdgeEventRethrow(const TActorId& edgeActor, TDuration simTimeout = TDuration::Max()) { + typename TEvent::TPtr GrabEdgeEventRethrow(const TActorId& edgeActor, TDuration simTimeout = TDuration::Max()) { try { return GrabEdgeEvent<TEvent>(edgeActor, simTimeout); } catch (...) { @@ -462,7 +462,7 @@ namespace NActors { } void SetDispatcherRandomSeed(TInstant time, ui64 iteration); - TString GetActorName(const TActorId& actorId) const; + TString GetActorName(const TActorId& actorId) const; const TVector<ui64>& GetTxAllocatorTabletIds() const { return TxAllocatorTabletIds; } void SetTxAllocatorTabletIds(const TVector<ui64>& ids) { TxAllocatorTabletIds = ids; } @@ -493,7 +493,7 @@ namespace NActors { } private: - IActor* FindActor(const TActorId& actorId, TNodeDataBase* node) const; + IActor* FindActor(const TActorId& actorId, TNodeDataBase* node) const; void SendInternal(IEventHandle* ev, ui32 nodeIndex, bool viaActorSystem); TEventMailBox& GetMailbox(ui32 nodeId, ui32 hint); void ClearMailbox(ui32 nodeId, ui32 hint); @@ -526,7 +526,7 @@ namespace NActors { ui64 DispatchCyclesCount; ui64 DispatchedEventsCount; ui64 DispatchedEventsLimit = 2'500'000; - TActorId CurrentRecipient; + TActorId CurrentRecipient; ui64 DispatcherRandomSeed; TIntrusivePtr<IRandomProvider> DispatcherRandomProvider; TAutoPtr<TLogBackend> LogBackend; @@ -559,9 +559,9 @@ namespace NActors { TIntrusivePtr<NInterconnect::TPollerThreads> Poller; volatile ui64* ActorSystemTimestamp; volatile ui64* ActorSystemMonotonic; - TVector<std::pair<TActorId, TActorSetupCmd> > LocalServices; - TMap<TActorId, IActor*> LocalServicesActors; - TMap<IActor*, TActorId> ActorToActorId; + TVector<std::pair<TActorId, TActorSetupCmd> > LocalServices; + TMap<TActorId, IActor*> LocalServicesActors; + TMap<IActor*, TActorId> ActorToActorId; THolder<TMailboxTable> MailboxTable; std::shared_ptr<void> AppData0; THolder<TActorSystem> ActorSystem; @@ -613,8 +613,8 @@ namespace NActors { TProgramShouldContinue ShouldContinue; TMap<ui32, TIntrusivePtr<TNodeDataBase>> Nodes; ui64 CurrentTimestamp; - TSet<TActorId> EdgeActors; - THashMap<TEventMailboxId, TActorId, TEventMailboxId::THash> EdgeActorByMailbox; + TSet<TActorId> EdgeActors; + THashMap<TEventMailboxId, TActorId, TEventMailboxId::THash> EdgeActorByMailbox; TDuration DispatchTimeout; TDuration ReschedulingDelay; TEventObserver ObserverFunc; @@ -622,10 +622,10 @@ namespace NActors { TEventFilter EventFilterFunc; TScheduledEventFilter ScheduledEventFilterFunc; TRegistrationObserver RegistrationObserver; - TSet<TActorId> BlockedOutput; - TSet<TActorId> ScheduleWhiteList; - THashMap<TActorId, TActorId> ScheduleWhiteListParent; - THashMap<TActorId, TString> ActorNames; + TSet<TActorId> BlockedOutput; + TSet<TActorId> ScheduleWhiteList; + THashMap<TActorId, TActorId> ScheduleWhiteListParent; + THashMap<TActorId, TString> ActorNames; TDispatchContext* CurrentDispatchContext; TVector<ui64> TxAllocatorTabletIds; @@ -686,7 +686,7 @@ namespace NActors { class IStrandingDecoratorFactory { public: virtual ~IStrandingDecoratorFactory() {} - virtual IActor* Wrap(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors) = 0; + virtual IActor* Wrap(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors) = 0; }; struct IReplyChecker { diff --git a/library/cpp/codecs/ut/codecs_ut.cpp b/library/cpp/codecs/ut/codecs_ut.cpp index 0f24c8158f..caf6089aef 100644 --- a/library/cpp/codecs/ut/codecs_ut.cpp +++ b/library/cpp/codecs/ut/codecs_ut.cpp @@ -914,7 +914,7 @@ private: { TBufferInput bin(buff); c = ICodec::Restore(&bin); - UNIT_ASSERT(c->AlreadyTrained()); + UNIT_ASSERT(c->AlreadyTrained()); } } @@ -937,7 +937,7 @@ private: UNIT_ASSERT_EQUAL_C(AsStrBuf(inlearn[i]), AsStrBuf(vecl), PrintError(TStringBuf(inlearn[i].data(), inlearn[i].size()), - TStringBuf(vecl.data(), vecl.size()), c->GetName(), i)); + TStringBuf(vecl.data(), vecl.size()), c->GetName(), i)); } } } @@ -961,7 +961,7 @@ private: c->Decode(AsStrBuf(out), in1); UNIT_ASSERT_EQUAL_C(AsStrBuf(in[i]), AsStrBuf(in1), PrintError(TStringBuf(in[i].data(), in[i].size()), - TStringBuf(in1.data(), in1.size()), c->GetName(), i)); + TStringBuf(in1.data(), in1.size()), c->GetName(), i)); } } } diff --git a/library/cpp/containers/comptrie/loader/loader.cpp b/library/cpp/containers/comptrie/loader/loader.cpp index 22f282d406..4811e9d521 100644 --- a/library/cpp/containers/comptrie/loader/loader.cpp +++ b/library/cpp/containers/comptrie/loader/loader.cpp @@ -1 +1 @@ -#include "loader.h" +#include "loader.h" diff --git a/library/cpp/containers/comptrie/loader/ya.make b/library/cpp/containers/comptrie/loader/ya.make index e62c8a76fa..1e23e442a0 100644 --- a/library/cpp/containers/comptrie/loader/ya.make +++ b/library/cpp/containers/comptrie/loader/ya.make @@ -4,7 +4,7 @@ OWNER(my34) SRCS( loader.h - loader.cpp + loader.cpp ) PEERDIR( diff --git a/library/cpp/grpc/client/grpc_client_low.h b/library/cpp/grpc/client/grpc_client_low.h index 356d1e1f0b..ab0a0627be 100644 --- a/library/cpp/grpc/client/grpc_client_low.h +++ b/library/cpp/grpc/client/grpc_client_low.h @@ -10,7 +10,7 @@ #include <deque> #include <typeindex> #include <typeinfo> -#include <variant> +#include <variant> #include <vector> #include <unordered_map> #include <unordered_set> @@ -185,7 +185,7 @@ using TAdvancedResponseCallback = std::function<void (const grpc::ClientContext& struct TCallMeta { std::shared_ptr<grpc::CallCredentials> CallCredentials; std::vector<std::pair<TString, TString>> Aux; - std::variant<TDuration, TInstant> Timeout; // timeout as duration from now or time point in future + std::variant<TDuration, TInstant> Timeout; // timeout as duration from now or time point in future }; class TGRpcRequestProcessorCommon { @@ -197,17 +197,17 @@ protected: if (meta.CallCredentials) { Context.set_credentials(meta.CallCredentials); } - if (const TDuration* timeout = std::get_if<TDuration>(&meta.Timeout)) { - if (*timeout) { - auto deadline = gpr_time_add( - gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_micros(timeout->MicroSeconds(), GPR_TIMESPAN)); - Context.set_deadline(deadline); - } - } else if (const TInstant* deadline = std::get_if<TInstant>(&meta.Timeout)) { - if (*deadline) { - Context.set_deadline(gpr_time_from_micros(deadline->MicroSeconds(), GPR_CLOCK_MONOTONIC)); - } + if (const TDuration* timeout = std::get_if<TDuration>(&meta.Timeout)) { + if (*timeout) { + auto deadline = gpr_time_add( + gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_micros(timeout->MicroSeconds(), GPR_TIMESPAN)); + Context.set_deadline(deadline); + } + } else if (const TInstant* deadline = std::get_if<TInstant>(&meta.Timeout)) { + if (*deadline) { + Context.set_deadline(gpr_time_from_micros(deadline->MicroSeconds(), GPR_CLOCK_MONOTONIC)); + } } } diff --git a/library/cpp/grpc/server/actors/logger.cpp b/library/cpp/grpc/server/actors/logger.cpp index 176675366a..d8b2042576 100644 --- a/library/cpp/grpc/server/actors/logger.cpp +++ b/library/cpp/grpc/server/actors/logger.cpp @@ -1,45 +1,45 @@ -#include "logger.h" - -namespace NGrpc { -namespace { - -static_assert( - ui16(TLOG_EMERG) == ui16(NActors::NLog::PRI_EMERG) && - ui16(TLOG_DEBUG) == ui16(NActors::NLog::PRI_DEBUG), - "log levels in the library/log and library/cpp/actors don't match"); - -class TActorSystemLogger final: public TLogger { -public: - TActorSystemLogger(NActors::TActorSystem& as, NActors::NLog::EComponent component) noexcept - : ActorSystem_{as} - , Component_{component} - { - } - -protected: - bool DoIsEnabled(ELogPriority p) const noexcept override { - const auto* settings = static_cast<::NActors::NLog::TSettings*>(ActorSystem_.LoggerSettings()); - const auto priority = static_cast<::NActors::NLog::EPriority>(p); - - return settings && settings->Satisfies(priority, Component_, 0); - } - - void DoWrite(ELogPriority p, const char* format, va_list args) noexcept override { - Y_VERIFY_DEBUG(DoIsEnabled(p)); - - const auto priority = static_cast<::NActors::NLog::EPriority>(p); - ::NActors::MemLogAdapter(ActorSystem_, priority, Component_, format, args); - } - -private: - NActors::TActorSystem& ActorSystem_; - NActors::NLog::EComponent Component_; -}; - -} // namespace - -TLoggerPtr CreateActorSystemLogger(NActors::TActorSystem& as, NActors::NLog::EComponent component) { - return MakeIntrusive<TActorSystemLogger>(as, component); -} - -} // namespace NGrpc +#include "logger.h" + +namespace NGrpc { +namespace { + +static_assert( + ui16(TLOG_EMERG) == ui16(NActors::NLog::PRI_EMERG) && + ui16(TLOG_DEBUG) == ui16(NActors::NLog::PRI_DEBUG), + "log levels in the library/log and library/cpp/actors don't match"); + +class TActorSystemLogger final: public TLogger { +public: + TActorSystemLogger(NActors::TActorSystem& as, NActors::NLog::EComponent component) noexcept + : ActorSystem_{as} + , Component_{component} + { + } + +protected: + bool DoIsEnabled(ELogPriority p) const noexcept override { + const auto* settings = static_cast<::NActors::NLog::TSettings*>(ActorSystem_.LoggerSettings()); + const auto priority = static_cast<::NActors::NLog::EPriority>(p); + + return settings && settings->Satisfies(priority, Component_, 0); + } + + void DoWrite(ELogPriority p, const char* format, va_list args) noexcept override { + Y_VERIFY_DEBUG(DoIsEnabled(p)); + + const auto priority = static_cast<::NActors::NLog::EPriority>(p); + ::NActors::MemLogAdapter(ActorSystem_, priority, Component_, format, args); + } + +private: + NActors::TActorSystem& ActorSystem_; + NActors::NLog::EComponent Component_; +}; + +} // namespace + +TLoggerPtr CreateActorSystemLogger(NActors::TActorSystem& as, NActors::NLog::EComponent component) { + return MakeIntrusive<TActorSystemLogger>(as, component); +} + +} // namespace NGrpc diff --git a/library/cpp/grpc/server/actors/logger.h b/library/cpp/grpc/server/actors/logger.h index c066a40add..abf9270f7b 100644 --- a/library/cpp/grpc/server/actors/logger.h +++ b/library/cpp/grpc/server/actors/logger.h @@ -1,11 +1,11 @@ -#pragma once - -#include <library/cpp/actors/core/actorsystem.h> -#include <library/cpp/actors/core/log.h> -#include <library/cpp/grpc/server/logger.h> - -namespace NGrpc { - -TLoggerPtr CreateActorSystemLogger(NActors::TActorSystem& as, NActors::NLog::EComponent component); - -} // namespace NGrpc +#pragma once + +#include <library/cpp/actors/core/actorsystem.h> +#include <library/cpp/actors/core/log.h> +#include <library/cpp/grpc/server/logger.h> + +namespace NGrpc { + +TLoggerPtr CreateActorSystemLogger(NActors::TActorSystem& as, NActors::NLog::EComponent component); + +} // namespace NGrpc diff --git a/library/cpp/grpc/server/actors/ya.make b/library/cpp/grpc/server/actors/ya.make index 072db84142..6c9d80aa45 100644 --- a/library/cpp/grpc/server/actors/ya.make +++ b/library/cpp/grpc/server/actors/ya.make @@ -1,13 +1,13 @@ -LIBRARY() - -OWNER(g:kikimr g:solomon) - -SRCS( - logger.cpp -) - -PEERDIR( - library/cpp/actors/core -) - -END() +LIBRARY() + +OWNER(g:kikimr g:solomon) + +SRCS( + logger.cpp +) + +PEERDIR( + library/cpp/actors/core +) + +END() diff --git a/library/cpp/grpc/server/event_callback.h b/library/cpp/grpc/server/event_callback.h index 13d9bb46b2..d0b700b3c9 100644 --- a/library/cpp/grpc/server/event_callback.h +++ b/library/cpp/grpc/server/event_callback.h @@ -2,7 +2,7 @@ #include "grpc_server.h" -namespace NGrpc { +namespace NGrpc { enum class EQueueEventStatus { OK, @@ -10,7 +10,7 @@ enum class EQueueEventStatus { }; template<class TCallback> -class TQueueEventCallback: public IQueueEvent { +class TQueueEventCallback: public IQueueEvent { public: TQueueEventCallback(const TCallback& callback) : Callback(callback) @@ -33,9 +33,9 @@ private: TCallback Callback; }; -// Implementation of IQueueEvent that reduces allocations +// Implementation of IQueueEvent that reduces allocations template<class TSelf> -class TQueueFixedEvent: private IQueueEvent { +class TQueueFixedEvent: private IQueueEvent { using TCallback = void (TSelf::*)(EQueueEventStatus); public: @@ -44,7 +44,7 @@ public: , Callback(callback) { } - IQueueEvent* Prepare() { + IQueueEvent* Prepare() { Self->Ref(); return this; } @@ -65,16 +65,16 @@ private: }; template<class TCallback> -inline IQueueEvent* MakeQueueEventCallback(TCallback&& callback) { +inline IQueueEvent* MakeQueueEventCallback(TCallback&& callback) { return new TQueueEventCallback<TCallback>(std::forward<TCallback>(callback)); } template<class T> -inline IQueueEvent* MakeQueueEventCallback(T* self, void (T::*method)(EQueueEventStatus)) { +inline IQueueEvent* MakeQueueEventCallback(T* self, void (T::*method)(EQueueEventStatus)) { using TPtr = TIntrusivePtr<T>; return MakeQueueEventCallback([self = TPtr(self), method] (EQueueEventStatus status) { ((*self).*method)(status); }); } -} // namespace NGrpc +} // namespace NGrpc diff --git a/library/cpp/grpc/server/grpc_async_ctx_base.h b/library/cpp/grpc/server/grpc_async_ctx_base.h index 65341fa1ad..51356d4ce5 100644 --- a/library/cpp/grpc/server/grpc_async_ctx_base.h +++ b/library/cpp/grpc/server/grpc_async_ctx_base.h @@ -5,17 +5,17 @@ #include <util/generic/vector.h> #include <util/generic/string.h> #include <util/system/yassert.h> -#include <util/generic/set.h> +#include <util/generic/set.h> #include <grpc++/server.h> #include <grpc++/server_context.h> #include <chrono> -namespace NGrpc { +namespace NGrpc { template<typename TService> -class TBaseAsyncContext: public ICancelableContext { +class TBaseAsyncContext: public ICancelableContext { public: TBaseAsyncContext(typename TService::TCurrentGRpcService::AsyncService* service, grpc::ServerCompletionQueue* cq) : Service(service) @@ -29,44 +29,44 @@ public: TInstant Deadline() const { // The timeout transferred in "grpc-timeout" header [1] and calculated from the deadline - // right before the request is getting to be send. - // 1. https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md - // + // right before the request is getting to be send. + // 1. https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md + // // After this timeout calculated back to the deadline on the server side // using server grpc GPR_CLOCK_MONOTONIC time (raw_deadline() method). // deadline() method convert this to epoch related deadline GPR_CLOCK_REALTIME // - + std::chrono::system_clock::time_point t = Context.deadline(); if (t == std::chrono::system_clock::time_point::max()) { return TInstant::Max(); - } + } auto us = std::chrono::time_point_cast<std::chrono::microseconds>(t); return TInstant::MicroSeconds(us.time_since_epoch().count()); - } - - TSet<TStringBuf> GetPeerMetaKeys() const { - TSet<TStringBuf> keys; - for (const auto& [key, _]: Context.client_metadata()) { - keys.emplace(key.data(), key.size()); - } - return keys; - } - - TVector<TStringBuf> GetPeerMetaValues(TStringBuf key) const { + } + + TSet<TStringBuf> GetPeerMetaKeys() const { + TSet<TStringBuf> keys; + for (const auto& [key, _]: Context.client_metadata()) { + keys.emplace(key.data(), key.size()); + } + return keys; + } + + TVector<TStringBuf> GetPeerMetaValues(TStringBuf key) const { const auto& clientMetadata = Context.client_metadata(); - const auto range = clientMetadata.equal_range(grpc::string_ref{key.data(), key.size()}); - if (range.first == range.second) { - return {}; - } - - TVector<TStringBuf> values; - values.reserve(std::distance(range.first, range.second)); - + const auto range = clientMetadata.equal_range(grpc::string_ref{key.data(), key.size()}); + if (range.first == range.second) { + return {}; + } + + TVector<TStringBuf> values; + values.reserve(std::distance(range.first, range.second)); + for (auto it = range.first; it != range.second; ++it) { - values.emplace_back(it->second.data(), it->second.size()); + values.emplace_back(it->second.data(), it->second.size()); } - return values; + return values; } grpc_compression_level GetCompressionLevel() const { @@ -91,4 +91,4 @@ protected: grpc::ServerContext Context; }; -} // namespace NGrpc +} // namespace NGrpc diff --git a/library/cpp/grpc/server/grpc_counters.cpp b/library/cpp/grpc/server/grpc_counters.cpp index bdd72b3292..fa96e0100b 100644 --- a/library/cpp/grpc/server/grpc_counters.cpp +++ b/library/cpp/grpc/server/grpc_counters.cpp @@ -1,45 +1,45 @@ #include "grpc_counters.h" - -namespace NGrpc { -namespace { - -class TFakeCounterBlock final: public ICounterBlock { -private: - void CountNotOkRequest() override { - } - - void CountNotOkResponse() override { - } - - void CountNotAuthenticated() override { - } - - void CountResourceExhausted() override { - } - - void CountRequestBytes(ui32 /*requestSize*/) override { - } - - void CountResponseBytes(ui32 /*responseSize*/) override { - } - - void StartProcessing(ui32 /*requestSize*/) override { - } - - void FinishProcessing( - ui32 /*requestSize*/, - ui32 /*responseSize*/, - bool /*ok*/, - ui32 /*status*/, - TDuration /*requestDuration*/) override - { - } -}; - -} // namespace - -ICounterBlockPtr FakeCounterBlock() { - return MakeIntrusive<TFakeCounterBlock>(); -} - -} // namespace NGrpc + +namespace NGrpc { +namespace { + +class TFakeCounterBlock final: public ICounterBlock { +private: + void CountNotOkRequest() override { + } + + void CountNotOkResponse() override { + } + + void CountNotAuthenticated() override { + } + + void CountResourceExhausted() override { + } + + void CountRequestBytes(ui32 /*requestSize*/) override { + } + + void CountResponseBytes(ui32 /*responseSize*/) override { + } + + void StartProcessing(ui32 /*requestSize*/) override { + } + + void FinishProcessing( + ui32 /*requestSize*/, + ui32 /*responseSize*/, + bool /*ok*/, + ui32 /*status*/, + TDuration /*requestDuration*/) override + { + } +}; + +} // namespace + +ICounterBlockPtr FakeCounterBlock() { + return MakeIntrusive<TFakeCounterBlock>(); +} + +} // namespace NGrpc diff --git a/library/cpp/grpc/server/grpc_counters.h b/library/cpp/grpc/server/grpc_counters.h index a591beb84e..0b6c36c84c 100644 --- a/library/cpp/grpc/server/grpc_counters.h +++ b/library/cpp/grpc/server/grpc_counters.h @@ -1,10 +1,10 @@ #pragma once -#include <library/cpp/monlib/dynamic_counters/percentile/percentile.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/percentile/percentile.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <util/generic/ptr.h> -namespace NGrpc { +namespace NGrpc { struct ICounterBlock : public TThrRefBase { virtual void CountNotOkRequest() = 0; @@ -14,7 +14,7 @@ struct ICounterBlock : public TThrRefBase { virtual void CountRequestBytes(ui32 requestSize) = 0; virtual void CountResponseBytes(ui32 responseSize) = 0; virtual void StartProcessing(ui32 requestSize) = 0; - virtual void FinishProcessing(ui32 requestSize, ui32 responseSize, bool ok, ui32 status, TDuration requestDuration) = 0; + virtual void FinishProcessing(ui32 requestSize, ui32 responseSize, bool ok, ui32 status, TDuration requestDuration) = 0; virtual void CountRequestsWithoutDatabase() {} virtual void CountRequestsWithoutToken() {} virtual void CountRequestWithoutTls() {} @@ -126,11 +126,11 @@ public: using TCounterBlockPtr = TIntrusivePtr<TCounterBlock>; -/** - * Creates new instance of ICounterBlock implementation which does nothing. - * - * @return new instance - */ -ICounterBlockPtr FakeCounterBlock(); - -} // namespace NGrpc +/** + * Creates new instance of ICounterBlock implementation which does nothing. + * + * @return new instance + */ +ICounterBlockPtr FakeCounterBlock(); + +} // namespace NGrpc diff --git a/library/cpp/grpc/server/grpc_request.cpp b/library/cpp/grpc/server/grpc_request.cpp index 60db2f230d..d18a32776f 100644 --- a/library/cpp/grpc/server/grpc_request.cpp +++ b/library/cpp/grpc/server/grpc_request.cpp @@ -1,10 +1,10 @@ #include "grpc_request.h" -namespace NGrpc { +namespace NGrpc { const char* GRPC_USER_AGENT_HEADER = "user-agent"; -class TStreamAdaptor: public IStreamAdaptor { +class TStreamAdaptor: public IStreamAdaptor { public: TStreamAdaptor() : StreamIsReady_(true) @@ -56,4 +56,4 @@ IStreamAdaptor::TPtr CreateStreamAdaptor() { return std::make_unique<TStreamAdaptor>(); } -} // namespace NGrpc +} // namespace NGrpc diff --git a/library/cpp/grpc/server/grpc_request.h b/library/cpp/grpc/server/grpc_request.h index dd9041eec7..5bd8d3902b 100644 --- a/library/cpp/grpc/server/grpc_request.h +++ b/library/cpp/grpc/server/grpc_request.h @@ -4,19 +4,19 @@ #include <google/protobuf/arena.h> #include <google/protobuf/message.h> -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <library/cpp/logger/priority.h> -#include "grpc_response.h" +#include "grpc_response.h" #include "event_callback.h" -#include "grpc_async_ctx_base.h" -#include "grpc_counters.h" +#include "grpc_async_ctx_base.h" +#include "grpc_counters.h" #include "grpc_request_base.h" #include "grpc_server.h" -#include "logger.h" +#include "logger.h" + +#include <util/system/hp_timer.h> -#include <util/system/hp_timer.h> - #include <grpc++/server.h> #include <grpc++/server_context.h> #include <grpc++/support/async_stream.h> @@ -24,7 +24,7 @@ #include <grpc++/support/byte_buffer.h> #include <grpc++/impl/codegen/async_stream.h> -namespace NGrpc { +namespace NGrpc { class IStreamAdaptor { public: @@ -57,7 +57,7 @@ public: grpc::ServerCompletionQueue* cq, TOnRequest cb, TRequestCallback requestCallback, - const char* name, + const char* name, TLoggerPtr logger, ICounterBlockPtr counters, IGRpcRequestLimiterPtr limiter) @@ -67,10 +67,10 @@ public: , RequestCallback_(requestCallback) , StreamRequestCallback_(nullptr) , Name_(name) - , Logger_(std::move(logger)) + , Logger_(std::move(logger)) , Counters_(std::move(counters)) , RequestLimiter_(std::move(limiter)) - , Writer_(new grpc::ServerAsyncResponseWriter<TUniversalResponseRef<TOut>>(&this->Context)) + , Writer_(new grpc::ServerAsyncResponseWriter<TUniversalResponseRef<TOut>>(&this->Context)) , StateFunc_(&TThis::SetRequestDone) { AuthState_ = Server_->NeedAuth() ? TAuthState(true) : TAuthState(false); @@ -85,7 +85,7 @@ public: grpc::ServerCompletionQueue* cq, TOnRequest cb, TStreamRequestCallback requestCallback, - const char* name, + const char* name, TLoggerPtr logger, ICounterBlockPtr counters, IGRpcRequestLimiterPtr limiter) @@ -95,7 +95,7 @@ public: , RequestCallback_(nullptr) , StreamRequestCallback_(requestCallback) , Name_(name) - , Logger_(std::move(logger)) + , Logger_(std::move(logger)) , Counters_(std::move(counters)) , RequestLimiter_(std::move(limiter)) , StreamWriter_(new grpc::ServerAsyncWriter<TUniversalResponse<TOut>>(&this->Context)) @@ -157,13 +157,13 @@ public: TInstant Deadline() const override { return TBaseAsyncContext<TService>::Deadline(); - } - - TSet<TStringBuf> GetPeerMetaKeys() const override { - return TBaseAsyncContext<TService>::GetPeerMetaKeys(); - } - - TVector<TStringBuf> GetPeerMetaValues(TStringBuf key) const override { + } + + TSet<TStringBuf> GetPeerMetaKeys() const override { + return TBaseAsyncContext<TService>::GetPeerMetaKeys(); + } + + TVector<TStringBuf> GetPeerMetaValues(TStringBuf key) const override { return TBaseAsyncContext<TService>::GetPeerMetaValues(key); } @@ -233,10 +233,10 @@ private: if (!Server_->IsShuttingDown()) { if (RequestCallback_) { MakeIntrusive<TThis>( - Server_, this->Service, this->CQ, Cb_, RequestCallback_, Name_, Logger_, Counters_->Clone(), RequestLimiter_)->Run(); + Server_, this->Service, this->CQ, Cb_, RequestCallback_, Name_, Logger_, Counters_->Clone(), RequestLimiter_)->Run(); } else { MakeIntrusive<TThis>( - Server_, this->Service, this->CQ, Cb_, StreamRequestCallback_, Name_, Logger_, Counters_->Clone(), RequestLimiter_)->Run(); + Server_, this->Service, this->CQ, Cb_, StreamRequestCallback_, Name_, Logger_, Counters_->Clone(), RequestLimiter_)->Run(); } } } @@ -257,20 +257,20 @@ private: StateFunc_ = &TThis::SetFinishDone; ResponseSize = sz; Y_VERIFY(this->Context.c_call()); - Writer_->Finish(TUniversalResponseRef<TOut>(resp), grpc::Status::OK, GetGRpcTag()); + Writer_->Finish(TUniversalResponseRef<TOut>(resp), grpc::Status::OK, GetGRpcTag()); } else { GRPC_LOG_DEBUG(Logger_, "[%p] issuing response Name# %s data# %s peer# %s (enqueued)", this, Name_, makeResponseString().data(), this->Context.peer().c_str()); - - // because of std::function cannot hold move-only captured object - // we allocate shared object on heap to avoid message copy - auto uResp = MakeIntrusive<TUniversalResponse<TOut>>(resp); - auto cb = [this, uResp = std::move(uResp), sz, &makeResponseString]() { + + // because of std::function cannot hold move-only captured object + // we allocate shared object on heap to avoid message copy + auto uResp = MakeIntrusive<TUniversalResponse<TOut>>(resp); + auto cb = [this, uResp = std::move(uResp), sz, &makeResponseString]() { GRPC_LOG_DEBUG(Logger_, "[%p] issuing response Name# %s data# %s peer# %s (pushed to grpc)", this, Name_, makeResponseString().data(), this->Context.peer().c_str()); StateFunc_ = &TThis::NextReply; ResponseSize += sz; - StreamWriter_->Write(*uResp, GetGRpcTag()); + StreamWriter_->Write(*uResp, GetGRpcTag()); }; StreamAdaptor_->Enqueue(std::move(cb), false); } @@ -283,20 +283,20 @@ private: this->Context.peer().c_str()); StateFunc_ = &TThis::SetFinishDone; ResponseSize = sz; - Writer_->Finish(TUniversalResponseRef<TOut>(resp), grpc::Status::OK, GetGRpcTag()); + Writer_->Finish(TUniversalResponseRef<TOut>(resp), grpc::Status::OK, GetGRpcTag()); } else { GRPC_LOG_DEBUG(Logger_, "[%p] issuing response Name# %s data# byteString peer# %s (enqueued)", this, Name_, this->Context.peer().c_str()); - - // because of std::function cannot hold move-only captured object - // we allocate shared object on heap to avoid buffer copy - auto uResp = MakeIntrusive<TUniversalResponse<TOut>>(resp); - auto cb = [this, uResp = std::move(uResp), sz]() { + + // because of std::function cannot hold move-only captured object + // we allocate shared object on heap to avoid buffer copy + auto uResp = MakeIntrusive<TUniversalResponse<TOut>>(resp); + auto cb = [this, uResp = std::move(uResp), sz]() { GRPC_LOG_DEBUG(Logger_, "[%p] issuing response Name# %s data# byteString peer# %s (pushed to grpc)", this, Name_, this->Context.peer().c_str()); StateFunc_ = &TThis::NextReply; ResponseSize += sz; - StreamWriter_->Write(*uResp, GetGRpcTag()); + StreamWriter_->Write(*uResp, GetGRpcTag()); }; StreamAdaptor_->Enqueue(std::move(cb), false); } @@ -314,8 +314,8 @@ private: GRPC_LOG_DEBUG(Logger_, "[%p] issuing response Name# %s nodata (%s) peer# %s, grpc status# (%d)", this, Name_, msg.c_str(), this->Context.peer().c_str(), (int)code); StateFunc_ = &TThis::SetFinishError; - TOut resp; - Writer_->Finish(TUniversalResponseRef<TOut>(&resp), grpc::Status(code, msg), GetGRpcTag()); + TOut resp; + Writer_->Finish(TUniversalResponseRef<TOut>(&resp), grpc::Status(code, msg), GetGRpcTag()); } else { GRPC_LOG_DEBUG(Logger_, "[%p] issuing response Name# %s nodata (%s) peer# %s, grpc status# (%d)" " (enqueued)", this, Name_, msg.c_str(), this->Context.peer().c_str(), (int)code); @@ -380,7 +380,7 @@ private: } auto maybeToken = GetPeerMetaValues(TStringBuf("x-ydb-auth-ticket")); if (maybeToken.empty() || maybeToken[0].empty()) { - TString db{maybeDatabase ? maybeDatabase[0] : TStringBuf{}}; + TString db{maybeDatabase ? maybeDatabase[0] : TStringBuf{}}; Counters_->CountRequestsWithoutToken(); GRPC_LOG_DEBUG(Logger_, "[%p] received request without user token " "Name# %s data# %s peer# %s database# %s", this, Name_, @@ -484,12 +484,12 @@ private: TOnRequest Cb_; TRequestCallback RequestCallback_; TStreamRequestCallback StreamRequestCallback_; - const char* const Name_; + const char* const Name_; TLoggerPtr Logger_; ICounterBlockPtr Counters_; IGRpcRequestLimiterPtr RequestLimiter_; - THolder<grpc::ServerAsyncResponseWriter<TUniversalResponseRef<TOut>>> Writer_; + THolder<grpc::ServerAsyncResponseWriter<TUniversalResponseRef<TOut>>> Writer_; THolder<grpc::ServerAsyncWriterInterface<TUniversalResponse<TOut>>> StreamWriter_; TStateFunc StateFunc_; TIn* Request_; @@ -520,10 +520,10 @@ public: typename TBase::TOnRequest cb, typename TBase::TRequestCallback requestCallback, const char* name, - TLoggerPtr logger, + TLoggerPtr logger, ICounterBlockPtr counters, IGRpcRequestLimiterPtr limiter = nullptr) - : TBase{server, service, cq, std::move(cb), std::move(requestCallback), name, std::move(logger), std::move(counters), std::move(limiter)} + : TBase{server, service, cq, std::move(cb), std::move(requestCallback), name, std::move(logger), std::move(counters), std::move(limiter)} { } @@ -533,11 +533,11 @@ public: typename TBase::TOnRequest cb, typename TBase::TStreamRequestCallback requestCallback, const char* name, - TLoggerPtr logger, + TLoggerPtr logger, ICounterBlockPtr counters) - : TBase{server, service, cq, std::move(cb), std::move(requestCallback), name, std::move(logger), std::move(counters), nullptr} + : TBase{server, service, cq, std::move(cb), std::move(requestCallback), name, std::move(logger), std::move(counters), nullptr} { } }; -} // namespace NGrpc +} // namespace NGrpc diff --git a/library/cpp/grpc/server/grpc_request_base.h b/library/cpp/grpc/server/grpc_request_base.h index b61cf553aa..fcfce1c181 100644 --- a/library/cpp/grpc/server/grpc_request_base.h +++ b/library/cpp/grpc/server/grpc_request_base.h @@ -9,7 +9,7 @@ namespace grpc { class ByteBuffer; } -namespace NGrpc { +namespace NGrpc { extern const char* GRPC_USER_AGENT_HEADER; @@ -30,7 +30,7 @@ struct TAuthState { //! An interface that may be used to limit concurrency of requests -class IGRpcRequestLimiter: public TThrRefBase { +class IGRpcRequestLimiter: public TThrRefBase { public: virtual bool IncRequest() = 0; virtual void DecRequest() = 0; @@ -39,7 +39,7 @@ public: using IGRpcRequestLimiterPtr = TIntrusivePtr<IGRpcRequestLimiter>; //! State of current request -class IRequestContextBase: public TThrRefBase { +class IRequestContextBase: public TThrRefBase { public: enum class EFinishStatus { OK, @@ -72,12 +72,12 @@ public: //! Returns deadline (server epoch related) if peer set it on its side, or Instanse::Max() otherwise virtual TInstant Deadline() const = 0; - - //! Returns available peer metadata keys - virtual TSet<TStringBuf> GetPeerMetaKeys() const = 0; - + + //! Returns available peer metadata keys + virtual TSet<TStringBuf> GetPeerMetaKeys() const = 0; + //! Returns peer optional metavalue - virtual TVector<TStringBuf> GetPeerMetaValues(TStringBuf key) const = 0; + virtual TVector<TStringBuf> GetPeerMetaValues(TStringBuf key) const = 0; //! Returns request compression level virtual grpc_compression_level GetCompressionLevel() const = 0; @@ -113,4 +113,4 @@ public: virtual bool SslServer() const = 0; }; -} // namespace NGrpc +} // namespace NGrpc diff --git a/library/cpp/grpc/server/grpc_response.h b/library/cpp/grpc/server/grpc_response.h index 47b22c28d0..8e9afe44d5 100644 --- a/library/cpp/grpc/server/grpc_response.h +++ b/library/cpp/grpc/server/grpc_response.h @@ -1,90 +1,90 @@ -#pragma once - -#include <grpc++/impl/codegen/byte_buffer.h> -#include <grpc++/impl/codegen/proto_utils.h> - -#include <variant> - -namespace NGrpc { - -/** - * Universal response that owns underlying message or buffer. - */ -template <typename TMsg> +#pragma once + +#include <grpc++/impl/codegen/byte_buffer.h> +#include <grpc++/impl/codegen/proto_utils.h> + +#include <variant> + +namespace NGrpc { + +/** + * Universal response that owns underlying message or buffer. + */ +template <typename TMsg> class TUniversalResponse: public TAtomicRefCount<TUniversalResponse<TMsg>>, public TMoveOnly { - friend class grpc::SerializationTraits<TUniversalResponse<TMsg>>; - -public: - explicit TUniversalResponse(NProtoBuf::Message* msg) noexcept - : Data_{TMsg{}} - { - std::get<TMsg>(Data_).Swap(static_cast<TMsg*>(msg)); - } - - explicit TUniversalResponse(grpc::ByteBuffer* buffer) noexcept - : Data_{grpc::ByteBuffer{}} - { - std::get<grpc::ByteBuffer>(Data_).Swap(buffer); - } - -private: - std::variant<TMsg, grpc::ByteBuffer> Data_; -}; - -/** - * Universal response that only keeps reference to underlying message or buffer. - */ -template <typename TMsg> -class TUniversalResponseRef: private TMoveOnly { - friend class grpc::SerializationTraits<TUniversalResponseRef<TMsg>>; - -public: - explicit TUniversalResponseRef(const NProtoBuf::Message* msg) - : Data_{msg} - { - } - - explicit TUniversalResponseRef(const grpc::ByteBuffer* buffer) - : Data_{buffer} - { - } - -private: - std::variant<const NProtoBuf::Message*, const grpc::ByteBuffer*> Data_; -}; - -} // namespace NGrpc - -namespace grpc { - -template <typename TMsg> -class SerializationTraits<NGrpc::TUniversalResponse<TMsg>> { -public: - static Status Serialize( - const NGrpc::TUniversalResponse<TMsg>& resp, - ByteBuffer* buffer, - bool* ownBuffer) - { - return std::visit([&](const auto& data) { - using T = std::decay_t<decltype(data)>; - return SerializationTraits<T>::Serialize(data, buffer, ownBuffer); - }, resp.Data_); - } -}; - -template <typename TMsg> -class SerializationTraits<NGrpc::TUniversalResponseRef<TMsg>> { -public: - static Status Serialize( - const NGrpc::TUniversalResponseRef<TMsg>& resp, - ByteBuffer* buffer, - bool* ownBuffer) - { - return std::visit([&](const auto* data) { - using T = std::decay_t<std::remove_pointer_t<decltype(data)>>; - return SerializationTraits<T>::Serialize(*data, buffer, ownBuffer); - }, resp.Data_); - } -}; - -} // namespace grpc + friend class grpc::SerializationTraits<TUniversalResponse<TMsg>>; + +public: + explicit TUniversalResponse(NProtoBuf::Message* msg) noexcept + : Data_{TMsg{}} + { + std::get<TMsg>(Data_).Swap(static_cast<TMsg*>(msg)); + } + + explicit TUniversalResponse(grpc::ByteBuffer* buffer) noexcept + : Data_{grpc::ByteBuffer{}} + { + std::get<grpc::ByteBuffer>(Data_).Swap(buffer); + } + +private: + std::variant<TMsg, grpc::ByteBuffer> Data_; +}; + +/** + * Universal response that only keeps reference to underlying message or buffer. + */ +template <typename TMsg> +class TUniversalResponseRef: private TMoveOnly { + friend class grpc::SerializationTraits<TUniversalResponseRef<TMsg>>; + +public: + explicit TUniversalResponseRef(const NProtoBuf::Message* msg) + : Data_{msg} + { + } + + explicit TUniversalResponseRef(const grpc::ByteBuffer* buffer) + : Data_{buffer} + { + } + +private: + std::variant<const NProtoBuf::Message*, const grpc::ByteBuffer*> Data_; +}; + +} // namespace NGrpc + +namespace grpc { + +template <typename TMsg> +class SerializationTraits<NGrpc::TUniversalResponse<TMsg>> { +public: + static Status Serialize( + const NGrpc::TUniversalResponse<TMsg>& resp, + ByteBuffer* buffer, + bool* ownBuffer) + { + return std::visit([&](const auto& data) { + using T = std::decay_t<decltype(data)>; + return SerializationTraits<T>::Serialize(data, buffer, ownBuffer); + }, resp.Data_); + } +}; + +template <typename TMsg> +class SerializationTraits<NGrpc::TUniversalResponseRef<TMsg>> { +public: + static Status Serialize( + const NGrpc::TUniversalResponseRef<TMsg>& resp, + ByteBuffer* buffer, + bool* ownBuffer) + { + return std::visit([&](const auto* data) { + using T = std::decay_t<std::remove_pointer_t<decltype(data)>>; + return SerializationTraits<T>::Serialize(*data, buffer, ownBuffer); + }, resp.Data_); + } +}; + +} // namespace grpc diff --git a/library/cpp/grpc/server/grpc_server.cpp b/library/cpp/grpc/server/grpc_server.cpp index 4f4c7412fc..7437b7a8f5 100644 --- a/library/cpp/grpc/server/grpc_server.cpp +++ b/library/cpp/grpc/server/grpc_server.cpp @@ -15,7 +15,7 @@ #endif -namespace NGrpc { +namespace NGrpc { using NThreading::TFuture; @@ -82,7 +82,7 @@ void TGRpcServer::Start() { service->SetGlobalLimiterHandle(&Limiter_); } - class TKeepAliveOption: public grpc::ServerBuilderOption { + class TKeepAliveOption: public grpc::ServerBuilderOption { public: TKeepAliveOption(int idle, int interval) : Idle(idle) @@ -153,7 +153,7 @@ void TGRpcServer::Start() { size_t index = 0; for (IGRpcServicePtr service : Services_) { // TODO: provide something else for services instead of ServerCompletionQueue - service->InitService(CQS_[index++ % CQS_.size()].get(), Options_.Logger); + service->InitService(CQS_[index++ % CQS_.size()].get(), Options_.Logger); } if (Options_.UseCompletionQueuePerThread) { @@ -237,4 +237,4 @@ TString TGRpcServer::GetHost() const { return Options_.Host; } -} // namespace NGrpc +} // namespace NGrpc diff --git a/library/cpp/grpc/server/grpc_server.h b/library/cpp/grpc/server/grpc_server.h index 24c8caa78d..d6814a90a0 100644 --- a/library/cpp/grpc/server/grpc_server.h +++ b/library/cpp/grpc/server/grpc_server.h @@ -1,7 +1,7 @@ #pragma once #include "grpc_request_base.h" -#include "logger.h" +#include "logger.h" #include <library/cpp/threading/future/future.h> @@ -17,7 +17,7 @@ #include <grpc++/grpc++.h> -namespace NGrpc { +namespace NGrpc { constexpr ui64 DEFAULT_GRPC_MESSAGE_SIZE_LIMIT = 64000000; @@ -95,9 +95,9 @@ struct TServerOptions { DECLARE_FIELD(ExternalListener, IExternalListener::TPtr, nullptr); - //! Logger which will be used to write logs about requests handling (iff appropriate log level is enabled). - DECLARE_FIELD(Logger, TLoggerPtr, nullptr); - + //! Logger which will be used to write logs about requests handling (iff appropriate log level is enabled). + DECLARE_FIELD(Logger, TLoggerPtr, nullptr); + #undef DECLARE_FIELD }; @@ -161,11 +161,11 @@ private: using TGlobalLimiter = TInFlightLimiterImpl<i64>; -class IGRpcService: public TThrRefBase { +class IGRpcService: public TThrRefBase { public: virtual grpc::Service* GetService() = 0; virtual void StopService() noexcept = 0; - virtual void InitService(grpc::ServerCompletionQueue* cq, TLoggerPtr logger) = 0; + virtual void InitService(grpc::ServerCompletionQueue* cq, TLoggerPtr logger) = 0; virtual void SetGlobalLimiterHandle(TGlobalLimiter* limiter) = 0; virtual bool IsUnsafeToShutdown() const = 0; virtual size_t RequestsInProgress() const = 0; @@ -178,7 +178,7 @@ public: }; template<typename T> -class TGrpcServiceBase: public IGRpcService { +class TGrpcServiceBase: public IGRpcService { public: class TShutdownGuard { using TOwner = TGrpcServiceBase<T>; @@ -353,4 +353,4 @@ private: TGlobalLimiter Limiter_; }; -} // namespace NGrpc +} // namespace NGrpc diff --git a/library/cpp/grpc/server/logger.h b/library/cpp/grpc/server/logger.h index 5e44d83d67..53af26be9c 100644 --- a/library/cpp/grpc/server/logger.h +++ b/library/cpp/grpc/server/logger.h @@ -1,43 +1,43 @@ -#pragma once - -#include <library/cpp/logger/priority.h> - -#include <util/generic/ptr.h> - -namespace NGrpc { - -class TLogger: public TThrRefBase { -protected: - TLogger() = default; - -public: - [[nodiscard]] - bool IsEnabled(ELogPriority priority) const noexcept { - return DoIsEnabled(priority); - } - - void Y_PRINTF_FORMAT(3, 4) Write(ELogPriority priority, const char* format, ...) noexcept { - va_list args; - va_start(args, format); - DoWrite(priority, format, args); - va_end(args); - } - -protected: - virtual bool DoIsEnabled(ELogPriority priority) const noexcept = 0; - virtual void DoWrite(ELogPriority p, const char* format, va_list args) noexcept = 0; -}; - -using TLoggerPtr = TIntrusivePtr<TLogger>; - -#define GRPC_LOG_DEBUG(logger, format, ...) \ - if (logger && logger->IsEnabled(ELogPriority::TLOG_DEBUG)) { \ - logger->Write(ELogPriority::TLOG_DEBUG, format, __VA_ARGS__); \ - } else { } - -#define GRPC_LOG_INFO(logger, format, ...) \ - if (logger && logger->IsEnabled(ELogPriority::TLOG_INFO)) { \ - logger->Write(ELogPriority::TLOG_INFO, format, __VA_ARGS__); \ - } else { } - -} // namespace NGrpc +#pragma once + +#include <library/cpp/logger/priority.h> + +#include <util/generic/ptr.h> + +namespace NGrpc { + +class TLogger: public TThrRefBase { +protected: + TLogger() = default; + +public: + [[nodiscard]] + bool IsEnabled(ELogPriority priority) const noexcept { + return DoIsEnabled(priority); + } + + void Y_PRINTF_FORMAT(3, 4) Write(ELogPriority priority, const char* format, ...) noexcept { + va_list args; + va_start(args, format); + DoWrite(priority, format, args); + va_end(args); + } + +protected: + virtual bool DoIsEnabled(ELogPriority priority) const noexcept = 0; + virtual void DoWrite(ELogPriority p, const char* format, va_list args) noexcept = 0; +}; + +using TLoggerPtr = TIntrusivePtr<TLogger>; + +#define GRPC_LOG_DEBUG(logger, format, ...) \ + if (logger && logger->IsEnabled(ELogPriority::TLOG_DEBUG)) { \ + logger->Write(ELogPriority::TLOG_DEBUG, format, __VA_ARGS__); \ + } else { } + +#define GRPC_LOG_INFO(logger, format, ...) \ + if (logger && logger->IsEnabled(ELogPriority::TLOG_INFO)) { \ + logger->Write(ELogPriority::TLOG_INFO, format, __VA_ARGS__); \ + } else { } + +} // namespace NGrpc diff --git a/library/cpp/grpc/server/ut/grpc_response_ut.cpp b/library/cpp/grpc/server/ut/grpc_response_ut.cpp index cb66478e94..8abc4e4e0e 100644 --- a/library/cpp/grpc/server/ut/grpc_response_ut.cpp +++ b/library/cpp/grpc/server/ut/grpc_response_ut.cpp @@ -1,88 +1,88 @@ -#include <library/cpp/grpc/server/grpc_response.h> -#include <library/cpp/testing/unittest/registar.h> - -#include <google/protobuf/duration.pb.h> -#include <grpc++/impl/codegen/proto_utils.h> -#include <grpc++/impl/grpc_library.h> - -static ::grpc::internal::GrpcLibraryInitializer grpcInitializer; - -using namespace NGrpc; - -using google::protobuf::Duration; - -Y_UNIT_TEST_SUITE(ResponseTest) { - - template <typename T> - grpc::ByteBuffer Serialize(T resp) { - grpc::ByteBuffer buf; - bool ownBuf = false; - grpc::Status status = grpc::SerializationTraits<T>::Serialize(resp, &buf, &ownBuf); - UNIT_ASSERT(status.ok()); - return buf; - } - - template <typename T> - T Deserialize(grpc::ByteBuffer* buf) { - T message; - auto status = grpc::SerializationTraits<T>::Deserialize(buf, &message); - UNIT_ASSERT(status.ok()); - return message; - } - - Y_UNIT_TEST(UniversalResponseMsg) { - Duration d1; - d1.set_seconds(12345); - d1.set_nanos(67890); - - auto buf = Serialize(TUniversalResponse<Duration>(&d1)); - Duration d2 = Deserialize<Duration>(&buf); - - UNIT_ASSERT_VALUES_EQUAL(d2.seconds(), 12345); - UNIT_ASSERT_VALUES_EQUAL(d2.nanos(), 67890); - } - - Y_UNIT_TEST(UniversalResponseBuf) { - Duration d1; - d1.set_seconds(123); - d1.set_nanos(456); - - TString data = d1.SerializeAsString(); - grpc::Slice dataSlice{data.data(), data.size()}; - grpc::ByteBuffer dataBuf{&dataSlice, 1}; - - auto buf = Serialize(TUniversalResponse<Duration>(&dataBuf)); - Duration d2 = Deserialize<Duration>(&buf); - - UNIT_ASSERT_VALUES_EQUAL(d2.seconds(), 123); - UNIT_ASSERT_VALUES_EQUAL(d2.nanos(), 456); - } - - Y_UNIT_TEST(UniversalResponseRefMsg) { - Duration d1; - d1.set_seconds(12345); - d1.set_nanos(67890); - - auto buf = Serialize(TUniversalResponseRef<Duration>(&d1)); - Duration d2 = Deserialize<Duration>(&buf); - - UNIT_ASSERT_VALUES_EQUAL(d2.seconds(), 12345); - UNIT_ASSERT_VALUES_EQUAL(d2.nanos(), 67890); - } - - Y_UNIT_TEST(UniversalResponseRefBuf) { - Duration d1; - d1.set_seconds(123); - d1.set_nanos(456); - - TString data = d1.SerializeAsString(); - grpc::Slice dataSlice{data.data(), data.size()}; - grpc::ByteBuffer dataBuf{&dataSlice, 1}; - - auto buf = Serialize(TUniversalResponseRef<Duration>(&dataBuf)); - Duration d2 = Deserialize<Duration>(&buf); - - UNIT_ASSERT_VALUES_EQUAL(d2.seconds(), 123); - UNIT_ASSERT_VALUES_EQUAL(d2.nanos(), 456); - } -} +#include <library/cpp/grpc/server/grpc_response.h> +#include <library/cpp/testing/unittest/registar.h> + +#include <google/protobuf/duration.pb.h> +#include <grpc++/impl/codegen/proto_utils.h> +#include <grpc++/impl/grpc_library.h> + +static ::grpc::internal::GrpcLibraryInitializer grpcInitializer; + +using namespace NGrpc; + +using google::protobuf::Duration; + +Y_UNIT_TEST_SUITE(ResponseTest) { + + template <typename T> + grpc::ByteBuffer Serialize(T resp) { + grpc::ByteBuffer buf; + bool ownBuf = false; + grpc::Status status = grpc::SerializationTraits<T>::Serialize(resp, &buf, &ownBuf); + UNIT_ASSERT(status.ok()); + return buf; + } + + template <typename T> + T Deserialize(grpc::ByteBuffer* buf) { + T message; + auto status = grpc::SerializationTraits<T>::Deserialize(buf, &message); + UNIT_ASSERT(status.ok()); + return message; + } + + Y_UNIT_TEST(UniversalResponseMsg) { + Duration d1; + d1.set_seconds(12345); + d1.set_nanos(67890); + + auto buf = Serialize(TUniversalResponse<Duration>(&d1)); + Duration d2 = Deserialize<Duration>(&buf); + + UNIT_ASSERT_VALUES_EQUAL(d2.seconds(), 12345); + UNIT_ASSERT_VALUES_EQUAL(d2.nanos(), 67890); + } + + Y_UNIT_TEST(UniversalResponseBuf) { + Duration d1; + d1.set_seconds(123); + d1.set_nanos(456); + + TString data = d1.SerializeAsString(); + grpc::Slice dataSlice{data.data(), data.size()}; + grpc::ByteBuffer dataBuf{&dataSlice, 1}; + + auto buf = Serialize(TUniversalResponse<Duration>(&dataBuf)); + Duration d2 = Deserialize<Duration>(&buf); + + UNIT_ASSERT_VALUES_EQUAL(d2.seconds(), 123); + UNIT_ASSERT_VALUES_EQUAL(d2.nanos(), 456); + } + + Y_UNIT_TEST(UniversalResponseRefMsg) { + Duration d1; + d1.set_seconds(12345); + d1.set_nanos(67890); + + auto buf = Serialize(TUniversalResponseRef<Duration>(&d1)); + Duration d2 = Deserialize<Duration>(&buf); + + UNIT_ASSERT_VALUES_EQUAL(d2.seconds(), 12345); + UNIT_ASSERT_VALUES_EQUAL(d2.nanos(), 67890); + } + + Y_UNIT_TEST(UniversalResponseRefBuf) { + Duration d1; + d1.set_seconds(123); + d1.set_nanos(456); + + TString data = d1.SerializeAsString(); + grpc::Slice dataSlice{data.data(), data.size()}; + grpc::ByteBuffer dataBuf{&dataSlice, 1}; + + auto buf = Serialize(TUniversalResponseRef<Duration>(&dataBuf)); + Duration d2 = Deserialize<Duration>(&buf); + + UNIT_ASSERT_VALUES_EQUAL(d2.seconds(), 123); + UNIT_ASSERT_VALUES_EQUAL(d2.nanos(), 456); + } +} diff --git a/library/cpp/grpc/server/ut/stream_adaptor_ut.cpp b/library/cpp/grpc/server/ut/stream_adaptor_ut.cpp index 3457e98bf1..c34d3b8c2b 100644 --- a/library/cpp/grpc/server/ut/stream_adaptor_ut.cpp +++ b/library/cpp/grpc/server/ut/stream_adaptor_ut.cpp @@ -1,14 +1,14 @@ -#include <library/cpp/grpc/server/grpc_request.h> +#include <library/cpp/grpc/server/grpc_request.h> #include <library/cpp/testing/unittest/registar.h> #include <library/cpp/testing/unittest/tests_data.h> #include <util/system/thread.h> #include <util/thread/pool.h> -using namespace NGrpc; +using namespace NGrpc; // Here we emulate stream data producer -class TOrderedProducer: public TThread { +class TOrderedProducer: public TThread { public: TOrderedProducer(IStreamAdaptor* adaptor, ui64 max, bool withSleep, std::function<void(ui64)>&& consumerOp) : TThread(&ThreadProc, this) diff --git a/library/cpp/grpc/server/ut/ya.make b/library/cpp/grpc/server/ut/ya.make index ff6c8fdb7b..feb3291af9 100644 --- a/library/cpp/grpc/server/ut/ya.make +++ b/library/cpp/grpc/server/ut/ya.make @@ -1,19 +1,19 @@ -UNITTEST_FOR(library/cpp/grpc/server) +UNITTEST_FOR(library/cpp/grpc/server) OWNER( dcherednik g:kikimr ) -TIMEOUT(600) -SIZE(MEDIUM) +TIMEOUT(600) +SIZE(MEDIUM) PEERDIR( - library/cpp/grpc/server + library/cpp/grpc/server ) SRCS( - grpc_response_ut.cpp + grpc_response_ut.cpp stream_adaptor_ut.cpp ) diff --git a/library/cpp/grpc/server/ya.make b/library/cpp/grpc/server/ya.make index b0f262e5dc..356a1b6793 100644 --- a/library/cpp/grpc/server/ya.make +++ b/library/cpp/grpc/server/ya.make @@ -16,10 +16,10 @@ GENERATE_ENUM_SERIALIZATION(grpc_request_base.h) PEERDIR( contrib/libs/grpc - library/cpp/monlib/dynamic_counters/percentile + library/cpp/monlib/dynamic_counters/percentile ) END() - -RECURSE_FOR_TESTS(ut) - + +RECURSE_FOR_TESTS(ut) + diff --git a/library/cpp/grpc/ya.make b/library/cpp/grpc/ya.make index 7d96e067d1..3635124115 100644 --- a/library/cpp/grpc/ya.make +++ b/library/cpp/grpc/ya.make @@ -1,5 +1,5 @@ RECURSE( client - common - server + common + server ) diff --git a/library/cpp/histogram/hdr/histogram.cpp b/library/cpp/histogram/hdr/histogram.cpp index 4e799ce61f..a213d5d8fd 100644 --- a/library/cpp/histogram/hdr/histogram.cpp +++ b/library/cpp/histogram/hdr/histogram.cpp @@ -1,155 +1,155 @@ -#include "histogram.h" - +#include "histogram.h" + #include <util/generic/cast.h> -#include <util/generic/yexception.h> - -#include <contrib/libs/hdr_histogram/src/hdr_histogram.h> - -namespace NHdr { - namespace { - struct hdr_histogram* CreateHistogram( - i64 lowestDiscernibleValue, i64 highestTrackableValue, - i32 numberOfSignificantValueDigits, IAllocator* allocator) { - struct hdr_histogram_bucket_config cfg; - - int r = hdr_calculate_bucket_config( - lowestDiscernibleValue, highestTrackableValue, - numberOfSignificantValueDigits, &cfg); - if (r) { - ythrow yexception() << "illegal arguments values"; - } - - size_t histogramSize = sizeof(struct hdr_histogram) + - cfg.counts_len * sizeof(i64); - - IAllocator::TBlock mem = allocator->Allocate(histogramSize); - struct hdr_histogram* histogram = +#include <util/generic/yexception.h> + +#include <contrib/libs/hdr_histogram/src/hdr_histogram.h> + +namespace NHdr { + namespace { + struct hdr_histogram* CreateHistogram( + i64 lowestDiscernibleValue, i64 highestTrackableValue, + i32 numberOfSignificantValueDigits, IAllocator* allocator) { + struct hdr_histogram_bucket_config cfg; + + int r = hdr_calculate_bucket_config( + lowestDiscernibleValue, highestTrackableValue, + numberOfSignificantValueDigits, &cfg); + if (r) { + ythrow yexception() << "illegal arguments values"; + } + + size_t histogramSize = sizeof(struct hdr_histogram) + + cfg.counts_len * sizeof(i64); + + IAllocator::TBlock mem = allocator->Allocate(histogramSize); + struct hdr_histogram* histogram = reinterpret_cast<struct hdr_histogram*>(mem.Data); - - // memset will ensure that all of the function pointers are null - memset(histogram, 0, histogramSize); - - hdr_init_preallocated(histogram, &cfg); - return histogram; - } - - } - - THistogram::THistogram(i64 lowestDiscernibleValue, i64 highestTrackableValue, - i32 numberOfSignificantValueDigits, IAllocator* allocator) - : Data_(CreateHistogram( - lowestDiscernibleValue, highestTrackableValue, - numberOfSignificantValueDigits, allocator)) - , Allocator_(allocator) - { - } - - THistogram::~THistogram() { - if (Data_) { - size_t size = GetMemorySize(); - Allocator_->Release({Data_.Release(), size}); - } - } - - // Histogram structure querying support ----------------------------------- - - i64 THistogram::GetLowestDiscernibleValue() const { - return Data_->lowest_trackable_value; - } - - i64 THistogram::GetHighestTrackableValue() const { - return Data_->highest_trackable_value; - } - - i32 THistogram::GetNumberOfSignificantValueDigits() const { - return Data_->significant_figures; - } - - size_t THistogram::GetMemorySize() const { - return hdr_get_memory_size(Data_.Get()); - } - - i32 THistogram::GetCountsLen() const { - return Data_->counts_len; - } - - i64 THistogram::GetTotalCount() const { - return Data_->total_count; - } - - // Value recording support ------------------------------------------------ - - bool THistogram::RecordValue(i64 value) { - return hdr_record_value(Data_.Get(), value); - } - - bool THistogram::RecordValues(i64 value, i64 count) { - return hdr_record_values(Data_.Get(), value, count); - } - - bool THistogram::RecordValueWithExpectedInterval(i64 value, i64 expectedInterval) { - return hdr_record_corrected_value(Data_.Get(), value, expectedInterval); - } - - bool THistogram::RecordValuesWithExpectedInterval( - i64 value, i64 count, i64 expectedInterval) { - return hdr_record_corrected_values( - Data_.Get(), value, count, expectedInterval); - } - - i64 THistogram::Add(const THistogram& rhs) { - return hdr_add(Data_.Get(), rhs.Data_.Get()); - } - - i64 THistogram::AddWithExpectedInterval(const THistogram& rhs, i64 expectedInterval) { - return hdr_add_while_correcting_for_coordinated_omission( - Data_.Get(), rhs.Data_.Get(), expectedInterval); - } - - // Histogram Data access support ------------------------------------------ - - i64 THistogram::GetMin() const { - return hdr_min(Data_.Get()); - } - - i64 THistogram::GetMax() const { - return hdr_max(Data_.Get()); - } - - double THistogram::GetMean() const { - return hdr_mean(Data_.Get()); - } - - double THistogram::GetStdDeviation() const { - return hdr_stddev(Data_.Get()); - } - - i64 THistogram::GetValueAtPercentile(double percentile) const { - return hdr_value_at_percentile(Data_.Get(), percentile); - } - - i64 THistogram::GetCountAtValue(i64 value) const { - return hdr_count_at_value(Data_.Get(), value); - } - - bool THistogram::ValuesAreEqual(i64 v1, i64 v2) const { - return hdr_values_are_equivalent(Data_.Get(), v1, v2); - } - - i64 THistogram::GetLowestEquivalentValue(i64 value) const { - return hdr_lowest_equivalent_value(Data_.Get(), value); - } - - i64 THistogram::GetHighestEquivalentValue(i64 value) const { - return hdr_next_non_equivalent_value(Data_.Get(), value) - 1; - } - - i64 THistogram::GetMedianEquivalentValue(i64 value) const { - return hdr_median_equivalent_value(Data_.Get(), value); - } - - void THistogram::Reset() { - hdr_reset(Data_.Get()); - } - -} + + // memset will ensure that all of the function pointers are null + memset(histogram, 0, histogramSize); + + hdr_init_preallocated(histogram, &cfg); + return histogram; + } + + } + + THistogram::THistogram(i64 lowestDiscernibleValue, i64 highestTrackableValue, + i32 numberOfSignificantValueDigits, IAllocator* allocator) + : Data_(CreateHistogram( + lowestDiscernibleValue, highestTrackableValue, + numberOfSignificantValueDigits, allocator)) + , Allocator_(allocator) + { + } + + THistogram::~THistogram() { + if (Data_) { + size_t size = GetMemorySize(); + Allocator_->Release({Data_.Release(), size}); + } + } + + // Histogram structure querying support ----------------------------------- + + i64 THistogram::GetLowestDiscernibleValue() const { + return Data_->lowest_trackable_value; + } + + i64 THistogram::GetHighestTrackableValue() const { + return Data_->highest_trackable_value; + } + + i32 THistogram::GetNumberOfSignificantValueDigits() const { + return Data_->significant_figures; + } + + size_t THistogram::GetMemorySize() const { + return hdr_get_memory_size(Data_.Get()); + } + + i32 THistogram::GetCountsLen() const { + return Data_->counts_len; + } + + i64 THistogram::GetTotalCount() const { + return Data_->total_count; + } + + // Value recording support ------------------------------------------------ + + bool THistogram::RecordValue(i64 value) { + return hdr_record_value(Data_.Get(), value); + } + + bool THistogram::RecordValues(i64 value, i64 count) { + return hdr_record_values(Data_.Get(), value, count); + } + + bool THistogram::RecordValueWithExpectedInterval(i64 value, i64 expectedInterval) { + return hdr_record_corrected_value(Data_.Get(), value, expectedInterval); + } + + bool THistogram::RecordValuesWithExpectedInterval( + i64 value, i64 count, i64 expectedInterval) { + return hdr_record_corrected_values( + Data_.Get(), value, count, expectedInterval); + } + + i64 THistogram::Add(const THistogram& rhs) { + return hdr_add(Data_.Get(), rhs.Data_.Get()); + } + + i64 THistogram::AddWithExpectedInterval(const THistogram& rhs, i64 expectedInterval) { + return hdr_add_while_correcting_for_coordinated_omission( + Data_.Get(), rhs.Data_.Get(), expectedInterval); + } + + // Histogram Data access support ------------------------------------------ + + i64 THistogram::GetMin() const { + return hdr_min(Data_.Get()); + } + + i64 THistogram::GetMax() const { + return hdr_max(Data_.Get()); + } + + double THistogram::GetMean() const { + return hdr_mean(Data_.Get()); + } + + double THistogram::GetStdDeviation() const { + return hdr_stddev(Data_.Get()); + } + + i64 THistogram::GetValueAtPercentile(double percentile) const { + return hdr_value_at_percentile(Data_.Get(), percentile); + } + + i64 THistogram::GetCountAtValue(i64 value) const { + return hdr_count_at_value(Data_.Get(), value); + } + + bool THistogram::ValuesAreEqual(i64 v1, i64 v2) const { + return hdr_values_are_equivalent(Data_.Get(), v1, v2); + } + + i64 THistogram::GetLowestEquivalentValue(i64 value) const { + return hdr_lowest_equivalent_value(Data_.Get(), value); + } + + i64 THistogram::GetHighestEquivalentValue(i64 value) const { + return hdr_next_non_equivalent_value(Data_.Get(), value) - 1; + } + + i64 THistogram::GetMedianEquivalentValue(i64 value) const { + return hdr_median_equivalent_value(Data_.Get(), value); + } + + void THistogram::Reset() { + hdr_reset(Data_.Get()); + } + +} diff --git a/library/cpp/histogram/hdr/histogram.h b/library/cpp/histogram/hdr/histogram.h index b1b27b4c4f..5f1cebbd9f 100644 --- a/library/cpp/histogram/hdr/histogram.h +++ b/library/cpp/histogram/hdr/histogram.h @@ -1,303 +1,303 @@ -#pragma once - -#include <util/generic/ptr.h> -#include <util/generic/noncopyable.h> -#include <util/memory/alloc.h> - -struct hdr_histogram; - -namespace NHdr { - /** - * A High Dynamic Range (HDR) Histogram - * - * THdrHistogram supports the recording and analyzing sampled data value counts - * across a configurable integer value range with configurable value precision - * within the range. Value precision is expressed as the number of significant - * digits in the value recording, and provides control over value quantization - * behavior across the value range and the subsequent value resolution at any - * given level. - */ - class THistogram: public TMoveOnly { - public: - /** - * Construct a histogram given the Highest value to be tracked and a number - * of significant decimal digits. The histogram will be constructed to - * implicitly track (distinguish from 0) values as low as 1. Default - * allocator will be used to allocate underlying memory. - * - * @param highestTrackableValue The highest value to be tracked by the - * histogram. Must be a positive integer that is literal >= 2. - * - * @param numberOfSignificantValueDigits Specifies the precision to use. - * This is the number of significant decimal digits to which the - * histogram will maintain value resolution and separation. Must be - * a non-negative integer between 0 and 5. - */ - THistogram(i64 highestTrackableValue, i32 numberOfSignificantValueDigits) - : THistogram(1, highestTrackableValue, numberOfSignificantValueDigits) - { - } - - /** - * Construct a histogram given the Lowest and Highest values to be tracked - * and a number of significant decimal digits. Providing a - * lowestDiscernibleValue is useful in situations where the units used for - * the histogram's values are much smaller that the minimal accuracy - * required. E.g. when tracking time values stated in nanosecond units, - * where the minimal accuracy required is a microsecond, the proper value - * for lowestDiscernibleValue would be 1000. - * - * @param lowestDiscernibleValue The lowest value that can be discerned - * (distinguished from 0) by the histogram. Must be a positive - * integer that is >= 1. May be internally rounded down to nearest - * power of 2. - * - * @param highestTrackableValue The highest value to be tracked by the - * histogram. Must be a positive integer that is - * >= (2 * lowestDiscernibleValue). - * - * @param numberOfSignificantValueDigits Specifies the precision to use. - * This is the number of significant decimal digits to which the - * histogram will maintain value resolution and separation. Must be - * a non-negative integer between 0 and 5. - * - * @param allocator Specifies allocator which will be used to allocate - * memory for histogram. - */ - THistogram(i64 lowestDiscernibleValue, i64 highestTrackableValue, - i32 numberOfSignificantValueDigits, - IAllocator* allocator = TDefaultAllocator::Instance()); - - ~THistogram(); - - // Histogram structure querying support ----------------------------------- - - /** - * @return The configured lowestDiscernibleValue - */ - i64 GetLowestDiscernibleValue() const; - - /** - * @return The configured highestTrackableValue - */ - i64 GetHighestTrackableValue() const; - - /** - * @return The configured numberOfSignificantValueDigits - */ - i32 GetNumberOfSignificantValueDigits() const; - - /** - * @return The size of allocated memory for histogram - */ - size_t GetMemorySize() const; - - /** - * @return The number of created counters - */ - i32 GetCountsLen() const; - - /** - * @return The total count of all recorded values in the histogram - */ - i64 GetTotalCount() const; - - // Value recording support ------------------------------------------------ - - /** - * Records a value in the histogram, will round this value of to a - * precision at or better than the NumberOfSignificantValueDigits specified - * at construction time. - * - * @param value Value to add to the histogram - * @return false if the value is larger than the HighestTrackableValue - * and can't be recorded, true otherwise. - */ - bool RecordValue(i64 value); - - /** - * Records count values in the histogram, will round this value of to a - * precision at or better than the NumberOfSignificantValueDigits specified - * at construction time. - * - * @param value Value to add to the histogram - * @param count Number of values to add to the histogram - * @return false if the value is larger than the HighestTrackableValue - * and can't be recorded, true otherwise. - */ - bool RecordValues(i64 value, i64 count); - - /** - * Records a value in the histogram and backfill based on an expected - * interval. Value will be rounded this to a precision at or better - * than the NumberOfSignificantValueDigits specified at contruction time. - * This is specifically used for recording latency. If the value is larger - * than the expectedInterval then the latency recording system has - * experienced co-ordinated omission. This method fills in the values that - * would have occured had the client providing the load not been blocked. - * - * @param value Value to add to the histogram - * @param expectedInterval The delay between recording values - * @return false if the value is larger than the HighestTrackableValue - * and can't be recorded, true otherwise. - */ - bool RecordValueWithExpectedInterval(i64 value, i64 expectedInterval); - - /** - * Record a value in the histogram count times. Applies the same correcting - * logic as {@link THistogram::RecordValueWithExpectedInterval}. - * - * @param value Value to add to the histogram - * @param count Number of values to add to the histogram - * @param expectedInterval The delay between recording values. - * @return false if the value is larger than the HighestTrackableValue - * and can't be recorded, true otherwise. - */ - bool RecordValuesWithExpectedInterval( - i64 value, i64 count, i64 expectedInterval); - - /** - * Adds all of the values from rhs to this histogram. Will return the - * number of values that are dropped when copying. Values will be dropped - * if they around outside of [LowestDiscernibleValue, GetHighestTrackableValue]. - * - * @param rhs Histogram to copy values from. - * @return The number of values dropped when copying. - */ - i64 Add(const THistogram& rhs); - - /** - * Adds all of the values from rhs to this histogram. Will return the - * number of values that are dropped when copying. Values will be dropped - * if they around outside of [LowestDiscernibleValue, GetHighestTrackableValue]. - * Applies the same correcting logic as - * {@link THistogram::RecordValueWithExpectedInterval}. - * - * @param rhs Histogram to copy values from. - * @return The number of values dropped when copying. - */ - i64 AddWithExpectedInterval(const THistogram& rhs, i64 expectedInterval); - - // Histogram Data access support ------------------------------------------ - - /** - * Get the lowest recorded value level in the histogram. If the histogram - * has no recorded values, the value returned is undefined. - * - * @return the Min value recorded in the histogram - */ - i64 GetMin() const; - - /** - * Get the highest recorded value level in the histogram. If the histogram - * has no recorded values, the value returned is undefined. - * - * @return the Max value recorded in the histogram - */ - i64 GetMax() const; - - /** - * Get the computed mean value of all recorded values in the histogram - * - * @return the mean value (in value units) of the histogram data - */ - double GetMean() const; - - /** - * Get the computed standard deviation of all recorded values in the histogram - * - * @return the standard deviation (in value units) of the histogram data - */ - double GetStdDeviation() const; - - /** - * Get the value at a given percentile. - * Note that two values are "equivalent" in this statement if - * {@link THistogram::ValuesAreEquivalent} would return true. - * - * @param percentile The percentile for which to return the associated - * value - * @return The value that the given percentage of the overall recorded - * value entries in the histogram are either smaller than or - * equivalent to. When the percentile is 0.0, returns the value - * that all value entries in the histogram are either larger than - * or equivalent to. - */ - i64 GetValueAtPercentile(double percentile) const; - - /** - * Get the count of recorded values at a specific value (to within the - * histogram resolution at the value level). - * - * @param value The value for which to provide the recorded count - * @return The total count of values recorded in the histogram within the - * value range that is >= GetLowestEquivalentValue(value) and - * <= GetHighestEquivalentValue(value) - */ - i64 GetCountAtValue(i64 value) const; - - /** - * Determine if two values are equivalent with the histogram's resolution. - * Where "equivalent" means that value samples recorded for any two - * equivalent values are counted in a common total count. - * - * @param v1 first value to compare - * @param v2 second value to compare - * @return True if values are equivalent with the histogram's resolution. - */ - bool ValuesAreEqual(i64 v1, i64 v2) const; - - /** - * Get the lowest value that is equivalent to the given value within the - * histogram's resolution. Where "equivalent" means that value samples - * recorded for any two equivalent values are counted in a common total - * count. - * - * @param value The given value - * @return The lowest value that is equivalent to the given value within - * the histogram's resolution. - */ - i64 GetLowestEquivalentValue(i64 value) const; - - /** - * Get the highest value that is equivalent to the given value within the - * histogram's resolution. Where "equivalent" means that value samples - * recorded for any two equivalent values are counted in a common total - * count. - * - * @param value The given value - * @return The highest value that is equivalent to the given value within - * the histogram's resolution. - */ - i64 GetHighestEquivalentValue(i64 value) const; - - /** - * Get a value that lies in the middle (rounded up) of the range of values - * equivalent the given value. Where "equivalent" means that value samples - * recorded for any two equivalent values are counted in a common total - * count. - * - * @param value The given value - * @return The value lies in the middle (rounded up) of the range of values - * equivalent the given value. - */ - i64 GetMedianEquivalentValue(i64 value) const; - - // misc functions --------------------------------------------------------- - - /** - * Reset a histogram to zero - empty out a histogram and re-initialise it. - * If you want to re-use an existing histogram, but reset everything back - * to zero, this is the routine to use. - */ - void Reset(); - - const hdr_histogram* GetHdrHistogramImpl() const { - return Data_.Get(); - } - - private: - THolder<hdr_histogram> Data_; - IAllocator* Allocator_; - }; -} +#pragma once + +#include <util/generic/ptr.h> +#include <util/generic/noncopyable.h> +#include <util/memory/alloc.h> + +struct hdr_histogram; + +namespace NHdr { + /** + * A High Dynamic Range (HDR) Histogram + * + * THdrHistogram supports the recording and analyzing sampled data value counts + * across a configurable integer value range with configurable value precision + * within the range. Value precision is expressed as the number of significant + * digits in the value recording, and provides control over value quantization + * behavior across the value range and the subsequent value resolution at any + * given level. + */ + class THistogram: public TMoveOnly { + public: + /** + * Construct a histogram given the Highest value to be tracked and a number + * of significant decimal digits. The histogram will be constructed to + * implicitly track (distinguish from 0) values as low as 1. Default + * allocator will be used to allocate underlying memory. + * + * @param highestTrackableValue The highest value to be tracked by the + * histogram. Must be a positive integer that is literal >= 2. + * + * @param numberOfSignificantValueDigits Specifies the precision to use. + * This is the number of significant decimal digits to which the + * histogram will maintain value resolution and separation. Must be + * a non-negative integer between 0 and 5. + */ + THistogram(i64 highestTrackableValue, i32 numberOfSignificantValueDigits) + : THistogram(1, highestTrackableValue, numberOfSignificantValueDigits) + { + } + + /** + * Construct a histogram given the Lowest and Highest values to be tracked + * and a number of significant decimal digits. Providing a + * lowestDiscernibleValue is useful in situations where the units used for + * the histogram's values are much smaller that the minimal accuracy + * required. E.g. when tracking time values stated in nanosecond units, + * where the minimal accuracy required is a microsecond, the proper value + * for lowestDiscernibleValue would be 1000. + * + * @param lowestDiscernibleValue The lowest value that can be discerned + * (distinguished from 0) by the histogram. Must be a positive + * integer that is >= 1. May be internally rounded down to nearest + * power of 2. + * + * @param highestTrackableValue The highest value to be tracked by the + * histogram. Must be a positive integer that is + * >= (2 * lowestDiscernibleValue). + * + * @param numberOfSignificantValueDigits Specifies the precision to use. + * This is the number of significant decimal digits to which the + * histogram will maintain value resolution and separation. Must be + * a non-negative integer between 0 and 5. + * + * @param allocator Specifies allocator which will be used to allocate + * memory for histogram. + */ + THistogram(i64 lowestDiscernibleValue, i64 highestTrackableValue, + i32 numberOfSignificantValueDigits, + IAllocator* allocator = TDefaultAllocator::Instance()); + + ~THistogram(); + + // Histogram structure querying support ----------------------------------- + + /** + * @return The configured lowestDiscernibleValue + */ + i64 GetLowestDiscernibleValue() const; + + /** + * @return The configured highestTrackableValue + */ + i64 GetHighestTrackableValue() const; + + /** + * @return The configured numberOfSignificantValueDigits + */ + i32 GetNumberOfSignificantValueDigits() const; + + /** + * @return The size of allocated memory for histogram + */ + size_t GetMemorySize() const; + + /** + * @return The number of created counters + */ + i32 GetCountsLen() const; + + /** + * @return The total count of all recorded values in the histogram + */ + i64 GetTotalCount() const; + + // Value recording support ------------------------------------------------ + + /** + * Records a value in the histogram, will round this value of to a + * precision at or better than the NumberOfSignificantValueDigits specified + * at construction time. + * + * @param value Value to add to the histogram + * @return false if the value is larger than the HighestTrackableValue + * and can't be recorded, true otherwise. + */ + bool RecordValue(i64 value); + + /** + * Records count values in the histogram, will round this value of to a + * precision at or better than the NumberOfSignificantValueDigits specified + * at construction time. + * + * @param value Value to add to the histogram + * @param count Number of values to add to the histogram + * @return false if the value is larger than the HighestTrackableValue + * and can't be recorded, true otherwise. + */ + bool RecordValues(i64 value, i64 count); + + /** + * Records a value in the histogram and backfill based on an expected + * interval. Value will be rounded this to a precision at or better + * than the NumberOfSignificantValueDigits specified at contruction time. + * This is specifically used for recording latency. If the value is larger + * than the expectedInterval then the latency recording system has + * experienced co-ordinated omission. This method fills in the values that + * would have occured had the client providing the load not been blocked. + * + * @param value Value to add to the histogram + * @param expectedInterval The delay between recording values + * @return false if the value is larger than the HighestTrackableValue + * and can't be recorded, true otherwise. + */ + bool RecordValueWithExpectedInterval(i64 value, i64 expectedInterval); + + /** + * Record a value in the histogram count times. Applies the same correcting + * logic as {@link THistogram::RecordValueWithExpectedInterval}. + * + * @param value Value to add to the histogram + * @param count Number of values to add to the histogram + * @param expectedInterval The delay between recording values. + * @return false if the value is larger than the HighestTrackableValue + * and can't be recorded, true otherwise. + */ + bool RecordValuesWithExpectedInterval( + i64 value, i64 count, i64 expectedInterval); + + /** + * Adds all of the values from rhs to this histogram. Will return the + * number of values that are dropped when copying. Values will be dropped + * if they around outside of [LowestDiscernibleValue, GetHighestTrackableValue]. + * + * @param rhs Histogram to copy values from. + * @return The number of values dropped when copying. + */ + i64 Add(const THistogram& rhs); + + /** + * Adds all of the values from rhs to this histogram. Will return the + * number of values that are dropped when copying. Values will be dropped + * if they around outside of [LowestDiscernibleValue, GetHighestTrackableValue]. + * Applies the same correcting logic as + * {@link THistogram::RecordValueWithExpectedInterval}. + * + * @param rhs Histogram to copy values from. + * @return The number of values dropped when copying. + */ + i64 AddWithExpectedInterval(const THistogram& rhs, i64 expectedInterval); + + // Histogram Data access support ------------------------------------------ + + /** + * Get the lowest recorded value level in the histogram. If the histogram + * has no recorded values, the value returned is undefined. + * + * @return the Min value recorded in the histogram + */ + i64 GetMin() const; + + /** + * Get the highest recorded value level in the histogram. If the histogram + * has no recorded values, the value returned is undefined. + * + * @return the Max value recorded in the histogram + */ + i64 GetMax() const; + + /** + * Get the computed mean value of all recorded values in the histogram + * + * @return the mean value (in value units) of the histogram data + */ + double GetMean() const; + + /** + * Get the computed standard deviation of all recorded values in the histogram + * + * @return the standard deviation (in value units) of the histogram data + */ + double GetStdDeviation() const; + + /** + * Get the value at a given percentile. + * Note that two values are "equivalent" in this statement if + * {@link THistogram::ValuesAreEquivalent} would return true. + * + * @param percentile The percentile for which to return the associated + * value + * @return The value that the given percentage of the overall recorded + * value entries in the histogram are either smaller than or + * equivalent to. When the percentile is 0.0, returns the value + * that all value entries in the histogram are either larger than + * or equivalent to. + */ + i64 GetValueAtPercentile(double percentile) const; + + /** + * Get the count of recorded values at a specific value (to within the + * histogram resolution at the value level). + * + * @param value The value for which to provide the recorded count + * @return The total count of values recorded in the histogram within the + * value range that is >= GetLowestEquivalentValue(value) and + * <= GetHighestEquivalentValue(value) + */ + i64 GetCountAtValue(i64 value) const; + + /** + * Determine if two values are equivalent with the histogram's resolution. + * Where "equivalent" means that value samples recorded for any two + * equivalent values are counted in a common total count. + * + * @param v1 first value to compare + * @param v2 second value to compare + * @return True if values are equivalent with the histogram's resolution. + */ + bool ValuesAreEqual(i64 v1, i64 v2) const; + + /** + * Get the lowest value that is equivalent to the given value within the + * histogram's resolution. Where "equivalent" means that value samples + * recorded for any two equivalent values are counted in a common total + * count. + * + * @param value The given value + * @return The lowest value that is equivalent to the given value within + * the histogram's resolution. + */ + i64 GetLowestEquivalentValue(i64 value) const; + + /** + * Get the highest value that is equivalent to the given value within the + * histogram's resolution. Where "equivalent" means that value samples + * recorded for any two equivalent values are counted in a common total + * count. + * + * @param value The given value + * @return The highest value that is equivalent to the given value within + * the histogram's resolution. + */ + i64 GetHighestEquivalentValue(i64 value) const; + + /** + * Get a value that lies in the middle (rounded up) of the range of values + * equivalent the given value. Where "equivalent" means that value samples + * recorded for any two equivalent values are counted in a common total + * count. + * + * @param value The given value + * @return The value lies in the middle (rounded up) of the range of values + * equivalent the given value. + */ + i64 GetMedianEquivalentValue(i64 value) const; + + // misc functions --------------------------------------------------------- + + /** + * Reset a histogram to zero - empty out a histogram and re-initialise it. + * If you want to re-use an existing histogram, but reset everything back + * to zero, this is the routine to use. + */ + void Reset(); + + const hdr_histogram* GetHdrHistogramImpl() const { + return Data_.Get(); + } + + private: + THolder<hdr_histogram> Data_; + IAllocator* Allocator_; + }; +} diff --git a/library/cpp/histogram/hdr/histogram_iter.cpp b/library/cpp/histogram/hdr/histogram_iter.cpp index 4975348e22..d251fd5dd9 100644 --- a/library/cpp/histogram/hdr/histogram_iter.cpp +++ b/library/cpp/histogram/hdr/histogram_iter.cpp @@ -1,146 +1,146 @@ -#include "histogram_iter.h" - -#include <contrib/libs/hdr_histogram/src/hdr_histogram.h> - -namespace NHdr { - // TBaseHistogramIterator ----------------------------------------------------- - TBaseHistogramIterator::TBaseHistogramIterator() - : Iter_(new hdr_iter) - { - } - - TBaseHistogramIterator::~TBaseHistogramIterator() { - } - - bool TBaseHistogramIterator::Next() { - return hdr_iter_next(Iter_.Get()); - } - - i32 TBaseHistogramIterator::GetCountsIndex() const { - return Iter_->counts_index; - } - - i32 TBaseHistogramIterator::GetTotalCount() const { - return Iter_->total_count; - } - - i64 TBaseHistogramIterator::GetCount() const { - return Iter_->count; - } - - i64 TBaseHistogramIterator::GetCumulativeCount() const { - return Iter_->cumulative_count; - } - - i64 TBaseHistogramIterator::GetValue() const { - return Iter_->value; - } - - i64 TBaseHistogramIterator::GetHighestEquivalentValue() const { - return Iter_->highest_equivalent_value; - } - - i64 TBaseHistogramIterator::GetLowestEquivalentValue() const { - return Iter_->lowest_equivalent_value; - } - - i64 TBaseHistogramIterator::GetMedianEquivalentValue() const { - return Iter_->median_equivalent_value; - } - - i64 TBaseHistogramIterator::GetValueIteratedFrom() const { - return Iter_->value_iterated_from; - } - - i64 TBaseHistogramIterator::GetValueIteratedTo() const { - return Iter_->value_iterated_to; - } - - // TAllValuesIterator --------------------------------------------------------- - - TAllValuesIterator::TAllValuesIterator(const THistogram& histogram) { - hdr_iter_init(Iter_.Get(), histogram.GetHdrHistogramImpl()); - } - - // TRecordedValuesIterator ---------------------------------------------------- - - TRecordedValuesIterator::TRecordedValuesIterator(const THistogram& histogram) { - hdr_iter_recorded_init(Iter_.Get(), histogram.GetHdrHistogramImpl()); - } - - i64 TRecordedValuesIterator::GetCountAddedInThisIterationStep() const { - return Iter_->specifics.recorded.count_added_in_this_iteration_step; - } - - // TPercentileIterator -------------------------------------------------------- - - TPercentileIterator::TPercentileIterator( - const THistogram& histogram, ui32 ticksPerHalfDistance) { - hdr_iter_percentile_init( - Iter_.Get(), histogram.GetHdrHistogramImpl(), - ticksPerHalfDistance); - } - - i32 TPercentileIterator::GetTicketsPerHalfDistance() const { - return Iter_->specifics.percentiles.ticks_per_half_distance; - } - - double TPercentileIterator::GetPercentileToIterateTo() const { - return Iter_->specifics.percentiles.percentile_to_iterate_to; - } - - double TPercentileIterator::GetPercentile() const { - return Iter_->specifics.percentiles.percentile; - } - - // TLinearIterator ------------------------------------------------------------ - - TLinearIterator::TLinearIterator( - const THistogram& histogram, i64 valueUnitsPerBucket) { - hdr_iter_linear_init( - Iter_.Get(), histogram.GetHdrHistogramImpl(), valueUnitsPerBucket); - } - - i64 TLinearIterator::GetValueUnitsPerBucket() const { - return Iter_->specifics.linear.value_units_per_bucket; - } - - i64 TLinearIterator::GetCountAddedInThisIterationStep() const { - return Iter_->specifics.linear.count_added_in_this_iteration_step; - } - - i64 TLinearIterator::GetNextValueReportingLevel() const { - return Iter_->specifics.linear.next_value_reporting_level; - } - - i64 TLinearIterator::GetNextValueReportingLevelLowestEquivalent() const { - return Iter_->specifics.linear.next_value_reporting_level_lowest_equivalent; - } - - // TLogarithmicIterator ------------------------------------------------------- - - TLogarithmicIterator::TLogarithmicIterator( - const THistogram& histogram, i64 valueUnitsInFirstBucket, - double logBase) { - hdr_iter_log_init( - Iter_.Get(), histogram.GetHdrHistogramImpl(), - valueUnitsInFirstBucket, logBase); - } - - double TLogarithmicIterator::GetLogBase() const { - return Iter_->specifics.log.log_base; - } - - i64 TLogarithmicIterator::GetCountAddedInThisIterationStep() const { - return Iter_->specifics.log.count_added_in_this_iteration_step; - } - - i64 TLogarithmicIterator::GetNextValueReportingLevel() const { - return Iter_->specifics.log.next_value_reporting_level; - } - - i64 TLogarithmicIterator::GetNextValueReportingLevelLowestEquivalent() const { - return Iter_->specifics.log.next_value_reporting_level_lowest_equivalent; - } - -} +#include "histogram_iter.h" + +#include <contrib/libs/hdr_histogram/src/hdr_histogram.h> + +namespace NHdr { + // TBaseHistogramIterator ----------------------------------------------------- + TBaseHistogramIterator::TBaseHistogramIterator() + : Iter_(new hdr_iter) + { + } + + TBaseHistogramIterator::~TBaseHistogramIterator() { + } + + bool TBaseHistogramIterator::Next() { + return hdr_iter_next(Iter_.Get()); + } + + i32 TBaseHistogramIterator::GetCountsIndex() const { + return Iter_->counts_index; + } + + i32 TBaseHistogramIterator::GetTotalCount() const { + return Iter_->total_count; + } + + i64 TBaseHistogramIterator::GetCount() const { + return Iter_->count; + } + + i64 TBaseHistogramIterator::GetCumulativeCount() const { + return Iter_->cumulative_count; + } + + i64 TBaseHistogramIterator::GetValue() const { + return Iter_->value; + } + + i64 TBaseHistogramIterator::GetHighestEquivalentValue() const { + return Iter_->highest_equivalent_value; + } + + i64 TBaseHistogramIterator::GetLowestEquivalentValue() const { + return Iter_->lowest_equivalent_value; + } + + i64 TBaseHistogramIterator::GetMedianEquivalentValue() const { + return Iter_->median_equivalent_value; + } + + i64 TBaseHistogramIterator::GetValueIteratedFrom() const { + return Iter_->value_iterated_from; + } + + i64 TBaseHistogramIterator::GetValueIteratedTo() const { + return Iter_->value_iterated_to; + } + + // TAllValuesIterator --------------------------------------------------------- + + TAllValuesIterator::TAllValuesIterator(const THistogram& histogram) { + hdr_iter_init(Iter_.Get(), histogram.GetHdrHistogramImpl()); + } + + // TRecordedValuesIterator ---------------------------------------------------- + + TRecordedValuesIterator::TRecordedValuesIterator(const THistogram& histogram) { + hdr_iter_recorded_init(Iter_.Get(), histogram.GetHdrHistogramImpl()); + } + + i64 TRecordedValuesIterator::GetCountAddedInThisIterationStep() const { + return Iter_->specifics.recorded.count_added_in_this_iteration_step; + } + + // TPercentileIterator -------------------------------------------------------- + + TPercentileIterator::TPercentileIterator( + const THistogram& histogram, ui32 ticksPerHalfDistance) { + hdr_iter_percentile_init( + Iter_.Get(), histogram.GetHdrHistogramImpl(), + ticksPerHalfDistance); + } + + i32 TPercentileIterator::GetTicketsPerHalfDistance() const { + return Iter_->specifics.percentiles.ticks_per_half_distance; + } + + double TPercentileIterator::GetPercentileToIterateTo() const { + return Iter_->specifics.percentiles.percentile_to_iterate_to; + } + + double TPercentileIterator::GetPercentile() const { + return Iter_->specifics.percentiles.percentile; + } + + // TLinearIterator ------------------------------------------------------------ + + TLinearIterator::TLinearIterator( + const THistogram& histogram, i64 valueUnitsPerBucket) { + hdr_iter_linear_init( + Iter_.Get(), histogram.GetHdrHistogramImpl(), valueUnitsPerBucket); + } + + i64 TLinearIterator::GetValueUnitsPerBucket() const { + return Iter_->specifics.linear.value_units_per_bucket; + } + + i64 TLinearIterator::GetCountAddedInThisIterationStep() const { + return Iter_->specifics.linear.count_added_in_this_iteration_step; + } + + i64 TLinearIterator::GetNextValueReportingLevel() const { + return Iter_->specifics.linear.next_value_reporting_level; + } + + i64 TLinearIterator::GetNextValueReportingLevelLowestEquivalent() const { + return Iter_->specifics.linear.next_value_reporting_level_lowest_equivalent; + } + + // TLogarithmicIterator ------------------------------------------------------- + + TLogarithmicIterator::TLogarithmicIterator( + const THistogram& histogram, i64 valueUnitsInFirstBucket, + double logBase) { + hdr_iter_log_init( + Iter_.Get(), histogram.GetHdrHistogramImpl(), + valueUnitsInFirstBucket, logBase); + } + + double TLogarithmicIterator::GetLogBase() const { + return Iter_->specifics.log.log_base; + } + + i64 TLogarithmicIterator::GetCountAddedInThisIterationStep() const { + return Iter_->specifics.log.count_added_in_this_iteration_step; + } + + i64 TLogarithmicIterator::GetNextValueReportingLevel() const { + return Iter_->specifics.log.next_value_reporting_level; + } + + i64 TLogarithmicIterator::GetNextValueReportingLevelLowestEquivalent() const { + return Iter_->specifics.log.next_value_reporting_level_lowest_equivalent; + } + +} diff --git a/library/cpp/histogram/hdr/histogram_iter.h b/library/cpp/histogram/hdr/histogram_iter.h index 05aa869e81..adfc1616e3 100644 --- a/library/cpp/histogram/hdr/histogram_iter.h +++ b/library/cpp/histogram/hdr/histogram_iter.h @@ -1,231 +1,231 @@ -#pragma once - -#include "histogram.h" - -struct hdr_iter; - -namespace NHdr { - /** - * Used for iterating through histogram values. - */ - class TBaseHistogramIterator { - public: - /** - * Iterate to the next value for the iterator. If there are no more values - * available return false. - * - * @return 'false' if there are no values remaining for this iterator. - */ - bool Next(); - - /** - * @return Raw index into the counts array. - */ - i32 GetCountsIndex() const; - - /** - * @return Snapshot of the length at the time the iterator is created. - */ - i32 GetTotalCount() const; - - /** - * @return Value directly from array for the current countsIndex. - */ - i64 GetCount() const; - - /** - * @return Sum of all of the counts up to and including the count at - * this index. - */ - i64 GetCumulativeCount() const; - - /** - * @return The current value based on countsIndex. - */ - i64 GetValue() const; - - /** - * @return The highest value that is equivalent to the current value - * within the histogram's resolution. - */ - i64 GetHighestEquivalentValue() const; - - /** - * @return The lowest value that is equivalent to the current value - * within the histogram's resolution. - */ - i64 GetLowestEquivalentValue() const; - - /** - * @return The value lies in the middle (rounded up) of the range of - * values equivalent the current value. - */ - i64 GetMedianEquivalentValue() const; - - /** - * @return The actual value level that was iterated from by the iterator. - */ - i64 GetValueIteratedFrom() const; - - /** - * @return The actual value level that was iterated to by the iterator. - */ - i64 GetValueIteratedTo() const; - - protected: - // must not be instantiated directly - TBaseHistogramIterator(); - ~TBaseHistogramIterator(); - - protected: - THolder<hdr_iter> Iter_; - }; - - /** - * Used for iterating through histogram values using the finest granularity - * steps supported by the underlying representation. The iteration steps - * through all possible unit value levels, regardless of whether or not there - * were recorded values for that value level, and terminates when all recorded - * histogram values are exhausted. - */ - class TAllValuesIterator: public TBaseHistogramIterator { - public: - /** - * @param histogram The histogram this iterator will operate on - */ - explicit TAllValuesIterator(const THistogram& histogram); - }; - - /** - * Used for iterating through all recorded histogram values using the finest - * granularity steps supported by the underlying representation. The iteration - * steps through all non-zero recorded value counts, and terminates when all - * recorded histogram values are exhausted. - */ - class TRecordedValuesIterator: public TBaseHistogramIterator { - public: - /** - * @param histogram The histogram this iterator will operate on - */ - explicit TRecordedValuesIterator(const THistogram& histogram); - - /** - * @return The count of recorded values in the histogram that were added - * to the totalCount as a result on this iteration step. Since - * multiple iteration steps may occur with overlapping equivalent - * value ranges, the count may be lower than the count found at - * the value (e.g. multiple linear steps or percentile levels can - * occur within a single equivalent value range). - */ - i64 GetCountAddedInThisIterationStep() const; - }; - - /** - * Used for iterating through histogram values according to percentile levels. - * The iteration is performed in steps that start at 0% and reduce their - * distance to 100% according to the <i>percentileTicksPerHalfDistance</i> - * parameter, ultimately reaching 100% when all recorded histogram - * values are exhausted. - */ - class TPercentileIterator: public TBaseHistogramIterator { - public: - /** - * @param histogram The histogram this iterator will operate on - * @param ticksPerHalfDistance The number of equal-sized iteration steps - * per half-distance to 100%. - */ - TPercentileIterator(const THistogram& histogram, ui32 ticksPerHalfDistance); - - /** - * @return The number of equal-sized iteration steps per half-distance - * to 100%. - */ - i32 GetTicketsPerHalfDistance() const; - - double GetPercentileToIterateTo() const; - - /** - * @return The percentile of recorded values in the histogram at values - * equal or smaller than valueIteratedTo. - * - */ - double GetPercentile() const; - }; - - /** - * Used for iterating through histogram values in linear steps. The iteration - * is performed in steps of <i>valueUnitsPerBucket</i> in size, terminating - * when all recorded histogram values are exhausted. Note that each iteration - * "bucket" includes values up to and including the next bucket boundary value. - */ - class TLinearIterator: public TBaseHistogramIterator { - public: - /** - * @param histogram The histogram this iterator will operate on - * @param valueUnitsPerBucket The size (in value units) of each bucket - * iteration. - */ - TLinearIterator(const THistogram& histogram, i64 valueUnitsPerBucket); - - /** - * @return The size (in value units) of each bucket iteration. - */ - i64 GetValueUnitsPerBucket() const; - - /** - * @return The count of recorded values in the histogram that were added - * to the totalCount as a result on this iteration step. Since - * multiple iteration steps may occur with overlapping equivalent - * value ranges, the count may be lower than the count found at - * the value (e.g. multiple linear steps or percentile levels can - * occur within a single equivalent value range). - */ - i64 GetCountAddedInThisIterationStep() const; - - i64 GetNextValueReportingLevel() const; - - i64 GetNextValueReportingLevelLowestEquivalent() const; - }; - - /** - * Used for iterating through histogram values in logarithmically increasing - * levels. The iteration is performed in steps that start at - * <i>valueUnitsInFirstBucket</i> and increase exponentially according to - * <i>logBase</i>, terminating when all recorded histogram values are - * exhausted. Note that each iteration "bucket" includes values up to and - * including the next bucket boundary value. - */ - class TLogarithmicIterator: public TBaseHistogramIterator { - public: - /** - * @param histogram The histogram this iterator will operate on - * @param valueUnitsInFirstBucket the size (in value units) of the first - * value bucket step - * @param logBase the multiplier by which the bucket size is expanded in - * each iteration step. - */ - TLogarithmicIterator( - const THistogram& histogram, i64 valueUnitsInFirstBucket, - double logBase); - - /** - * @return The multiplier by which the bucket size is expanded in each - * iteration step. - */ - double GetLogBase() const; - - /** - * @return The count of recorded values in the histogram that were added - * to the totalCount as a result on this iteration step. Since - * multiple iteration steps may occur with overlapping equivalent - * value ranges, the count may be lower than the count found at - * the value (e.g. multiple linear steps or percentile levels can - * occur within a single equivalent value range). - */ - i64 GetCountAddedInThisIterationStep() const; - - i64 GetNextValueReportingLevel() const; - - i64 GetNextValueReportingLevelLowestEquivalent() const; - }; -} +#pragma once + +#include "histogram.h" + +struct hdr_iter; + +namespace NHdr { + /** + * Used for iterating through histogram values. + */ + class TBaseHistogramIterator { + public: + /** + * Iterate to the next value for the iterator. If there are no more values + * available return false. + * + * @return 'false' if there are no values remaining for this iterator. + */ + bool Next(); + + /** + * @return Raw index into the counts array. + */ + i32 GetCountsIndex() const; + + /** + * @return Snapshot of the length at the time the iterator is created. + */ + i32 GetTotalCount() const; + + /** + * @return Value directly from array for the current countsIndex. + */ + i64 GetCount() const; + + /** + * @return Sum of all of the counts up to and including the count at + * this index. + */ + i64 GetCumulativeCount() const; + + /** + * @return The current value based on countsIndex. + */ + i64 GetValue() const; + + /** + * @return The highest value that is equivalent to the current value + * within the histogram's resolution. + */ + i64 GetHighestEquivalentValue() const; + + /** + * @return The lowest value that is equivalent to the current value + * within the histogram's resolution. + */ + i64 GetLowestEquivalentValue() const; + + /** + * @return The value lies in the middle (rounded up) of the range of + * values equivalent the current value. + */ + i64 GetMedianEquivalentValue() const; + + /** + * @return The actual value level that was iterated from by the iterator. + */ + i64 GetValueIteratedFrom() const; + + /** + * @return The actual value level that was iterated to by the iterator. + */ + i64 GetValueIteratedTo() const; + + protected: + // must not be instantiated directly + TBaseHistogramIterator(); + ~TBaseHistogramIterator(); + + protected: + THolder<hdr_iter> Iter_; + }; + + /** + * Used for iterating through histogram values using the finest granularity + * steps supported by the underlying representation. The iteration steps + * through all possible unit value levels, regardless of whether or not there + * were recorded values for that value level, and terminates when all recorded + * histogram values are exhausted. + */ + class TAllValuesIterator: public TBaseHistogramIterator { + public: + /** + * @param histogram The histogram this iterator will operate on + */ + explicit TAllValuesIterator(const THistogram& histogram); + }; + + /** + * Used for iterating through all recorded histogram values using the finest + * granularity steps supported by the underlying representation. The iteration + * steps through all non-zero recorded value counts, and terminates when all + * recorded histogram values are exhausted. + */ + class TRecordedValuesIterator: public TBaseHistogramIterator { + public: + /** + * @param histogram The histogram this iterator will operate on + */ + explicit TRecordedValuesIterator(const THistogram& histogram); + + /** + * @return The count of recorded values in the histogram that were added + * to the totalCount as a result on this iteration step. Since + * multiple iteration steps may occur with overlapping equivalent + * value ranges, the count may be lower than the count found at + * the value (e.g. multiple linear steps or percentile levels can + * occur within a single equivalent value range). + */ + i64 GetCountAddedInThisIterationStep() const; + }; + + /** + * Used for iterating through histogram values according to percentile levels. + * The iteration is performed in steps that start at 0% and reduce their + * distance to 100% according to the <i>percentileTicksPerHalfDistance</i> + * parameter, ultimately reaching 100% when all recorded histogram + * values are exhausted. + */ + class TPercentileIterator: public TBaseHistogramIterator { + public: + /** + * @param histogram The histogram this iterator will operate on + * @param ticksPerHalfDistance The number of equal-sized iteration steps + * per half-distance to 100%. + */ + TPercentileIterator(const THistogram& histogram, ui32 ticksPerHalfDistance); + + /** + * @return The number of equal-sized iteration steps per half-distance + * to 100%. + */ + i32 GetTicketsPerHalfDistance() const; + + double GetPercentileToIterateTo() const; + + /** + * @return The percentile of recorded values in the histogram at values + * equal or smaller than valueIteratedTo. + * + */ + double GetPercentile() const; + }; + + /** + * Used for iterating through histogram values in linear steps. The iteration + * is performed in steps of <i>valueUnitsPerBucket</i> in size, terminating + * when all recorded histogram values are exhausted. Note that each iteration + * "bucket" includes values up to and including the next bucket boundary value. + */ + class TLinearIterator: public TBaseHistogramIterator { + public: + /** + * @param histogram The histogram this iterator will operate on + * @param valueUnitsPerBucket The size (in value units) of each bucket + * iteration. + */ + TLinearIterator(const THistogram& histogram, i64 valueUnitsPerBucket); + + /** + * @return The size (in value units) of each bucket iteration. + */ + i64 GetValueUnitsPerBucket() const; + + /** + * @return The count of recorded values in the histogram that were added + * to the totalCount as a result on this iteration step. Since + * multiple iteration steps may occur with overlapping equivalent + * value ranges, the count may be lower than the count found at + * the value (e.g. multiple linear steps or percentile levels can + * occur within a single equivalent value range). + */ + i64 GetCountAddedInThisIterationStep() const; + + i64 GetNextValueReportingLevel() const; + + i64 GetNextValueReportingLevelLowestEquivalent() const; + }; + + /** + * Used for iterating through histogram values in logarithmically increasing + * levels. The iteration is performed in steps that start at + * <i>valueUnitsInFirstBucket</i> and increase exponentially according to + * <i>logBase</i>, terminating when all recorded histogram values are + * exhausted. Note that each iteration "bucket" includes values up to and + * including the next bucket boundary value. + */ + class TLogarithmicIterator: public TBaseHistogramIterator { + public: + /** + * @param histogram The histogram this iterator will operate on + * @param valueUnitsInFirstBucket the size (in value units) of the first + * value bucket step + * @param logBase the multiplier by which the bucket size is expanded in + * each iteration step. + */ + TLogarithmicIterator( + const THistogram& histogram, i64 valueUnitsInFirstBucket, + double logBase); + + /** + * @return The multiplier by which the bucket size is expanded in each + * iteration step. + */ + double GetLogBase() const; + + /** + * @return The count of recorded values in the histogram that were added + * to the totalCount as a result on this iteration step. Since + * multiple iteration steps may occur with overlapping equivalent + * value ranges, the count may be lower than the count found at + * the value (e.g. multiple linear steps or percentile levels can + * occur within a single equivalent value range). + */ + i64 GetCountAddedInThisIterationStep() const; + + i64 GetNextValueReportingLevel() const; + + i64 GetNextValueReportingLevelLowestEquivalent() const; + }; +} diff --git a/library/cpp/histogram/hdr/histogram_iter_ut.cpp b/library/cpp/histogram/hdr/histogram_iter_ut.cpp index 7a843dec65..9c291a2547 100644 --- a/library/cpp/histogram/hdr/histogram_iter_ut.cpp +++ b/library/cpp/histogram/hdr/histogram_iter_ut.cpp @@ -1,210 +1,210 @@ -#include "histogram_iter.h" - +#include "histogram_iter.h" + #include <library/cpp/testing/unittest/registar.h> - -using namespace NHdr; - + +using namespace NHdr; + Y_UNIT_TEST_SUITE(THistogramIterTest) { Y_UNIT_TEST(RecordedValues) { - THistogram h(TDuration::Hours(1).MicroSeconds(), 3); - UNIT_ASSERT(h.RecordValues(1000, 1000)); - UNIT_ASSERT(h.RecordValue(1000 * 1000)); - - int index = 0; - TRecordedValuesIterator it(h); - - while (it.Next()) { - i64 countInBucket = it.GetCount(); - i64 countInStep = it.GetCountAddedInThisIterationStep(); - if (index == 0) { - UNIT_ASSERT_EQUAL(countInBucket, 1000); - UNIT_ASSERT_EQUAL(countInStep, 1000); - } else if (index == 1) { - UNIT_ASSERT_EQUAL(countInBucket, 1); - UNIT_ASSERT_EQUAL(countInStep, 1); - } else { - UNIT_FAIL("unexpected index value: " << index); - } - - index++; - } - - UNIT_ASSERT_EQUAL(index, 2); - } - + THistogram h(TDuration::Hours(1).MicroSeconds(), 3); + UNIT_ASSERT(h.RecordValues(1000, 1000)); + UNIT_ASSERT(h.RecordValue(1000 * 1000)); + + int index = 0; + TRecordedValuesIterator it(h); + + while (it.Next()) { + i64 countInBucket = it.GetCount(); + i64 countInStep = it.GetCountAddedInThisIterationStep(); + if (index == 0) { + UNIT_ASSERT_EQUAL(countInBucket, 1000); + UNIT_ASSERT_EQUAL(countInStep, 1000); + } else if (index == 1) { + UNIT_ASSERT_EQUAL(countInBucket, 1); + UNIT_ASSERT_EQUAL(countInStep, 1); + } else { + UNIT_FAIL("unexpected index value: " << index); + } + + index++; + } + + UNIT_ASSERT_EQUAL(index, 2); + } + Y_UNIT_TEST(CorrectedRecordedValues) { - THistogram h(TDuration::Hours(1).MicroSeconds(), 3); - UNIT_ASSERT(h.RecordValuesWithExpectedInterval(1000, 1000, 1000)); - UNIT_ASSERT(h.RecordValueWithExpectedInterval(1000 * 1000, 1000)); - - int index = 0; - i64 totalCount = 0; - TRecordedValuesIterator it(h); - - while (it.Next()) { - i64 countInBucket = it.GetCount(); - i64 countInStep = it.GetCountAddedInThisIterationStep(); - if (index == 0) { - UNIT_ASSERT_EQUAL(countInBucket, 1001); - UNIT_ASSERT_EQUAL(countInStep, 1001); - } else { - UNIT_ASSERT(countInBucket >= 1); - UNIT_ASSERT(countInStep >= 1); - } - index++; - totalCount += countInStep; - } - - UNIT_ASSERT_EQUAL(index, 1000); - UNIT_ASSERT_EQUAL(totalCount, 2000); - } - + THistogram h(TDuration::Hours(1).MicroSeconds(), 3); + UNIT_ASSERT(h.RecordValuesWithExpectedInterval(1000, 1000, 1000)); + UNIT_ASSERT(h.RecordValueWithExpectedInterval(1000 * 1000, 1000)); + + int index = 0; + i64 totalCount = 0; + TRecordedValuesIterator it(h); + + while (it.Next()) { + i64 countInBucket = it.GetCount(); + i64 countInStep = it.GetCountAddedInThisIterationStep(); + if (index == 0) { + UNIT_ASSERT_EQUAL(countInBucket, 1001); + UNIT_ASSERT_EQUAL(countInStep, 1001); + } else { + UNIT_ASSERT(countInBucket >= 1); + UNIT_ASSERT(countInStep >= 1); + } + index++; + totalCount += countInStep; + } + + UNIT_ASSERT_EQUAL(index, 1000); + UNIT_ASSERT_EQUAL(totalCount, 2000); + } + Y_UNIT_TEST(LinearValues) { - THistogram h(TDuration::Hours(1).MicroSeconds(), 3); - UNIT_ASSERT(h.RecordValues(1000, 1000)); - UNIT_ASSERT(h.RecordValue(1000 * 1000)); - - int index = 0; - TLinearIterator it(h, 1000); - - while (it.Next()) { - i64 countInBucket = it.GetCount(); - i64 countInStep = it.GetCountAddedInThisIterationStep(); - if (index == 0) { - UNIT_ASSERT_EQUAL(countInBucket, 1000); - UNIT_ASSERT_EQUAL(countInStep, 1000); - } else if (index == 999) { - UNIT_ASSERT_EQUAL(countInBucket, 1); - UNIT_ASSERT_EQUAL(countInStep, 1); - } else { - UNIT_ASSERT_EQUAL(countInBucket, 0); - UNIT_ASSERT_EQUAL(countInStep, 0); - } - - index++; - } - - UNIT_ASSERT_EQUAL(index, 1000); - } - + THistogram h(TDuration::Hours(1).MicroSeconds(), 3); + UNIT_ASSERT(h.RecordValues(1000, 1000)); + UNIT_ASSERT(h.RecordValue(1000 * 1000)); + + int index = 0; + TLinearIterator it(h, 1000); + + while (it.Next()) { + i64 countInBucket = it.GetCount(); + i64 countInStep = it.GetCountAddedInThisIterationStep(); + if (index == 0) { + UNIT_ASSERT_EQUAL(countInBucket, 1000); + UNIT_ASSERT_EQUAL(countInStep, 1000); + } else if (index == 999) { + UNIT_ASSERT_EQUAL(countInBucket, 1); + UNIT_ASSERT_EQUAL(countInStep, 1); + } else { + UNIT_ASSERT_EQUAL(countInBucket, 0); + UNIT_ASSERT_EQUAL(countInStep, 0); + } + + index++; + } + + UNIT_ASSERT_EQUAL(index, 1000); + } + Y_UNIT_TEST(CorrectLinearValues) { - THistogram h(TDuration::Hours(1).MicroSeconds(), 3); - UNIT_ASSERT(h.RecordValuesWithExpectedInterval(1000, 1000, 1000)); - UNIT_ASSERT(h.RecordValueWithExpectedInterval(1000 * 1000, 1000)); - - int index = 0; - i64 totalCount = 0; - TLinearIterator it(h, 1000); - - while (it.Next()) { - i64 countInBucket = it.GetCount(); - i64 countInStep = it.GetCountAddedInThisIterationStep(); - - if (index == 0) { - UNIT_ASSERT_EQUAL(countInBucket, 1001); - UNIT_ASSERT_EQUAL(countInStep, 1001); - } else { - UNIT_ASSERT_EQUAL(countInBucket, 1); - UNIT_ASSERT_EQUAL(countInStep, 1); - } - - index++; - totalCount += countInStep; - } - - UNIT_ASSERT_EQUAL(index, 1000); - UNIT_ASSERT_EQUAL(totalCount, 2000); - } - + THistogram h(TDuration::Hours(1).MicroSeconds(), 3); + UNIT_ASSERT(h.RecordValuesWithExpectedInterval(1000, 1000, 1000)); + UNIT_ASSERT(h.RecordValueWithExpectedInterval(1000 * 1000, 1000)); + + int index = 0; + i64 totalCount = 0; + TLinearIterator it(h, 1000); + + while (it.Next()) { + i64 countInBucket = it.GetCount(); + i64 countInStep = it.GetCountAddedInThisIterationStep(); + + if (index == 0) { + UNIT_ASSERT_EQUAL(countInBucket, 1001); + UNIT_ASSERT_EQUAL(countInStep, 1001); + } else { + UNIT_ASSERT_EQUAL(countInBucket, 1); + UNIT_ASSERT_EQUAL(countInStep, 1); + } + + index++; + totalCount += countInStep; + } + + UNIT_ASSERT_EQUAL(index, 1000); + UNIT_ASSERT_EQUAL(totalCount, 2000); + } + Y_UNIT_TEST(LogarithmicValues) { - THistogram h(TDuration::Hours(1).MicroSeconds(), 3); - UNIT_ASSERT(h.RecordValues(1000, 1000)); - UNIT_ASSERT(h.RecordValue(1000 * 1000)); - - int index = 0; - i64 expectedValue = 1000; - TLogarithmicIterator it(h, 1000, 2.0); - - while (it.Next()) { - i64 value = it.GetValue(); - i64 countInBucket = it.GetCount(); - i64 countInStep = it.GetCountAddedInThisIterationStep(); - - UNIT_ASSERT_EQUAL(value, expectedValue); - - if (index == 0) { - UNIT_ASSERT_EQUAL(countInBucket, 1000); - UNIT_ASSERT_EQUAL(countInStep, 1000); - } else if (index == 10) { - UNIT_ASSERT_EQUAL(countInBucket, 0); - UNIT_ASSERT_EQUAL(countInStep, 1); - } else { - UNIT_ASSERT_EQUAL(countInBucket, 0); - UNIT_ASSERT_EQUAL(countInStep, 0); - } - - index++; - expectedValue *= 2; - } - - UNIT_ASSERT_EQUAL(index, 11); - } - + THistogram h(TDuration::Hours(1).MicroSeconds(), 3); + UNIT_ASSERT(h.RecordValues(1000, 1000)); + UNIT_ASSERT(h.RecordValue(1000 * 1000)); + + int index = 0; + i64 expectedValue = 1000; + TLogarithmicIterator it(h, 1000, 2.0); + + while (it.Next()) { + i64 value = it.GetValue(); + i64 countInBucket = it.GetCount(); + i64 countInStep = it.GetCountAddedInThisIterationStep(); + + UNIT_ASSERT_EQUAL(value, expectedValue); + + if (index == 0) { + UNIT_ASSERT_EQUAL(countInBucket, 1000); + UNIT_ASSERT_EQUAL(countInStep, 1000); + } else if (index == 10) { + UNIT_ASSERT_EQUAL(countInBucket, 0); + UNIT_ASSERT_EQUAL(countInStep, 1); + } else { + UNIT_ASSERT_EQUAL(countInBucket, 0); + UNIT_ASSERT_EQUAL(countInStep, 0); + } + + index++; + expectedValue *= 2; + } + + UNIT_ASSERT_EQUAL(index, 11); + } + Y_UNIT_TEST(CorrectedLogarithmicValues) { - THistogram h(TDuration::Hours(1).MicroSeconds(), 3); - UNIT_ASSERT(h.RecordValuesWithExpectedInterval(1000, 1000, 1000)); - UNIT_ASSERT(h.RecordValueWithExpectedInterval(1000 * 1000, 1000)); - - int index = 0; - i64 totalCount = 0; - i64 expectedValue = 1000; - TLogarithmicIterator it(h, 1000, 2.0); - - while (it.Next()) { - i64 value = it.GetValue(); - i64 countInBucket = it.GetCount(); - i64 countInStep = it.GetCountAddedInThisIterationStep(); - - UNIT_ASSERT_EQUAL(value, expectedValue); - - if (index == 0) { - UNIT_ASSERT_EQUAL(countInBucket, 1001); - UNIT_ASSERT_EQUAL(countInStep, 1001); - } - - index++; - totalCount += countInStep; - expectedValue *= 2; - } - - UNIT_ASSERT_EQUAL(index, 11); - UNIT_ASSERT_EQUAL(totalCount, 2000); - } - + THistogram h(TDuration::Hours(1).MicroSeconds(), 3); + UNIT_ASSERT(h.RecordValuesWithExpectedInterval(1000, 1000, 1000)); + UNIT_ASSERT(h.RecordValueWithExpectedInterval(1000 * 1000, 1000)); + + int index = 0; + i64 totalCount = 0; + i64 expectedValue = 1000; + TLogarithmicIterator it(h, 1000, 2.0); + + while (it.Next()) { + i64 value = it.GetValue(); + i64 countInBucket = it.GetCount(); + i64 countInStep = it.GetCountAddedInThisIterationStep(); + + UNIT_ASSERT_EQUAL(value, expectedValue); + + if (index == 0) { + UNIT_ASSERT_EQUAL(countInBucket, 1001); + UNIT_ASSERT_EQUAL(countInStep, 1001); + } + + index++; + totalCount += countInStep; + expectedValue *= 2; + } + + UNIT_ASSERT_EQUAL(index, 11); + UNIT_ASSERT_EQUAL(totalCount, 2000); + } + Y_UNIT_TEST(LinearIterBucketsCorrectly) { - THistogram h(255, 2); - UNIT_ASSERT(h.RecordValue(193)); - UNIT_ASSERT(h.RecordValue(255)); - UNIT_ASSERT(h.RecordValue(0)); - UNIT_ASSERT(h.RecordValue(1)); - UNIT_ASSERT(h.RecordValue(64)); - UNIT_ASSERT(h.RecordValue(128)); - - int index = 0; - i64 totalCount = 0; - TLinearIterator it(h, 64); - - while (it.Next()) { - if (index == 0) { - // change after iterator was created - UNIT_ASSERT(h.RecordValue(2)); - } - - index++; - totalCount += it.GetCountAddedInThisIterationStep(); - } - - UNIT_ASSERT_EQUAL(index, 4); - UNIT_ASSERT_EQUAL(totalCount, 6); - } -} + THistogram h(255, 2); + UNIT_ASSERT(h.RecordValue(193)); + UNIT_ASSERT(h.RecordValue(255)); + UNIT_ASSERT(h.RecordValue(0)); + UNIT_ASSERT(h.RecordValue(1)); + UNIT_ASSERT(h.RecordValue(64)); + UNIT_ASSERT(h.RecordValue(128)); + + int index = 0; + i64 totalCount = 0; + TLinearIterator it(h, 64); + + while (it.Next()) { + if (index == 0) { + // change after iterator was created + UNIT_ASSERT(h.RecordValue(2)); + } + + index++; + totalCount += it.GetCountAddedInThisIterationStep(); + } + + UNIT_ASSERT_EQUAL(index, 4); + UNIT_ASSERT_EQUAL(totalCount, 6); + } +} diff --git a/library/cpp/histogram/hdr/histogram_ut.cpp b/library/cpp/histogram/hdr/histogram_ut.cpp index 5885575313..4841b76e71 100644 --- a/library/cpp/histogram/hdr/histogram_ut.cpp +++ b/library/cpp/histogram/hdr/histogram_ut.cpp @@ -1,178 +1,178 @@ -#include "histogram.h" - +#include "histogram.h" + #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/cast.h> - -using namespace NHdr; - -void LoadData(THistogram* h1, THistogram* h2) { - for (int i = 0; i < 1000; i++) { - UNIT_ASSERT(h1->RecordValue(1000)); - UNIT_ASSERT(h2->RecordValueWithExpectedInterval(1000, 1000)); - } - - UNIT_ASSERT(h1->RecordValue(1000 * 1000)); - UNIT_ASSERT(h2->RecordValueWithExpectedInterval(1000 * 1000, 1000)); -} - + +#include <util/generic/cast.h> + +using namespace NHdr; + +void LoadData(THistogram* h1, THistogram* h2) { + for (int i = 0; i < 1000; i++) { + UNIT_ASSERT(h1->RecordValue(1000)); + UNIT_ASSERT(h2->RecordValueWithExpectedInterval(1000, 1000)); + } + + UNIT_ASSERT(h1->RecordValue(1000 * 1000)); + UNIT_ASSERT(h2->RecordValueWithExpectedInterval(1000 * 1000, 1000)); +} + Y_UNIT_TEST_SUITE(THistogramTest) { Y_UNIT_TEST(Creation) { - THistogram h(TDuration::Hours(1).MicroSeconds(), 3); - UNIT_ASSERT_EQUAL(h.GetMemorySize(), 188512); - UNIT_ASSERT_EQUAL(h.GetCountsLen(), 23552); - } - + THistogram h(TDuration::Hours(1).MicroSeconds(), 3); + UNIT_ASSERT_EQUAL(h.GetMemorySize(), 188512); + UNIT_ASSERT_EQUAL(h.GetCountsLen(), 23552); + } + Y_UNIT_TEST(CreateWithLargeValues) { - THistogram h(20L * 1000 * 1000, 100L * 1000 * 1000, 5); - UNIT_ASSERT(h.RecordValue(100L * 1000 * 1000)); - UNIT_ASSERT(h.RecordValue(20L * 1000 * 1000)); - UNIT_ASSERT(h.RecordValue(30L * 1000 * 1000)); - - i64 v50 = h.GetValueAtPercentile(50.0); - i64 v8333 = h.GetValueAtPercentile(83.33); - i64 v8334 = h.GetValueAtPercentile(83.34); - i64 v99 = h.GetValueAtPercentile(99.0); - - UNIT_ASSERT_EQUAL(v50, 33554431); - UNIT_ASSERT_EQUAL(v8333, 33554431); - UNIT_ASSERT_EQUAL(v8334, 100663295); - UNIT_ASSERT_EQUAL(v99, 100663295); - - UNIT_ASSERT(h.ValuesAreEqual(v50, 20L * 1000 * 1000)); - UNIT_ASSERT(h.ValuesAreEqual(v8333, 30L * 1000 * 1000)); - UNIT_ASSERT(h.ValuesAreEqual(v8334, 100L * 1000 * 1000)); - UNIT_ASSERT(h.ValuesAreEqual(v99, 100L * 1000 * 1000)); - } - + THistogram h(20L * 1000 * 1000, 100L * 1000 * 1000, 5); + UNIT_ASSERT(h.RecordValue(100L * 1000 * 1000)); + UNIT_ASSERT(h.RecordValue(20L * 1000 * 1000)); + UNIT_ASSERT(h.RecordValue(30L * 1000 * 1000)); + + i64 v50 = h.GetValueAtPercentile(50.0); + i64 v8333 = h.GetValueAtPercentile(83.33); + i64 v8334 = h.GetValueAtPercentile(83.34); + i64 v99 = h.GetValueAtPercentile(99.0); + + UNIT_ASSERT_EQUAL(v50, 33554431); + UNIT_ASSERT_EQUAL(v8333, 33554431); + UNIT_ASSERT_EQUAL(v8334, 100663295); + UNIT_ASSERT_EQUAL(v99, 100663295); + + UNIT_ASSERT(h.ValuesAreEqual(v50, 20L * 1000 * 1000)); + UNIT_ASSERT(h.ValuesAreEqual(v8333, 30L * 1000 * 1000)); + UNIT_ASSERT(h.ValuesAreEqual(v8334, 100L * 1000 * 1000)); + UNIT_ASSERT(h.ValuesAreEqual(v99, 100L * 1000 * 1000)); + } + Y_UNIT_TEST(InvalidSignificantValueDigits) { - UNIT_ASSERT_EXCEPTION(THistogram(1000, -1), yexception); - UNIT_ASSERT_EXCEPTION(THistogram(1000, 0), yexception); - UNIT_ASSERT_EXCEPTION(THistogram(1000, 6), yexception); - } - + UNIT_ASSERT_EXCEPTION(THistogram(1000, -1), yexception); + UNIT_ASSERT_EXCEPTION(THistogram(1000, 0), yexception); + UNIT_ASSERT_EXCEPTION(THistogram(1000, 6), yexception); + } + Y_UNIT_TEST(InvalidLowestDiscernibleValue) { - UNIT_ASSERT_EXCEPTION(THistogram(0, 100, 3), yexception); - UNIT_ASSERT_EXCEPTION(THistogram(110, 100, 3), yexception); - } - + UNIT_ASSERT_EXCEPTION(THistogram(0, 100, 3), yexception); + UNIT_ASSERT_EXCEPTION(THistogram(110, 100, 3), yexception); + } + Y_UNIT_TEST(TotalCount) { - i64 oneHour = SafeIntegerCast<i64>(TDuration::Hours(1).MicroSeconds()); - THistogram h1(oneHour, 3); - THistogram h2(oneHour, 3); - LoadData(&h1, &h2); - - UNIT_ASSERT_EQUAL(h1.GetTotalCount(), 1001); - UNIT_ASSERT_EQUAL(h2.GetTotalCount(), 2000); - } - + i64 oneHour = SafeIntegerCast<i64>(TDuration::Hours(1).MicroSeconds()); + THistogram h1(oneHour, 3); + THistogram h2(oneHour, 3); + LoadData(&h1, &h2); + + UNIT_ASSERT_EQUAL(h1.GetTotalCount(), 1001); + UNIT_ASSERT_EQUAL(h2.GetTotalCount(), 2000); + } + Y_UNIT_TEST(StatsValues) { - i64 oneHour = SafeIntegerCast<i64>(TDuration::Hours(1).MicroSeconds()); - THistogram h1(oneHour, 3); - THistogram h2(oneHour, 3); - LoadData(&h1, &h2); - - // h1 - histogram without correction - { - UNIT_ASSERT_EQUAL(h1.GetMin(), 1000); - UNIT_ASSERT_EQUAL(h1.GetMax(), 1000447); - UNIT_ASSERT(h1.ValuesAreEqual(h1.GetMax(), 1000 * 1000)); - - // >>> numpy.mean([1000 for i in range(1000)] + [1000000]) - // 1998.0019980019979 - UNIT_ASSERT_DOUBLES_EQUAL(h1.GetMean(), 1998, 0.5); - - // >>> numpy.std([1000 for i in range(1000)] + [1000000]) - // 31559.59423085126 - UNIT_ASSERT_DOUBLES_EQUAL(h1.GetStdDeviation(), 31559, 10); - } - - // h2 - histogram with correction of co-ordinated omission - { - UNIT_ASSERT_EQUAL(h2.GetMin(), 1000); - UNIT_ASSERT_EQUAL(h2.GetMax(), 1000447); - UNIT_ASSERT(h2.ValuesAreEqual(h1.GetMax(), 1000 * 1000)); - UNIT_ASSERT_DOUBLES_EQUAL(h2.GetMean(), 250752, 0.5); - UNIT_ASSERT_DOUBLES_EQUAL(h2.GetStdDeviation(), 322557, 0.5); - } - } - + i64 oneHour = SafeIntegerCast<i64>(TDuration::Hours(1).MicroSeconds()); + THistogram h1(oneHour, 3); + THistogram h2(oneHour, 3); + LoadData(&h1, &h2); + + // h1 - histogram without correction + { + UNIT_ASSERT_EQUAL(h1.GetMin(), 1000); + UNIT_ASSERT_EQUAL(h1.GetMax(), 1000447); + UNIT_ASSERT(h1.ValuesAreEqual(h1.GetMax(), 1000 * 1000)); + + // >>> numpy.mean([1000 for i in range(1000)] + [1000000]) + // 1998.0019980019979 + UNIT_ASSERT_DOUBLES_EQUAL(h1.GetMean(), 1998, 0.5); + + // >>> numpy.std([1000 for i in range(1000)] + [1000000]) + // 31559.59423085126 + UNIT_ASSERT_DOUBLES_EQUAL(h1.GetStdDeviation(), 31559, 10); + } + + // h2 - histogram with correction of co-ordinated omission + { + UNIT_ASSERT_EQUAL(h2.GetMin(), 1000); + UNIT_ASSERT_EQUAL(h2.GetMax(), 1000447); + UNIT_ASSERT(h2.ValuesAreEqual(h1.GetMax(), 1000 * 1000)); + UNIT_ASSERT_DOUBLES_EQUAL(h2.GetMean(), 250752, 0.5); + UNIT_ASSERT_DOUBLES_EQUAL(h2.GetStdDeviation(), 322557, 0.5); + } + } + Y_UNIT_TEST(Percentiles) { - i64 oneHour = SafeIntegerCast<i64>(TDuration::Hours(1).MicroSeconds()); - THistogram h1(oneHour, 3); - THistogram h2(oneHour, 3); - LoadData(&h1, &h2); - - // >>> a = [1000 for i in range(1000)] + [1000000] - // >>> [(p, numpy.percentile(a, p)) for p in [50, 90, 99, 99.99, 99.999, 100]] - // [(50, 1000.0), (90, 1000.0), (99, 1000.0), (99.99, 900099.99999986368), (99.999, 990009.99999989558), (100, 1000000.0)] - - // h1 - histogram without correction - { - i64 v50 = h1.GetValueAtPercentile(50); - i64 v90 = h1.GetValueAtPercentile(90); - i64 v99 = h1.GetValueAtPercentile(99); - i64 v9999 = h1.GetValueAtPercentile(99.99); - i64 v99999 = h1.GetValueAtPercentile(99.999); - i64 v100 = h1.GetValueAtPercentile(100); - - UNIT_ASSERT_EQUAL(v50, 1000); - UNIT_ASSERT_EQUAL(v90, 1000); - UNIT_ASSERT_EQUAL(v99, 1000); - UNIT_ASSERT_EQUAL(v9999, 1000447); - UNIT_ASSERT_EQUAL(v99999, 1000447); - UNIT_ASSERT_EQUAL(v100, 1000447); - - UNIT_ASSERT(h1.ValuesAreEqual(v50, 1000)); - UNIT_ASSERT(h1.ValuesAreEqual(v90, 1000)); - UNIT_ASSERT(h1.ValuesAreEqual(v99, 1000)); - UNIT_ASSERT(h1.ValuesAreEqual(v9999, 1000 * 1000)); - UNIT_ASSERT(h1.ValuesAreEqual(v99999, 1000 * 1000)); - UNIT_ASSERT(h1.ValuesAreEqual(v100, 1000 * 1000)); - } - - // h2 - histogram with correction of co-ordinated omission - { - i64 v50 = h2.GetValueAtPercentile(50); - i64 v90 = h2.GetValueAtPercentile(90); - i64 v99 = h2.GetValueAtPercentile(99); - i64 v9999 = h2.GetValueAtPercentile(99.99); - i64 v99999 = h2.GetValueAtPercentile(99.999); - i64 v100 = h2.GetValueAtPercentile(100); - - UNIT_ASSERT_EQUAL(v50, 1000); - UNIT_ASSERT_EQUAL(v90, 800255); - UNIT_ASSERT_EQUAL(v99, 980479); - UNIT_ASSERT_EQUAL(v9999, 1000447); - UNIT_ASSERT_EQUAL(v99999, 1000447); - UNIT_ASSERT_EQUAL(v100, 1000447); - - UNIT_ASSERT(h2.ValuesAreEqual(v50, 1000)); - UNIT_ASSERT(h2.ValuesAreEqual(v90, 800 * 1000)); - UNIT_ASSERT(h2.ValuesAreEqual(v99, 980 * 1000)); - UNIT_ASSERT(h2.ValuesAreEqual(v9999, 1000 * 1000)); - UNIT_ASSERT(h2.ValuesAreEqual(v99999, 1000 * 1000)); - UNIT_ASSERT(h2.ValuesAreEqual(v100, 1000 * 1000)); - } - } - + i64 oneHour = SafeIntegerCast<i64>(TDuration::Hours(1).MicroSeconds()); + THistogram h1(oneHour, 3); + THistogram h2(oneHour, 3); + LoadData(&h1, &h2); + + // >>> a = [1000 for i in range(1000)] + [1000000] + // >>> [(p, numpy.percentile(a, p)) for p in [50, 90, 99, 99.99, 99.999, 100]] + // [(50, 1000.0), (90, 1000.0), (99, 1000.0), (99.99, 900099.99999986368), (99.999, 990009.99999989558), (100, 1000000.0)] + + // h1 - histogram without correction + { + i64 v50 = h1.GetValueAtPercentile(50); + i64 v90 = h1.GetValueAtPercentile(90); + i64 v99 = h1.GetValueAtPercentile(99); + i64 v9999 = h1.GetValueAtPercentile(99.99); + i64 v99999 = h1.GetValueAtPercentile(99.999); + i64 v100 = h1.GetValueAtPercentile(100); + + UNIT_ASSERT_EQUAL(v50, 1000); + UNIT_ASSERT_EQUAL(v90, 1000); + UNIT_ASSERT_EQUAL(v99, 1000); + UNIT_ASSERT_EQUAL(v9999, 1000447); + UNIT_ASSERT_EQUAL(v99999, 1000447); + UNIT_ASSERT_EQUAL(v100, 1000447); + + UNIT_ASSERT(h1.ValuesAreEqual(v50, 1000)); + UNIT_ASSERT(h1.ValuesAreEqual(v90, 1000)); + UNIT_ASSERT(h1.ValuesAreEqual(v99, 1000)); + UNIT_ASSERT(h1.ValuesAreEqual(v9999, 1000 * 1000)); + UNIT_ASSERT(h1.ValuesAreEqual(v99999, 1000 * 1000)); + UNIT_ASSERT(h1.ValuesAreEqual(v100, 1000 * 1000)); + } + + // h2 - histogram with correction of co-ordinated omission + { + i64 v50 = h2.GetValueAtPercentile(50); + i64 v90 = h2.GetValueAtPercentile(90); + i64 v99 = h2.GetValueAtPercentile(99); + i64 v9999 = h2.GetValueAtPercentile(99.99); + i64 v99999 = h2.GetValueAtPercentile(99.999); + i64 v100 = h2.GetValueAtPercentile(100); + + UNIT_ASSERT_EQUAL(v50, 1000); + UNIT_ASSERT_EQUAL(v90, 800255); + UNIT_ASSERT_EQUAL(v99, 980479); + UNIT_ASSERT_EQUAL(v9999, 1000447); + UNIT_ASSERT_EQUAL(v99999, 1000447); + UNIT_ASSERT_EQUAL(v100, 1000447); + + UNIT_ASSERT(h2.ValuesAreEqual(v50, 1000)); + UNIT_ASSERT(h2.ValuesAreEqual(v90, 800 * 1000)); + UNIT_ASSERT(h2.ValuesAreEqual(v99, 980 * 1000)); + UNIT_ASSERT(h2.ValuesAreEqual(v9999, 1000 * 1000)); + UNIT_ASSERT(h2.ValuesAreEqual(v99999, 1000 * 1000)); + UNIT_ASSERT(h2.ValuesAreEqual(v100, 1000 * 1000)); + } + } + Y_UNIT_TEST(OutOfRangeValues) { - THistogram h(1000, 4); - UNIT_ASSERT(h.RecordValue(32767)); - UNIT_ASSERT(!h.RecordValue(32768)); - } - + THistogram h(1000, 4); + UNIT_ASSERT(h.RecordValue(32767)); + UNIT_ASSERT(!h.RecordValue(32768)); + } + Y_UNIT_TEST(Reset) { - THistogram h(TDuration::Hours(1).MicroSeconds(), 3); - UNIT_ASSERT(h.RecordValues(1000, 1000)); - UNIT_ASSERT(h.RecordValue(1000 * 1000)); - UNIT_ASSERT_EQUAL(h.GetTotalCount(), 1001); - - h.Reset(); - - UNIT_ASSERT_EQUAL(h.GetTotalCount(), 0); - UNIT_ASSERT_EQUAL(h.GetMin(), Max<i64>()); - UNIT_ASSERT_EQUAL(h.GetMax(), 0); - UNIT_ASSERT_EQUAL(h.GetValueAtPercentile(99.0), 0); - } -} + THistogram h(TDuration::Hours(1).MicroSeconds(), 3); + UNIT_ASSERT(h.RecordValues(1000, 1000)); + UNIT_ASSERT(h.RecordValue(1000 * 1000)); + UNIT_ASSERT_EQUAL(h.GetTotalCount(), 1001); + + h.Reset(); + + UNIT_ASSERT_EQUAL(h.GetTotalCount(), 0); + UNIT_ASSERT_EQUAL(h.GetMin(), Max<i64>()); + UNIT_ASSERT_EQUAL(h.GetMax(), 0); + UNIT_ASSERT_EQUAL(h.GetValueAtPercentile(99.0), 0); + } +} diff --git a/library/cpp/histogram/hdr/ut/ya.make b/library/cpp/histogram/hdr/ut/ya.make index cce7245612..13ceb143c8 100644 --- a/library/cpp/histogram/hdr/ut/ya.make +++ b/library/cpp/histogram/hdr/ut/ya.make @@ -2,12 +2,12 @@ OWNER( g:util jamel ) - + UNITTEST_FOR(library/cpp/histogram/hdr) - -SRCS( - histogram_ut.cpp - histogram_iter_ut.cpp -) - -END() + +SRCS( + histogram_ut.cpp + histogram_iter_ut.cpp +) + +END() diff --git a/library/cpp/histogram/hdr/ya.make b/library/cpp/histogram/hdr/ya.make index f5732e8a1a..885099608d 100644 --- a/library/cpp/histogram/hdr/ya.make +++ b/library/cpp/histogram/hdr/ya.make @@ -1,17 +1,17 @@ -LIBRARY() - +LIBRARY() + OWNER( g:util jamel ) - -SRCS( - histogram.cpp - histogram_iter.cpp -) - -PEERDIR( - contrib/libs/hdr_histogram -) - -END() + +SRCS( + histogram.cpp + histogram_iter.cpp +) + +PEERDIR( + contrib/libs/hdr_histogram +) + +END() diff --git a/library/cpp/histogram/ya.make b/library/cpp/histogram/ya.make index 218aba76ad..77cfd96902 100644 --- a/library/cpp/histogram/ya.make +++ b/library/cpp/histogram/ya.make @@ -1,9 +1,9 @@ -RECURSE( +RECURSE( adaptive - hdr - hdr/ut + hdr + hdr/ut simple simple/ut rt rt/ut -) +) diff --git a/library/cpp/http/server/options.h b/library/cpp/http/server/options.h index f837ef0b08..38eda0e5e7 100644 --- a/library/cpp/http/server/options.h +++ b/library/cpp/http/server/options.h @@ -18,18 +18,18 @@ public: using TBindAddresses = TVector<TNetworkAddress>; void BindAddresses(TBindAddresses& ret) const; - inline THttpServerOptions& AddBindAddress(const TString& address, ui16 port) { + inline THttpServerOptions& AddBindAddress(const TString& address, ui16 port) { const TAddr addr = { address, port, }; BindSockaddr.push_back(addr); - return *this; + return *this; } - inline THttpServerOptions& AddBindAddress(const TString& address) { - return AddBindAddress(address, 0); + inline THttpServerOptions& AddBindAddress(const TString& address) { + return AddBindAddress(address, 0); } inline THttpServerOptions& EnableKeepAlive(bool enable) noexcept { diff --git a/library/cpp/http/server/response.h b/library/cpp/http/server/response.h index ff03ddebd5..a75cb85605 100644 --- a/library/cpp/http/server/response.h +++ b/library/cpp/http/server/response.h @@ -68,13 +68,13 @@ public: return Code; } - THttpResponse& SetHttpCode(HttpCodes code) { - Code = code; - return *this; - } - + THttpResponse& SetHttpCode(HttpCodes code) { + Code = code; + return *this; + } + void OutTo(IOutputStream& out) const; - + private: HttpCodes Code; THttpHeaders Headers; diff --git a/library/cpp/ipv6_address/ut/ipv6_address_ut.cpp b/library/cpp/ipv6_address/ut/ipv6_address_ut.cpp index d6ab403449..73bb7cffdd 100644 --- a/library/cpp/ipv6_address/ut/ipv6_address_ut.cpp +++ b/library/cpp/ipv6_address/ut/ipv6_address_ut.cpp @@ -89,8 +89,8 @@ void TIpv6AddressTest::CheckAddressValidity() { static_assert(partsV4 == intV4); const auto parsedV4 = TIpv6Address::FromString("12.34.56.78", Ok); - UNIT_ASSERT(Ok); - UNIT_ASSERT_EQUAL(parsedV4, partsV4); + UNIT_ASSERT(Ok); + UNIT_ASSERT_EQUAL(parsedV4, partsV4); constexpr TIpv6Address partsV6 {0xFB, 0x1634, 0x19, 0xABED, 0, 0x8001, 0x1670, 0x742}; static_assert(partsV6.Type() == TIpv6Address::Ipv6); @@ -99,8 +99,8 @@ void TIpv6AddressTest::CheckAddressValidity() { static_assert(partsV6 == intV6); const auto parsedV6 = TIpv6Address::FromString("FB:1634:19:ABED:0:8001:1670:742", Ok); - UNIT_ASSERT(Ok); - UNIT_ASSERT_EQUAL(parsedV6, partsV6); + UNIT_ASSERT(Ok); + UNIT_ASSERT_EQUAL(parsedV6, partsV6); static_assert(Get127001() == TIpv6Address(0x7F000001, TIpv6Address::Ipv4)); static_assert(Get1() == TIpv6Address(0, 0, 0, 0, 0, 0, 0, 1)); diff --git a/library/cpp/lwtrace/mon/mon_lwtrace.cpp b/library/cpp/lwtrace/mon/mon_lwtrace.cpp index caad0e81a2..a61ee9ce22 100644 --- a/library/cpp/lwtrace/mon/mon_lwtrace.cpp +++ b/library/cpp/lwtrace/mon/mon_lwtrace.cpp @@ -6,9 +6,9 @@ #include <google/protobuf/text_format.h> #include <library/cpp/lwtrace/mon/analytics/all.h> #include <library/cpp/lwtrace/all.h> -#include <library/cpp/monlib/service/pages/mon_page.h> -#include <library/cpp/monlib/service/pages/resource_mon_page.h> -#include <library/cpp/monlib/service/pages/templates.h> +#include <library/cpp/monlib/service/pages/mon_page.h> +#include <library/cpp/monlib/service/pages/resource_mon_page.h> +#include <library/cpp/monlib/service/pages/templates.h> #include <library/cpp/resource/resource.h> #include <library/cpp/string_utils/base64/base64.h> #include <library/cpp/html/pcdata/pcdata.h> diff --git a/library/cpp/lwtrace/mon/mon_lwtrace.h b/library/cpp/lwtrace/mon/mon_lwtrace.h index 4cfd24ad9d..8030f6ea61 100644 --- a/library/cpp/lwtrace/mon/mon_lwtrace.h +++ b/library/cpp/lwtrace/mon/mon_lwtrace.h @@ -1,7 +1,7 @@ #pragma once #include <library/cpp/lwtrace/protos/lwtrace.pb.h> -#include <library/cpp/monlib/service/monservice.h> +#include <library/cpp/monlib/service/monservice.h> #include <library/cpp/lwtrace/control.h> #include <util/generic/vector.h> diff --git a/library/cpp/lwtrace/mon/ya.make b/library/cpp/lwtrace/mon/ya.make index fea1ad3150..bdcb315754 100644 --- a/library/cpp/lwtrace/mon/ya.make +++ b/library/cpp/lwtrace/mon/ya.make @@ -47,7 +47,7 @@ PEERDIR( library/cpp/html/pcdata library/cpp/lwtrace library/cpp/lwtrace/mon/analytics - library/cpp/monlib/dynamic_counters + library/cpp/monlib/dynamic_counters library/cpp/resource library/cpp/string_utils/base64 ) diff --git a/library/cpp/messagebus/messqueue.cpp b/library/cpp/messagebus/messqueue.cpp index 6197b6bbf3..3474d62705 100644 --- a/library/cpp/messagebus/messqueue.cpp +++ b/library/cpp/messagebus/messqueue.cpp @@ -159,8 +159,8 @@ TBusServerSessionPtr TBusMessageQueue::CreateDestination(TBusProtocol* proto, IB } catch (...) { Y_FAIL("create destination failure: %s", CurrentExceptionMessage().c_str()); } -} - +} + void TBusMessageQueue::Add(TIntrusivePtr<TBusSessionImpl> session) { TGuard<TMutex> scope(Lock); Sessions.push_back(session); diff --git a/library/cpp/messagebus/monitoring/mon_proto.proto b/library/cpp/messagebus/monitoring/mon_proto.proto index eda77de7a5..73b6614481 100644 --- a/library/cpp/messagebus/monitoring/mon_proto.proto +++ b/library/cpp/messagebus/monitoring/mon_proto.proto @@ -1,4 +1,4 @@ -import "library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto"; +import "library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto"; package NBus; @@ -29,19 +29,19 @@ message TMessageStatusRecord { } message TConnectionStatusMonRecord { - optional uint32 SendQueueSize = 1 [ (NMonProto.Metric).Type = GAUGE ]; + optional uint32 SendQueueSize = 1 [ (NMonProto.Metric).Type = GAUGE ]; // client only - optional uint32 AckMessagesSize = 2 [ (NMonProto.Metric).Type = GAUGE ]; - optional uint32 ErrorCount = 3 [ (NMonProto.Metric).Type = RATE ]; + optional uint32 AckMessagesSize = 2 [ (NMonProto.Metric).Type = GAUGE ]; + optional uint32 ErrorCount = 3 [ (NMonProto.Metric).Type = RATE ]; - optional uint64 WriteBytes = 10 [ (NMonProto.Metric).Type = RATE ]; + optional uint64 WriteBytes = 10 [ (NMonProto.Metric).Type = RATE ]; optional uint64 WriteBytesCompressed = 11; - optional uint64 WriteMessages = 12 [ (NMonProto.Metric).Type = RATE ]; + optional uint64 WriteMessages = 12 [ (NMonProto.Metric).Type = RATE ]; optional uint64 WriteSyscalls = 13; optional uint64 WriteActs = 14; - optional uint64 ReadBytes = 20 [ (NMonProto.Metric).Type = RATE ]; + optional uint64 ReadBytes = 20 [ (NMonProto.Metric).Type = RATE ]; optional uint64 ReadBytesCompressed = 21; - optional uint64 ReadMessages = 22 [ (NMonProto.Metric).Type = RATE ]; + optional uint64 ReadMessages = 22 [ (NMonProto.Metric).Type = RATE ]; optional uint64 ReadSyscalls = 23; optional uint64 ReadActs = 24; @@ -49,7 +49,7 @@ message TConnectionStatusMonRecord { } message TSessionStatusMonRecord { - optional uint32 InFlight = 1 [ (NMonProto.Metric).Type = GAUGE ]; - optional uint32 ConnectionCount = 2 [ (NMonProto.Metric).Type = GAUGE ]; - optional uint32 ConnectCount = 3 [ (NMonProto.Metric).Type = RATE ]; + optional uint32 InFlight = 1 [ (NMonProto.Metric).Type = GAUGE ]; + optional uint32 ConnectionCount = 2 [ (NMonProto.Metric).Type = GAUGE ]; + optional uint32 ConnectCount = 3 [ (NMonProto.Metric).Type = RATE ]; } diff --git a/library/cpp/messagebus/monitoring/ya.make b/library/cpp/messagebus/monitoring/ya.make index 7eec26150f..25782492b1 100644 --- a/library/cpp/messagebus/monitoring/ya.make +++ b/library/cpp/messagebus/monitoring/ya.make @@ -3,7 +3,7 @@ PROTO_LIBRARY() OWNER(g:messagebus) PEERDIR( - library/cpp/monlib/encode/legacy_protobuf/protos + library/cpp/monlib/encode/legacy_protobuf/protos ) SRCS( diff --git a/library/cpp/messagebus/network.h b/library/cpp/messagebus/network.h index 6f589bd8d8..cc4bd76ea3 100644 --- a/library/cpp/messagebus/network.h +++ b/library/cpp/messagebus/network.h @@ -8,7 +8,7 @@ #include <utility> -namespace NBus { +namespace NBus { namespace NPrivate { void SetSockOptTcpCork(SOCKET s, bool value); @@ -24,5 +24,5 @@ namespace NBus { }; std::pair<unsigned, TVector<TBindResult>> BindOnPort(int port, bool reusePort); - + } diff --git a/library/cpp/messagebus/session.cpp b/library/cpp/messagebus/session.cpp index 7da9a931c1..46a7ece6a8 100644 --- a/library/cpp/messagebus/session.cpp +++ b/library/cpp/messagebus/session.cpp @@ -124,7 +124,7 @@ TBusClientSessionPtr TBusClientSession::Create(TBusProtocol* proto, IBusClientHa TBusServerSessionPtr TBusServerSession::Create(TBusProtocol* proto, IBusServerHandler* handler, const TBusServerSessionConfig& config, TBusMessageQueuePtr queue) { return queue->CreateDestination(proto, handler, config); } - + TBusServerSessionPtr TBusServerSession::Create(TBusProtocol* proto, IBusServerHandler* handler, const TBusServerSessionConfig& config, TBusMessageQueuePtr queue, const TVector<TBindResult>& bindTo) { - return queue->CreateDestination(proto, handler, config, bindTo); -} + return queue->CreateDestination(proto, handler, config, bindTo); +} diff --git a/library/cpp/messagebus/session.h b/library/cpp/messagebus/session.h index b1734a89e8..fb12ab7c22 100644 --- a/library/cpp/messagebus/session.h +++ b/library/cpp/messagebus/session.h @@ -124,10 +124,10 @@ namespace NBus { static TBusServerSessionPtr Create( TBusProtocol* proto, IBusServerHandler* handler, - const TBusServerSessionConfig& config, - TBusMessageQueuePtr queue, + const TBusServerSessionConfig& config, + TBusMessageQueuePtr queue, const TVector<TBindResult>& bindTo); - + // TODO: make parameter non-const virtual EMessageStatus SendReply(const TBusIdentity& ident, TBusMessage* pRep) = 0; diff --git a/library/cpp/messagebus/session_impl.cpp b/library/cpp/messagebus/session_impl.cpp index 5e11c70d89..ddf9f360c4 100644 --- a/library/cpp/messagebus/session_impl.cpp +++ b/library/cpp/messagebus/session_impl.cpp @@ -485,23 +485,23 @@ void TBusSessionImpl::Act(TConnectionTag) { void TBusSessionImpl::Listen(int port, TBusMessageQueue* q) { Listen(BindOnPort(port, Config.ReusePort).second, q); -} - +} + void TBusSessionImpl::Listen(const TVector<TBindResult>& bindTo, TBusMessageQueue* q) { Y_ASSERT(q == Queue); - int actualPort = -1; + int actualPort = -1; for (const TBindResult& br : bindTo) { - if (actualPort == -1) { - actualPort = br.Addr.GetPort(); + if (actualPort == -1) { + actualPort = br.Addr.GetPort(); } else { - Y_VERIFY(actualPort == br.Addr.GetPort(), "state check"); + Y_VERIFY(actualPort == br.Addr.GetPort(), "state check"); } if (Config.SocketToS >= 0) { - SetSocketToS(*br.Socket, &(br.Addr), Config.SocketToS); + SetSocketToS(*br.Socket, &(br.Addr), Config.SocketToS); } - TAcceptorPtr acceptor(new TAcceptor(this, ++LastAcceptorId, br.Socket->Release(), br.Addr)); + TAcceptorPtr acceptor(new TAcceptor(this, ++LastAcceptorId, br.Socket->Release(), br.Addr)); TConnectionsGuard guard(ConnectionsLock); InsertAcceptorLockAcquired(acceptor.Get()); diff --git a/library/cpp/messagebus/www/www.cpp b/library/cpp/messagebus/www/www.cpp index 222195e70b..62ec241d85 100644 --- a/library/cpp/messagebus/www/www.cpp +++ b/library/cpp/messagebus/www/www.cpp @@ -4,7 +4,7 @@ #include "html_output.h" #include <library/cpp/messagebus/remote_connection_status.h> -#include <library/cpp/monlib/deprecated/json/writer.h> +#include <library/cpp/monlib/deprecated/json/writer.h> #include <library/cpp/archive/yarchive.h> #include <library/cpp/http/fetch/httpfsm.h> @@ -621,57 +621,57 @@ struct TBusWww::TImpl { } } - void WriteQueueSensors(NMonitoring::TDeprecatedJsonWriter& sj, TStringBuf queueName, TBusMessageQueue* queue) { + void WriteQueueSensors(NMonitoring::TDeprecatedJsonWriter& sj, TStringBuf queueName, TBusMessageQueue* queue) { auto status = queue->GetStatusRecordInternal(); - sj.OpenMetric(); + sj.OpenMetric(); sj.WriteLabels("mb_queue", queueName, "sensor", "WorkQueueSize"); sj.WriteValue(status.ExecutorStatus.WorkQueueSize); - sj.CloseMetric(); + sj.CloseMetric(); } - void WriteMessageCounterSensors(NMonitoring::TDeprecatedJsonWriter& sj, + void WriteMessageCounterSensors(NMonitoring::TDeprecatedJsonWriter& sj, TStringBuf labelName, TStringBuf sessionName, bool read, const TMessageCounter& counter) { TStringBuf readOrWrite = read ? "read" : "write"; - sj.OpenMetric(); + sj.OpenMetric(); sj.WriteLabels(labelName, sessionName, "mb_dir", readOrWrite, "sensor", "MessageBytes"); sj.WriteValue(counter.BytesData); sj.WriteModeDeriv(); - sj.CloseMetric(); + sj.CloseMetric(); - sj.OpenMetric(); + sj.OpenMetric(); sj.WriteLabels(labelName, sessionName, "mb_dir", readOrWrite, "sensor", "MessageCount"); sj.WriteValue(counter.Count); sj.WriteModeDeriv(); - sj.CloseMetric(); + sj.CloseMetric(); } - void WriteSessionStatus(NMonitoring::TDeprecatedJsonWriter& sj, TStringBuf sessionName, bool client, + void WriteSessionStatus(NMonitoring::TDeprecatedJsonWriter& sj, TStringBuf sessionName, bool client, TBusSession* session) { TStringBuf labelName = client ? "mb_client_session" : "mb_server_session"; auto status = session->GetStatusRecordInternal(); - sj.OpenMetric(); + sj.OpenMetric(); sj.WriteLabels(labelName, sessionName, "sensor", "InFlightCount"); sj.WriteValue(status.Status.InFlightCount); - sj.CloseMetric(); + sj.CloseMetric(); - sj.OpenMetric(); + sj.OpenMetric(); sj.WriteLabels(labelName, sessionName, "sensor", "InFlightSize"); sj.WriteValue(status.Status.InFlightSize); - sj.CloseMetric(); + sj.CloseMetric(); - sj.OpenMetric(); + sj.OpenMetric(); sj.WriteLabels(labelName, sessionName, "sensor", "SendQueueSize"); sj.WriteValue(status.ConnectionStatusSummary.WriterStatus.SendQueueSize); - sj.CloseMetric(); + sj.CloseMetric(); if (client) { - sj.OpenMetric(); + sj.OpenMetric(); sj.WriteLabels(labelName, sessionName, "sensor", "AckMessagesSize"); sj.WriteValue(status.ConnectionStatusSummary.WriterStatus.AckMessagesSize); - sj.CloseMetric(); + sj.CloseMetric(); } WriteMessageCounterSensors(sj, labelName, sessionName, false, @@ -686,10 +686,10 @@ struct TBusWww::TImpl { Y_UNUSED(ss); bool all = q == "" && cs == "" && ss == ""; - NMonitoring::TDeprecatedJsonWriter sj(&Os); + NMonitoring::TDeprecatedJsonWriter sj(&Os); sj.OpenDocument(); - sj.OpenMetrics(); + sj.OpenMetrics(); for (unsigned i = 0; i < Outer->Queues.size(); ++i) { TString queueName = Outer->Queues.Entries[i].first; @@ -716,7 +716,7 @@ struct TBusWww::TImpl { } } - sj.CloseMetrics(); + sj.CloseMetrics(); sj.CloseDocument(); } diff --git a/library/cpp/messagebus/www/ya.make b/library/cpp/messagebus/www/ya.make index de2fc0beca..972390cea3 100644 --- a/library/cpp/messagebus/www/ya.make +++ b/library/cpp/messagebus/www/ya.make @@ -22,7 +22,7 @@ PEERDIR( library/cpp/json/writer library/cpp/messagebus library/cpp/messagebus/oldmodule - library/cpp/monlib/deprecated/json + library/cpp/monlib/deprecated/json library/cpp/uri ) diff --git a/library/cpp/monlib/counters/counters.cpp b/library/cpp/monlib/counters/counters.cpp index f49589fac2..50dca4c577 100644 --- a/library/cpp/monlib/counters/counters.cpp +++ b/library/cpp/monlib/counters/counters.cpp @@ -2,7 +2,7 @@ #include "counters.h" namespace NMonitoring { - char* PrettyNumShort(i64 val, char* buf, size_t size) { + char* PrettyNumShort(i64 val, char* buf, size_t size) { static const char shorts[] = {' ', 'K', 'M', 'G', 'T', 'P', 'E'}; unsigned i = 0; i64 major = val; @@ -26,7 +26,7 @@ namespace NMonitoring { return buf; } - char* PrettyNum(i64 val, char* buf, size_t size) { + char* PrettyNum(i64 val, char* buf, size_t size) { Y_ASSERT(buf); if (size < 4) { buf[0] = 0; @@ -46,4 +46,4 @@ namespace NMonitoring { return buf; } -} +} diff --git a/library/cpp/monlib/counters/counters.h b/library/cpp/monlib/counters/counters.h index 71ee2b4527..038b55f0c8 100644 --- a/library/cpp/monlib/counters/counters.h +++ b/library/cpp/monlib/counters/counters.h @@ -19,330 +19,330 @@ #include <array> namespace NMonitoring { -#define BEGIN_OUTPUT_COUNTERS \ - void OutputImpl(IOutputStream& out) { \ +#define BEGIN_OUTPUT_COUNTERS \ + void OutputImpl(IOutputStream& out) { \ char prettyBuf[32]; -#define END_OUTPUT_COUNTERS \ - out.Flush(); \ - } +#define END_OUTPUT_COUNTERS \ + out.Flush(); \ + } #define OUTPUT_NAMED_COUNTER(var, name) out << name << ": \t" << var << NMonitoring::PrettyNum(var, prettyBuf, 32) << '\n' #define OUTPUT_COUNTER(var) OUTPUT_NAMED_COUNTER(var, #var); - char* PrettyNumShort(i64 val, char* buf, size_t size); - char* PrettyNum(i64 val, char* buf, size_t size); - - // This class is deprecated. Please consider to use - // library/cpp/monlib/metrics instead. See more info at - // https://wiki.yandex-team.ru/solomon/libs/monlib_cpp/ - class TDeprecatedCounter { - public: - using TValue = TAtomic; - using TValueBase = TAtomicBase; - - TDeprecatedCounter() - : Value() - , Derivative(false) - { - } - - TDeprecatedCounter(TValue value, bool derivative = false) - : Value(value) - , Derivative(derivative) - { - } - - bool ForDerivative() const { - return Derivative; - } - - operator TValueBase() const { - return AtomicGet(Value); - } - TValueBase Val() const { - return AtomicGet(Value); - } - - void Set(TValue val) { - AtomicSet(Value, val); - } - - TValueBase Inc() { - return AtomicIncrement(Value); - } - TValueBase Dec() { - return AtomicDecrement(Value); - } - - TValueBase Add(const TValue val) { - return AtomicAdd(Value, val); - } - TValueBase Sub(const TValue val) { - return AtomicAdd(Value, -val); - } - - // operator overloads convinient - void operator++() { - Inc(); - } - void operator++(int) { - Inc(); - } - - void operator--() { - Dec(); - } - void operator--(int) { - Dec(); - } - - void operator+=(TValue rhs) { - Add(rhs); - } - void operator-=(TValue rhs) { - Sub(rhs); - } - - TValueBase operator=(TValue rhs) { - AtomicSwap(&Value, rhs); - return rhs; - } - - bool operator!() const { - return AtomicGet(Value) == 0; - } + char* PrettyNumShort(i64 val, char* buf, size_t size); + char* PrettyNum(i64 val, char* buf, size_t size); + + // This class is deprecated. Please consider to use + // library/cpp/monlib/metrics instead. See more info at + // https://wiki.yandex-team.ru/solomon/libs/monlib_cpp/ + class TDeprecatedCounter { + public: + using TValue = TAtomic; + using TValueBase = TAtomicBase; + + TDeprecatedCounter() + : Value() + , Derivative(false) + { + } + + TDeprecatedCounter(TValue value, bool derivative = false) + : Value(value) + , Derivative(derivative) + { + } + + bool ForDerivative() const { + return Derivative; + } + + operator TValueBase() const { + return AtomicGet(Value); + } + TValueBase Val() const { + return AtomicGet(Value); + } + + void Set(TValue val) { + AtomicSet(Value, val); + } + + TValueBase Inc() { + return AtomicIncrement(Value); + } + TValueBase Dec() { + return AtomicDecrement(Value); + } + + TValueBase Add(const TValue val) { + return AtomicAdd(Value, val); + } + TValueBase Sub(const TValue val) { + return AtomicAdd(Value, -val); + } + + // operator overloads convinient + void operator++() { + Inc(); + } + void operator++(int) { + Inc(); + } + + void operator--() { + Dec(); + } + void operator--(int) { + Dec(); + } + + void operator+=(TValue rhs) { + Add(rhs); + } + void operator-=(TValue rhs) { + Sub(rhs); + } + + TValueBase operator=(TValue rhs) { + AtomicSwap(&Value, rhs); + return rhs; + } + + bool operator!() const { + return AtomicGet(Value) == 0; + } TAtomic& GetAtomic() { return Value; } - private: - TAtomic Value; - bool Derivative; - }; - - template <typename T> - struct TDeprecatedCountersBase { - virtual ~TDeprecatedCountersBase() { - } - - virtual void OutputImpl(IOutputStream&) = 0; - - static T& Instance() { - return *Singleton<T>(); - } - - static void Output(IOutputStream& out) { - Instance().OutputImpl(out); - } - }; - - // This class is deprecated. Please consider to use - // library/cpp/monlib/metrics instead. See more info at - // https://wiki.yandex-team.ru/solomon/libs/monlib_cpp/ - // - // Groups of G counters, defined by T type. - // Less(a,b) returns true, if a < b. - // It's threadsafe. - template <typename T, typename G, typename TL = TLess<T>> - class TDeprecatedCounterGroups { - public: - typedef TMap<T, G*> TGroups; - typedef TVector<T> TGroupsNames; - typedef THolder<TGroupsNames> TGroupsNamesPtr; - - private: - class TCollection { - struct TElement { - T* Name; - G* Counters; - - public: - static bool Compare(const TElement& a, const TElement& b) { - return Less(*(a.Name), *(b.Name)); - } - }; // TElement - private: - TArrayHolder<TElement> Elements; - size_t Size; - + private: + TAtomic Value; + bool Derivative; + }; + + template <typename T> + struct TDeprecatedCountersBase { + virtual ~TDeprecatedCountersBase() { + } + + virtual void OutputImpl(IOutputStream&) = 0; + + static T& Instance() { + return *Singleton<T>(); + } + + static void Output(IOutputStream& out) { + Instance().OutputImpl(out); + } + }; + + // This class is deprecated. Please consider to use + // library/cpp/monlib/metrics instead. See more info at + // https://wiki.yandex-team.ru/solomon/libs/monlib_cpp/ + // + // Groups of G counters, defined by T type. + // Less(a,b) returns true, if a < b. + // It's threadsafe. + template <typename T, typename G, typename TL = TLess<T>> + class TDeprecatedCounterGroups { + public: + typedef TMap<T, G*> TGroups; + typedef TVector<T> TGroupsNames; + typedef THolder<TGroupsNames> TGroupsNamesPtr; + + private: + class TCollection { + struct TElement { + T* Name; + G* Counters; + + public: + static bool Compare(const TElement& a, const TElement& b) { + return Less(*(a.Name), *(b.Name)); + } + }; // TElement + private: + TArrayHolder<TElement> Elements; + size_t Size; + public: - TCollection() - : Size(0) - { + TCollection() + : Size(0) + { } - TCollection(const TCollection& collection) + TCollection(const TCollection& collection) : Elements(new TElement[collection.Size]) - , Size(collection.Size) - { - for (int i = 0; i < Size; ++i) { - Elements[i] = collection.Elements[i]; - } + , Size(collection.Size) + { + for (int i = 0; i < Size; ++i) { + Elements[i] = collection.Elements[i]; + } } - TCollection(const TCollection& collection, T* name, G* counters) + TCollection(const TCollection& collection, T* name, G* counters) : Elements(new TElement[collection.Size + 1]) - , Size(collection.Size + 1) - { - for (size_t i = 0; i < Size - 1; ++i) { - Elements[i] = collection.Elements[i]; - } - Elements[Size - 1].Name = name; - Elements[Size - 1].Counters = counters; - for (size_t i = 1; i < Size; ++i) { - size_t j = i; - while (j > 0 && - TElement::Compare(Elements[j], Elements[j - 1])) { - std::swap(Elements[j], Elements[j - 1]); - --j; - } - } + , Size(collection.Size + 1) + { + for (size_t i = 0; i < Size - 1; ++i) { + Elements[i] = collection.Elements[i]; + } + Elements[Size - 1].Name = name; + Elements[Size - 1].Counters = counters; + for (size_t i = 1; i < Size; ++i) { + size_t j = i; + while (j > 0 && + TElement::Compare(Elements[j], Elements[j - 1])) { + std::swap(Elements[j], Elements[j - 1]); + --j; + } + } } - - G* Find(const T& name) const { - G* result = nullptr; - if (Size == 0) { - return nullptr; + + G* Find(const T& name) const { + G* result = nullptr; + if (Size == 0) { + return nullptr; } - size_t l = 0; - size_t r = Size - 1; - while (l < r) { - size_t m = (l + r) / 2; - if (Less(*(Elements[m].Name), name)) { - l = m + 1; - } else { - r = m; - } - } - if (!Less(*(Elements[l].Name), name) && !Less(name, *(Elements[l].Name))) { - result = Elements[l].Counters; - } - return result; + size_t l = 0; + size_t r = Size - 1; + while (l < r) { + size_t m = (l + r) / 2; + if (Less(*(Elements[m].Name), name)) { + l = m + 1; + } else { + r = m; + } + } + if (!Less(*(Elements[l].Name), name) && !Less(name, *(Elements[l].Name))) { + result = Elements[l].Counters; + } + return result; } - void Free() { - for (size_t i = 0; i < Size; ++i) { - T* name = Elements[i].Name; - G* counters = Elements[i].Counters; - Elements[i].Name = nullptr; - Elements[i].Counters = nullptr; - delete name; - delete counters; - } - Size = 0; + void Free() { + for (size_t i = 0; i < Size; ++i) { + T* name = Elements[i].Name; + G* counters = Elements[i].Counters; + Elements[i].Name = nullptr; + Elements[i].Counters = nullptr; + delete name; + delete counters; + } + Size = 0; } - - TGroupsNamesPtr GetNames() const { - TGroupsNamesPtr result(new TGroupsNames()); - for (size_t i = 0; i < Size; ++i) { - result->push_back(*(Elements[i].Name)); + + TGroupsNamesPtr GetNames() const { + TGroupsNamesPtr result(new TGroupsNames()); + for (size_t i = 0; i < Size; ++i) { + result->push_back(*(Elements[i].Name)); } - return result; + return result; } - }; // TCollection - struct TOldGroup { - TCollection* Collection; - ui64 Time; - }; - - private: - TCollection* Groups; - TList<TOldGroup> OldGroups; - TSpinLock AddMutex; - - ui64 Timeout; - - static TL Less; - - private: - G* Add(const T& name) { - TGuard<TSpinLock> guard(AddMutex); - G* result = Groups->Find(name); - if (result == nullptr) { - T* newName = new T(name); - G* newCounters = new G(); - TCollection* newGroups = - new TCollection(*Groups, newName, newCounters); - ui64 now = ::Now().MicroSeconds(); - TOldGroup group; - group.Collection = Groups; - group.Time = now; - OldGroups.push_back(group); - for (ui32 i = 0; i < 5; ++i) { - if (OldGroups.front().Time + Timeout < now) { - delete OldGroups.front().Collection; - OldGroups.front().Collection = nullptr; - OldGroups.pop_front(); - } else { - break; - } - } - Groups = newGroups; - result = Groups->Find(name); + }; // TCollection + struct TOldGroup { + TCollection* Collection; + ui64 Time; + }; + + private: + TCollection* Groups; + TList<TOldGroup> OldGroups; + TSpinLock AddMutex; + + ui64 Timeout; + + static TL Less; + + private: + G* Add(const T& name) { + TGuard<TSpinLock> guard(AddMutex); + G* result = Groups->Find(name); + if (result == nullptr) { + T* newName = new T(name); + G* newCounters = new G(); + TCollection* newGroups = + new TCollection(*Groups, newName, newCounters); + ui64 now = ::Now().MicroSeconds(); + TOldGroup group; + group.Collection = Groups; + group.Time = now; + OldGroups.push_back(group); + for (ui32 i = 0; i < 5; ++i) { + if (OldGroups.front().Time + Timeout < now) { + delete OldGroups.front().Collection; + OldGroups.front().Collection = nullptr; + OldGroups.pop_front(); + } else { + break; + } + } + Groups = newGroups; + result = Groups->Find(name); } return result; } - public: - TDeprecatedCounterGroups(ui64 timeout = 5 * 1000000L) { - Groups = new TCollection(); - Timeout = timeout; + public: + TDeprecatedCounterGroups(ui64 timeout = 5 * 1000000L) { + Groups = new TCollection(); + Timeout = timeout; } - virtual ~TDeprecatedCounterGroups() { - TGuard<TSpinLock> guard(AddMutex); - Groups->Free(); - delete Groups; - Groups = nullptr; - typename TList<TOldGroup>::iterator i; - for (i = OldGroups.begin(); i != OldGroups.end(); ++i) { - delete i->Collection; - i->Collection = nullptr; + virtual ~TDeprecatedCounterGroups() { + TGuard<TSpinLock> guard(AddMutex); + Groups->Free(); + delete Groups; + Groups = nullptr; + typename TList<TOldGroup>::iterator i; + for (i = OldGroups.begin(); i != OldGroups.end(); ++i) { + delete i->Collection; + i->Collection = nullptr; } - OldGroups.clear(); + OldGroups.clear(); } - bool Has(const T& name) const { - TCollection* groups = Groups; - return groups->Find(name) != nullptr; - } + bool Has(const T& name) const { + TCollection* groups = Groups; + return groups->Find(name) != nullptr; + } G* Find(const T& name) const { - TCollection* groups = Groups; - return groups->Find(name); + TCollection* groups = Groups; + return groups->Find(name); } - // Get group with the name, if it exists. - // If there is no group with the name, add new group. - G& Get(const T& name) { - G* result = Find(name); - if (result == nullptr) { - result = Add(name); - Y_ASSERT(result != nullptr); - } - return *result; + // Get group with the name, if it exists. + // If there is no group with the name, add new group. + G& Get(const T& name) { + G* result = Find(name); + if (result == nullptr) { + result = Add(name); + Y_ASSERT(result != nullptr); + } + return *result; } - // Get copy of groups names array. - TGroupsNamesPtr GetGroupsNames() const { - TCollection* groups = Groups; - TGroupsNamesPtr result = groups->GetNames(); - return result; + // Get copy of groups names array. + TGroupsNamesPtr GetGroupsNames() const { + TCollection* groups = Groups; + TGroupsNamesPtr result = groups->GetNames(); + return result; } - }; // TDeprecatedCounterGroups + }; // TDeprecatedCounterGroups - template <typename T, typename G, typename TL> - TL TDeprecatedCounterGroups<T, G, TL>::Less; -} + template <typename T, typename G, typename TL> + TL TDeprecatedCounterGroups<T, G, TL>::Less; +} -static inline IOutputStream& operator<<(IOutputStream& o, const NMonitoring::TDeprecatedCounter& rhs) { +static inline IOutputStream& operator<<(IOutputStream& o, const NMonitoring::TDeprecatedCounter& rhs) { return o << rhs.Val(); } template <size_t N> -static inline IOutputStream& operator<<(IOutputStream& o, const std::array<NMonitoring::TDeprecatedCounter, N>& rhs) { - for (typename std::array<NMonitoring::TDeprecatedCounter, N>::const_iterator it = rhs.begin(); it != rhs.end(); ++it) { +static inline IOutputStream& operator<<(IOutputStream& o, const std::array<NMonitoring::TDeprecatedCounter, N>& rhs) { + for (typename std::array<NMonitoring::TDeprecatedCounter, N>::const_iterator it = rhs.begin(); it != rhs.end(); ++it) { if (!!*it) o << *it << Endl; } diff --git a/library/cpp/monlib/counters/counters_ut.cpp b/library/cpp/monlib/counters/counters_ut.cpp index cd006fab2f..2845efb97b 100644 --- a/library/cpp/monlib/counters/counters_ut.cpp +++ b/library/cpp/monlib/counters/counters_ut.cpp @@ -1,49 +1,49 @@ -#include "counters.h" - +#include "counters.h" + #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/set.h> + +#include <util/generic/set.h> #include <util/thread/pool.h> - -using namespace NMonitoring; - -Y_UNIT_TEST_SUITE(TDeprecatedCountersTest) { + +using namespace NMonitoring; + +Y_UNIT_TEST_SUITE(TDeprecatedCountersTest) { Y_UNIT_TEST(CounterGroupsAreThreadSafe) { - const static ui32 GROUPS_COUNT = 1000; - const static ui32 THREADS_COUNT = 10; - - TDeprecatedCounterGroups<ui32, ui32> groups; - - auto adder = [&groups]() { - for (ui32 id = 0; id < GROUPS_COUNT; id++) { - groups.Get(id); - - // adds contention - ::NanoSleep(42); - } - }; - + const static ui32 GROUPS_COUNT = 1000; + const static ui32 THREADS_COUNT = 10; + + TDeprecatedCounterGroups<ui32, ui32> groups; + + auto adder = [&groups]() { + for (ui32 id = 0; id < GROUPS_COUNT; id++) { + groups.Get(id); + + // adds contention + ::NanoSleep(42); + } + }; + TThreadPool q; - q.Start(THREADS_COUNT); - for (ui32 i = 0; i < THREADS_COUNT; i++) { - q.SafeAddFunc(adder); - } - q.Stop(); - - // each group id is present - for (ui32 id = 0; id < GROUPS_COUNT; id++) { - UNIT_ASSERT(groups.Has(id)); - } - - // group names contains only appropriate ids - auto ids = groups.GetGroupsNames(); - for (ui32 id : *ids) { - UNIT_ASSERT(id < GROUPS_COUNT); - } - - // no duplication in group names + q.Start(THREADS_COUNT); + for (ui32 i = 0; i < THREADS_COUNT; i++) { + q.SafeAddFunc(adder); + } + q.Stop(); + + // each group id is present + for (ui32 id = 0; id < GROUPS_COUNT; id++) { + UNIT_ASSERT(groups.Has(id)); + } + + // group names contains only appropriate ids + auto ids = groups.GetGroupsNames(); + for (ui32 id : *ids) { + UNIT_ASSERT(id < GROUPS_COUNT); + } + + // no duplication in group names TSet<ui32> uniqueIds(ids->begin(), ids->end()); - UNIT_ASSERT_EQUAL(ids->size(), uniqueIds.size()); - UNIT_ASSERT_EQUAL(ids->size(), GROUPS_COUNT); - } -} + UNIT_ASSERT_EQUAL(ids->size(), uniqueIds.size()); + UNIT_ASSERT_EQUAL(ids->size(), GROUPS_COUNT); + } +} diff --git a/library/cpp/monlib/counters/histogram.cpp b/library/cpp/monlib/counters/histogram.cpp index 6a9d7a1f0b..46cf4e6ec8 100644 --- a/library/cpp/monlib/counters/histogram.cpp +++ b/library/cpp/monlib/counters/histogram.cpp @@ -1,40 +1,40 @@ -#include "histogram.h" - -namespace NMonitoring { - void THistogramSnapshot::Print(IOutputStream* out) const { - (*out) << "mean: " << Mean - << ", stddev: " << StdDeviation - << ", min: " << Min - << ", max: " << Max - << ", 50%: " << Percentile50 - << ", 75%: " << Percentile75 - << ", 90%: " << Percentile90 - << ", 95%: " << Percentile95 - << ", 98%: " << Percentile98 - << ", 99%: " << Percentile99 +#include "histogram.h" + +namespace NMonitoring { + void THistogramSnapshot::Print(IOutputStream* out) const { + (*out) << "mean: " << Mean + << ", stddev: " << StdDeviation + << ", min: " << Min + << ", max: " << Max + << ", 50%: " << Percentile50 + << ", 75%: " << Percentile75 + << ", 90%: " << Percentile90 + << ", 95%: " << Percentile95 + << ", 98%: " << Percentile98 + << ", 99%: " << Percentile99 << ", 99.9%: " << Percentile999 << ", count: " << TotalCount; - } - - void THdrHistogram::TakeSnaphot(THistogramSnapshot* snapshot) { - with_lock (Lock_) { - // TODO: get data with single traverse - snapshot->Mean = Data_.GetMean(); - snapshot->StdDeviation = Data_.GetStdDeviation(); - snapshot->Min = Data_.GetMin(); - snapshot->Max = Data_.GetMax(); - snapshot->Percentile50 = Data_.GetValueAtPercentile(50.0); - snapshot->Percentile75 = Data_.GetValueAtPercentile(75.0); - snapshot->Percentile90 = Data_.GetValueAtPercentile(90.0); - snapshot->Percentile95 = Data_.GetValueAtPercentile(95.0); - snapshot->Percentile98 = Data_.GetValueAtPercentile(98.0); - snapshot->Percentile99 = Data_.GetValueAtPercentile(99.0); - snapshot->Percentile999 = Data_.GetValueAtPercentile(99.9); + } + + void THdrHistogram::TakeSnaphot(THistogramSnapshot* snapshot) { + with_lock (Lock_) { + // TODO: get data with single traverse + snapshot->Mean = Data_.GetMean(); + snapshot->StdDeviation = Data_.GetStdDeviation(); + snapshot->Min = Data_.GetMin(); + snapshot->Max = Data_.GetMax(); + snapshot->Percentile50 = Data_.GetValueAtPercentile(50.0); + snapshot->Percentile75 = Data_.GetValueAtPercentile(75.0); + snapshot->Percentile90 = Data_.GetValueAtPercentile(90.0); + snapshot->Percentile95 = Data_.GetValueAtPercentile(95.0); + snapshot->Percentile98 = Data_.GetValueAtPercentile(98.0); + snapshot->Percentile99 = Data_.GetValueAtPercentile(99.0); + snapshot->Percentile999 = Data_.GetValueAtPercentile(99.9); snapshot->TotalCount = Data_.GetTotalCount(); - - // cleanup histogram data - Data_.Reset(); - } - } - -} + + // cleanup histogram data + Data_.Reset(); + } + } + +} diff --git a/library/cpp/monlib/counters/histogram.h b/library/cpp/monlib/counters/histogram.h index e6bc625daf..96361b0023 100644 --- a/library/cpp/monlib/counters/histogram.h +++ b/library/cpp/monlib/counters/histogram.h @@ -1,189 +1,189 @@ -#pragma once - +#pragma once + #include <library/cpp/histogram/hdr/histogram.h> - -#include <util/system/spinlock.h> -#include <util/stream/output.h> - -namespace NMonitoring { - /** - * A statistical snapshot of values recorded in histogram. - */ - struct THistogramSnapshot { - double Mean; - double StdDeviation; - i64 Min; - i64 Max; - i64 Percentile50; - i64 Percentile75; - i64 Percentile90; - i64 Percentile95; - i64 Percentile98; - i64 Percentile99; - i64 Percentile999; + +#include <util/system/spinlock.h> +#include <util/stream/output.h> + +namespace NMonitoring { + /** + * A statistical snapshot of values recorded in histogram. + */ + struct THistogramSnapshot { + double Mean; + double StdDeviation; + i64 Min; + i64 Max; + i64 Percentile50; + i64 Percentile75; + i64 Percentile90; + i64 Percentile95; + i64 Percentile98; + i64 Percentile99; + i64 Percentile999; i64 TotalCount; - - void Print(IOutputStream* out) const; - }; - - /** - * Special counter which calculates the distribution of a value. - */ - class THdrHistogram { - public: - /** - * Construct a histogram given the Lowest and Highest values to be tracked - * and a number of significant decimal digits. Providing a - * lowestDiscernibleValue is useful in situations where the units used for - * the histogram's values are much smaller that the minimal accuracy - * required. E.g. when tracking time values stated in nanosecond units, - * where the minimal accuracy required is a microsecond, the proper value - * for lowestDiscernibleValue would be 1000. - * - * @param lowestDiscernibleValue The lowest value that can be discerned - * (distinguished from 0) by the histogram. Must be a positive - * integer that is >= 1. May be internally rounded down to nearest - * power of 2. - * - * @param highestTrackableValue The highest value to be tracked by the - * histogram. Must be a positive integer that is - * >= (2 * lowestDiscernibleValue). - * - * @param numberOfSignificantValueDigits Specifies the precision to use. - * This is the number of significant decimal digits to which the - * histogram will maintain value resolution and separation. Must be - * a non-negative integer between 0 and 5. - */ - THdrHistogram(i64 lowestDiscernibleValue, i64 highestTrackableValue, - i32 numberOfSignificantValueDigits) - : Data_(lowestDiscernibleValue, highestTrackableValue, - numberOfSignificantValueDigits) { - } - - /** - * Records a value in the histogram, will round this value of to a - * precision at or better than the NumberOfSignificantValueDigits specified - * at construction time. - * - * @param value Value to add to the histogram - * @return false if the value is larger than the HighestTrackableValue - * and can't be recorded, true otherwise. - */ - bool RecordValue(i64 value) { - with_lock (Lock_) { - return Data_.RecordValue(value); - } - } - - /** - * Records count values in the histogram, will round this value of to a - * precision at or better than the NumberOfSignificantValueDigits specified - * at construction time. - * - * @param value Value to add to the histogram - * @param count Number of values to add to the histogram - * @return false if the value is larger than the HighestTrackableValue - * and can't be recorded, true otherwise. - */ - bool RecordValues(i64 value, i64 count) { - with_lock (Lock_) { - return Data_.RecordValues(value, count); - } - } - - /** - * Records a value in the histogram and backfill based on an expected - * interval. Value will be rounded this to a precision at or better - * than the NumberOfSignificantValueDigits specified at contruction time. - * This is specifically used for recording latency. If the value is larger - * than the expectedInterval then the latency recording system has - * experienced co-ordinated omission. This method fills in the values that - * would have occured had the client providing the load not been blocked. - * - * @param value Value to add to the histogram - * @param expectedInterval The delay between recording values - * @return false if the value is larger than the HighestTrackableValue - * and can't be recorded, true otherwise. - */ - bool RecordValueWithExpectedInterval(i64 value, i64 expectedInterval) { - with_lock (Lock_) { - return Data_.RecordValueWithExpectedInterval(value, expectedInterval); - } - } - - /** - * Record a value in the histogram count times. Applies the same correcting - * logic as {@link THdrHistogram::RecordValueWithExpectedInterval}. - * - * @param value Value to add to the histogram - * @param count Number of values to add to the histogram - * @param expectedInterval The delay between recording values. - * @return false if the value is larger than the HighestTrackableValue - * and can't be recorded, true otherwise. - */ - bool RecordValuesWithExpectedInterval( - i64 value, i64 count, i64 expectedInterval) { - with_lock (Lock_) { - return Data_.RecordValuesWithExpectedInterval( - value, count, expectedInterval); - } - } - - /** - * @return The configured lowestDiscernibleValue - */ - i64 GetLowestDiscernibleValue() const { - with_lock (Lock_) { - return Data_.GetLowestDiscernibleValue(); - } - } - - /** - * @return The configured highestTrackableValue - */ - i64 GetHighestTrackableValue() const { - with_lock (Lock_) { - return Data_.GetHighestTrackableValue(); - } - } - - /** - * @return The configured numberOfSignificantValueDigits - */ - i32 GetNumberOfSignificantValueDigits() const { - with_lock (Lock_) { - return Data_.GetNumberOfSignificantValueDigits(); - } - } - - /** - * @return The total count of all recorded values in the histogram - */ - i64 GetTotalCount() const { - with_lock (Lock_) { - return Data_.GetTotalCount(); - } - } - - /** - * Place a copy of the value counts accumulated since the last snapshot - * was taken into {@code snapshot}. Calling this member-function will - * reset the value counts, and start accumulating value counts for the - * next interval. - * - * @param snapshot the structure into which the values should be copied. - */ - void TakeSnaphot(THistogramSnapshot* snapshot); - - private: - mutable TSpinLock Lock_; - NHdr::THistogram Data_; - }; - -} - -template <> -inline void Out<NMonitoring::THistogramSnapshot>( - IOutputStream& out, const NMonitoring::THistogramSnapshot& snapshot) { - snapshot.Print(&out); -} + + void Print(IOutputStream* out) const; + }; + + /** + * Special counter which calculates the distribution of a value. + */ + class THdrHistogram { + public: + /** + * Construct a histogram given the Lowest and Highest values to be tracked + * and a number of significant decimal digits. Providing a + * lowestDiscernibleValue is useful in situations where the units used for + * the histogram's values are much smaller that the minimal accuracy + * required. E.g. when tracking time values stated in nanosecond units, + * where the minimal accuracy required is a microsecond, the proper value + * for lowestDiscernibleValue would be 1000. + * + * @param lowestDiscernibleValue The lowest value that can be discerned + * (distinguished from 0) by the histogram. Must be a positive + * integer that is >= 1. May be internally rounded down to nearest + * power of 2. + * + * @param highestTrackableValue The highest value to be tracked by the + * histogram. Must be a positive integer that is + * >= (2 * lowestDiscernibleValue). + * + * @param numberOfSignificantValueDigits Specifies the precision to use. + * This is the number of significant decimal digits to which the + * histogram will maintain value resolution and separation. Must be + * a non-negative integer between 0 and 5. + */ + THdrHistogram(i64 lowestDiscernibleValue, i64 highestTrackableValue, + i32 numberOfSignificantValueDigits) + : Data_(lowestDiscernibleValue, highestTrackableValue, + numberOfSignificantValueDigits) { + } + + /** + * Records a value in the histogram, will round this value of to a + * precision at or better than the NumberOfSignificantValueDigits specified + * at construction time. + * + * @param value Value to add to the histogram + * @return false if the value is larger than the HighestTrackableValue + * and can't be recorded, true otherwise. + */ + bool RecordValue(i64 value) { + with_lock (Lock_) { + return Data_.RecordValue(value); + } + } + + /** + * Records count values in the histogram, will round this value of to a + * precision at or better than the NumberOfSignificantValueDigits specified + * at construction time. + * + * @param value Value to add to the histogram + * @param count Number of values to add to the histogram + * @return false if the value is larger than the HighestTrackableValue + * and can't be recorded, true otherwise. + */ + bool RecordValues(i64 value, i64 count) { + with_lock (Lock_) { + return Data_.RecordValues(value, count); + } + } + + /** + * Records a value in the histogram and backfill based on an expected + * interval. Value will be rounded this to a precision at or better + * than the NumberOfSignificantValueDigits specified at contruction time. + * This is specifically used for recording latency. If the value is larger + * than the expectedInterval then the latency recording system has + * experienced co-ordinated omission. This method fills in the values that + * would have occured had the client providing the load not been blocked. + * + * @param value Value to add to the histogram + * @param expectedInterval The delay between recording values + * @return false if the value is larger than the HighestTrackableValue + * and can't be recorded, true otherwise. + */ + bool RecordValueWithExpectedInterval(i64 value, i64 expectedInterval) { + with_lock (Lock_) { + return Data_.RecordValueWithExpectedInterval(value, expectedInterval); + } + } + + /** + * Record a value in the histogram count times. Applies the same correcting + * logic as {@link THdrHistogram::RecordValueWithExpectedInterval}. + * + * @param value Value to add to the histogram + * @param count Number of values to add to the histogram + * @param expectedInterval The delay between recording values. + * @return false if the value is larger than the HighestTrackableValue + * and can't be recorded, true otherwise. + */ + bool RecordValuesWithExpectedInterval( + i64 value, i64 count, i64 expectedInterval) { + with_lock (Lock_) { + return Data_.RecordValuesWithExpectedInterval( + value, count, expectedInterval); + } + } + + /** + * @return The configured lowestDiscernibleValue + */ + i64 GetLowestDiscernibleValue() const { + with_lock (Lock_) { + return Data_.GetLowestDiscernibleValue(); + } + } + + /** + * @return The configured highestTrackableValue + */ + i64 GetHighestTrackableValue() const { + with_lock (Lock_) { + return Data_.GetHighestTrackableValue(); + } + } + + /** + * @return The configured numberOfSignificantValueDigits + */ + i32 GetNumberOfSignificantValueDigits() const { + with_lock (Lock_) { + return Data_.GetNumberOfSignificantValueDigits(); + } + } + + /** + * @return The total count of all recorded values in the histogram + */ + i64 GetTotalCount() const { + with_lock (Lock_) { + return Data_.GetTotalCount(); + } + } + + /** + * Place a copy of the value counts accumulated since the last snapshot + * was taken into {@code snapshot}. Calling this member-function will + * reset the value counts, and start accumulating value counts for the + * next interval. + * + * @param snapshot the structure into which the values should be copied. + */ + void TakeSnaphot(THistogramSnapshot* snapshot); + + private: + mutable TSpinLock Lock_; + NHdr::THistogram Data_; + }; + +} + +template <> +inline void Out<NMonitoring::THistogramSnapshot>( + IOutputStream& out, const NMonitoring::THistogramSnapshot& snapshot) { + snapshot.Print(&out); +} diff --git a/library/cpp/monlib/counters/histogram_ut.cpp b/library/cpp/monlib/counters/histogram_ut.cpp index 654994d12f..5a0800505a 100644 --- a/library/cpp/monlib/counters/histogram_ut.cpp +++ b/library/cpp/monlib/counters/histogram_ut.cpp @@ -1,47 +1,47 @@ -#include "histogram.h" - +#include "histogram.h" + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - + +using namespace NMonitoring; + Y_UNIT_TEST_SUITE(THistorgamTest) { Y_UNIT_TEST(TakeSnapshot) { - THdrHistogram h(1, 10, 3); - UNIT_ASSERT(h.RecordValue(1)); - UNIT_ASSERT(h.RecordValue(2)); - UNIT_ASSERT(h.RecordValues(3, 10)); - UNIT_ASSERT(h.RecordValue(4)); - UNIT_ASSERT(h.RecordValue(5)); - - UNIT_ASSERT_EQUAL(h.GetTotalCount(), 14); - - THistogramSnapshot snapshot; - h.TakeSnaphot(&snapshot); - - UNIT_ASSERT_EQUAL(h.GetTotalCount(), 0); - - UNIT_ASSERT_EQUAL(snapshot.Min, 1); - UNIT_ASSERT_EQUAL(snapshot.Max, 5); - - // >>> a = [1, 2] + [3 for i in range(10)] + [4, 5] - // >>> numpy.mean(a) - // 3.0 - UNIT_ASSERT_DOUBLES_EQUAL(snapshot.Mean, 3.0, 1e-6); - - // >>> numpy.std(a) - // 0.84515425472851657 - UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.84515425472851657, 1e-6); - - // >>> [(p, round(numpy.percentile(a, p))) for p in [50, 75, 90, 95, 98, 99, 99.9, 100]] - // [(50, 3.0), (75, 3.0), (90, 4.0), (95, 4.0), (98, 5.0), (99, 5.0), (99.9, 5.0), (100, 5.0)] - UNIT_ASSERT_EQUAL(snapshot.Percentile50, 3); - UNIT_ASSERT_EQUAL(snapshot.Percentile75, 3); - UNIT_ASSERT_EQUAL(snapshot.Percentile90, 4); - UNIT_ASSERT_EQUAL(snapshot.Percentile95, 4); - UNIT_ASSERT_EQUAL(snapshot.Percentile98, 5); - UNIT_ASSERT_EQUAL(snapshot.Percentile99, 5); - UNIT_ASSERT_EQUAL(snapshot.Percentile999, 5); + THdrHistogram h(1, 10, 3); + UNIT_ASSERT(h.RecordValue(1)); + UNIT_ASSERT(h.RecordValue(2)); + UNIT_ASSERT(h.RecordValues(3, 10)); + UNIT_ASSERT(h.RecordValue(4)); + UNIT_ASSERT(h.RecordValue(5)); + + UNIT_ASSERT_EQUAL(h.GetTotalCount(), 14); + + THistogramSnapshot snapshot; + h.TakeSnaphot(&snapshot); + + UNIT_ASSERT_EQUAL(h.GetTotalCount(), 0); + + UNIT_ASSERT_EQUAL(snapshot.Min, 1); + UNIT_ASSERT_EQUAL(snapshot.Max, 5); + + // >>> a = [1, 2] + [3 for i in range(10)] + [4, 5] + // >>> numpy.mean(a) + // 3.0 + UNIT_ASSERT_DOUBLES_EQUAL(snapshot.Mean, 3.0, 1e-6); + + // >>> numpy.std(a) + // 0.84515425472851657 + UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.84515425472851657, 1e-6); + + // >>> [(p, round(numpy.percentile(a, p))) for p in [50, 75, 90, 95, 98, 99, 99.9, 100]] + // [(50, 3.0), (75, 3.0), (90, 4.0), (95, 4.0), (98, 5.0), (99, 5.0), (99.9, 5.0), (100, 5.0)] + UNIT_ASSERT_EQUAL(snapshot.Percentile50, 3); + UNIT_ASSERT_EQUAL(snapshot.Percentile75, 3); + UNIT_ASSERT_EQUAL(snapshot.Percentile90, 4); + UNIT_ASSERT_EQUAL(snapshot.Percentile95, 4); + UNIT_ASSERT_EQUAL(snapshot.Percentile98, 5); + UNIT_ASSERT_EQUAL(snapshot.Percentile99, 5); + UNIT_ASSERT_EQUAL(snapshot.Percentile999, 5); UNIT_ASSERT_EQUAL(snapshot.TotalCount, 14); - } -} + } +} diff --git a/library/cpp/monlib/counters/meter.cpp b/library/cpp/monlib/counters/meter.cpp index 2ecdb97666..6f15f173d1 100644 --- a/library/cpp/monlib/counters/meter.cpp +++ b/library/cpp/monlib/counters/meter.cpp @@ -1,4 +1,4 @@ -#include "meter.h" - -namespace NMonitoring { -} +#include "meter.h" + +namespace NMonitoring { +} diff --git a/library/cpp/monlib/counters/meter.h b/library/cpp/monlib/counters/meter.h index ea0bdad11f..1219f95c4d 100644 --- a/library/cpp/monlib/counters/meter.h +++ b/library/cpp/monlib/counters/meter.h @@ -1,285 +1,285 @@ -#pragma once - -#include <util/system/types.h> -#include <util/generic/noncopyable.h> -#include <util/system/atomic.h> - -#include <chrono> -#include <cstdlib> -#include <cmath> - -namespace NMonitoring { - /** - * An exponentially-weighted moving average. - * - * @see <a href="http://www.teamquest.com/pdfs/whitepaper/ldavg1.pdf"> - * UNIX Load Average Part 1: How It Works</a> - * @see <a href="http://www.teamquest.com/pdfs/whitepaper/ldavg2.pdf"> - * UNIX Load Average Part 2: Not Your Average Average</a> - * @see <a href="http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average">EMA</a> - */ - class TMovingAverage { - public: - enum { - INTERVAL = 5 // in seconds - }; - - public: - /** - * Creates a new EWMA which is equivalent to the UNIX one minute load - * average and which expects to be ticked every 5 seconds. - * - * @return a one-minute EWMA - */ - static TMovingAverage OneMinute() { - static const double M1_ALPHA = 1 - std::exp(-INTERVAL / 60.0 / 1); - return {M1_ALPHA, std::chrono::seconds(INTERVAL)}; - } - - /** - * Creates a new EWMA which is equivalent to the UNIX five minute load - * average and which expects to be ticked every 5 seconds. - * - * @return a five-minute EWMA - */ - static TMovingAverage FiveMinutes() { - static const double M5_ALPHA = 1 - std::exp(-INTERVAL / 60.0 / 5); - return {M5_ALPHA, std::chrono::seconds(INTERVAL)}; - } - - /** - * Creates a new EWMA which is equivalent to the UNIX fifteen minute load - * average and which expects to be ticked every 5 seconds. - * - * @return a fifteen-minute EWMA - */ - static TMovingAverage FifteenMinutes() { - static const double M15_ALPHA = 1 - std::exp(-INTERVAL / 60.0 / 15); - return {M15_ALPHA, std::chrono::seconds(INTERVAL)}; - } - - /** - * Create a new EWMA with a specific smoothing constant. - * - * @param alpha the smoothing constant - * @param interval the expected tick interval - */ - TMovingAverage(double alpha, std::chrono::seconds interval) - : Initialized_(0) - , Rate_(0) - , Uncounted_(0) - , Alpha_(alpha) - , Interval_(std::chrono::nanoseconds(interval).count()) - { - } - - TMovingAverage(const TMovingAverage& rhs) - : Initialized_(AtomicGet(rhs.Initialized_)) - , Rate_(AtomicGet(rhs.Rate_)) - , Uncounted_(AtomicGet(rhs.Uncounted_)) - , Alpha_(rhs.Alpha_) - , Interval_(rhs.Interval_) - { - } - - TMovingAverage& operator=(const TMovingAverage& rhs) { - AtomicSet(Initialized_, AtomicGet(Initialized_)); - AtomicSet(Rate_, AtomicGet(rhs.Rate_)); - AtomicSet(Uncounted_, AtomicGet(rhs.Uncounted_)); - Alpha_ = rhs.Alpha_; - Interval_ = rhs.Interval_; - return *this; - } - - /** - * Update the moving average with a new value. - * - * @param n the new value - */ - void Update(ui64 n = 1) { - AtomicAdd(Uncounted_, n); - } - - /** - * Mark the passage of time and decay the current rate accordingly. - */ - void Tick() { - double instantRate = AtomicSwap(&Uncounted_, 0) / Interval_; - if (AtomicGet(Initialized_)) { - double rate = AsDouble(AtomicGet(Rate_)); - rate += (Alpha_ * (instantRate - rate)); - AtomicSet(Rate_, AsAtomic(rate)); - } else { - AtomicSet(Rate_, AsAtomic(instantRate)); - AtomicSet(Initialized_, 1); - } - } - - /** - * @return the rate in the seconds - */ - double GetRate() const { - double rate = AsDouble(AtomicGet(Rate_)); - return rate * std::nano::den; - } - - private: - static double AsDouble(TAtomicBase val) { - union { - double D; - TAtomicBase A; - } doubleAtomic; - doubleAtomic.A = val; - return doubleAtomic.D; - } - - static TAtomicBase AsAtomic(double val) { - union { - double D; - TAtomicBase A; - } doubleAtomic; - doubleAtomic.D = val; - return doubleAtomic.A; - } - - private: - TAtomic Initialized_; - TAtomic Rate_; - TAtomic Uncounted_; - double Alpha_; - double Interval_; - }; - - /** - * A meter metric which measures mean throughput and one-, five-, and - * fifteen-minute exponentially-weighted moving average throughputs. - */ - template <typename TClock> - class TMeterImpl: private TNonCopyable { - public: - TMeterImpl() - : StartTime_(TClock::now()) - , LastTick_(StartTime_.time_since_epoch().count()) - , Count_(0) - , OneMinuteRate_(TMovingAverage::OneMinute()) - , FiveMinutesRate_(TMovingAverage::FiveMinutes()) - , FifteenMinutesRate_(TMovingAverage::FifteenMinutes()) - { - } - - /** - * Mark the occurrence of events. - * - * @param n the number of events - */ - void Mark(ui64 n = 1) { - TickIfNecessary(); - AtomicAdd(Count_, n); - OneMinuteRate_.Update(n); - FiveMinutesRate_.Update(n); - FifteenMinutesRate_.Update(n); - } - - /** - * Returns the one-minute exponentially-weighted moving average rate at - * which events have occurred since the meter was created. - * - * This rate has the same exponential decay factor as the one-minute load - * average in the top Unix command. - * - * @return the one-minute exponentially-weighted moving average rate at - * which events have occurred since the meter was created - */ - double GetOneMinuteRate() const { - return OneMinuteRate_.GetRate(); - } - - /** - * Returns the five-minute exponentially-weighted moving average rate at - * which events have occurred since the meter was created. - * - * This rate has the same exponential decay factor as the five-minute load - * average in the top Unix command. - * - * @return the five-minute exponentially-weighted moving average rate at - * which events have occurred since the meter was created - */ - double GetFiveMinutesRate() const { - return FiveMinutesRate_.GetRate(); - } - - /** - * Returns the fifteen-minute exponentially-weighted moving average rate - * at which events have occurred since the meter was created. - * - * This rate has the same exponential decay factor as the fifteen-minute - * load average in the top Unix command. - * - * @return the fifteen-minute exponentially-weighted moving average rate - * at which events have occurred since the meter was created - */ - double GetFifteenMinutesRate() const { - return FifteenMinutesRate_.GetRate(); - } - - /** - * @return the mean rate at which events have occurred since the meter - * was created - */ - double GetMeanRate() const { - if (GetCount() == 0) { - return 0.0; - } - - auto now = TClock::now(); - std::chrono::duration<double> elapsedSeconds = now - StartTime_; - return GetCount() / elapsedSeconds.count(); - } - - /** - * @return the number of events which have been marked - */ - ui64 GetCount() const { - return AtomicGet(Count_); - } - - private: - void TickIfNecessary() { - static ui64 TICK_INTERVAL_NS = - std::chrono::nanoseconds( - std::chrono::seconds(TMovingAverage::INTERVAL)) - .count(); - - auto oldTickNs = AtomicGet(LastTick_); - auto newTickNs = TClock::now().time_since_epoch().count(); - ui64 elapsedNs = std::abs(newTickNs - oldTickNs); - - if (elapsedNs > TICK_INTERVAL_NS) { - // adjust to interval begining - newTickNs -= elapsedNs % TICK_INTERVAL_NS; - if (AtomicCas(&LastTick_, newTickNs, oldTickNs)) { - ui64 requiredTicks = elapsedNs / TICK_INTERVAL_NS; - for (ui64 i = 0; i < requiredTicks; ++i) { - OneMinuteRate_.Tick(); - FiveMinutesRate_.Tick(); - FifteenMinutesRate_.Tick(); - } - } - } - } - - private: - const typename TClock::time_point StartTime_; - TAtomic LastTick_; - TAtomic Count_; - TMovingAverage OneMinuteRate_; - TMovingAverage FiveMinutesRate_; - TMovingAverage FifteenMinutesRate_; - }; - - using TSystemMeter = TMeterImpl<std::chrono::system_clock>; - using TSteadyMeter = TMeterImpl<std::chrono::steady_clock>; - using THighResMeter = TMeterImpl<std::chrono::high_resolution_clock>; - using TMeter = THighResMeter; - -} +#pragma once + +#include <util/system/types.h> +#include <util/generic/noncopyable.h> +#include <util/system/atomic.h> + +#include <chrono> +#include <cstdlib> +#include <cmath> + +namespace NMonitoring { + /** + * An exponentially-weighted moving average. + * + * @see <a href="http://www.teamquest.com/pdfs/whitepaper/ldavg1.pdf"> + * UNIX Load Average Part 1: How It Works</a> + * @see <a href="http://www.teamquest.com/pdfs/whitepaper/ldavg2.pdf"> + * UNIX Load Average Part 2: Not Your Average Average</a> + * @see <a href="http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average">EMA</a> + */ + class TMovingAverage { + public: + enum { + INTERVAL = 5 // in seconds + }; + + public: + /** + * Creates a new EWMA which is equivalent to the UNIX one minute load + * average and which expects to be ticked every 5 seconds. + * + * @return a one-minute EWMA + */ + static TMovingAverage OneMinute() { + static const double M1_ALPHA = 1 - std::exp(-INTERVAL / 60.0 / 1); + return {M1_ALPHA, std::chrono::seconds(INTERVAL)}; + } + + /** + * Creates a new EWMA which is equivalent to the UNIX five minute load + * average and which expects to be ticked every 5 seconds. + * + * @return a five-minute EWMA + */ + static TMovingAverage FiveMinutes() { + static const double M5_ALPHA = 1 - std::exp(-INTERVAL / 60.0 / 5); + return {M5_ALPHA, std::chrono::seconds(INTERVAL)}; + } + + /** + * Creates a new EWMA which is equivalent to the UNIX fifteen minute load + * average and which expects to be ticked every 5 seconds. + * + * @return a fifteen-minute EWMA + */ + static TMovingAverage FifteenMinutes() { + static const double M15_ALPHA = 1 - std::exp(-INTERVAL / 60.0 / 15); + return {M15_ALPHA, std::chrono::seconds(INTERVAL)}; + } + + /** + * Create a new EWMA with a specific smoothing constant. + * + * @param alpha the smoothing constant + * @param interval the expected tick interval + */ + TMovingAverage(double alpha, std::chrono::seconds interval) + : Initialized_(0) + , Rate_(0) + , Uncounted_(0) + , Alpha_(alpha) + , Interval_(std::chrono::nanoseconds(interval).count()) + { + } + + TMovingAverage(const TMovingAverage& rhs) + : Initialized_(AtomicGet(rhs.Initialized_)) + , Rate_(AtomicGet(rhs.Rate_)) + , Uncounted_(AtomicGet(rhs.Uncounted_)) + , Alpha_(rhs.Alpha_) + , Interval_(rhs.Interval_) + { + } + + TMovingAverage& operator=(const TMovingAverage& rhs) { + AtomicSet(Initialized_, AtomicGet(Initialized_)); + AtomicSet(Rate_, AtomicGet(rhs.Rate_)); + AtomicSet(Uncounted_, AtomicGet(rhs.Uncounted_)); + Alpha_ = rhs.Alpha_; + Interval_ = rhs.Interval_; + return *this; + } + + /** + * Update the moving average with a new value. + * + * @param n the new value + */ + void Update(ui64 n = 1) { + AtomicAdd(Uncounted_, n); + } + + /** + * Mark the passage of time and decay the current rate accordingly. + */ + void Tick() { + double instantRate = AtomicSwap(&Uncounted_, 0) / Interval_; + if (AtomicGet(Initialized_)) { + double rate = AsDouble(AtomicGet(Rate_)); + rate += (Alpha_ * (instantRate - rate)); + AtomicSet(Rate_, AsAtomic(rate)); + } else { + AtomicSet(Rate_, AsAtomic(instantRate)); + AtomicSet(Initialized_, 1); + } + } + + /** + * @return the rate in the seconds + */ + double GetRate() const { + double rate = AsDouble(AtomicGet(Rate_)); + return rate * std::nano::den; + } + + private: + static double AsDouble(TAtomicBase val) { + union { + double D; + TAtomicBase A; + } doubleAtomic; + doubleAtomic.A = val; + return doubleAtomic.D; + } + + static TAtomicBase AsAtomic(double val) { + union { + double D; + TAtomicBase A; + } doubleAtomic; + doubleAtomic.D = val; + return doubleAtomic.A; + } + + private: + TAtomic Initialized_; + TAtomic Rate_; + TAtomic Uncounted_; + double Alpha_; + double Interval_; + }; + + /** + * A meter metric which measures mean throughput and one-, five-, and + * fifteen-minute exponentially-weighted moving average throughputs. + */ + template <typename TClock> + class TMeterImpl: private TNonCopyable { + public: + TMeterImpl() + : StartTime_(TClock::now()) + , LastTick_(StartTime_.time_since_epoch().count()) + , Count_(0) + , OneMinuteRate_(TMovingAverage::OneMinute()) + , FiveMinutesRate_(TMovingAverage::FiveMinutes()) + , FifteenMinutesRate_(TMovingAverage::FifteenMinutes()) + { + } + + /** + * Mark the occurrence of events. + * + * @param n the number of events + */ + void Mark(ui64 n = 1) { + TickIfNecessary(); + AtomicAdd(Count_, n); + OneMinuteRate_.Update(n); + FiveMinutesRate_.Update(n); + FifteenMinutesRate_.Update(n); + } + + /** + * Returns the one-minute exponentially-weighted moving average rate at + * which events have occurred since the meter was created. + * + * This rate has the same exponential decay factor as the one-minute load + * average in the top Unix command. + * + * @return the one-minute exponentially-weighted moving average rate at + * which events have occurred since the meter was created + */ + double GetOneMinuteRate() const { + return OneMinuteRate_.GetRate(); + } + + /** + * Returns the five-minute exponentially-weighted moving average rate at + * which events have occurred since the meter was created. + * + * This rate has the same exponential decay factor as the five-minute load + * average in the top Unix command. + * + * @return the five-minute exponentially-weighted moving average rate at + * which events have occurred since the meter was created + */ + double GetFiveMinutesRate() const { + return FiveMinutesRate_.GetRate(); + } + + /** + * Returns the fifteen-minute exponentially-weighted moving average rate + * at which events have occurred since the meter was created. + * + * This rate has the same exponential decay factor as the fifteen-minute + * load average in the top Unix command. + * + * @return the fifteen-minute exponentially-weighted moving average rate + * at which events have occurred since the meter was created + */ + double GetFifteenMinutesRate() const { + return FifteenMinutesRate_.GetRate(); + } + + /** + * @return the mean rate at which events have occurred since the meter + * was created + */ + double GetMeanRate() const { + if (GetCount() == 0) { + return 0.0; + } + + auto now = TClock::now(); + std::chrono::duration<double> elapsedSeconds = now - StartTime_; + return GetCount() / elapsedSeconds.count(); + } + + /** + * @return the number of events which have been marked + */ + ui64 GetCount() const { + return AtomicGet(Count_); + } + + private: + void TickIfNecessary() { + static ui64 TICK_INTERVAL_NS = + std::chrono::nanoseconds( + std::chrono::seconds(TMovingAverage::INTERVAL)) + .count(); + + auto oldTickNs = AtomicGet(LastTick_); + auto newTickNs = TClock::now().time_since_epoch().count(); + ui64 elapsedNs = std::abs(newTickNs - oldTickNs); + + if (elapsedNs > TICK_INTERVAL_NS) { + // adjust to interval begining + newTickNs -= elapsedNs % TICK_INTERVAL_NS; + if (AtomicCas(&LastTick_, newTickNs, oldTickNs)) { + ui64 requiredTicks = elapsedNs / TICK_INTERVAL_NS; + for (ui64 i = 0; i < requiredTicks; ++i) { + OneMinuteRate_.Tick(); + FiveMinutesRate_.Tick(); + FifteenMinutesRate_.Tick(); + } + } + } + } + + private: + const typename TClock::time_point StartTime_; + TAtomic LastTick_; + TAtomic Count_; + TMovingAverage OneMinuteRate_; + TMovingAverage FiveMinutesRate_; + TMovingAverage FifteenMinutesRate_; + }; + + using TSystemMeter = TMeterImpl<std::chrono::system_clock>; + using TSteadyMeter = TMeterImpl<std::chrono::steady_clock>; + using THighResMeter = TMeterImpl<std::chrono::high_resolution_clock>; + using TMeter = THighResMeter; + +} diff --git a/library/cpp/monlib/counters/meter_ut.cpp b/library/cpp/monlib/counters/meter_ut.cpp index 39b1f0440a..b507d16fbd 100644 --- a/library/cpp/monlib/counters/meter_ut.cpp +++ b/library/cpp/monlib/counters/meter_ut.cpp @@ -1,41 +1,41 @@ -#include "meter.h" - +#include "meter.h" + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - -struct TMockClock { - using duration = std::chrono::nanoseconds; - using rep = duration::rep; - using period = duration::period; - using time_point = std::chrono::time_point<TMockClock, duration>; - - static time_point now() noexcept { - static int index = 0; - return index++ < 2 ? time_point() : time_point(std::chrono::seconds(10)); - } -}; - -using TMockMeter = TMeterImpl<TMockClock>; - + +using namespace NMonitoring; + +struct TMockClock { + using duration = std::chrono::nanoseconds; + using rep = duration::rep; + using period = duration::period; + using time_point = std::chrono::time_point<TMockClock, duration>; + + static time_point now() noexcept { + static int index = 0; + return index++ < 2 ? time_point() : time_point(std::chrono::seconds(10)); + } +}; + +using TMockMeter = TMeterImpl<TMockClock>; + Y_UNIT_TEST_SUITE(TMeterTest) { Y_UNIT_TEST(StartsOutWithNoRatesOrCount) { - TMeter meter; - UNIT_ASSERT_EQUAL(meter.GetCount(), 0L); - UNIT_ASSERT_DOUBLES_EQUAL(meter.GetMeanRate(), 0.0, 0.0001); - UNIT_ASSERT_DOUBLES_EQUAL(meter.GetOneMinuteRate(), 0.0, 0.0001); - UNIT_ASSERT_DOUBLES_EQUAL(meter.GetFiveMinutesRate(), 0.0, 0.0001); - UNIT_ASSERT_DOUBLES_EQUAL(meter.GetFifteenMinutesRate(), 0.0, 0.0001); - } - + TMeter meter; + UNIT_ASSERT_EQUAL(meter.GetCount(), 0L); + UNIT_ASSERT_DOUBLES_EQUAL(meter.GetMeanRate(), 0.0, 0.0001); + UNIT_ASSERT_DOUBLES_EQUAL(meter.GetOneMinuteRate(), 0.0, 0.0001); + UNIT_ASSERT_DOUBLES_EQUAL(meter.GetFiveMinutesRate(), 0.0, 0.0001); + UNIT_ASSERT_DOUBLES_EQUAL(meter.GetFifteenMinutesRate(), 0.0, 0.0001); + } + Y_UNIT_TEST(MarksEventsAndUpdatesRatesAndCount) { - TMockMeter meter; - meter.Mark(); - meter.Mark(2); - UNIT_ASSERT_EQUAL(meter.GetCount(), 3L); - UNIT_ASSERT_DOUBLES_EQUAL(meter.GetMeanRate(), 0.3, 0.001); - UNIT_ASSERT_DOUBLES_EQUAL(meter.GetOneMinuteRate(), 0.1840, 0.0001); - UNIT_ASSERT_DOUBLES_EQUAL(meter.GetFiveMinutesRate(), 0.1966, 0.0001); - UNIT_ASSERT_DOUBLES_EQUAL(meter.GetFifteenMinutesRate(), 0.1988, 0.0001); - } -} + TMockMeter meter; + meter.Mark(); + meter.Mark(2); + UNIT_ASSERT_EQUAL(meter.GetCount(), 3L); + UNIT_ASSERT_DOUBLES_EQUAL(meter.GetMeanRate(), 0.3, 0.001); + UNIT_ASSERT_DOUBLES_EQUAL(meter.GetOneMinuteRate(), 0.1840, 0.0001); + UNIT_ASSERT_DOUBLES_EQUAL(meter.GetFiveMinutesRate(), 0.1966, 0.0001); + UNIT_ASSERT_DOUBLES_EQUAL(meter.GetFifteenMinutesRate(), 0.1988, 0.0001); + } +} diff --git a/library/cpp/monlib/counters/timer.h b/library/cpp/monlib/counters/timer.h index 5b234e0907..03dfb35337 100644 --- a/library/cpp/monlib/counters/timer.h +++ b/library/cpp/monlib/counters/timer.h @@ -1,176 +1,176 @@ -#pragma once - -#include "histogram.h" - +#pragma once + +#include "histogram.h" + #include <util/generic/scope.h> -#include <chrono> - -namespace NMonitoring { - /** - * A timer counter which aggregates timing durations and provides duration - * statistics in selected time resolution. - */ - template <typename TResolution> - class TTimerImpl { - public: - /** - * Construct a timer given the Lowest and Highest values to be tracked - * and a number of significant decimal digits. Providing a - * lowestDiscernibleValue is useful in situations where the units used for - * the timer's values are much smaller that the minimal accuracy - * required. E.g. when tracking time values stated in nanosecond units, - * where the minimal accuracy required is a microsecond, the proper value - * for lowestDiscernibleValue would be 1000. - * - * @param min The lowest value that can be discerned (distinguished from - * 0) by the timer. Must be a positive integer that is >= 1. - * May be internally rounded down to nearest power of 2. - * - * @param max The highest value to be tracked by the timer. Must be a - * positive integer that is >= (2 * min). - * - * @param numberOfSignificantValueDigits Specifies the precision to use. - * This is the number of significant decimal digits to which the - * timer will maintain value resolution and separation. Must be - * a non-negative integer between 0 and 5. - */ - TTimerImpl(ui64 min, ui64 max, i32 numberOfSignificantValueDigits = 3) - : TTimerImpl(TResolution(min), TResolution(max), - numberOfSignificantValueDigits) { - } - - /** - * Construct a timer given the Lowest and Highest values to be tracked - * and a number of significant decimal digits. - * - * @param min The lowest value that can be discerned (distinguished from - * 0) by the timer. - * - * @param max The highest value to be tracked by the histogram. Must be a - * positive integer that is >= (2 * min). - * - * @param numberOfSignificantValueDigits Specifies the precision to use. - */ - template <typename TDurationMin, typename TDurationMax> - TTimerImpl(TDurationMin min, TDurationMax max, - i32 numberOfSignificantValueDigits = 3) - : Histogram_(std::chrono::duration_cast<TResolution>(min).count(), - std::chrono::duration_cast<TResolution>(max).count(), - numberOfSignificantValueDigits) { - } - - /** - * Records a value in the timer with timer resulution. Recorded value will - * be rounded to a precision at or better than the - * NumberOfSignificantValueDigits specified at construction time. - * - * @param duration duration to add to the timer - * @return false if the value is larger than the max and can't be recorded, - * true otherwise. - */ - bool RecordValue(ui64 duration) { - return Histogram_.RecordValue(duration); - } - - /** - * Records a duration in the timer. Recorded value will be converted to - * the timer resulution and rounded to a precision at or better than the - * NumberOfSignificantValueDigits specified at construction time. - * - * @param duration duration to add to the timer - * @return false if the value is larger than the max and can't be recorded, - * true otherwise. - */ - template <typename TDuration> - bool RecordValue(TDuration duration) { - auto count = static_cast<ui64>( - std::chrono::duration_cast<TResolution>(duration).count()); - return RecordValue(count); - } - - /** - * Records count values in the timer with timer resulution. Recorded value will - * be rounded to a precision at or better than the - * NumberOfSignificantValueDigits specified at construction time. - * - * @param duration duration to add to the timer - * @param count number of values to add to the histogram - * @return false if the value is larger than the max and can't be recorded, - * true otherwise. - */ - bool RecordValues(ui64 duration, ui64 count) { - return Histogram_.RecordValues(duration, count); - } - - /** - * Measures a time of functor execution. - * - * @param fn functor whose duration should be timed - */ - template <typename TFunc> - void Measure(TFunc&& fn) { - using TClock = std::chrono::high_resolution_clock; - - auto start = TClock::now(); +#include <chrono> + +namespace NMonitoring { + /** + * A timer counter which aggregates timing durations and provides duration + * statistics in selected time resolution. + */ + template <typename TResolution> + class TTimerImpl { + public: + /** + * Construct a timer given the Lowest and Highest values to be tracked + * and a number of significant decimal digits. Providing a + * lowestDiscernibleValue is useful in situations where the units used for + * the timer's values are much smaller that the minimal accuracy + * required. E.g. when tracking time values stated in nanosecond units, + * where the minimal accuracy required is a microsecond, the proper value + * for lowestDiscernibleValue would be 1000. + * + * @param min The lowest value that can be discerned (distinguished from + * 0) by the timer. Must be a positive integer that is >= 1. + * May be internally rounded down to nearest power of 2. + * + * @param max The highest value to be tracked by the timer. Must be a + * positive integer that is >= (2 * min). + * + * @param numberOfSignificantValueDigits Specifies the precision to use. + * This is the number of significant decimal digits to which the + * timer will maintain value resolution and separation. Must be + * a non-negative integer between 0 and 5. + */ + TTimerImpl(ui64 min, ui64 max, i32 numberOfSignificantValueDigits = 3) + : TTimerImpl(TResolution(min), TResolution(max), + numberOfSignificantValueDigits) { + } + + /** + * Construct a timer given the Lowest and Highest values to be tracked + * and a number of significant decimal digits. + * + * @param min The lowest value that can be discerned (distinguished from + * 0) by the timer. + * + * @param max The highest value to be tracked by the histogram. Must be a + * positive integer that is >= (2 * min). + * + * @param numberOfSignificantValueDigits Specifies the precision to use. + */ + template <typename TDurationMin, typename TDurationMax> + TTimerImpl(TDurationMin min, TDurationMax max, + i32 numberOfSignificantValueDigits = 3) + : Histogram_(std::chrono::duration_cast<TResolution>(min).count(), + std::chrono::duration_cast<TResolution>(max).count(), + numberOfSignificantValueDigits) { + } + + /** + * Records a value in the timer with timer resulution. Recorded value will + * be rounded to a precision at or better than the + * NumberOfSignificantValueDigits specified at construction time. + * + * @param duration duration to add to the timer + * @return false if the value is larger than the max and can't be recorded, + * true otherwise. + */ + bool RecordValue(ui64 duration) { + return Histogram_.RecordValue(duration); + } + + /** + * Records a duration in the timer. Recorded value will be converted to + * the timer resulution and rounded to a precision at or better than the + * NumberOfSignificantValueDigits specified at construction time. + * + * @param duration duration to add to the timer + * @return false if the value is larger than the max and can't be recorded, + * true otherwise. + */ + template <typename TDuration> + bool RecordValue(TDuration duration) { + auto count = static_cast<ui64>( + std::chrono::duration_cast<TResolution>(duration).count()); + return RecordValue(count); + } + + /** + * Records count values in the timer with timer resulution. Recorded value will + * be rounded to a precision at or better than the + * NumberOfSignificantValueDigits specified at construction time. + * + * @param duration duration to add to the timer + * @param count number of values to add to the histogram + * @return false if the value is larger than the max and can't be recorded, + * true otherwise. + */ + bool RecordValues(ui64 duration, ui64 count) { + return Histogram_.RecordValues(duration, count); + } + + /** + * Measures a time of functor execution. + * + * @param fn functor whose duration should be timed + */ + template <typename TFunc> + void Measure(TFunc&& fn) { + using TClock = std::chrono::high_resolution_clock; + + auto start = TClock::now(); Y_SCOPE_EXIT(this, start) { - RecordValue(TClock::now() - start); - }; - - fn(); - } - - /** - * Place a copy of the value counts accumulated since the last snapshot - * was taken into {@code snapshot}. Calling this member-function will - * reset the value counts, and start accumulating value counts for the - * next interval. - * - * @param snapshot the structure into which the values should be copied. - */ - void TakeSnapshot(THistogramSnapshot* snapshot) { - Histogram_.TakeSnaphot(snapshot); - } - - private: - THdrHistogram Histogram_; - }; - - /** - * Timer template instantiations for certain time resolutions. - */ - using TTimerNs = TTimerImpl<std::chrono::nanoseconds>; - using TTimerUs = TTimerImpl<std::chrono::microseconds>; - using TTimerMs = TTimerImpl<std::chrono::milliseconds>; - using TTimerS = TTimerImpl<std::chrono::seconds>; - - /** - * A timing scope to record elapsed time since creation. - */ - template <typename TTimer, typename TFunc = std::function<void(std::chrono::high_resolution_clock::duration)>> - class TTimerScope { - using TClock = std::chrono::high_resolution_clock; - - public: - explicit TTimerScope(TTimer* timer, TFunc* callback = nullptr) - : Timer_(timer) - , StartTime_(TClock::now()) - , Callback_(callback) - { - } - - ~TTimerScope() { - TClock::duration duration = TClock::now() - StartTime_; - if (Callback_) { - (*Callback_)(duration); - } - Timer_->RecordValue(duration); + RecordValue(TClock::now() - start); + }; + + fn(); + } + + /** + * Place a copy of the value counts accumulated since the last snapshot + * was taken into {@code snapshot}. Calling this member-function will + * reset the value counts, and start accumulating value counts for the + * next interval. + * + * @param snapshot the structure into which the values should be copied. + */ + void TakeSnapshot(THistogramSnapshot* snapshot) { + Histogram_.TakeSnaphot(snapshot); + } + + private: + THdrHistogram Histogram_; + }; + + /** + * Timer template instantiations for certain time resolutions. + */ + using TTimerNs = TTimerImpl<std::chrono::nanoseconds>; + using TTimerUs = TTimerImpl<std::chrono::microseconds>; + using TTimerMs = TTimerImpl<std::chrono::milliseconds>; + using TTimerS = TTimerImpl<std::chrono::seconds>; + + /** + * A timing scope to record elapsed time since creation. + */ + template <typename TTimer, typename TFunc = std::function<void(std::chrono::high_resolution_clock::duration)>> + class TTimerScope { + using TClock = std::chrono::high_resolution_clock; + + public: + explicit TTimerScope(TTimer* timer, TFunc* callback = nullptr) + : Timer_(timer) + , StartTime_(TClock::now()) + , Callback_(callback) + { } - - private: - TTimer* Timer_; - TClock::time_point StartTime_; - TFunc* Callback_; - }; -} + + ~TTimerScope() { + TClock::duration duration = TClock::now() - StartTime_; + if (Callback_) { + (*Callback_)(duration); + } + Timer_->RecordValue(duration); + } + + private: + TTimer* Timer_; + TClock::time_point StartTime_; + TFunc* Callback_; + }; +} diff --git a/library/cpp/monlib/counters/timer_ut.cpp b/library/cpp/monlib/counters/timer_ut.cpp index f92d38a445..c5cd07e89d 100644 --- a/library/cpp/monlib/counters/timer_ut.cpp +++ b/library/cpp/monlib/counters/timer_ut.cpp @@ -1,14 +1,14 @@ -#include "timer.h" - +#include "timer.h" + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; -using namespace std::literals::chrono_literals; - + +using namespace NMonitoring; +using namespace std::literals::chrono_literals; + class TCallback { public: - explicit TCallback(int value) - : Value_(value){}; + explicit TCallback(int value) + : Value_(value){}; void operator()(std::chrono::high_resolution_clock::duration duration) { Value_ = duration.count(); }; @@ -18,50 +18,50 @@ public: Y_UNIT_TEST_SUITE(TTimerTest) { Y_UNIT_TEST(RecordValue) { - TTimerNs timerNs(1ns, 1s); - UNIT_ASSERT(timerNs.RecordValue(10us)); - - TTimerUs timerUs(1us, 1s); - UNIT_ASSERT(timerUs.RecordValue(10us)); - - THistogramSnapshot snapshot; - timerNs.TakeSnapshot(&snapshot); - UNIT_ASSERT_EQUAL(snapshot.Min, 10000); - UNIT_ASSERT_EQUAL(snapshot.Max, 10007); - UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.0, 1e-6); - - timerUs.TakeSnapshot(&snapshot); - UNIT_ASSERT_EQUAL(snapshot.Min, 10); - UNIT_ASSERT_EQUAL(snapshot.Max, 10); - UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.0, 1e-6); - } - + TTimerNs timerNs(1ns, 1s); + UNIT_ASSERT(timerNs.RecordValue(10us)); + + TTimerUs timerUs(1us, 1s); + UNIT_ASSERT(timerUs.RecordValue(10us)); + + THistogramSnapshot snapshot; + timerNs.TakeSnapshot(&snapshot); + UNIT_ASSERT_EQUAL(snapshot.Min, 10000); + UNIT_ASSERT_EQUAL(snapshot.Max, 10007); + UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.0, 1e-6); + + timerUs.TakeSnapshot(&snapshot); + UNIT_ASSERT_EQUAL(snapshot.Min, 10); + UNIT_ASSERT_EQUAL(snapshot.Max, 10); + UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.0, 1e-6); + } + Y_UNIT_TEST(Measure) { - TTimerNs timer(1ns, 1s); - timer.Measure([]() { - Sleep(TDuration::MilliSeconds(1)); - }); - THistogramSnapshot snapshot; - timer.TakeSnapshot(&snapshot); - - UNIT_ASSERT(snapshot.Min > std::chrono::nanoseconds(1ms).count()); - UNIT_ASSERT(snapshot.Max > std::chrono::nanoseconds(1ms).count()); - UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.0, 1e-6); - } - + TTimerNs timer(1ns, 1s); + timer.Measure([]() { + Sleep(TDuration::MilliSeconds(1)); + }); + THistogramSnapshot snapshot; + timer.TakeSnapshot(&snapshot); + + UNIT_ASSERT(snapshot.Min > std::chrono::nanoseconds(1ms).count()); + UNIT_ASSERT(snapshot.Max > std::chrono::nanoseconds(1ms).count()); + UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.0, 1e-6); + } + Y_UNIT_TEST(TimerScope) { - TTimerUs timer(1us, 1000s); - { - TTimerScope<TTimerUs> scope(&timer); - Sleep(TDuration::MilliSeconds(10)); - } - THistogramSnapshot snapshot; - timer.TakeSnapshot(&snapshot); - - UNIT_ASSERT(snapshot.Min > std::chrono::microseconds(10ms).count()); - UNIT_ASSERT(snapshot.Max > std::chrono::microseconds(10ms).count()); - UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.0, 1e-6); - } + TTimerUs timer(1us, 1000s); + { + TTimerScope<TTimerUs> scope(&timer); + Sleep(TDuration::MilliSeconds(10)); + } + THistogramSnapshot snapshot; + timer.TakeSnapshot(&snapshot); + + UNIT_ASSERT(snapshot.Min > std::chrono::microseconds(10ms).count()); + UNIT_ASSERT(snapshot.Max > std::chrono::microseconds(10ms).count()); + UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.0, 1e-6); + } Y_UNIT_TEST(TimerScopeWithCallback) { TCallback callback(0); @@ -78,4 +78,4 @@ Y_UNIT_TEST_SUITE(TTimerTest) { UNIT_ASSERT_DOUBLES_EQUAL(snapshot.StdDeviation, 0.0, 1e-6); UNIT_ASSERT(callback.Value_ > std::chrono::microseconds(10ms).count()); } -} +} diff --git a/library/cpp/monlib/counters/ut/ya.make b/library/cpp/monlib/counters/ut/ya.make index 3c8540c67d..999dadb199 100644 --- a/library/cpp/monlib/counters/ut/ya.make +++ b/library/cpp/monlib/counters/ut/ya.make @@ -1,12 +1,12 @@ -UNITTEST_FOR(library/cpp/monlib/counters) - -OWNER(jamel) - -SRCS( - counters_ut.cpp - histogram_ut.cpp - meter_ut.cpp - timer_ut.cpp -) - -END() +UNITTEST_FOR(library/cpp/monlib/counters) + +OWNER(jamel) + +SRCS( + counters_ut.cpp + histogram_ut.cpp + meter_ut.cpp + timer_ut.cpp +) + +END() diff --git a/library/cpp/monlib/counters/ya.make b/library/cpp/monlib/counters/ya.make index d569608035..aa1a671bf8 100644 --- a/library/cpp/monlib/counters/ya.make +++ b/library/cpp/monlib/counters/ya.make @@ -1,15 +1,15 @@ -LIBRARY() - -OWNER(jamel) - -SRCS( - counters.cpp - histogram.cpp - meter.cpp -) - -PEERDIR( +LIBRARY() + +OWNER(jamel) + +SRCS( + counters.cpp + histogram.cpp + meter.cpp +) + +PEERDIR( library/cpp/histogram/hdr -) - -END() +) + +END() diff --git a/library/cpp/monlib/deprecated/json/ut/ya.make b/library/cpp/monlib/deprecated/json/ut/ya.make index 3c4c338882..18315993b5 100644 --- a/library/cpp/monlib/deprecated/json/ut/ya.make +++ b/library/cpp/monlib/deprecated/json/ut/ya.make @@ -1,4 +1,4 @@ -UNITTEST_FOR(library/cpp/monlib/deprecated/json) +UNITTEST_FOR(library/cpp/monlib/deprecated/json) OWNER( jamel @@ -6,7 +6,7 @@ OWNER( ) SRCS( - writer_ut.cpp + writer_ut.cpp ) END() diff --git a/library/cpp/monlib/deprecated/json/writer.cpp b/library/cpp/monlib/deprecated/json/writer.cpp index fca3834ebc..a581f2e07a 100644 --- a/library/cpp/monlib/deprecated/json/writer.cpp +++ b/library/cpp/monlib/deprecated/json/writer.cpp @@ -1,100 +1,100 @@ -#include "writer.h" - -namespace NMonitoring { - TDeprecatedJsonWriter::TDeprecatedJsonWriter(IOutputStream* out) - : JsonWriter(out, false) - , State(STATE_ROOT) - { - } - - void TDeprecatedJsonWriter::TransitionState(EState current, EState next) { - if (State != current) { - ythrow yexception() << "wrong state"; - } - State = next; - } - - void TDeprecatedJsonWriter::OpenDocument() { - TransitionState(STATE_ROOT, STATE_DOCUMENT); - JsonWriter.OpenMap(); - } - - void TDeprecatedJsonWriter::CloseDocument() { - TransitionState(STATE_DOCUMENT, STATE_ROOT); - JsonWriter.CloseMap(); - JsonWriter.Flush(); - } - - void TDeprecatedJsonWriter::OpenCommonLabels() { - TransitionState(STATE_DOCUMENT, STATE_COMMON_LABELS); - JsonWriter.Write("commonLabels"); - JsonWriter.OpenMap(); - } - - void TDeprecatedJsonWriter::CloseCommonLabels() { - TransitionState(STATE_COMMON_LABELS, STATE_DOCUMENT); - JsonWriter.CloseMap(); - } - - void TDeprecatedJsonWriter::WriteCommonLabel(TStringBuf name, TStringBuf value) { - TransitionState(STATE_COMMON_LABELS, STATE_COMMON_LABELS); - JsonWriter.Write(name, value); - } - - void TDeprecatedJsonWriter::OpenMetrics() { - TransitionState(STATE_DOCUMENT, STATE_METRICS); - JsonWriter.Write("sensors"); - JsonWriter.OpenArray(); - } - - void TDeprecatedJsonWriter::CloseMetrics() { - TransitionState(STATE_METRICS, STATE_DOCUMENT); - JsonWriter.CloseArray(); - } - - void TDeprecatedJsonWriter::OpenMetric() { - TransitionState(STATE_METRICS, STATE_METRIC); - JsonWriter.OpenMap(); - } - - void TDeprecatedJsonWriter::CloseMetric() { - TransitionState(STATE_METRIC, STATE_METRICS); - JsonWriter.CloseMap(); - } - - void TDeprecatedJsonWriter::OpenLabels() { - TransitionState(STATE_METRIC, STATE_LABELS); - JsonWriter.Write("labels"); - JsonWriter.OpenMap(); - } - - void TDeprecatedJsonWriter::CloseLabels() { - TransitionState(STATE_LABELS, STATE_METRIC); - JsonWriter.CloseMap(); - } - - void TDeprecatedJsonWriter::WriteLabel(TStringBuf name, TStringBuf value) { - TransitionState(STATE_LABELS, STATE_LABELS); - JsonWriter.Write(name, value); - } - - void TDeprecatedJsonWriter::WriteModeDeriv() { - TransitionState(STATE_METRIC, STATE_METRIC); - JsonWriter.Write("mode", "deriv"); - } - - void TDeprecatedJsonWriter::WriteValue(long long value) { - TransitionState(STATE_METRIC, STATE_METRIC); - JsonWriter.Write("value", value); - } - - void TDeprecatedJsonWriter::WriteDoubleValue(double value) { - TransitionState(STATE_METRIC, STATE_METRIC); - JsonWriter.Write("value", value); - } - - void TDeprecatedJsonWriter::WriteTs(ui64 ts) { - TransitionState(STATE_METRIC, STATE_METRIC); - JsonWriter.Write("ts", ts); - } +#include "writer.h" + +namespace NMonitoring { + TDeprecatedJsonWriter::TDeprecatedJsonWriter(IOutputStream* out) + : JsonWriter(out, false) + , State(STATE_ROOT) + { + } + + void TDeprecatedJsonWriter::TransitionState(EState current, EState next) { + if (State != current) { + ythrow yexception() << "wrong state"; + } + State = next; + } + + void TDeprecatedJsonWriter::OpenDocument() { + TransitionState(STATE_ROOT, STATE_DOCUMENT); + JsonWriter.OpenMap(); + } + + void TDeprecatedJsonWriter::CloseDocument() { + TransitionState(STATE_DOCUMENT, STATE_ROOT); + JsonWriter.CloseMap(); + JsonWriter.Flush(); + } + + void TDeprecatedJsonWriter::OpenCommonLabels() { + TransitionState(STATE_DOCUMENT, STATE_COMMON_LABELS); + JsonWriter.Write("commonLabels"); + JsonWriter.OpenMap(); + } + + void TDeprecatedJsonWriter::CloseCommonLabels() { + TransitionState(STATE_COMMON_LABELS, STATE_DOCUMENT); + JsonWriter.CloseMap(); + } + + void TDeprecatedJsonWriter::WriteCommonLabel(TStringBuf name, TStringBuf value) { + TransitionState(STATE_COMMON_LABELS, STATE_COMMON_LABELS); + JsonWriter.Write(name, value); + } + + void TDeprecatedJsonWriter::OpenMetrics() { + TransitionState(STATE_DOCUMENT, STATE_METRICS); + JsonWriter.Write("sensors"); + JsonWriter.OpenArray(); + } + + void TDeprecatedJsonWriter::CloseMetrics() { + TransitionState(STATE_METRICS, STATE_DOCUMENT); + JsonWriter.CloseArray(); + } + + void TDeprecatedJsonWriter::OpenMetric() { + TransitionState(STATE_METRICS, STATE_METRIC); + JsonWriter.OpenMap(); + } + + void TDeprecatedJsonWriter::CloseMetric() { + TransitionState(STATE_METRIC, STATE_METRICS); + JsonWriter.CloseMap(); + } + + void TDeprecatedJsonWriter::OpenLabels() { + TransitionState(STATE_METRIC, STATE_LABELS); + JsonWriter.Write("labels"); + JsonWriter.OpenMap(); + } + + void TDeprecatedJsonWriter::CloseLabels() { + TransitionState(STATE_LABELS, STATE_METRIC); + JsonWriter.CloseMap(); + } + + void TDeprecatedJsonWriter::WriteLabel(TStringBuf name, TStringBuf value) { + TransitionState(STATE_LABELS, STATE_LABELS); + JsonWriter.Write(name, value); + } + + void TDeprecatedJsonWriter::WriteModeDeriv() { + TransitionState(STATE_METRIC, STATE_METRIC); + JsonWriter.Write("mode", "deriv"); + } + + void TDeprecatedJsonWriter::WriteValue(long long value) { + TransitionState(STATE_METRIC, STATE_METRIC); + JsonWriter.Write("value", value); + } + + void TDeprecatedJsonWriter::WriteDoubleValue(double value) { + TransitionState(STATE_METRIC, STATE_METRIC); + JsonWriter.Write("value", value); + } + + void TDeprecatedJsonWriter::WriteTs(ui64 ts) { + TransitionState(STATE_METRIC, STATE_METRIC); + JsonWriter.Write("ts", ts); + } } diff --git a/library/cpp/monlib/deprecated/json/writer.h b/library/cpp/monlib/deprecated/json/writer.h index 003992dd9f..183288143c 100644 --- a/library/cpp/monlib/deprecated/json/writer.h +++ b/library/cpp/monlib/deprecated/json/writer.h @@ -2,30 +2,30 @@ #include <library/cpp/json/json_writer.h> -namespace NMonitoring { - /** - * Deprecated writer of Solomon JSON format - * https://wiki.yandex-team.ru/solomon/api/dataformat/json - * - * This writer will be deleted soon, so please consider to use - * high level library library/cpp/monlib/encode which is decoupled from the - * particular format. - */ - class TDeprecatedJsonWriter { +namespace NMonitoring { + /** + * Deprecated writer of Solomon JSON format + * https://wiki.yandex-team.ru/solomon/api/dataformat/json + * + * This writer will be deleted soon, so please consider to use + * high level library library/cpp/monlib/encode which is decoupled from the + * particular format. + */ + class TDeprecatedJsonWriter { private: NJson::TJsonWriter JsonWriter; enum EState { STATE_ROOT, STATE_DOCUMENT, STATE_COMMON_LABELS, - STATE_METRICS, - STATE_METRIC, + STATE_METRICS, + STATE_METRIC, STATE_LABELS, }; EState State; - + public: - explicit TDeprecatedJsonWriter(IOutputStream* out); + explicit TDeprecatedJsonWriter(IOutputStream* out); void OpenDocument(); void CloseDocument(); @@ -35,11 +35,11 @@ namespace NMonitoring { void WriteCommonLabel(TStringBuf name, TStringBuf value); - void OpenMetrics(); - void CloseMetrics(); + void OpenMetrics(); + void CloseMetrics(); - void OpenMetric(); - void CloseMetric(); + void OpenMetric(); + void CloseMetric(); void OpenLabels(); void CloseLabels(); @@ -59,13 +59,13 @@ namespace NMonitoring { void WriteDoubleValue(double d); void WriteTs(ui64 ts); - + private: void WriteLabelsInner(TStringBuf name, TStringBuf value) { WriteLabel(name, value); } - template <typename... T> + template <typename... T> void WriteLabelsInner(TStringBuf name, TStringBuf value, T... pairs) { WriteLabel(name, value); WriteLabelsInner(pairs...); @@ -73,4 +73,4 @@ namespace NMonitoring { inline void TransitionState(EState current, EState next); }; -} +} diff --git a/library/cpp/monlib/deprecated/json/writer_ut.cpp b/library/cpp/monlib/deprecated/json/writer_ut.cpp index f39fe85f1c..1f9fc8f393 100644 --- a/library/cpp/monlib/deprecated/json/writer_ut.cpp +++ b/library/cpp/monlib/deprecated/json/writer_ut.cpp @@ -1,30 +1,30 @@ -#include "writer.h" - +#include "writer.h" + #include <library/cpp/testing/unittest/registar.h> -using namespace NMonitoring; +using namespace NMonitoring; -Y_UNIT_TEST_SUITE(JsonWriterTests) { +Y_UNIT_TEST_SUITE(JsonWriterTests) { Y_UNIT_TEST(One) { TStringStream ss; - TDeprecatedJsonWriter w(&ss); + TDeprecatedJsonWriter w(&ss); w.OpenDocument(); - w.OpenMetrics(); + w.OpenMetrics(); for (int i = 0; i < 5; ++i) { - w.OpenMetric(); + w.OpenMetric(); w.OpenLabels(); - w.WriteLabel("user", TString("") + (char)('a' + i)); - w.WriteLabel("name", "NWrites"); + w.WriteLabel("user", TString("") + (char)('a' + i)); + w.WriteLabel("name", "NWrites"); w.CloseLabels(); if (i % 2 == 0) { w.WriteModeDeriv(); } w.WriteValue(10l); - w.CloseMetric(); + w.CloseMetric(); } - w.CloseMetrics(); + w.CloseMetrics(); w.CloseDocument(); //Cout << ss.Str() << "\n"; diff --git a/library/cpp/monlib/deprecated/json/ya.make b/library/cpp/monlib/deprecated/json/ya.make index b20030dd31..0ca903ee62 100644 --- a/library/cpp/monlib/deprecated/json/ya.make +++ b/library/cpp/monlib/deprecated/json/ya.make @@ -1,26 +1,26 @@ LIBRARY() -# Deprecated writer of Solomon JSON format +# Deprecated writer of Solomon JSON format # https://wiki.yandex-team.ru/solomon/api/dataformat/json -# -# This writer will be deleted soon, so please consider to use -# high level library library/cpp/monlib/encode which is decoupled from the -# particular format. +# +# This writer will be deleted soon, so please consider to use +# high level library library/cpp/monlib/encode which is decoupled from the +# particular format. OWNER( jamel g:solomon ) -SRCS( - writer.h - writer.cpp -) - +SRCS( + writer.h + writer.cpp +) + PEERDIR( library/cpp/json ) END() - -RECURSE_FOR_TESTS(ut) + +RECURSE_FOR_TESTS(ut) diff --git a/library/cpp/monlib/deprecated/ya.make b/library/cpp/monlib/deprecated/ya.make index 7d541ab2a8..9345139aee 100644 --- a/library/cpp/monlib/deprecated/ya.make +++ b/library/cpp/monlib/deprecated/ya.make @@ -1,8 +1,8 @@ -OWNER( - g:solomon - jamel -) - -RECURSE( - json -) +OWNER( + g:solomon + jamel +) + +RECURSE( + json +) diff --git a/library/cpp/monlib/dynamic_counters/contention_ut.cpp b/library/cpp/monlib/dynamic_counters/contention_ut.cpp index 9b6f8af254..8798044ee3 100644 --- a/library/cpp/monlib/dynamic_counters/contention_ut.cpp +++ b/library/cpp/monlib/dynamic_counters/contention_ut.cpp @@ -28,7 +28,7 @@ Y_UNIT_TEST_SUITE(TDynamicCountersContentionTest) { Thread.Join(); } - void OnCounter(const TString& /*labelName*/, const TString& /*labelValue*/, const TCounterForPtr* /*counter*/) override { + void OnCounter(const TString& /*labelName*/, const TString& /*labelValue*/, const TCounterForPtr* /*counter*/) override { Ev.Signal(); Response.Wait(); } @@ -36,10 +36,10 @@ Y_UNIT_TEST_SUITE(TDynamicCountersContentionTest) { void OnHistogram(const TString& /*labelName*/, const TString& /*labelValue*/, IHistogramSnapshotPtr /*snapshot*/, bool /*derivative*/) override { } - void OnGroupBegin(const TString& /*labelName*/, const TString& /*labelValue*/, const TDynamicCounters* /*group*/) override { + void OnGroupBegin(const TString& /*labelName*/, const TString& /*labelValue*/, const TDynamicCounters* /*group*/) override { } - void OnGroupEnd(const TString& /*labelName*/, const TString& /*labelValue*/, const TDynamicCounters* /*group*/) override { + void OnGroupEnd(const TString& /*labelName*/, const TString& /*labelValue*/, const TDynamicCounters* /*group*/) override { } private: diff --git a/library/cpp/monlib/dynamic_counters/counters.cpp b/library/cpp/monlib/dynamic_counters/counters.cpp index 96de74b3c9..3635d87d0d 100644 --- a/library/cpp/monlib/dynamic_counters/counters.cpp +++ b/library/cpp/monlib/dynamic_counters/counters.cpp @@ -1,7 +1,7 @@ -#include "counters.h" - -#include <library/cpp/monlib/service/pages/templates.h> - +#include "counters.h" + +#include <library/cpp/monlib/service/pages/templates.h> + #include <util/generic/cast.h> using namespace NMonitoring; @@ -45,14 +45,14 @@ namespace { } static constexpr TStringBuf INDENT = " "; - + TDynamicCounters::TDynamicCounters(EVisibility vis) { Visibility_ = vis; -} +} -TDynamicCounters::~TDynamicCounters() { -} +TDynamicCounters::~TDynamicCounters() { +} TDynamicCounters::TCounterPtr TDynamicCounters::GetExpiringCounter(const TString& value, bool derivative, EVisibility vis) { return GetExpiringNamedCounter("sensor", value, derivative, vis); @@ -72,20 +72,20 @@ TDynamicCounters::TCounterPtr TDynamicCounters::GetNamedCounter(const TString& n THistogramPtr TDynamicCounters::GetHistogram(const TString& value, IHistogramCollectorPtr collector, bool derivative, EVisibility vis) { return GetNamedHistogram("sensor", value, std::move(collector), derivative, vis); -} - +} + THistogramPtr TDynamicCounters::GetNamedHistogram(const TString& name, const TString& value, IHistogramCollectorPtr collector, bool derivative, EVisibility vis) { return AsHistogramRef(GetNamedCounterImpl<false, THistogramCounter>(name, value, std::move(collector), derivative, vis)); } - + THistogramPtr TDynamicCounters::GetExpiringHistogram(const TString& value, IHistogramCollectorPtr collector, bool derivative, EVisibility vis) { return GetExpiringNamedHistogram("sensor", value, std::move(collector), derivative, vis); } - + THistogramPtr TDynamicCounters::GetExpiringNamedHistogram(const TString& name, const TString& value, IHistogramCollectorPtr collector, bool derivative, EVisibility vis) { return AsHistogramRef(GetNamedCounterImpl<true, TExpiringHistogramCounter>(name, value, std::move(collector), derivative, vis)); -} - +} + TDynamicCounters::TCounterPtr TDynamicCounters::FindCounter(const TString& value) const { return FindNamedCounter("sensor", value); } @@ -113,7 +113,7 @@ void TDynamicCounters::RemoveNamedCounter(const TString& name, const TString &va } } -TIntrusivePtr<TDynamicCounters> TDynamicCounters::GetSubgroup(const TString& name, const TString& value) { +TIntrusivePtr<TDynamicCounters> TDynamicCounters::GetSubgroup(const TString& name, const TString& value) { auto res = FindSubgroup(name, value); if (!res) { auto g = LockForUpdate("GetSubgroup", name, value); @@ -128,7 +128,7 @@ TIntrusivePtr<TDynamicCounters> TDynamicCounters::GetSubgroup(const TString& nam return res; } -TIntrusivePtr<TDynamicCounters> TDynamicCounters::FindSubgroup(const TString& name, const TString& value) const { +TIntrusivePtr<TDynamicCounters> TDynamicCounters::FindSubgroup(const TString& name, const TString& value) const { TReadGuard g(Lock); const auto it = Counters.find({name, value}); return it != Counters.end() ? AsDynamicCounters(it->second) : nullptr; @@ -183,7 +183,7 @@ void TDynamicCounters::RegisterSubgroup(const TString& name, const TString& valu RegisterCountable(name, value, subgroup); } -void TDynamicCounters::OutputHtml(IOutputStream& os) const { +void TDynamicCounters::OutputHtml(IOutputStream& os) const { HTML(os) { PRE() { OutputPlainText(os); @@ -191,7 +191,7 @@ void TDynamicCounters::OutputHtml(IOutputStream& os) const { } } -void TDynamicCounters::EnumerateSubgroups(const std::function<void(const TString& name, const TString& value)>& output) const { +void TDynamicCounters::EnumerateSubgroups(const std::function<void(const TString& name, const TString& value)>& output) const { TReadGuard g(Lock); for (const auto& [key, value] : Counters) { if (AsDynamicCounters(value)) { @@ -209,29 +209,29 @@ void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent) for (const auto& [key, value] : snap) { if (const auto counter = AsCounter(value)) { - os << indent + os << indent << key.LabelName << '=' << key.LabelValue - << ": " << counter->Val() + << ": " << counter->Val() << outputVisibilityMarker(counter->Visibility()) - << '\n'; + << '\n'; } else if (const auto histogram = AsHistogram(value)) { - os << indent + os << indent << key.LabelName << '=' << key.LabelValue << ":" << outputVisibilityMarker(histogram->Visibility()) << "\n"; - - auto snapshot = histogram->Snapshot(); - for (ui32 i = 0, count = snapshot->Count(); i < count; i++) { + + auto snapshot = histogram->Snapshot(); + for (ui32 i = 0, count = snapshot->Count(); i < count; i++) { os << indent << INDENT << TStringBuf("bin="); - TBucketBound bound = snapshot->UpperBound(i); - if (bound == Max<TBucketBound>()) { + TBucketBound bound = snapshot->UpperBound(i); + if (bound == Max<TBucketBound>()) { os << TStringBuf("inf"); - } else { - os << bound; - } - os << ": " << snapshot->Value(i) << '\n'; - } + } else { + os << bound; + } + os << ": " << snapshot->Value(i) << '\n'; + } } } @@ -239,22 +239,22 @@ void TDynamicCounters::OutputPlainText(IOutputStream& os, const TString& indent) if (const auto subgroup = AsDynamicCounters(value)) { os << "\n"; os << indent << key.LabelName << "=" << key.LabelValue << ":\n"; - subgroup->OutputPlainText(os, indent + INDENT); + subgroup->OutputPlainText(os, indent + INDENT); } } } -void TDynamicCounters::Accept(const TString& labelName, const TString& labelValue, ICountableConsumer& consumer) const { +void TDynamicCounters::Accept(const TString& labelName, const TString& labelValue, ICountableConsumer& consumer) const { if (!IsVisible(Visibility(), consumer.Visibility())) { return; } - consumer.OnGroupBegin(labelName, labelValue, this); + consumer.OnGroupBegin(labelName, labelValue, this); for (auto& [key, value] : ReadSnapshot()) { value->Accept(key.LabelName, key.LabelValue, consumer); - } - consumer.OnGroupEnd(labelName, labelValue, this); -} + } + consumer.OnGroupEnd(labelName, labelValue, this); +} void TDynamicCounters::RemoveExpired() const { if (AtomicGet(ExpiringCount) == 0) { diff --git a/library/cpp/monlib/dynamic_counters/counters.h b/library/cpp/monlib/dynamic_counters/counters.h index bc78538ef8..dc178cfbe0 100644 --- a/library/cpp/monlib/dynamic_counters/counters.h +++ b/library/cpp/monlib/dynamic_counters/counters.h @@ -1,24 +1,24 @@ #pragma once -#include <library/cpp/monlib/counters/counters.h> -#include <library/cpp/monlib/metrics/histogram_collector.h> - +#include <library/cpp/monlib/counters/counters.h> +#include <library/cpp/monlib/metrics/histogram_collector.h> + #include <library/cpp/threading/light_rw_lock/lightrwlock.h> #include <library/cpp/containers/stack_vector/stack_vec.h> #include <util/generic/cast.h> #include <util/generic/map.h> #include <util/generic/ptr.h> -#include <util/string/cast.h> +#include <util/string/cast.h> #include <util/system/rwlock.h> - + #include <functional> namespace NMonitoring { - struct TCounterForPtr; - struct TDynamicCounters; - struct ICountableConsumer; - + struct TCounterForPtr; + struct TDynamicCounters; + struct ICountableConsumer; + struct TCountableBase: public TAtomicRefCount<TCountableBase> { // Private means that the object must not be serialized unless the consumer @@ -31,12 +31,12 @@ namespace NMonitoring { Private, }; - virtual ~TCountableBase() { - } - - virtual void Accept( - const TString& labelName, const TString& labelValue, - ICountableConsumer& consumer) const = 0; + virtual ~TCountableBase() { + } + + virtual void Accept( + const TString& labelName, const TString& labelValue, + ICountableConsumer& consumer) const = 0; virtual EVisibility Visibility() const { return Visibility_; @@ -56,64 +56,64 @@ namespace NMonitoring { return true; } - struct ICountableConsumer { - virtual ~ICountableConsumer() { - } - - virtual void OnCounter( - const TString& labelName, const TString& labelValue, - const TCounterForPtr* counter) = 0; - - virtual void OnHistogram( - const TString& labelName, const TString& labelValue, + struct ICountableConsumer { + virtual ~ICountableConsumer() { + } + + virtual void OnCounter( + const TString& labelName, const TString& labelValue, + const TCounterForPtr* counter) = 0; + + virtual void OnHistogram( + const TString& labelName, const TString& labelValue, IHistogramSnapshotPtr snapshot, bool derivative) = 0; - - virtual void OnGroupBegin( - const TString& labelName, const TString& labelValue, - const TDynamicCounters* group) = 0; - - virtual void OnGroupEnd( - const TString& labelName, const TString& labelValue, - const TDynamicCounters* group) = 0; + + virtual void OnGroupBegin( + const TString& labelName, const TString& labelValue, + const TDynamicCounters* group) = 0; + + virtual void OnGroupEnd( + const TString& labelName, const TString& labelValue, + const TDynamicCounters* group) = 0; virtual TCountableBase::EVisibility Visibility() const { return TCountableBase::EVisibility::Unspecified; } - }; - + }; + #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4522) // multiple assignment operators specified #endif // _MSC_VER - struct TCounterForPtr: public TDeprecatedCounter, public TCountableBase { + struct TCounterForPtr: public TDeprecatedCounter, public TCountableBase { TCounterForPtr(bool derivative = false, EVisibility vis = EVisibility::Public) - : TDeprecatedCounter(0ULL, derivative) - { + : TDeprecatedCounter(0ULL, derivative) + { Visibility_ = vis; - } - + } + TCounterForPtr(const TCounterForPtr&) = delete; TCounterForPtr& operator=(const TCounterForPtr& other) = delete; - void Accept( - const TString& labelName, const TString& labelValue, - ICountableConsumer& consumer) const override { + void Accept( + const TString& labelName, const TString& labelValue, + ICountableConsumer& consumer) const override { if (IsVisible(Visibility(), consumer.Visibility())) { consumer.OnCounter(labelName, labelValue, this); } - } - + } + TCountableBase::EVisibility Visibility() const override { return Visibility_; } - using TDeprecatedCounter::operator++; - using TDeprecatedCounter::operator--; - using TDeprecatedCounter::operator+=; - using TDeprecatedCounter::operator-=; - using TDeprecatedCounter::operator=; - using TDeprecatedCounter::operator!; + using TDeprecatedCounter::operator++; + using TDeprecatedCounter::operator--; + using TDeprecatedCounter::operator+=; + using TDeprecatedCounter::operator-=; + using TDeprecatedCounter::operator=; + using TDeprecatedCounter::operator!; }; struct TExpiringCounter: public TCounterForPtr { @@ -124,27 +124,27 @@ namespace NMonitoring { } void Reset() { - TDeprecatedCounter::operator=(0); + TDeprecatedCounter::operator=(0); } }; - struct THistogramCounter: public TCountableBase { + struct THistogramCounter: public TCountableBase { explicit THistogramCounter( IHistogramCollectorPtr collector, bool derivative = true, EVisibility vis = EVisibility::Public) - : Collector_(std::move(collector)) + : Collector_(std::move(collector)) , Derivative_(derivative) - { + { Visibility_ = vis; - } - - void Collect(i64 value) { - Collector_->Collect(value); - } - - void Collect(i64 value, ui32 count) { - Collector_->Collect(value, count); - } - + } + + void Collect(i64 value) { + Collector_->Collect(value); + } + + void Collect(i64 value, ui32 count) { + Collector_->Collect(value, count); + } + void Collect(double value, ui32 count) { Collector_->Collect(value, count); } @@ -153,34 +153,34 @@ namespace NMonitoring { Collector_->Collect(snapshot); } - void Accept( - const TString& labelName, const TString& labelValue, - ICountableConsumer& consumer) const override - { + void Accept( + const TString& labelName, const TString& labelValue, + ICountableConsumer& consumer) const override + { if (IsVisible(Visibility(), consumer.Visibility())) { consumer.OnHistogram(labelName, labelValue, Collector_->Snapshot(), Derivative_); } - } - + } + void Reset() { Collector_->Reset(); } - IHistogramSnapshotPtr Snapshot() const { - return Collector_->Snapshot(); - } - - private: - IHistogramCollectorPtr Collector_; + IHistogramSnapshotPtr Snapshot() const { + return Collector_->Snapshot(); + } + + private: + IHistogramCollectorPtr Collector_; bool Derivative_; - }; - + }; + struct TExpiringHistogramCounter: public THistogramCounter { using THistogramCounter::THistogramCounter; }; - using THistogramPtr = TIntrusivePtr<THistogramCounter>; - + using THistogramPtr = TIntrusivePtr<THistogramCounter>; + #ifdef _MSC_VER #pragma warning(pop) #endif @@ -203,8 +203,8 @@ namespace NMonitoring { struct TChildId { TString LabelName; TString LabelValue; - TChildId() { - } + TChildId() { + } TChildId(const TString& labelName, const TString& labelValue) : LabelName(labelName) , LabelValue(labelValue) @@ -230,7 +230,7 @@ namespace NMonitoring { /// XXX: hack for deferred removal of expired counters. Remove once Output* functions are not used for serialization mutable TCounters Counters; mutable TAtomic ExpiringCount = 0; - + public: TDynamicCounters(TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public); @@ -306,7 +306,7 @@ namespace NMonitoring { const TString& value, bool derivative = false, TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public); - + THistogramPtr GetExpiringHistogram( const TString& value, IHistogramCollectorPtr collector, @@ -344,15 +344,15 @@ namespace NMonitoring { TIntrusivePtr<TDynamicCounters> subgroup); void OutputHtml(IOutputStream& os) const; - void EnumerateSubgroups(const std::function<void(const TString& name, const TString& value)>& output) const; + void EnumerateSubgroups(const std::function<void(const TString& name, const TString& value)>& output) const; // mostly for debugging purposes -- use accept with encoder instead void OutputPlainText(IOutputStream& os, const TString& indent = "") const; - void Accept( - const TString& labelName, const TString& labelValue, - ICountableConsumer& consumer) const override; - + void Accept( + const TString& labelName, const TString& labelValue, + ICountableConsumer& consumer) const override; + private: TCounters Resign() { TCounters counters; diff --git a/library/cpp/monlib/dynamic_counters/counters_ut.cpp b/library/cpp/monlib/dynamic_counters/counters_ut.cpp index 512728be1d..3591037e0a 100644 --- a/library/cpp/monlib/dynamic_counters/counters_ut.cpp +++ b/library/cpp/monlib/dynamic_counters/counters_ut.cpp @@ -1,101 +1,101 @@ -#include "counters.h" - +#include "counters.h" + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - -class TCountersPrinter: public ICountableConsumer { -public: + +using namespace NMonitoring; + +class TCountersPrinter: public ICountableConsumer { +public: TCountersPrinter(IOutputStream* out) - : Out_(out) - , Level_(0) - { - } - -private: - void OnCounter( - const TString& labelName, const TString& labelValue, - const TCounterForPtr* counter) override { - Indent(Out_, Level_) - << labelName << ':' << labelValue - << " = " << counter->Val() << '\n'; - } - - void OnHistogram( - const TString& labelName, const TString& labelValue, + : Out_(out) + , Level_(0) + { + } + +private: + void OnCounter( + const TString& labelName, const TString& labelValue, + const TCounterForPtr* counter) override { + Indent(Out_, Level_) + << labelName << ':' << labelValue + << " = " << counter->Val() << '\n'; + } + + void OnHistogram( + const TString& labelName, const TString& labelValue, IHistogramSnapshotPtr snapshot, bool /*derivative*/) override { - Indent(Out_, Level_) - << labelName << ':' << labelValue - << " = " << *snapshot << '\n'; - } - - void OnGroupBegin( - const TString& labelName, const TString& labelValue, - const TDynamicCounters*) override { - Indent(Out_, Level_++) << labelName << ':' << labelValue << " {\n"; - } - - void OnGroupEnd( - const TString&, const TString&, - const TDynamicCounters*) override { - Indent(Out_, --Level_) << "}\n"; - } - + Indent(Out_, Level_) + << labelName << ':' << labelValue + << " = " << *snapshot << '\n'; + } + + void OnGroupBegin( + const TString& labelName, const TString& labelValue, + const TDynamicCounters*) override { + Indent(Out_, Level_++) << labelName << ':' << labelValue << " {\n"; + } + + void OnGroupEnd( + const TString&, const TString&, + const TDynamicCounters*) override { + Indent(Out_, --Level_) << "}\n"; + } + static IOutputStream& Indent(IOutputStream* out, int level) { - for (int i = 0; i < level; i++) { - out->Write(" "); - } - return *out; - } - -private: + for (int i = 0; i < level; i++) { + out->Write(" "); + } + return *out; + } + +private: IOutputStream* Out_; - int Level_ = 0; -}; - + int Level_ = 0; +}; + Y_UNIT_TEST_SUITE(TDynamicCountersTest) { Y_UNIT_TEST(CountersConsumer) { - TDynamicCounterPtr rootGroup(new TDynamicCounters()); - - auto usersCounter = rootGroup->GetNamedCounter("users", "count"); - *usersCounter = 7; - - auto hostGroup = rootGroup->GetSubgroup("counters", "resources"); - auto cpuCounter = hostGroup->GetNamedCounter("resource", "cpu"); - *cpuCounter = 30; - - auto memGroup = hostGroup->GetSubgroup("resource", "mem"); - auto usedCounter = memGroup->GetCounter("used"); - auto freeCounter = memGroup->GetCounter("free"); - *usedCounter = 100; - *freeCounter = 28; - - auto netGroup = hostGroup->GetSubgroup("resource", "net"); - auto rxCounter = netGroup->GetCounter("rx", true); - auto txCounter = netGroup->GetCounter("tx", true); - *rxCounter = 8; - *txCounter = 9; - - TStringStream ss; - TCountersPrinter printer(&ss); - rootGroup->Accept("root", "counters", printer); - - UNIT_ASSERT_STRINGS_EQUAL(ss.Str(), - "root:counters {\n" - " counters:resources {\n" - " resource:cpu = 30\n" - " resource:mem {\n" - " sensor:free = 28\n" - " sensor:used = 100\n" - " }\n" - " resource:net {\n" - " sensor:rx = 8\n" - " sensor:tx = 9\n" - " }\n" - " }\n" - " users:count = 7\n" - "}\n"); - } + TDynamicCounterPtr rootGroup(new TDynamicCounters()); + + auto usersCounter = rootGroup->GetNamedCounter("users", "count"); + *usersCounter = 7; + + auto hostGroup = rootGroup->GetSubgroup("counters", "resources"); + auto cpuCounter = hostGroup->GetNamedCounter("resource", "cpu"); + *cpuCounter = 30; + + auto memGroup = hostGroup->GetSubgroup("resource", "mem"); + auto usedCounter = memGroup->GetCounter("used"); + auto freeCounter = memGroup->GetCounter("free"); + *usedCounter = 100; + *freeCounter = 28; + + auto netGroup = hostGroup->GetSubgroup("resource", "net"); + auto rxCounter = netGroup->GetCounter("rx", true); + auto txCounter = netGroup->GetCounter("tx", true); + *rxCounter = 8; + *txCounter = 9; + + TStringStream ss; + TCountersPrinter printer(&ss); + rootGroup->Accept("root", "counters", printer); + + UNIT_ASSERT_STRINGS_EQUAL(ss.Str(), + "root:counters {\n" + " counters:resources {\n" + " resource:cpu = 30\n" + " resource:mem {\n" + " sensor:free = 28\n" + " sensor:used = 100\n" + " }\n" + " resource:net {\n" + " sensor:rx = 8\n" + " sensor:tx = 9\n" + " }\n" + " }\n" + " users:count = 7\n" + "}\n"); + } Y_UNIT_TEST(MergeSubgroup) { TDynamicCounterPtr rootGroup(new TDynamicCounters()); @@ -249,7 +249,7 @@ Y_UNIT_TEST_SUITE(TDynamicCountersTest) { UNIT_ASSERT_STRINGS_EQUAL(ss.Str(), "root:counters {\n" "}\n"); - } + } Y_UNIT_TEST(ExpiringCountersDiesAfterRegistry) { TDynamicCounters::TCounterPtr ptr; @@ -266,24 +266,24 @@ Y_UNIT_TEST_SUITE(TDynamicCountersTest) { " sensor:foo = 0\n" "}\n"); } - } - - Y_UNIT_TEST(HistogramCounter) { - TDynamicCounterPtr rootGroup(new TDynamicCounters()); - - auto h = rootGroup->GetHistogram("timeMillis", ExponentialHistogram(4, 2)); - for (i64 i = 1; i < 100; i++) { - h->Collect(i); - } - - TStringStream ss; - TCountersPrinter printer(&ss); - rootGroup->Accept("root", "counters", printer); - UNIT_ASSERT_STRINGS_EQUAL(ss.Str(), - "root:counters {\n" - " sensor:timeMillis = {1: 1, 2: 1, 4: 2, inf: 95}\n" - "}\n"); - } + } + + Y_UNIT_TEST(HistogramCounter) { + TDynamicCounterPtr rootGroup(new TDynamicCounters()); + + auto h = rootGroup->GetHistogram("timeMillis", ExponentialHistogram(4, 2)); + for (i64 i = 1; i < 100; i++) { + h->Collect(i); + } + + TStringStream ss; + TCountersPrinter printer(&ss); + rootGroup->Accept("root", "counters", printer); + UNIT_ASSERT_STRINGS_EQUAL(ss.Str(), + "root:counters {\n" + " sensor:timeMillis = {1: 1, 2: 1, 4: 2, inf: 95}\n" + "}\n"); + } Y_UNIT_TEST(CounterLookupCounter) { TDynamicCounterPtr rootGroup(new TDynamicCounters()); @@ -339,4 +339,4 @@ Y_UNIT_TEST_SUITE(TDynamicCountersTest) { histogram = rootGroup->FindNamedHistogram("name", "histogram2"); UNIT_ASSERT(histogram); } -} +} diff --git a/library/cpp/monlib/dynamic_counters/encode.cpp b/library/cpp/monlib/dynamic_counters/encode.cpp index 8a8b31314b..ffa48d276e 100644 --- a/library/cpp/monlib/dynamic_counters/encode.cpp +++ b/library/cpp/monlib/dynamic_counters/encode.cpp @@ -1,131 +1,131 @@ -#include "encode.h" - -#include <library/cpp/monlib/encode/encoder.h> -#include <library/cpp/monlib/encode/json/json.h> -#include <library/cpp/monlib/encode/spack/spack_v1.h> +#include "encode.h" + +#include <library/cpp/monlib/encode/encoder.h> +#include <library/cpp/monlib/encode/json/json.h> +#include <library/cpp/monlib/encode/spack/spack_v1.h> #include <library/cpp/monlib/encode/prometheus/prometheus.h> - -#include <util/stream/str.h> - -namespace NMonitoring { - namespace { - constexpr TInstant ZERO_TIME = TInstant::Zero(); - - class TConsumer final: public ICountableConsumer { - using TLabel = std::pair<TString, TString>; // name, value - - public: - explicit TConsumer(NMonitoring::IMetricEncoderPtr encoderImpl, TCountableBase::EVisibility vis) - : EncoderImpl_(std::move(encoderImpl)) + +#include <util/stream/str.h> + +namespace NMonitoring { + namespace { + constexpr TInstant ZERO_TIME = TInstant::Zero(); + + class TConsumer final: public ICountableConsumer { + using TLabel = std::pair<TString, TString>; // name, value + + public: + explicit TConsumer(NMonitoring::IMetricEncoderPtr encoderImpl, TCountableBase::EVisibility vis) + : EncoderImpl_(std::move(encoderImpl)) , Visibility_{vis} - { - } - - void OnCounter( - const TString& labelName, const TString& labelValue, - const TCounterForPtr* counter) override { - NMonitoring::EMetricType metricType = counter->ForDerivative() - ? NMonitoring::EMetricType::RATE - : NMonitoring::EMetricType::GAUGE; - EncoderImpl_->OnMetricBegin(metricType); - EncodeLabels(labelName, labelValue); - - if (metricType == NMonitoring::EMetricType::GAUGE) { - EncoderImpl_->OnDouble(ZERO_TIME, static_cast<double>(counter->Val())); - } else { - EncoderImpl_->OnUint64(ZERO_TIME, counter->Val()); - } - - EncoderImpl_->OnMetricEnd(); - } - - void OnHistogram( - const TString& labelName, const TString& labelValue, + { + } + + void OnCounter( + const TString& labelName, const TString& labelValue, + const TCounterForPtr* counter) override { + NMonitoring::EMetricType metricType = counter->ForDerivative() + ? NMonitoring::EMetricType::RATE + : NMonitoring::EMetricType::GAUGE; + EncoderImpl_->OnMetricBegin(metricType); + EncodeLabels(labelName, labelValue); + + if (metricType == NMonitoring::EMetricType::GAUGE) { + EncoderImpl_->OnDouble(ZERO_TIME, static_cast<double>(counter->Val())); + } else { + EncoderImpl_->OnUint64(ZERO_TIME, counter->Val()); + } + + EncoderImpl_->OnMetricEnd(); + } + + void OnHistogram( + const TString& labelName, const TString& labelValue, IHistogramSnapshotPtr snapshot, bool derivative) override { NMonitoring::EMetricType metricType = derivative ? EMetricType::HIST_RATE : EMetricType::HIST; EncoderImpl_->OnMetricBegin(metricType); - EncodeLabels(labelName, labelValue); - EncoderImpl_->OnHistogram(ZERO_TIME, snapshot); - EncoderImpl_->OnMetricEnd(); - } - - void OnGroupBegin( - const TString& labelName, const TString& labelValue, - const TDynamicCounters*) override { + EncodeLabels(labelName, labelValue); + EncoderImpl_->OnHistogram(ZERO_TIME, snapshot); + EncoderImpl_->OnMetricEnd(); + } + + void OnGroupBegin( + const TString& labelName, const TString& labelValue, + const TDynamicCounters*) override { if (labelName.empty() && labelValue.empty()) { - // root group has empty label name and value - EncoderImpl_->OnStreamBegin(); - } else { - ParentLabels_.emplace_back(labelName, labelValue); - } - } - - void OnGroupEnd( - const TString& labelName, const TString& labelValue, - const TDynamicCounters*) override { + // root group has empty label name and value + EncoderImpl_->OnStreamBegin(); + } else { + ParentLabels_.emplace_back(labelName, labelValue); + } + } + + void OnGroupEnd( + const TString& labelName, const TString& labelValue, + const TDynamicCounters*) override { if (labelName.empty() && labelValue.empty()) { - // root group has empty label name and value - EncoderImpl_->OnStreamEnd(); - EncoderImpl_->Close(); - } else { - ParentLabels_.pop_back(); - } - } - + // root group has empty label name and value + EncoderImpl_->OnStreamEnd(); + EncoderImpl_->Close(); + } else { + ParentLabels_.pop_back(); + } + } + TCountableBase::EVisibility Visibility() const override { return Visibility_; } - private: - void EncodeLabels(const TString& labelName, const TString& labelValue) { - EncoderImpl_->OnLabelsBegin(); - for (const auto& label : ParentLabels_) { - EncoderImpl_->OnLabel(label.first, label.second); - } - EncoderImpl_->OnLabel(labelName, labelValue); - EncoderImpl_->OnLabelsEnd(); - } - - private: - NMonitoring::IMetricEncoderPtr EncoderImpl_; - TVector<TLabel> ParentLabels_; + private: + void EncodeLabels(const TString& labelName, const TString& labelValue) { + EncoderImpl_->OnLabelsBegin(); + for (const auto& label : ParentLabels_) { + EncoderImpl_->OnLabel(label.first, label.second); + } + EncoderImpl_->OnLabel(labelName, labelValue); + EncoderImpl_->OnLabelsEnd(); + } + + private: + NMonitoring::IMetricEncoderPtr EncoderImpl_; + TVector<TLabel> ParentLabels_; TCountableBase::EVisibility Visibility_; - }; - - } - + }; + + } + THolder<ICountableConsumer> CreateEncoder(IOutputStream* out, EFormat format, TCountableBase::EVisibility vis) { - switch (format) { - case EFormat::JSON: + switch (format) { + case EFormat::JSON: return MakeHolder<TConsumer>(NMonitoring::EncoderJson(out), vis); - case EFormat::SPACK: + case EFormat::SPACK: return MakeHolder<TConsumer>(NMonitoring::EncoderSpackV1( - out, - NMonitoring::ETimePrecision::SECONDS, + out, + NMonitoring::ETimePrecision::SECONDS, NMonitoring::ECompression::ZSTD), vis); case EFormat::PROMETHEUS: return MakeHolder<TConsumer>(NMonitoring::EncoderPrometheus( out), vis); - default: - ythrow yexception() << "unsupported metric encoding format: " << format; - break; - } - } - + default: + ythrow yexception() << "unsupported metric encoding format: " << format; + break; + } + } + THolder<ICountableConsumer> AsCountableConsumer(IMetricEncoderPtr encoder, TCountableBase::EVisibility visibility) { return MakeHolder<TConsumer>(std::move(encoder), visibility); } - void ToJson(const TDynamicCounters& counters, IOutputStream* out) { - TConsumer consumer{EncoderJson(out), TCountableBase::EVisibility::Public}; - counters.Accept(TString{}, TString{}, consumer); - } - - TString ToJson(const TDynamicCounters& counters) { - TStringStream ss; - ToJson(counters, &ss); - return ss.Str(); - } - -} + void ToJson(const TDynamicCounters& counters, IOutputStream* out) { + TConsumer consumer{EncoderJson(out), TCountableBase::EVisibility::Public}; + counters.Accept(TString{}, TString{}, consumer); + } + + TString ToJson(const TDynamicCounters& counters) { + TStringStream ss; + ToJson(counters, &ss); + return ss.Str(); + } + +} diff --git a/library/cpp/monlib/dynamic_counters/encode.h b/library/cpp/monlib/dynamic_counters/encode.h index 81e924a034..c79964d7cb 100644 --- a/library/cpp/monlib/dynamic_counters/encode.h +++ b/library/cpp/monlib/dynamic_counters/encode.h @@ -1,23 +1,23 @@ -#pragma once - -#include "counters.h" - +#pragma once + +#include "counters.h" + #include <library/cpp/monlib/encode/encoder.h> -#include <library/cpp/monlib/encode/format.h> - -namespace NMonitoring { - +#include <library/cpp/monlib/encode/format.h> + +namespace NMonitoring { + THolder<ICountableConsumer> CreateEncoder( IOutputStream* out, EFormat format, TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public ); - + THolder<ICountableConsumer> AsCountableConsumer( NMonitoring::IMetricEncoderPtr encoder, TCountableBase::EVisibility visibility = TCountableBase::EVisibility::Public); - void ToJson(const TDynamicCounters& counters, IOutputStream* out); - - TString ToJson(const TDynamicCounters& counters); -} + void ToJson(const TDynamicCounters& counters, IOutputStream* out); + + TString ToJson(const TDynamicCounters& counters); +} diff --git a/library/cpp/monlib/dynamic_counters/encode_ut.cpp b/library/cpp/monlib/dynamic_counters/encode_ut.cpp index 9e5bd74f91..52d77b6b41 100644 --- a/library/cpp/monlib/dynamic_counters/encode_ut.cpp +++ b/library/cpp/monlib/dynamic_counters/encode_ut.cpp @@ -1,172 +1,172 @@ -#include "encode.h" - -#include <library/cpp/monlib/encode/json/json.h> -#include <library/cpp/monlib/encode/spack/spack_v1.h> -#include <library/cpp/monlib/encode/protobuf/protobuf.h> - -#include <library/cpp/monlib/encode/protobuf/protos/samples.pb.h> +#include "encode.h" + +#include <library/cpp/monlib/encode/json/json.h> +#include <library/cpp/monlib/encode/spack/spack_v1.h> +#include <library/cpp/monlib/encode/protobuf/protobuf.h> + +#include <library/cpp/monlib/encode/protobuf/protos/samples.pb.h> #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/buffer.h> -#include <util/stream/buffer.h> - -namespace NMonitoring { - struct TTestData: public TDynamicCounters { - TTestData() { - auto hostGroup = GetSubgroup("counters", "resources"); - { - auto cpuCounter = hostGroup->GetNamedCounter("resource", "cpu"); - *cpuCounter = 30; - - auto memGroup = hostGroup->GetSubgroup("resource", "mem"); - auto usedCounter = memGroup->GetCounter("used"); - auto freeCounter = memGroup->GetCounter("free"); - *usedCounter = 100; - *freeCounter = 28; - - auto netGroup = hostGroup->GetSubgroup("resource", "net"); - auto rxCounter = netGroup->GetCounter("rx", true); - auto txCounter = netGroup->GetCounter("tx", true); - *rxCounter = 8; - *txCounter = 9; - } - - auto usersCounter = GetNamedCounter("users", "count"); - *usersCounter = 7; - - auto responseTimeMillis = GetHistogram("responseTimeMillis", ExplicitHistogram({1, 5, 10, 15, 20, 100, 200})); - for (i64 i = 0; i < 400; i++) { - responseTimeMillis->Collect(i); - } - } - }; - - void AssertLabelsEqual(const NProto::TLabel& l, TStringBuf name, TStringBuf value) { - UNIT_ASSERT_STRINGS_EQUAL(l.GetName(), name); - UNIT_ASSERT_STRINGS_EQUAL(l.GetValue(), value); - } - - void AssertResult(const NProto::TSingleSamplesList& samples) { - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 7); - - { - auto s = samples.GetSamples(0); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); - AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); - AssertLabelsEqual(s.GetLabels(1), "resource", "cpu"); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_DOUBLES_EQUAL(s.GetFloat64(), 30.0, Min<double>()); - } - { - auto s = samples.GetSamples(1); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 3); - AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); - AssertLabelsEqual(s.GetLabels(1), "resource", "mem"); - AssertLabelsEqual(s.GetLabels(2), "sensor", "free"); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_DOUBLES_EQUAL(s.GetFloat64(), 28.0, Min<double>()); - } - { - auto s = samples.GetSamples(2); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 3); - AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); - AssertLabelsEqual(s.GetLabels(1), "resource", "mem"); - AssertLabelsEqual(s.GetLabels(2), "sensor", "used"); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_DOUBLES_EQUAL(s.GetFloat64(), 100.0, Min<double>()); - } - { - auto s = samples.GetSamples(3); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 3); - AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); - AssertLabelsEqual(s.GetLabels(1), "resource", "net"); - AssertLabelsEqual(s.GetLabels(2), "sensor", "rx"); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); - UNIT_ASSERT_VALUES_EQUAL(s.GetUint64(), 8); - } - { - auto s = samples.GetSamples(4); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 3); - AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); - AssertLabelsEqual(s.GetLabels(1), "resource", "net"); - AssertLabelsEqual(s.GetLabels(2), "sensor", "tx"); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); - UNIT_ASSERT_VALUES_EQUAL(s.GetUint64(), 9); - } - { - auto s = samples.GetSamples(5); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelsEqual(s.GetLabels(0), "sensor", "responseTimeMillis"); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HIST_RATE); - - const NProto::THistogram& h = s.GetHistogram(); - - UNIT_ASSERT_EQUAL(h.BoundsSize(), 8); - UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(0), 1, Min<double>()); - UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(1), 5, Min<double>()); - UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(2), 10, Min<double>()); - UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(3), 15, Min<double>()); - UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(4), 20, Min<double>()); - UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(5), 100, Min<double>()); - UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(6), 200, Min<double>()); - UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(7), Max<double>(), Min<double>()); - - UNIT_ASSERT_EQUAL(h.ValuesSize(), 8); - UNIT_ASSERT_EQUAL(h.GetValues(0), 2); - UNIT_ASSERT_EQUAL(h.GetValues(1), 4); - UNIT_ASSERT_EQUAL(h.GetValues(2), 5); - UNIT_ASSERT_EQUAL(h.GetValues(3), 5); - UNIT_ASSERT_EQUAL(h.GetValues(4), 5); - UNIT_ASSERT_EQUAL(h.GetValues(5), 80); - UNIT_ASSERT_EQUAL(h.GetValues(6), 100); - UNIT_ASSERT_EQUAL(h.GetValues(7), 199); - } - { - auto s = samples.GetSamples(6); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelsEqual(s.GetLabels(0), "users", "count"); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_DOUBLES_EQUAL(s.GetFloat64(), 7, Min<double>()); - } - } - + +#include <util/generic/buffer.h> +#include <util/stream/buffer.h> + +namespace NMonitoring { + struct TTestData: public TDynamicCounters { + TTestData() { + auto hostGroup = GetSubgroup("counters", "resources"); + { + auto cpuCounter = hostGroup->GetNamedCounter("resource", "cpu"); + *cpuCounter = 30; + + auto memGroup = hostGroup->GetSubgroup("resource", "mem"); + auto usedCounter = memGroup->GetCounter("used"); + auto freeCounter = memGroup->GetCounter("free"); + *usedCounter = 100; + *freeCounter = 28; + + auto netGroup = hostGroup->GetSubgroup("resource", "net"); + auto rxCounter = netGroup->GetCounter("rx", true); + auto txCounter = netGroup->GetCounter("tx", true); + *rxCounter = 8; + *txCounter = 9; + } + + auto usersCounter = GetNamedCounter("users", "count"); + *usersCounter = 7; + + auto responseTimeMillis = GetHistogram("responseTimeMillis", ExplicitHistogram({1, 5, 10, 15, 20, 100, 200})); + for (i64 i = 0; i < 400; i++) { + responseTimeMillis->Collect(i); + } + } + }; + + void AssertLabelsEqual(const NProto::TLabel& l, TStringBuf name, TStringBuf value) { + UNIT_ASSERT_STRINGS_EQUAL(l.GetName(), name); + UNIT_ASSERT_STRINGS_EQUAL(l.GetValue(), value); + } + + void AssertResult(const NProto::TSingleSamplesList& samples) { + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 7); + + { + auto s = samples.GetSamples(0); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); + AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); + AssertLabelsEqual(s.GetLabels(1), "resource", "cpu"); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_DOUBLES_EQUAL(s.GetFloat64(), 30.0, Min<double>()); + } + { + auto s = samples.GetSamples(1); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 3); + AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); + AssertLabelsEqual(s.GetLabels(1), "resource", "mem"); + AssertLabelsEqual(s.GetLabels(2), "sensor", "free"); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_DOUBLES_EQUAL(s.GetFloat64(), 28.0, Min<double>()); + } + { + auto s = samples.GetSamples(2); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 3); + AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); + AssertLabelsEqual(s.GetLabels(1), "resource", "mem"); + AssertLabelsEqual(s.GetLabels(2), "sensor", "used"); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_DOUBLES_EQUAL(s.GetFloat64(), 100.0, Min<double>()); + } + { + auto s = samples.GetSamples(3); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 3); + AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); + AssertLabelsEqual(s.GetLabels(1), "resource", "net"); + AssertLabelsEqual(s.GetLabels(2), "sensor", "rx"); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); + UNIT_ASSERT_VALUES_EQUAL(s.GetUint64(), 8); + } + { + auto s = samples.GetSamples(4); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 3); + AssertLabelsEqual(s.GetLabels(0), "counters", "resources"); + AssertLabelsEqual(s.GetLabels(1), "resource", "net"); + AssertLabelsEqual(s.GetLabels(2), "sensor", "tx"); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); + UNIT_ASSERT_VALUES_EQUAL(s.GetUint64(), 9); + } + { + auto s = samples.GetSamples(5); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelsEqual(s.GetLabels(0), "sensor", "responseTimeMillis"); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HIST_RATE); + + const NProto::THistogram& h = s.GetHistogram(); + + UNIT_ASSERT_EQUAL(h.BoundsSize(), 8); + UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(0), 1, Min<double>()); + UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(1), 5, Min<double>()); + UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(2), 10, Min<double>()); + UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(3), 15, Min<double>()); + UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(4), 20, Min<double>()); + UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(5), 100, Min<double>()); + UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(6), 200, Min<double>()); + UNIT_ASSERT_DOUBLES_EQUAL(h.GetBounds(7), Max<double>(), Min<double>()); + + UNIT_ASSERT_EQUAL(h.ValuesSize(), 8); + UNIT_ASSERT_EQUAL(h.GetValues(0), 2); + UNIT_ASSERT_EQUAL(h.GetValues(1), 4); + UNIT_ASSERT_EQUAL(h.GetValues(2), 5); + UNIT_ASSERT_EQUAL(h.GetValues(3), 5); + UNIT_ASSERT_EQUAL(h.GetValues(4), 5); + UNIT_ASSERT_EQUAL(h.GetValues(5), 80); + UNIT_ASSERT_EQUAL(h.GetValues(6), 100); + UNIT_ASSERT_EQUAL(h.GetValues(7), 199); + } + { + auto s = samples.GetSamples(6); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelsEqual(s.GetLabels(0), "users", "count"); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_DOUBLES_EQUAL(s.GetFloat64(), 7, Min<double>()); + } + } + Y_UNIT_TEST_SUITE(TDynamicCountersEncodeTest) { - TTestData Data; - + TTestData Data; + Y_UNIT_TEST(Json) { - TString result; - { - TStringOutput out(result); - auto encoder = CreateEncoder(&out, EFormat::JSON); - Data.Accept(TString(), TString(), *encoder); - } - - NProto::TSingleSamplesList samples; - { - auto e = EncoderProtobuf(&samples); - DecodeJson(result, e.Get()); - } - - AssertResult(samples); - } - + TString result; + { + TStringOutput out(result); + auto encoder = CreateEncoder(&out, EFormat::JSON); + Data.Accept(TString(), TString(), *encoder); + } + + NProto::TSingleSamplesList samples; + { + auto e = EncoderProtobuf(&samples); + DecodeJson(result, e.Get()); + } + + AssertResult(samples); + } + Y_UNIT_TEST(Spack) { - TBuffer result; - { - TBufferOutput out(result); - auto encoder = CreateEncoder(&out, EFormat::SPACK); - Data.Accept(TString(), TString(), *encoder); - } - - NProto::TSingleSamplesList samples; - { - auto e = EncoderProtobuf(&samples); - TBufferInput in(result); - DecodeSpackV1(&in, e.Get()); - } - - AssertResult(samples); - } + TBuffer result; + { + TBufferOutput out(result); + auto encoder = CreateEncoder(&out, EFormat::SPACK); + Data.Accept(TString(), TString(), *encoder); + } + + NProto::TSingleSamplesList samples; + { + auto e = EncoderProtobuf(&samples); + TBufferInput in(result); + DecodeSpackV1(&in, e.Get()); + } + + AssertResult(samples); + } Y_UNIT_TEST(PrivateSubgroupIsNotSerialized) { TBuffer result; @@ -209,18 +209,18 @@ namespace NMonitoring { AssertResult(samples); } - - Y_UNIT_TEST(ToJson) { - TString result = ToJson(Data); - - NProto::TSingleSamplesList samples; - { - auto e = EncoderProtobuf(&samples); - DecodeJson(result, e.Get()); - } - - AssertResult(samples); - } - } - -} + + Y_UNIT_TEST(ToJson) { + TString result = ToJson(Data); + + NProto::TSingleSamplesList samples; + { + auto e = EncoderProtobuf(&samples); + DecodeJson(result, e.Get()); + } + + AssertResult(samples); + } + } + +} diff --git a/library/cpp/monlib/dynamic_counters/golovan_page.cpp b/library/cpp/monlib/dynamic_counters/golovan_page.cpp index 03a5b1a399..49cf2d39bb 100644 --- a/library/cpp/monlib/dynamic_counters/golovan_page.cpp +++ b/library/cpp/monlib/dynamic_counters/golovan_page.cpp @@ -1,6 +1,6 @@ -#include "golovan_page.h" +#include "golovan_page.h" -#include <library/cpp/monlib/service/pages/templates.h> +#include <library/cpp/monlib/service/pages/templates.h> #include <util/string/split.h> #include <util/system/tls.h> @@ -40,8 +40,8 @@ public: } void OnHistogram(const TString&, const TString&, IHistogramSnapshotPtr, bool) override { - } - + } + void OnGroupBegin(const TString&, const TString& value, const TDynamicCounters*) override { prefix += value; if (!value.empty()) { diff --git a/library/cpp/monlib/dynamic_counters/golovan_page.h b/library/cpp/monlib/dynamic_counters/golovan_page.h index 855b4e9eab..e1772c7734 100644 --- a/library/cpp/monlib/dynamic_counters/golovan_page.h +++ b/library/cpp/monlib/dynamic_counters/golovan_page.h @@ -1,8 +1,8 @@ #pragma once -#include "counters.h" +#include "counters.h" -#include <library/cpp/monlib/service/pages/mon_page.h> +#include <library/cpp/monlib/service/pages/mon_page.h> #include <util/generic/ptr.h> @@ -19,7 +19,7 @@ public: TOutputCallback outputCallback = nullptr); void Output(NMonitoring::IMonHttpRequest& request) override; - + private: TOutputCallback OutputCallback; }; diff --git a/library/cpp/monlib/dynamic_counters/page.cpp b/library/cpp/monlib/dynamic_counters/page.cpp index e554d330ad..5124a47bb3 100644 --- a/library/cpp/monlib/dynamic_counters/page.cpp +++ b/library/cpp/monlib/dynamic_counters/page.cpp @@ -1,31 +1,31 @@ -#include "page.h" -#include "encode.h" +#include "page.h" +#include "encode.h" + +#include <library/cpp/monlib/service/pages/templates.h> +#include <library/cpp/string_utils/quote/quote.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); +namespace { + Y_POD_STATIC_THREAD(TDynamicCounters*) + currentCounters(nullptr); } TMaybe<EFormat> ParseFormat(TStringBuf str) { if (str == TStringBuf("json")) { - return EFormat::JSON; + return EFormat::JSON; } else if (str == TStringBuf("spack")) { - return EFormat::SPACK; + return EFormat::SPACK; } else if (str == TStringBuf("prometheus")) { return EFormat::PROMETHEUS; - } else { - return Nothing(); - } -} - + } else { + return Nothing(); + } +} + void TDynamicCountersPage::Output(NMonitoring::IMonHttpRequest& request) { if (OutputCallback) { OutputCallback(); @@ -41,10 +41,10 @@ void TDynamicCountersPage::Output(NMonitoring::IMonHttpRequest& request) { .SkipEmpty() .Collect(&parts); - TMaybe<EFormat> format = !parts.empty() ? ParseFormat(parts.back()) : Nothing(); - if (format) { + 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; @@ -72,27 +72,27 @@ void TDynamicCountersPage::Output(NMonitoring::IMonHttpRequest& request) { } } - if (!format) { - currentCounters = counters.Get(); + if (!format) { + currentCounters = counters.Get(); THtmlMonPage::Output(request); - currentCounters = nullptr; - return; + currentCounters = nullptr; + return; } - - IOutputStream& out = request.Output(); - if (*format == EFormat::JSON) { - out << HTTPOKJSON; - } else if (*format == EFormat::SPACK) { - out << HTTPOKSPACK; + + 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(); + } 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) { @@ -113,10 +113,10 @@ void TDynamicCountersPage::BeforePre(IMonHttpRequest& request) { out << " for <a href='https://wiki.yandex-team.ru/solomon/'>Solomon</a>"; } - H5() { - out << "Counters subgroups"; + H5() { + out << "Counters subgroups"; } - UL() { + UL() { currentCounters->EnumerateSubgroups([&](const TString& name, const TString& value) { LI() { TString pathPart = name + "=" + value; @@ -124,11 +124,11 @@ void TDynamicCountersPage::BeforePre(IMonHttpRequest& request) { out << "\n<a href='" << request.GetPath() << "/" << pathPart << "'>" << name << " " << value << "</a>"; } }); - } + } - H4() { - out << "Counters as text"; - } + H4() { + out << "Counters as text"; + } } } diff --git a/library/cpp/monlib/dynamic_counters/page.h b/library/cpp/monlib/dynamic_counters/page.h index 159ddaf578..1f0ef6a5ea 100644 --- a/library/cpp/monlib/dynamic_counters/page.h +++ b/library/cpp/monlib/dynamic_counters/page.h @@ -1,9 +1,9 @@ #pragma once -#include "counters.h" - -#include <library/cpp/monlib/service/pages/pre_mon_page.h> - +#include "counters.h" + +#include <library/cpp/monlib/service/pages/pre_mon_page.h> + #include <util/generic/ptr.h> #include <functional> @@ -28,7 +28,7 @@ namespace NMonitoring { public: TDynamicCountersPage(const TString& path, - const TString& title, + const TString& title, TIntrusivePtr<TDynamicCounters> counters, TOutputCallback outputCallback = nullptr) : TPreMonPage(path, title) diff --git a/library/cpp/monlib/dynamic_counters/percentile/percentile_base.h b/library/cpp/monlib/dynamic_counters/percentile/percentile_base.h index ee242b1cdb..d3c825c43d 100644 --- a/library/cpp/monlib/dynamic_counters/percentile/percentile_base.h +++ b/library/cpp/monlib/dynamic_counters/percentile/percentile_base.h @@ -1,6 +1,6 @@ #pragma once -#include <library/cpp/monlib/dynamic_counters/counters.h> +#include <library/cpp/monlib/dynamic_counters/counters.h> #include <util/string/printf.h> diff --git a/library/cpp/monlib/dynamic_counters/percentile/ut/ya.make b/library/cpp/monlib/dynamic_counters/percentile/ut/ya.make index 9859d87de2..f9f3564101 100644 --- a/library/cpp/monlib/dynamic_counters/percentile/ut/ya.make +++ b/library/cpp/monlib/dynamic_counters/percentile/ut/ya.make @@ -1,4 +1,4 @@ -UNITTEST_FOR(library/cpp/monlib/dynamic_counters/percentile) +UNITTEST_FOR(library/cpp/monlib/dynamic_counters/percentile) OWNER(alexvru g:kikimr g:solomon) diff --git a/library/cpp/monlib/dynamic_counters/percentile/ya.make b/library/cpp/monlib/dynamic_counters/percentile/ya.make index 3480330470..cb52cdd9ad 100644 --- a/library/cpp/monlib/dynamic_counters/percentile/ya.make +++ b/library/cpp/monlib/dynamic_counters/percentile/ya.make @@ -9,7 +9,7 @@ LIBRARY() PEERDIR( library/cpp/containers/stack_vector - library/cpp/monlib/dynamic_counters + library/cpp/monlib/dynamic_counters ) END() diff --git a/library/cpp/monlib/dynamic_counters/ut/ya.make b/library/cpp/monlib/dynamic_counters/ut/ya.make index b0a7c7aa41..8242f2fe30 100644 --- a/library/cpp/monlib/dynamic_counters/ut/ya.make +++ b/library/cpp/monlib/dynamic_counters/ut/ya.make @@ -1,16 +1,16 @@ -UNITTEST_FOR(library/cpp/monlib/dynamic_counters) - -OWNER(jamel) - -SRCS( +UNITTEST_FOR(library/cpp/monlib/dynamic_counters) + +OWNER(jamel) + +SRCS( contention_ut.cpp - counters_ut.cpp - encode_ut.cpp -) - -PEERDIR( - library/cpp/monlib/encode/protobuf - library/cpp/monlib/encode/json -) - -END() + counters_ut.cpp + encode_ut.cpp +) + +PEERDIR( + library/cpp/monlib/encode/protobuf + library/cpp/monlib/encode/json +) + +END() diff --git a/library/cpp/monlib/dynamic_counters/ya.make b/library/cpp/monlib/dynamic_counters/ya.make index cd65c4a4c9..aafe1c34be 100644 --- a/library/cpp/monlib/dynamic_counters/ya.make +++ b/library/cpp/monlib/dynamic_counters/ya.make @@ -1,27 +1,27 @@ -LIBRARY() - +LIBRARY() + OWNER( g:solomon jamel ) - -NO_WSHADOW() - -SRCS( - counters.cpp - encode.cpp - golovan_page.cpp - page.cpp -) - -PEERDIR( + +NO_WSHADOW() + +SRCS( + counters.cpp + encode.cpp + golovan_page.cpp + page.cpp +) + +PEERDIR( library/cpp/containers/stack_vector - library/cpp/monlib/encode/json - library/cpp/monlib/encode/spack + library/cpp/monlib/encode/json + library/cpp/monlib/encode/spack library/cpp/monlib/encode/prometheus - library/cpp/monlib/service/pages + library/cpp/monlib/service/pages library/cpp/string_utils/quote library/cpp/threading/light_rw_lock -) - -END() +) + +END() diff --git a/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp b/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp index b3d86b57ea..87c832d642 100644 --- a/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp +++ b/library/cpp/monlib/encode/buffered/buffered_encoder_base.cpp @@ -18,57 +18,57 @@ void TBufferedEncoderBase::OnCommonTime(TInstant time) { CommonTime_ = time; } -void TBufferedEncoderBase::OnMetricBegin(EMetricType type) { - State_.Switch(TEncoderState::EState::ROOT, TEncoderState::EState::METRIC); - Metrics_.emplace_back(); - Metrics_.back().MetricType = type; +void TBufferedEncoderBase::OnMetricBegin(EMetricType type) { + State_.Switch(TEncoderState::EState::ROOT, TEncoderState::EState::METRIC); + Metrics_.emplace_back(); + Metrics_.back().MetricType = type; } -void TBufferedEncoderBase::OnMetricEnd() { - State_.Switch(TEncoderState::EState::METRIC, TEncoderState::EState::ROOT); +void TBufferedEncoderBase::OnMetricEnd() { + State_.Switch(TEncoderState::EState::METRIC, TEncoderState::EState::ROOT); - switch (MetricsMergingMode_) { - case EMetricsMergingMode::MERGE_METRICS: { - auto& metric = Metrics_.back(); - Sort(metric.Labels, [] (const TPooledLabel& lhs, const TPooledLabel& rhs) { + switch (MetricsMergingMode_) { + case EMetricsMergingMode::MERGE_METRICS: { + auto& metric = Metrics_.back(); + Sort(metric.Labels, [] (const TPooledLabel& lhs, const TPooledLabel& rhs) { return std::tie(lhs.Key, lhs.Value) < std::tie(rhs.Key, rhs.Value); }); - auto it = MetricMap_.find(metric.Labels); - if (it == std::end(MetricMap_)) { - MetricMap_.emplace(metric.Labels, Metrics_.size() - 1); + auto it = MetricMap_.find(metric.Labels); + if (it == std::end(MetricMap_)) { + MetricMap_.emplace(metric.Labels, Metrics_.size() - 1); } else { - auto& existing = Metrics_[it->second].TimeSeries; + auto& existing = Metrics_[it->second].TimeSeries; - Y_ENSURE(existing.GetValueType() == metric.TimeSeries.GetValueType(), + Y_ENSURE(existing.GetValueType() == metric.TimeSeries.GetValueType(), "Time series point type mismatch: expected " << existing.GetValueType() << " but found " << metric.TimeSeries.GetValueType() << ", labels '" << FormatLabels(metric.Labels) << "'"); - existing.CopyFrom(metric.TimeSeries); - Metrics_.pop_back(); + existing.CopyFrom(metric.TimeSeries); + Metrics_.pop_back(); } break; } - case EMetricsMergingMode::DEFAULT: + case EMetricsMergingMode::DEFAULT: break; } } void TBufferedEncoderBase::OnLabelsBegin() { - if (State_ == TEncoderState::EState::METRIC) { - State_ = TEncoderState::EState::METRIC_LABELS; + if (State_ == TEncoderState::EState::METRIC) { + State_ = TEncoderState::EState::METRIC_LABELS; } else if (State_ == TEncoderState::EState::ROOT) { State_ = TEncoderState::EState::COMMON_LABELS; } else { - State_.ThrowInvalid("expected METRIC or ROOT"); + State_.ThrowInvalid("expected METRIC or ROOT"); } } void TBufferedEncoderBase::OnLabelsEnd() { - if (State_ == TEncoderState::EState::METRIC_LABELS) { - State_ = TEncoderState::EState::METRIC; + if (State_ == TEncoderState::EState::METRIC_LABELS) { + State_ = TEncoderState::EState::METRIC; } else if (State_ == TEncoderState::EState::COMMON_LABELS) { State_ = TEncoderState::EState::ROOT; } else { @@ -76,10 +76,10 @@ void TBufferedEncoderBase::OnLabelsEnd() { } } -void TBufferedEncoderBase::OnLabel(TStringBuf name, TStringBuf value) { +void TBufferedEncoderBase::OnLabel(TStringBuf name, TStringBuf value) { TPooledLabels* labels; - if (State_ == TEncoderState::EState::METRIC_LABELS) { - labels = &Metrics_.back().Labels; + if (State_ == TEncoderState::EState::METRIC_LABELS) { + labels = &Metrics_.back().Labels; } else if (State_ == TEncoderState::EState::COMMON_LABELS) { labels = &CommonLabels_; } else { @@ -102,46 +102,46 @@ void TBufferedEncoderBase::OnLabel(ui32 name, ui32 value) { labels->emplace_back(LabelNamesPool_.GetByIndex(name), LabelValuesPool_.GetByIndex(value)); } -std::pair<ui32, ui32> TBufferedEncoderBase::PrepareLabel(TStringBuf name, TStringBuf value) { +std::pair<ui32, ui32> TBufferedEncoderBase::PrepareLabel(TStringBuf name, TStringBuf value) { auto nameLabel = LabelNamesPool_.PutIfAbsent(name); auto valueLabel = LabelValuesPool_.PutIfAbsent(value); return std::make_pair(nameLabel->Index, valueLabel->Index); } void TBufferedEncoderBase::OnDouble(TInstant time, double value) { - State_.Expect(TEncoderState::EState::METRIC); - TMetric& metric = Metrics_.back(); - metric.TimeSeries.Add(time, value); + State_.Expect(TEncoderState::EState::METRIC); + TMetric& metric = Metrics_.back(); + metric.TimeSeries.Add(time, value); +} + +void TBufferedEncoderBase::OnInt64(TInstant time, i64 value) { + State_.Expect(TEncoderState::EState::METRIC); + TMetric& metric = Metrics_.back(); + metric.TimeSeries.Add(time, value); } -void TBufferedEncoderBase::OnInt64(TInstant time, i64 value) { - State_.Expect(TEncoderState::EState::METRIC); - TMetric& metric = Metrics_.back(); - metric.TimeSeries.Add(time, value); -} - void TBufferedEncoderBase::OnUint64(TInstant time, ui64 value) { - State_.Expect(TEncoderState::EState::METRIC); - TMetric& metric = Metrics_.back(); - metric.TimeSeries.Add(time, value); + State_.Expect(TEncoderState::EState::METRIC); + TMetric& metric = Metrics_.back(); + metric.TimeSeries.Add(time, value); +} + +void TBufferedEncoderBase::OnHistogram(TInstant time, IHistogramSnapshotPtr s) { + State_.Expect(TEncoderState::EState::METRIC); + TMetric& metric = Metrics_.back(); + metric.TimeSeries.Add(time, s.Get()); } -void TBufferedEncoderBase::OnHistogram(TInstant time, IHistogramSnapshotPtr s) { - State_.Expect(TEncoderState::EState::METRIC); - TMetric& metric = Metrics_.back(); - metric.TimeSeries.Add(time, s.Get()); -} - void TBufferedEncoderBase::OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr s) { - State_.Expect(TEncoderState::EState::METRIC); - TMetric& metric = Metrics_.back(); - metric.TimeSeries.Add(time, s.Get()); + State_.Expect(TEncoderState::EState::METRIC); + TMetric& metric = Metrics_.back(); + metric.TimeSeries.Add(time, s.Get()); } void TBufferedEncoderBase::OnLogHistogram(TInstant time, TLogHistogramSnapshotPtr s) { - State_.Expect(TEncoderState::EState::METRIC); - TMetric& metric = Metrics_.back(); - metric.TimeSeries.Add(time, s.Get()); + State_.Expect(TEncoderState::EState::METRIC); + TMetric& metric = Metrics_.back(); + metric.TimeSeries.Add(time, s.Get()); } TString TBufferedEncoderBase::FormatLabels(const TPooledLabels& labels) const { diff --git a/library/cpp/monlib/encode/buffered/buffered_encoder_base.h b/library/cpp/monlib/encode/buffered/buffered_encoder_base.h index d57ed5cd14..fe3714e58f 100644 --- a/library/cpp/monlib/encode/buffered/buffered_encoder_base.h +++ b/library/cpp/monlib/encode/buffered/buffered_encoder_base.h @@ -2,10 +2,10 @@ #include "string_pool.h" -#include <library/cpp/monlib/encode/encoder.h> -#include <library/cpp/monlib/encode/encoder_state.h> -#include <library/cpp/monlib/encode/format.h> -#include <library/cpp/monlib/metrics/metric_value.h> +#include <library/cpp/monlib/encode/encoder.h> +#include <library/cpp/monlib/encode/encoder_state.h> +#include <library/cpp/monlib/encode/format.h> +#include <library/cpp/monlib/metrics/metric_value.h> #include <util/datetime/base.h> #include <util/digest/numeric.h> @@ -13,30 +13,30 @@ namespace NMonitoring { -class TBufferedEncoderBase : public IMetricEncoder { +class TBufferedEncoderBase : public IMetricEncoder { public: void OnStreamBegin() override; void OnStreamEnd() override; void OnCommonTime(TInstant time) override; - void OnMetricBegin(EMetricType type) override; - void OnMetricEnd() override; + void OnMetricBegin(EMetricType type) override; + void OnMetricEnd() override; void OnLabelsBegin() override; void OnLabelsEnd() override; - void OnLabel(TStringBuf name, TStringBuf value) override; + void OnLabel(TStringBuf name, TStringBuf value) override; void OnLabel(ui32 name, ui32 value) override; - std::pair<ui32, ui32> PrepareLabel(TStringBuf name, TStringBuf value) override; + std::pair<ui32, ui32> PrepareLabel(TStringBuf name, TStringBuf value) override; void OnDouble(TInstant time, double value) override; - void OnInt64(TInstant time, i64 value) override; + void OnInt64(TInstant time, i64 value) override; void OnUint64(TInstant time, ui64 value) override; - void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override; + void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override; void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override; void OnLogHistogram(TInstant, TLogHistogramSnapshotPtr) override; - + protected: using TPooledStr = TStringPoolBuilder::TValue; @@ -74,12 +74,12 @@ protected: } }; - using TMetricMap = THashMap<TPooledLabels, size_t, TPooledLabelsHash>; + using TMetricMap = THashMap<TPooledLabels, size_t, TPooledLabelsHash>; - struct TMetric { - EMetricType MetricType = EMetricType::UNKNOWN; + struct TMetric { + EMetricType MetricType = EMetricType::UNKNOWN; TPooledLabels Labels; - TMetricTimeSeries TimeSeries; + TMetricTimeSeries TimeSeries; }; protected: @@ -92,9 +92,9 @@ protected: TStringPoolBuilder LabelValuesPool_; TInstant CommonTime_ = TInstant::Zero(); TPooledLabels CommonLabels_; - TVector<TMetric> Metrics_; - TMetricMap MetricMap_; - EMetricsMergingMode MetricsMergingMode_ = EMetricsMergingMode::DEFAULT; + TVector<TMetric> Metrics_; + TMetricMap MetricMap_; + EMetricsMergingMode MetricsMergingMode_ = EMetricsMergingMode::DEFAULT; }; } diff --git a/library/cpp/monlib/encode/buffered/string_pool.cpp b/library/cpp/monlib/encode/buffered/string_pool.cpp index 2015ae9860..b4c7988ba3 100644 --- a/library/cpp/monlib/encode/buffered/string_pool.cpp +++ b/library/cpp/monlib/encode/buffered/string_pool.cpp @@ -1,24 +1,24 @@ -#include "string_pool.h" - -namespace NMonitoring { - //////////////////////////////////////////////////////////////////////////////// - // TStringPoolBuilder - //////////////////////////////////////////////////////////////////////////////// - const TStringPoolBuilder::TValue* TStringPoolBuilder::PutIfAbsent(TStringBuf str) { +#include "string_pool.h" + +namespace NMonitoring { + //////////////////////////////////////////////////////////////////////////////// + // TStringPoolBuilder + //////////////////////////////////////////////////////////////////////////////// + const TStringPoolBuilder::TValue* TStringPoolBuilder::PutIfAbsent(TStringBuf str) { Y_ENSURE(!IsBuilt_, "Cannot add more values after string has been built"); - + auto [it, isInserted] = StrMap_.try_emplace(str, Max<ui32>(), 0); if (isInserted) { BytesSize_ += str.size(); it->second.Index = StrVector_.size(); StrVector_.emplace_back(it->first, &it->second); - } + } TValue* value = &it->second; - ++value->Frequency; - return value; - } - + ++value->Frequency; + return value; + } + const TStringPoolBuilder::TValue* TStringPoolBuilder::GetByIndex(ui32 index) const { return StrVector_.at(index).second; } @@ -29,30 +29,30 @@ namespace NMonitoring { std::sort(StrVector_.begin(), StrVector_.end(), [](auto& a, auto& b) { return a.second->Frequency > b.second->Frequency; }); - + ui32 i = 0; for (auto& value : StrVector_) { value.second->Index = i++; } - } - + } + IsBuilt_ = true; return *this; - } - - //////////////////////////////////////////////////////////////////////////////// - // TStringPool - //////////////////////////////////////////////////////////////////////////////// - void TStringPool::InitIndex(const char* data, ui32 size) { - const char* begin = data; - const char* end = begin + size; - for (const char* p = begin; p != end; ++p) { - if (*p == '\0') { - Index_.push_back(TStringBuf(begin, p)); - begin = p + 1; - } - } - } - -} + } + + //////////////////////////////////////////////////////////////////////////////// + // TStringPool + //////////////////////////////////////////////////////////////////////////////// + void TStringPool::InitIndex(const char* data, ui32 size) { + const char* begin = data; + const char* end = begin + size; + for (const char* p = begin; p != end; ++p) { + if (*p == '\0') { + Index_.push_back(TStringBuf(begin, p)); + begin = p + 1; + } + } + } + +} diff --git a/library/cpp/monlib/encode/buffered/string_pool.h b/library/cpp/monlib/encode/buffered/string_pool.h index 2d67fd37a3..00e5644608 100644 --- a/library/cpp/monlib/encode/buffered/string_pool.h +++ b/library/cpp/monlib/encode/buffered/string_pool.h @@ -1,14 +1,14 @@ -#pragma once - -#include <util/generic/hash.h> -#include <util/generic/vector.h> - -namespace NMonitoring { - //////////////////////////////////////////////////////////////////////////////// - // TStringPoolBuilder - //////////////////////////////////////////////////////////////////////////////// - class TStringPoolBuilder { - public: +#pragma once + +#include <util/generic/hash.h> +#include <util/generic/vector.h> + +namespace NMonitoring { + //////////////////////////////////////////////////////////////////////////////// + // TStringPoolBuilder + //////////////////////////////////////////////////////////////////////////////// + class TStringPoolBuilder { + public: struct TValue: TNonCopyable { TValue(ui32 idx, ui32 freq) : Index{idx} @@ -16,77 +16,77 @@ namespace NMonitoring { { } - ui32 Index; - ui32 Frequency; - }; - - public: - const TValue* PutIfAbsent(TStringBuf str); + ui32 Index; + ui32 Frequency; + }; + + public: + const TValue* PutIfAbsent(TStringBuf str); const TValue* GetByIndex(ui32 index) const; - + /// Determines whether pool must be sorted by value frequencies TStringPoolBuilder& SetSorted(bool sorted) { RequiresSorting_ = sorted; return *this; } - + TStringPoolBuilder& Build(); - TStringBuf Get(ui32 index) const { + TStringBuf Get(ui32 index) const { Y_ENSURE(IsBuilt_, "Pool must be sorted first"); - return StrVector_.at(index).first; - } - + return StrVector_.at(index).first; + } + TStringBuf Get(const TValue* value) const { return StrVector_.at(value->Index).first; } - template <typename TConsumer> - void ForEach(TConsumer&& c) { + template <typename TConsumer> + void ForEach(TConsumer&& c) { Y_ENSURE(IsBuilt_, "Pool must be sorted first"); - for (const auto& value : StrVector_) { - c(value.first, value.second->Index, value.second->Frequency); - } - } - - size_t BytesSize() const noexcept { - return BytesSize_; - } - - size_t Count() const noexcept { - return StrMap_.size(); - } - - private: - THashMap<TString, TValue> StrMap_; - TVector<std::pair<TStringBuf, TValue*>> StrVector_; + for (const auto& value : StrVector_) { + c(value.first, value.second->Index, value.second->Frequency); + } + } + + size_t BytesSize() const noexcept { + return BytesSize_; + } + + size_t Count() const noexcept { + return StrMap_.size(); + } + + private: + THashMap<TString, TValue> StrMap_; + TVector<std::pair<TStringBuf, TValue*>> StrVector_; bool RequiresSorting_ = false; bool IsBuilt_ = false; - size_t BytesSize_ = 0; - }; - - //////////////////////////////////////////////////////////////////////////////// - // TStringPool - //////////////////////////////////////////////////////////////////////////////// - class TStringPool { - public: - TStringPool(const char* data, ui32 size) { - InitIndex(data, size); - } - - TStringBuf Get(ui32 i) const { - return Index_.at(i); - } - + size_t BytesSize_ = 0; + }; + + //////////////////////////////////////////////////////////////////////////////// + // TStringPool + //////////////////////////////////////////////////////////////////////////////// + class TStringPool { + public: + TStringPool(const char* data, ui32 size) { + InitIndex(data, size); + } + + TStringBuf Get(ui32 i) const { + return Index_.at(i); + } + size_t Size() const { return Index_.size(); } - private: - void InitIndex(const char* data, ui32 size); - - private: - TVector<TStringBuf> Index_; - }; - -} + private: + void InitIndex(const char* data, ui32 size); + + private: + TVector<TStringBuf> Index_; + }; + +} diff --git a/library/cpp/monlib/encode/buffered/string_pool_ut.cpp b/library/cpp/monlib/encode/buffered/string_pool_ut.cpp index 7f8b4c6724..9fc3421d0b 100644 --- a/library/cpp/monlib/encode/buffered/string_pool_ut.cpp +++ b/library/cpp/monlib/encode/buffered/string_pool_ut.cpp @@ -1,84 +1,84 @@ -#include "string_pool.h" - +#include "string_pool.h" + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - + +using namespace NMonitoring; + Y_UNIT_TEST_SUITE(TStringPoolTest) { Y_UNIT_TEST(PutIfAbsent) { - TStringPoolBuilder strPool; + TStringPoolBuilder strPool; strPool.SetSorted(true); - auto* h1 = strPool.PutIfAbsent("one"); - auto* h2 = strPool.PutIfAbsent("two"); - auto* h3 = strPool.PutIfAbsent("two"); - UNIT_ASSERT(h1 != h2); - UNIT_ASSERT(h2 == h3); - - UNIT_ASSERT_VALUES_EQUAL(h1->Frequency, 1); + auto* h1 = strPool.PutIfAbsent("one"); + auto* h2 = strPool.PutIfAbsent("two"); + auto* h3 = strPool.PutIfAbsent("two"); + UNIT_ASSERT(h1 != h2); + UNIT_ASSERT(h2 == h3); + + UNIT_ASSERT_VALUES_EQUAL(h1->Frequency, 1); UNIT_ASSERT_VALUES_EQUAL(h1->Index, 0); - - UNIT_ASSERT_VALUES_EQUAL(h2->Frequency, 2); + + UNIT_ASSERT_VALUES_EQUAL(h2->Frequency, 2); UNIT_ASSERT_VALUES_EQUAL(h2->Index, 1); - - UNIT_ASSERT_VALUES_EQUAL(strPool.BytesSize(), 6); - UNIT_ASSERT_VALUES_EQUAL(strPool.Count(), 2); - } - + + UNIT_ASSERT_VALUES_EQUAL(strPool.BytesSize(), 6); + UNIT_ASSERT_VALUES_EQUAL(strPool.Count(), 2); + } + Y_UNIT_TEST(SortByFrequency) { - TStringPoolBuilder strPool; + TStringPoolBuilder strPool; strPool.SetSorted(true); - auto* h1 = strPool.PutIfAbsent("one"); - auto* h2 = strPool.PutIfAbsent("two"); - auto* h3 = strPool.PutIfAbsent("two"); - UNIT_ASSERT(h1 != h2); - UNIT_ASSERT(h2 == h3); - + auto* h1 = strPool.PutIfAbsent("one"); + auto* h2 = strPool.PutIfAbsent("two"); + auto* h3 = strPool.PutIfAbsent("two"); + UNIT_ASSERT(h1 != h2); + UNIT_ASSERT(h2 == h3); + strPool.Build(); - - UNIT_ASSERT_VALUES_EQUAL(h1->Frequency, 1); - UNIT_ASSERT_VALUES_EQUAL(h1->Index, 1); - - UNIT_ASSERT_VALUES_EQUAL(h2->Frequency, 2); - UNIT_ASSERT_VALUES_EQUAL(h2->Index, 0); - - UNIT_ASSERT_VALUES_EQUAL(strPool.BytesSize(), 6); - UNIT_ASSERT_VALUES_EQUAL(strPool.Count(), 2); - } - + + UNIT_ASSERT_VALUES_EQUAL(h1->Frequency, 1); + UNIT_ASSERT_VALUES_EQUAL(h1->Index, 1); + + UNIT_ASSERT_VALUES_EQUAL(h2->Frequency, 2); + UNIT_ASSERT_VALUES_EQUAL(h2->Index, 0); + + UNIT_ASSERT_VALUES_EQUAL(strPool.BytesSize(), 6); + UNIT_ASSERT_VALUES_EQUAL(strPool.Count(), 2); + } + Y_UNIT_TEST(ForEach) { - TStringPoolBuilder strPool; + TStringPoolBuilder strPool; strPool.SetSorted(true); - strPool.PutIfAbsent("one"); - strPool.PutIfAbsent("two"); - strPool.PutIfAbsent("two"); - strPool.PutIfAbsent("three"); - strPool.PutIfAbsent("three"); - strPool.PutIfAbsent("three"); - - UNIT_ASSERT_VALUES_EQUAL(strPool.BytesSize(), 11); - UNIT_ASSERT_VALUES_EQUAL(strPool.Count(), 3); - + strPool.PutIfAbsent("one"); + strPool.PutIfAbsent("two"); + strPool.PutIfAbsent("two"); + strPool.PutIfAbsent("three"); + strPool.PutIfAbsent("three"); + strPool.PutIfAbsent("three"); + + UNIT_ASSERT_VALUES_EQUAL(strPool.BytesSize(), 11); + UNIT_ASSERT_VALUES_EQUAL(strPool.Count(), 3); + strPool.Build(); - + TVector<TString> strings; TVector<ui32> indexes; TVector<ui32> frequences; - strPool.ForEach([&](TStringBuf str, ui32 index, ui32 freq) { - strings.emplace_back(str); - indexes.push_back(index); - frequences.push_back(freq); - }); - + strPool.ForEach([&](TStringBuf str, ui32 index, ui32 freq) { + strings.emplace_back(str); + indexes.push_back(index); + frequences.push_back(freq); + }); + TVector<TString> expectedStrings = {"three", "two", "one"}; - UNIT_ASSERT_EQUAL(strings, expectedStrings); - + UNIT_ASSERT_EQUAL(strings, expectedStrings); + TVector<ui32> expectedIndexes = {0, 1, 2}; - UNIT_ASSERT_EQUAL(indexes, expectedIndexes); - + UNIT_ASSERT_EQUAL(indexes, expectedIndexes); + TVector<ui32> expectedFrequences = {3, 2, 1}; - UNIT_ASSERT_EQUAL(frequences, expectedFrequences); - } -} + UNIT_ASSERT_EQUAL(frequences, expectedFrequences); + } +} diff --git a/library/cpp/monlib/encode/buffered/ut/ya.make b/library/cpp/monlib/encode/buffered/ut/ya.make index af2e09ac67..2157ac1490 100644 --- a/library/cpp/monlib/encode/buffered/ut/ya.make +++ b/library/cpp/monlib/encode/buffered/ut/ya.make @@ -1,4 +1,4 @@ -UNITTEST_FOR(library/cpp/monlib/encode/buffered) +UNITTEST_FOR(library/cpp/monlib/encode/buffered) OWNER( g:solomon diff --git a/library/cpp/monlib/encode/buffered/ya.make b/library/cpp/monlib/encode/buffered/ya.make index edaf29aa93..81b6a78b93 100644 --- a/library/cpp/monlib/encode/buffered/ya.make +++ b/library/cpp/monlib/encode/buffered/ya.make @@ -12,8 +12,8 @@ SRCS( ) PEERDIR( - library/cpp/monlib/encode - library/cpp/monlib/metrics + library/cpp/monlib/encode + library/cpp/monlib/metrics ) END() diff --git a/library/cpp/monlib/encode/encoder.cpp b/library/cpp/monlib/encode/encoder.cpp index 08b3fc4fd5..becf932689 100644 --- a/library/cpp/monlib/encode/encoder.cpp +++ b/library/cpp/monlib/encode/encoder.cpp @@ -1,6 +1,6 @@ -#include "encoder.h" - -namespace NMonitoring { - IMetricEncoder::~IMetricEncoder() { - } -} +#include "encoder.h" + +namespace NMonitoring { + IMetricEncoder::~IMetricEncoder() { + } +} diff --git a/library/cpp/monlib/encode/encoder.h b/library/cpp/monlib/encode/encoder.h index 5b307b4d45..a26a133d16 100644 --- a/library/cpp/monlib/encode/encoder.h +++ b/library/cpp/monlib/encode/encoder.h @@ -1,17 +1,17 @@ -#pragma once - -#include <util/generic/ptr.h> - -#include <library/cpp/monlib/metrics/metric_consumer.h> - -namespace NMonitoring { - class IMetricEncoder: public IMetricConsumer { - public: - virtual ~IMetricEncoder(); - - virtual void Close() = 0; - }; - - using IMetricEncoderPtr = THolder<IMetricEncoder>; - -} +#pragma once + +#include <util/generic/ptr.h> + +#include <library/cpp/monlib/metrics/metric_consumer.h> + +namespace NMonitoring { + class IMetricEncoder: public IMetricConsumer { + public: + virtual ~IMetricEncoder(); + + virtual void Close() = 0; + }; + + using IMetricEncoderPtr = THolder<IMetricEncoder>; + +} diff --git a/library/cpp/monlib/encode/encoder_state.cpp b/library/cpp/monlib/encode/encoder_state.cpp index 166369f876..0ece696b1a 100644 --- a/library/cpp/monlib/encode/encoder_state.cpp +++ b/library/cpp/monlib/encode/encoder_state.cpp @@ -1 +1 @@ -#include "encoder_state.h" +#include "encoder_state.h" diff --git a/library/cpp/monlib/encode/encoder_state.h b/library/cpp/monlib/encode/encoder_state.h index 51562a3d5f..e6a098f404 100644 --- a/library/cpp/monlib/encode/encoder_state.h +++ b/library/cpp/monlib/encode/encoder_state.h @@ -1,62 +1,62 @@ -#pragma once - +#pragma once + #include "encoder_state_enum.h" #include <util/generic/serialized_enum.h> -#include <util/generic/yexception.h> - +#include <util/generic/yexception.h> + -namespace NMonitoring { +namespace NMonitoring { template <typename EEncoderState> class TEncoderStateImpl { - public: + public: using EState = EEncoderState; - + explicit TEncoderStateImpl(EEncoderState state = EEncoderState::ROOT) - : State_(state) - { - } - + : State_(state) + { + } + TEncoderStateImpl& operator=(EEncoderState rhs) noexcept { - State_ = rhs; - return *this; - } - - inline bool operator==(EEncoderState rhs) const noexcept { - return State_ == rhs; - } - - inline bool operator!=(EEncoderState rhs) const noexcept { - return !operator==(rhs); - } - + State_ = rhs; + return *this; + } + + inline bool operator==(EEncoderState rhs) const noexcept { + return State_ == rhs; + } + + inline bool operator!=(EEncoderState rhs) const noexcept { + return !operator==(rhs); + } + [[noreturn]] inline void ThrowInvalid(TStringBuf message) const { - ythrow yexception() << "invalid encoder state: " - << ToStr() << ", " << message; - } - - inline void Expect(EEncoderState expected) const { - if (Y_UNLIKELY(State_ != expected)) { - ythrow yexception() - << "invalid encoder state: " << ToStr() + ythrow yexception() << "invalid encoder state: " + << ToStr() << ", " << message; + } + + inline void Expect(EEncoderState expected) const { + if (Y_UNLIKELY(State_ != expected)) { + ythrow yexception() + << "invalid encoder state: " << ToStr() << ", expected: " << TEncoderStateImpl(expected).ToStr(); - } - } - - inline void Switch(EEncoderState from, EEncoderState to) { - Expect(from); - State_ = to; - } - + } + } + + inline void Switch(EEncoderState from, EEncoderState to) { + Expect(from); + State_ = to; + } + TStringBuf ToStr() const noexcept { return NEnumSerializationRuntime::GetEnumNamesImpl<EEncoderState>().at(State_); } - - private: - EEncoderState State_; - }; - + + private: + EEncoderState State_; + }; + using TEncoderState = TEncoderStateImpl<EEncoderState>; } // namespace NMonitoring diff --git a/library/cpp/monlib/encode/encoder_state_enum.h b/library/cpp/monlib/encode/encoder_state_enum.h index 54f48a25e5..471604f91d 100644 --- a/library/cpp/monlib/encode/encoder_state_enum.h +++ b/library/cpp/monlib/encode/encoder_state_enum.h @@ -5,8 +5,8 @@ namespace NMonitoring { enum class EEncoderState { ROOT, COMMON_LABELS, - METRIC, - METRIC_LABELS, + METRIC, + METRIC_LABELS, }; } // namespace NMonitoring diff --git a/library/cpp/monlib/encode/fake/fake.cpp b/library/cpp/monlib/encode/fake/fake.cpp index 3bd3be8994..69d691361a 100644 --- a/library/cpp/monlib/encode/fake/fake.cpp +++ b/library/cpp/monlib/encode/fake/fake.cpp @@ -3,7 +3,7 @@ #include <util/datetime/base.h> namespace NMonitoring { - class TFakeEncoder: public IMetricEncoder { + class TFakeEncoder: public IMetricEncoder { public: void OnStreamBegin() override { } @@ -13,9 +13,9 @@ namespace NMonitoring { void OnCommonTime(TInstant) override { } - void OnMetricBegin(EMetricType) override { + void OnMetricBegin(EMetricType) override { } - void OnMetricEnd() override { + void OnMetricEnd() override { } void OnLabelsBegin() override { @@ -45,7 +45,7 @@ namespace NMonitoring { } }; - IMetricEncoderPtr EncoderFake() { + IMetricEncoderPtr EncoderFake() { return MakeHolder<TFakeEncoder>(); } } diff --git a/library/cpp/monlib/encode/fake/fake.h b/library/cpp/monlib/encode/fake/fake.h index 9b3e681c9b..8109326987 100644 --- a/library/cpp/monlib/encode/fake/fake.h +++ b/library/cpp/monlib/encode/fake/fake.h @@ -1,10 +1,10 @@ #pragma once -#include <library/cpp/monlib/encode/encoder.h> +#include <library/cpp/monlib/encode/encoder.h> class IOutputStream; namespace NMonitoring { - // Does nothing: just implements IMetricEncoder interface with stubs - IMetricEncoderPtr EncoderFake(); + // Does nothing: just implements IMetricEncoder interface with stubs + IMetricEncoderPtr EncoderFake(); } diff --git a/library/cpp/monlib/encode/format.cpp b/library/cpp/monlib/encode/format.cpp index d9bb4fcd04..400ce5a643 100644 --- a/library/cpp/monlib/encode/format.cpp +++ b/library/cpp/monlib/encode/format.cpp @@ -1,12 +1,12 @@ -#include "format.h" - -#include <util/string/ascii.h> +#include "format.h" + +#include <util/string/ascii.h> #include <util/string/split.h> -#include <util/string/strip.h> -#include <util/stream/output.h> -#include <util/string/cast.h> - -namespace NMonitoring { +#include <util/string/strip.h> +#include <util/stream/output.h> +#include <util/string/cast.h> + +namespace NMonitoring { static ECompression CompressionFromHeader(TStringBuf value) { if (value.empty()) { return ECompression::UNKNOWN; @@ -38,165 +38,165 @@ namespace NMonitoring { return EFormat::PROTOBUF; } else if (AsciiEqualsIgnoreCase(value, NFormatContenType::TEXT)) { return EFormat::TEXT; - } else if (AsciiEqualsIgnoreCase(value, NFormatContenType::PROMETHEUS)) { - return EFormat::PROMETHEUS; - } - + } else if (AsciiEqualsIgnoreCase(value, NFormatContenType::PROMETHEUS)) { + return EFormat::PROMETHEUS; + } + return EFormat::UNKNOWN; } EFormat FormatFromAcceptHeader(TStringBuf value) { EFormat result{EFormat::UNKNOWN}; - for (const auto& it : StringSplitter(value).Split(',').SkipEmpty()) { - TStringBuf token = StripString(it.Token()); - + for (const auto& it : StringSplitter(value).Split(',').SkipEmpty()) { + TStringBuf token = StripString(it.Token()); + result = FormatFromHttpMedia(token); if (result != EFormat::UNKNOWN) { break; - } - } - + } + } + return result; - } - + } + EFormat FormatFromContentType(TStringBuf value) { value = value.NextTok(';'); return FormatFromHttpMedia(value); } - TStringBuf ContentTypeByFormat(EFormat format) { - switch (format) { - case EFormat::SPACK: - return NFormatContenType::SPACK; - case EFormat::JSON: - return NFormatContenType::JSON; - case EFormat::PROTOBUF: - return NFormatContenType::PROTOBUF; - case EFormat::TEXT: - return NFormatContenType::TEXT; - case EFormat::PROMETHEUS: - return NFormatContenType::PROMETHEUS; - case EFormat::UNKNOWN: - return TStringBuf(); - } - - Y_FAIL(); // for GCC - } - - ECompression CompressionFromAcceptEncodingHeader(TStringBuf value) { + TStringBuf ContentTypeByFormat(EFormat format) { + switch (format) { + case EFormat::SPACK: + return NFormatContenType::SPACK; + case EFormat::JSON: + return NFormatContenType::JSON; + case EFormat::PROTOBUF: + return NFormatContenType::PROTOBUF; + case EFormat::TEXT: + return NFormatContenType::TEXT; + case EFormat::PROMETHEUS: + return NFormatContenType::PROMETHEUS; + case EFormat::UNKNOWN: + return TStringBuf(); + } + + Y_FAIL(); // for GCC + } + + ECompression CompressionFromAcceptEncodingHeader(TStringBuf value) { return CompressionFromHeader(value); } - + ECompression CompressionFromContentEncodingHeader(TStringBuf value) { return CompressionFromHeader(value); - } - - TStringBuf ContentEncodingByCompression(ECompression compression) { - switch (compression) { - case ECompression::IDENTITY: - return NFormatContentEncoding::IDENTITY; - case ECompression::ZLIB: - return NFormatContentEncoding::ZLIB; - case ECompression::LZ4: - return NFormatContentEncoding::LZ4; - case ECompression::ZSTD: - return NFormatContentEncoding::ZSTD; - case ECompression::UNKNOWN: - return TStringBuf(); - } - - Y_FAIL(); // for GCC - } - -} - -template <> -NMonitoring::EFormat FromStringImpl<NMonitoring::EFormat>(const char* str, size_t len) { - using NMonitoring::EFormat; - TStringBuf value(str, len); + } + + TStringBuf ContentEncodingByCompression(ECompression compression) { + switch (compression) { + case ECompression::IDENTITY: + return NFormatContentEncoding::IDENTITY; + case ECompression::ZLIB: + return NFormatContentEncoding::ZLIB; + case ECompression::LZ4: + return NFormatContentEncoding::LZ4; + case ECompression::ZSTD: + return NFormatContentEncoding::ZSTD; + case ECompression::UNKNOWN: + return TStringBuf(); + } + + Y_FAIL(); // for GCC + } + +} + +template <> +NMonitoring::EFormat FromStringImpl<NMonitoring::EFormat>(const char* str, size_t len) { + using NMonitoring::EFormat; + TStringBuf value(str, len); if (value == TStringBuf("SPACK")) { - return EFormat::SPACK; + return EFormat::SPACK; } else if (value == TStringBuf("JSON")) { - return EFormat::JSON; + return EFormat::JSON; } else if (value == TStringBuf("PROTOBUF")) { - return EFormat::PROTOBUF; + return EFormat::PROTOBUF; } else if (value == TStringBuf("TEXT")) { - return EFormat::TEXT; + return EFormat::TEXT; } else if (value == TStringBuf("PROMETHEUS")) { - return EFormat::PROMETHEUS; + return EFormat::PROMETHEUS; } else if (value == TStringBuf("UNKNOWN")) { - return EFormat::UNKNOWN; - } - ythrow yexception() << "unknown format: " << value; -} - -template <> -void Out<NMonitoring::EFormat>(IOutputStream& o, NMonitoring::EFormat f) { - using NMonitoring::EFormat; - switch (f) { - case EFormat::SPACK: + return EFormat::UNKNOWN; + } + ythrow yexception() << "unknown format: " << value; +} + +template <> +void Out<NMonitoring::EFormat>(IOutputStream& o, NMonitoring::EFormat f) { + using NMonitoring::EFormat; + switch (f) { + case EFormat::SPACK: o << TStringBuf("SPACK"); - return; - case EFormat::JSON: + return; + case EFormat::JSON: o << TStringBuf("JSON"); - return; - case EFormat::PROTOBUF: + return; + case EFormat::PROTOBUF: o << TStringBuf("PROTOBUF"); - return; - case EFormat::TEXT: + return; + case EFormat::TEXT: o << TStringBuf("TEXT"); - return; - case EFormat::PROMETHEUS: + return; + case EFormat::PROMETHEUS: o << TStringBuf("PROMETHEUS"); - return; - case EFormat::UNKNOWN: + return; + case EFormat::UNKNOWN: o << TStringBuf("UNKNOWN"); - return; - } - - Y_FAIL(); // for GCC -} - -template <> -NMonitoring::ECompression FromStringImpl<NMonitoring::ECompression>(const char* str, size_t len) { - using NMonitoring::ECompression; - TStringBuf value(str, len); + return; + } + + Y_FAIL(); // for GCC +} + +template <> +NMonitoring::ECompression FromStringImpl<NMonitoring::ECompression>(const char* str, size_t len) { + using NMonitoring::ECompression; + TStringBuf value(str, len); if (value == TStringBuf("IDENTITY")) { - return ECompression::IDENTITY; + return ECompression::IDENTITY; } else if (value == TStringBuf("ZLIB")) { - return ECompression::ZLIB; + return ECompression::ZLIB; } else if (value == TStringBuf("LZ4")) { - return ECompression::LZ4; + return ECompression::LZ4; } else if (value == TStringBuf("ZSTD")) { - return ECompression::ZSTD; + return ECompression::ZSTD; } else if (value == TStringBuf("UNKNOWN")) { - return ECompression::UNKNOWN; - } - ythrow yexception() << "unknown compression: " << value; -} - -template <> -void Out<NMonitoring::ECompression>(IOutputStream& o, NMonitoring::ECompression c) { - using NMonitoring::ECompression; - switch (c) { - case ECompression::IDENTITY: + return ECompression::UNKNOWN; + } + ythrow yexception() << "unknown compression: " << value; +} + +template <> +void Out<NMonitoring::ECompression>(IOutputStream& o, NMonitoring::ECompression c) { + using NMonitoring::ECompression; + switch (c) { + case ECompression::IDENTITY: o << TStringBuf("IDENTITY"); - return; - case ECompression::ZLIB: + return; + case ECompression::ZLIB: o << TStringBuf("ZLIB"); - return; - case ECompression::LZ4: + return; + case ECompression::LZ4: o << TStringBuf("LZ4"); - return; - case ECompression::ZSTD: + return; + case ECompression::ZSTD: o << TStringBuf("ZSTD"); - return; - case ECompression::UNKNOWN: + return; + case ECompression::UNKNOWN: o << TStringBuf("UNKNOWN"); - return; - } - - Y_FAIL(); // for GCC -} + return; + } + + Y_FAIL(); // for GCC +} diff --git a/library/cpp/monlib/encode/format.h b/library/cpp/monlib/encode/format.h index 8815a32a26..495d42d786 100644 --- a/library/cpp/monlib/encode/format.h +++ b/library/cpp/monlib/encode/format.h @@ -1,96 +1,96 @@ -#pragma once - -#include <util/generic/strbuf.h> - -namespace NMonitoring { - namespace NFormatContenType { +#pragma once + +#include <util/generic/strbuf.h> + +namespace NMonitoring { + namespace NFormatContenType { constexpr TStringBuf TEXT = "application/x-solomon-txt"; constexpr TStringBuf JSON = "application/json"; constexpr TStringBuf PROTOBUF = "application/x-solomon-pb"; constexpr TStringBuf SPACK = "application/x-solomon-spack"; constexpr TStringBuf PROMETHEUS = "text/plain"; - } - - namespace NFormatContentEncoding { + } + + namespace NFormatContentEncoding { constexpr TStringBuf IDENTITY = "identity"; constexpr TStringBuf ZLIB = "zlib"; constexpr TStringBuf LZ4 = "lz4"; constexpr TStringBuf ZSTD = "zstd"; - } - - /** - * Defines format types for metric encoders. - */ - enum class EFormat { - /** - * Special case when it was not possible to determine format. - */ - UNKNOWN, - - /** - * Read more https://wiki.yandex-team.ru/solomon/api/dataformat/spackv1 - */ - SPACK, - - /** - * Read more https://wiki.yandex-team.ru/solomon/api/dataformat/json - */ - JSON, - - /** - * Simple protobuf format, only for testing purposes. - */ - PROTOBUF, - - /** - * Simple text representation, only for debug purposes. - */ - TEXT, - - /** - * Prometheus text-based format - */ - PROMETHEUS, - }; - - /** - * Defines compression algorithms for metric encoders. - */ - enum class ECompression { - /** - * Special case when it was not possible to determine compression. - */ - UNKNOWN, - - /** - * Means no compression. - */ - IDENTITY, - - /** - * Using the zlib structure (defined in RFC 1950), with the - * deflate compression algorithm and Adler32 checkums. - */ - ZLIB, - - /** - * Using LZ4 compression algorithm (read http://lz4.org for more info) - * with XxHash32 checksums. - */ - LZ4, - - /** - * Using Zstandard compression algorithm (read http://zstd.net for more - * info) with XxHash32 checksums. - */ - ZSTD, - }; - - enum class EMetricsMergingMode { + } + + /** + * Defines format types for metric encoders. + */ + enum class EFormat { + /** + * Special case when it was not possible to determine format. + */ + UNKNOWN, + + /** + * Read more https://wiki.yandex-team.ru/solomon/api/dataformat/spackv1 + */ + SPACK, + + /** + * Read more https://wiki.yandex-team.ru/solomon/api/dataformat/json + */ + JSON, + + /** + * Simple protobuf format, only for testing purposes. + */ + PROTOBUF, + + /** + * Simple text representation, only for debug purposes. + */ + TEXT, + + /** + * Prometheus text-based format + */ + PROMETHEUS, + }; + + /** + * Defines compression algorithms for metric encoders. + */ + enum class ECompression { + /** + * Special case when it was not possible to determine compression. + */ + UNKNOWN, + + /** + * Means no compression. + */ + IDENTITY, + + /** + * Using the zlib structure (defined in RFC 1950), with the + * deflate compression algorithm and Adler32 checkums. + */ + ZLIB, + + /** + * Using LZ4 compression algorithm (read http://lz4.org for more info) + * with XxHash32 checksums. + */ + LZ4, + /** - * Do not merge metric batches. If several points of the same metric were + * Using Zstandard compression algorithm (read http://zstd.net for more + * info) with XxHash32 checksums. + */ + ZSTD, + }; + + enum class EMetricsMergingMode { + /** + * Do not merge metric batches. If several points of the same metric were * added multiple times accross different writes, paste them as - * separate metrics. + * separate metrics. * * Example: * COUNTER [(ts1, val1)] | COUNTER [(ts1, val1)] @@ -98,9 +98,9 @@ namespace NMonitoring { * COUNTER [(ts3, val3)] | COUNTER [(ts3, val3)] */ DEFAULT, - + /** - * If several points of the same metric were added multiple times across + * If several points of the same metric were added multiple times across * different writes, merge all values to one timeseries. * * Example: @@ -108,18 +108,18 @@ namespace NMonitoring { * COUNTER [(ts2, val2)] | --> COUNTER [(ts1, val1), (ts2, val2), (ts3, val3)] * COUNTER [(ts3, val3)] | */ - MERGE_METRICS, + MERGE_METRICS, }; - /** - * Matches serialization format by the given "Accept" header value. - * - * @param value value of the "Accept" header. - * @return most preffered serialization format type - */ + /** + * Matches serialization format by the given "Accept" header value. + * + * @param value value of the "Accept" header. + * @return most preffered serialization format type + */ EFormat FormatFromAcceptHeader(TStringBuf value); - - /** + + /** * Matches serialization format by the given "Content-Type" header value * * @param value value of the "Content-Type" header @@ -128,24 +128,24 @@ namespace NMonitoring { EFormat FormatFromContentType(TStringBuf value); /** - * Returns value for "Content-Type" header determined by the given - * format type. - * - * @param format serialization format type - * @return mime-type indentificator - * or empty string if format is UNKNOWN - */ - TStringBuf ContentTypeByFormat(EFormat format); - - /** - * Matches compression algorithm by the given "Accept-Encoding" header value. - * - * @param value value of the "Accept-Encoding" header. - * @return most preffered compression algorithm - */ - ECompression CompressionFromAcceptEncodingHeader(TStringBuf value); - - /** + * Returns value for "Content-Type" header determined by the given + * format type. + * + * @param format serialization format type + * @return mime-type indentificator + * or empty string if format is UNKNOWN + */ + TStringBuf ContentTypeByFormat(EFormat format); + + /** + * Matches compression algorithm by the given "Accept-Encoding" header value. + * + * @param value value of the "Accept-Encoding" header. + * @return most preffered compression algorithm + */ + ECompression CompressionFromAcceptEncodingHeader(TStringBuf value); + + /** * Matches compression algorithm by the given "Content-Encoding" header value. * * @param value value of the "Accept-Encoding" header. @@ -154,13 +154,13 @@ namespace NMonitoring { ECompression CompressionFromContentEncodingHeader(TStringBuf value); /** - * Returns value for "Content-Encoding" header determined by the given - * compression algorithm. - * - * @param compression encoding compression alg - * @return media-type compresion algorithm - * or empty string if compression is UNKNOWN - */ - TStringBuf ContentEncodingByCompression(ECompression compression); - -} + * Returns value for "Content-Encoding" header determined by the given + * compression algorithm. + * + * @param compression encoding compression alg + * @return media-type compresion algorithm + * or empty string if compression is UNKNOWN + */ + TStringBuf ContentEncodingByCompression(ECompression compression); + +} diff --git a/library/cpp/monlib/encode/format_ut.cpp b/library/cpp/monlib/encode/format_ut.cpp index 63475674d2..22a0e30c03 100644 --- a/library/cpp/monlib/encode/format_ut.cpp +++ b/library/cpp/monlib/encode/format_ut.cpp @@ -1,14 +1,14 @@ -#include "format.h" - +#include "format.h" + #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/string.h> -#include <util/string/builder.h> - -#include <array> - -using namespace NMonitoring; - + +#include <util/generic/string.h> +#include <util/string/builder.h> + +#include <array> + +using namespace NMonitoring; + Y_UNIT_TEST_SUITE(TFormatTest) { Y_UNIT_TEST(ContentTypeHeader) { UNIT_ASSERT_EQUAL(FormatFromContentType(""), EFormat::UNKNOWN); @@ -21,116 +21,116 @@ Y_UNIT_TEST_SUITE(TFormatTest) { Y_UNIT_TEST(AcceptHeader) { UNIT_ASSERT_EQUAL(FormatFromAcceptHeader(""), EFormat::UNKNOWN); UNIT_ASSERT_EQUAL(FormatFromAcceptHeader("*/*"), EFormat::UNKNOWN); - - UNIT_ASSERT_EQUAL( + + UNIT_ASSERT_EQUAL( FormatFromAcceptHeader("application/xml"), - EFormat::UNKNOWN); - - UNIT_ASSERT_EQUAL( + EFormat::UNKNOWN); + + UNIT_ASSERT_EQUAL( FormatFromAcceptHeader("application/json"), - EFormat::JSON); - - UNIT_ASSERT_EQUAL( + EFormat::JSON); + + UNIT_ASSERT_EQUAL( FormatFromAcceptHeader("application/x-solomon-spack"), - EFormat::SPACK); - - UNIT_ASSERT_EQUAL( + EFormat::SPACK); + + UNIT_ASSERT_EQUAL( FormatFromAcceptHeader("application/x-solomon-pb"), - EFormat::PROTOBUF); - - UNIT_ASSERT_EQUAL( - FormatFromAcceptHeader("application/x-solomon-txt"), - EFormat::TEXT); - - UNIT_ASSERT_EQUAL( + EFormat::PROTOBUF); + + UNIT_ASSERT_EQUAL( + FormatFromAcceptHeader("application/x-solomon-txt"), + EFormat::TEXT); + + UNIT_ASSERT_EQUAL( FormatFromAcceptHeader("application/json, text/plain"), - EFormat::JSON); - - UNIT_ASSERT_EQUAL( + EFormat::JSON); + + UNIT_ASSERT_EQUAL( FormatFromAcceptHeader("application/x-solomon-spack, application/json, text/plain"), - EFormat::SPACK); - - UNIT_ASSERT_EQUAL( + EFormat::SPACK); + + UNIT_ASSERT_EQUAL( FormatFromAcceptHeader(" , application/x-solomon-spack ,, application/json , text/plain"), - EFormat::SPACK); - - UNIT_ASSERT_EQUAL( + EFormat::SPACK); + + UNIT_ASSERT_EQUAL( FormatFromAcceptHeader("application/xml, application/x-solomon-spack, text/plain"), - EFormat::SPACK); - - UNIT_ASSERT_EQUAL( - FormatFromAcceptHeader("text/plain"), - EFormat::PROMETHEUS); - } - + EFormat::SPACK); + + UNIT_ASSERT_EQUAL( + FormatFromAcceptHeader("text/plain"), + EFormat::PROMETHEUS); + } + Y_UNIT_TEST(FormatToStrFromStr) { - const std::array<EFormat, 6> formats = {{ - EFormat::UNKNOWN, - EFormat::SPACK, - EFormat::JSON, - EFormat::PROTOBUF, - EFormat::TEXT, - EFormat::PROMETHEUS, - }}; - - for (EFormat f : formats) { - TString str = (TStringBuilder() << f); - EFormat g = FromString<EFormat>(str); - UNIT_ASSERT_EQUAL(f, g); - } - } - + const std::array<EFormat, 6> formats = {{ + EFormat::UNKNOWN, + EFormat::SPACK, + EFormat::JSON, + EFormat::PROTOBUF, + EFormat::TEXT, + EFormat::PROMETHEUS, + }}; + + for (EFormat f : formats) { + TString str = (TStringBuilder() << f); + EFormat g = FromString<EFormat>(str); + UNIT_ASSERT_EQUAL(f, g); + } + } + Y_UNIT_TEST(AcceptEncodingHeader) { - UNIT_ASSERT_EQUAL( - CompressionFromAcceptEncodingHeader(""), - ECompression::UNKNOWN); - - UNIT_ASSERT_EQUAL( - CompressionFromAcceptEncodingHeader("br"), - ECompression::UNKNOWN); - - UNIT_ASSERT_EQUAL( - CompressionFromAcceptEncodingHeader("identity"), - ECompression::IDENTITY); - - UNIT_ASSERT_EQUAL( - CompressionFromAcceptEncodingHeader("zlib"), - ECompression::ZLIB); - - UNIT_ASSERT_EQUAL( - CompressionFromAcceptEncodingHeader("lz4"), - ECompression::LZ4); - - UNIT_ASSERT_EQUAL( - CompressionFromAcceptEncodingHeader("zstd"), - ECompression::ZSTD); - - UNIT_ASSERT_EQUAL( - CompressionFromAcceptEncodingHeader("zstd, zlib"), - ECompression::ZSTD); - - UNIT_ASSERT_EQUAL( - CompressionFromAcceptEncodingHeader(" ,, , zstd , zlib"), - ECompression::ZSTD); - - UNIT_ASSERT_EQUAL( - CompressionFromAcceptEncodingHeader("br, deflate,lz4, zlib"), - ECompression::LZ4); - } - + UNIT_ASSERT_EQUAL( + CompressionFromAcceptEncodingHeader(""), + ECompression::UNKNOWN); + + UNIT_ASSERT_EQUAL( + CompressionFromAcceptEncodingHeader("br"), + ECompression::UNKNOWN); + + UNIT_ASSERT_EQUAL( + CompressionFromAcceptEncodingHeader("identity"), + ECompression::IDENTITY); + + UNIT_ASSERT_EQUAL( + CompressionFromAcceptEncodingHeader("zlib"), + ECompression::ZLIB); + + UNIT_ASSERT_EQUAL( + CompressionFromAcceptEncodingHeader("lz4"), + ECompression::LZ4); + + UNIT_ASSERT_EQUAL( + CompressionFromAcceptEncodingHeader("zstd"), + ECompression::ZSTD); + + UNIT_ASSERT_EQUAL( + CompressionFromAcceptEncodingHeader("zstd, zlib"), + ECompression::ZSTD); + + UNIT_ASSERT_EQUAL( + CompressionFromAcceptEncodingHeader(" ,, , zstd , zlib"), + ECompression::ZSTD); + + UNIT_ASSERT_EQUAL( + CompressionFromAcceptEncodingHeader("br, deflate,lz4, zlib"), + ECompression::LZ4); + } + Y_UNIT_TEST(CompressionToStrFromStr) { - const std::array<ECompression, 5> algs = {{ - ECompression::UNKNOWN, - ECompression::IDENTITY, - ECompression::ZLIB, - ECompression::LZ4, - ECompression::ZSTD, - }}; - - for (ECompression a : algs) { - TString str = (TStringBuilder() << a); - ECompression b = FromString<ECompression>(str); - UNIT_ASSERT_EQUAL(a, b); - } - } -} + const std::array<ECompression, 5> algs = {{ + ECompression::UNKNOWN, + ECompression::IDENTITY, + ECompression::ZLIB, + ECompression::LZ4, + ECompression::ZSTD, + }}; + + for (ECompression a : algs) { + TString str = (TStringBuilder() << a); + ECompression b = FromString<ECompression>(str); + UNIT_ASSERT_EQUAL(a, b); + } + } +} diff --git a/library/cpp/monlib/encode/fuzz/ya.make b/library/cpp/monlib/encode/fuzz/ya.make index 44b76eee49..d9ca172bae 100644 --- a/library/cpp/monlib/encode/fuzz/ya.make +++ b/library/cpp/monlib/encode/fuzz/ya.make @@ -1,5 +1,5 @@ RECURSE_ROOT_RELATIVE( - library/cpp/monlib/encode/json/fuzz - library/cpp/monlib/encode/prometheus/fuzz - library/cpp/monlib/encode/spack/fuzz + library/cpp/monlib/encode/json/fuzz + library/cpp/monlib/encode/prometheus/fuzz + library/cpp/monlib/encode/spack/fuzz ) diff --git a/library/cpp/monlib/encode/json/fuzz/main.cpp b/library/cpp/monlib/encode/json/fuzz/main.cpp index 65f98d8a8b..4f40310e06 100644 --- a/library/cpp/monlib/encode/json/fuzz/main.cpp +++ b/library/cpp/monlib/encode/json/fuzz/main.cpp @@ -1,5 +1,5 @@ -#include <library/cpp/monlib/encode/json/json.h> -#include <library/cpp/monlib/encode/fake/fake.h> +#include <library/cpp/monlib/encode/json/json.h> +#include <library/cpp/monlib/encode/fake/fake.h> #include <util/generic/strbuf.h> diff --git a/library/cpp/monlib/encode/json/fuzz/ya.make b/library/cpp/monlib/encode/json/fuzz/ya.make index 8ff5c6f9f9..75baa77716 100644 --- a/library/cpp/monlib/encode/json/fuzz/ya.make +++ b/library/cpp/monlib/encode/json/fuzz/ya.make @@ -6,8 +6,8 @@ OWNER( ) PEERDIR( - library/cpp/monlib/encode/json - library/cpp/monlib/encode/fake + library/cpp/monlib/encode/json + library/cpp/monlib/encode/fake ) SIZE(MEDIUM) diff --git a/library/cpp/monlib/encode/json/json.h b/library/cpp/monlib/encode/json/json.h index 2f0c8b0e1d..21530f20c3 100644 --- a/library/cpp/monlib/encode/json/json.h +++ b/library/cpp/monlib/encode/json/json.h @@ -1,20 +1,20 @@ -#pragma once - -#include <library/cpp/monlib/encode/encoder.h> -#include <library/cpp/monlib/encode/format.h> - +#pragma once -class IOutputStream; - -namespace NMonitoring { +#include <library/cpp/monlib/encode/encoder.h> +#include <library/cpp/monlib/encode/format.h> + + +class IOutputStream; + +namespace NMonitoring { class TJsonDecodeError: public yexception { }; - IMetricEncoderPtr EncoderJson(IOutputStream* out, int indentation = 0); - + IMetricEncoderPtr EncoderJson(IOutputStream* out, int indentation = 0); + /// Buffered encoder will merge series with same labels into one. - IMetricEncoderPtr BufferedEncoderJson(IOutputStream* out, int indentation = 0); + IMetricEncoderPtr BufferedEncoderJson(IOutputStream* out, int indentation = 0); IMetricEncoderPtr EncoderCloudJson(IOutputStream* out, int indentation = 0, @@ -25,5 +25,5 @@ namespace NMonitoring { TStringBuf metricNameLabel = "name"); void DecodeJson(TStringBuf data, IMetricConsumer* c, TStringBuf metricNameLabel = "name"); - -} + +} diff --git a/library/cpp/monlib/encode/json/json_decoder.cpp b/library/cpp/monlib/encode/json/json_decoder.cpp index c8824e1ccc..d44ff5fd28 100644 --- a/library/cpp/monlib/encode/json/json_decoder.cpp +++ b/library/cpp/monlib/encode/json/json_decoder.cpp @@ -1,24 +1,24 @@ -#include "json.h" -#include "typed_point.h" - +#include "json.h" +#include "typed_point.h" + #include <library/cpp/monlib/exception/exception.h> -#include <library/cpp/monlib/metrics/labels.h> -#include <library/cpp/monlib/metrics/metric_value.h> - +#include <library/cpp/monlib/metrics/labels.h> +#include <library/cpp/monlib/metrics/metric_value.h> + #include <library/cpp/json/json_reader.h> - -#include <util/datetime/base.h> -#include <util/string/cast.h> - -#include <limits> - -namespace NMonitoring { + +#include <util/datetime/base.h> +#include <util/string/cast.h> + +#include <limits> + +namespace NMonitoring { #define DECODE_ENSURE(COND, ...) MONLIB_ENSURE_EX(COND, TJsonDecodeError() << __VA_ARGS__) namespace { - + /////////////////////////////////////////////////////////////////////// // THistogramBuilder /////////////////////////////////////////////////////////////////////// @@ -32,11 +32,11 @@ public: } Bounds_.push_back(bound); } - + void AddValue(TBucketValue value) { Values_.push_back(value); } - + void AddInf(TBucketValue value) { InfPresented_ = true; InfValue_ = value; @@ -53,14 +53,14 @@ public: Bounds_.clear(); Values_.clear(); InfPresented_ = false; - + return snapshot; } - + bool Empty() const noexcept { return Bounds_.empty() && Values_.empty(); } - + void Clear() { Bounds_.clear(); Values_.clear(); @@ -69,7 +69,7 @@ public: private: TBucketBounds Bounds_; TBucketValues Values_; - + bool InfPresented_ = false; TBucketValue InfValue_; }; @@ -182,7 +182,7 @@ std::pair<double, bool> ParseSpecDouble(TStringBuf string) { return {0, false}; } } - + /////////////////////////////////////////////////////////////////////// // TMetricCollector /////////////////////////////////////////////////////////////////////// @@ -194,10 +194,10 @@ struct TMetricCollector { TLogHistogramBuilder LogHistBuilder; TTypedPoint LastPoint; TVector<TTypedPoint> TimeSeries; - + bool SeenTsOrValue = false; bool SeenTimeseries = false; - + void Clear() { Type = EMetricType::UNKNOWN; Labels.Clear(); @@ -209,20 +209,20 @@ struct TMetricCollector { SummaryBuilder.Clear(); LogHistBuilder.Clear(); } - + void AddLabel(const TLabel& label) { Labels.Add(label.Name(), label.Value()); } - + void SetLastTime(TInstant time) { LastPoint.SetTime(time); } - + template <typename T> void SetLastValue(T value) { LastPoint.SetValue(value); } - + void SaveLastPoint() { DECODE_ENSURE(LastPoint.GetTime() != TInstant::Zero(), "cannot add point without or zero timestamp"); @@ -248,21 +248,21 @@ struct TMetricCollector { } else { for (const auto& p: TimeSeries) { consumer(p.GetTime(), p.GetValueType(), p.GetValue()); - } + } } } }; - + struct TCommonParts { TInstant CommonTime; TLabels CommonLabels; }; - + class IHaltableMetricConsumer: public IMetricConsumer { public: virtual bool NeedToStop() const = 0; }; - + // TODO(ivanzhukov@): check all states for cases when a json document is invalid // e.g. "metrics" or "commonLabels" keys are specified multiple times class TCommonPartsCollector: public IHaltableMetricConsumer { @@ -433,11 +433,11 @@ class TDecoderJson final: public NJson::TJsonCallbacks { struct TState { enum EState { ROOT_OBJECT = 0x01, - + COMMON_LABELS, COMMON_TS, METRICS_ARRAY, - + METRIC_OBJECT, METRIC_NAME, METRIC_LABELS, @@ -462,21 +462,21 @@ class TDecoderJson final: public NJson::TJsonCallbacks { METRIC_LOG_HIST_START_POWER, METRIC_LOG_HIST_BUCKETS, }; - + constexpr EState Current() const noexcept { return static_cast<EState>(State_ & 0xFF); } - + void ToNext(EState state) noexcept { constexpr auto bitSize = 8 * sizeof(ui8); State_ = (State_ << bitSize) | static_cast<ui8>(state); } - + void ToPrev() noexcept { constexpr auto bitSize = 8 * sizeof(ui8); State_ = State_ >> bitSize; } - + private: ui64 State_ = static_cast<ui64>(ROOT_OBJECT); }; @@ -522,16 +522,16 @@ if (Y_UNLIKELY(!(CONDITION))) { \ LastMetric_.SetLastValue(static_cast<i64>(value)); State_.ToPrev(); break; - + case TState::METRIC_HIST_BOUNDS: LastMetric_.HistogramBuilder.AddBound(static_cast<double>(value)); break; - + case TState::METRIC_HIST_BUCKETS: PARSE_ENSURE(value >= 0 && static_cast<ui64>(value) <= Max<TBucketValues::value_type>(), "value is out of bounds " << value); LastMetric_.HistogramBuilder.AddValue(value); break; - + case TState::METRIC_HIST_INF: PARSE_ENSURE(value >= 0, "unexpected negative number in histogram inf: " << value); LastMetric_.HistogramBuilder.AddInf(value); @@ -584,7 +584,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } return true; } - + bool OnUInteger(unsigned long long value) override { switch (State_.Current()) { case TState::COMMON_TS: @@ -597,32 +597,32 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } break; - + case TState::METRIC_TS: LastMetric_.SetLastTime(TInstant::Seconds(value)); State_.ToPrev(); break; - + case TState::METRIC_VALUE: PARSE_ENSURE(value <= Max<ui64>(), "Metric value is out of bounds: " << value); LastMetric_.SetLastValue(static_cast<ui64>(value)); State_.ToPrev(); break; - + case TState::METRIC_HIST_BOUNDS: LastMetric_.HistogramBuilder.AddBound(static_cast<double>(value)); break; - + case TState::METRIC_HIST_BUCKETS: PARSE_ENSURE(value <= Max<TBucketValues::value_type>(), "Histogram bucket value is out of bounds: " << value); LastMetric_.HistogramBuilder.AddValue(value); break; - + case TState::METRIC_HIST_INF: LastMetric_.HistogramBuilder.AddInf(value); State_.ToPrev(); break; - + case TState::METRIC_DSUMMARY_COUNT: LastMetric_.SummaryBuilder.SetCount(value); State_.ToPrev(); @@ -669,18 +669,18 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } return true; } - + bool OnDouble(double value) override { switch (State_.Current()) { case TState::METRIC_VALUE: LastMetric_.SetLastValue(value); State_.ToPrev(); break; - + case TState::METRIC_HIST_BOUNDS: LastMetric_.HistogramBuilder.AddBound(value); break; - + case TState::METRIC_DSUMMARY_SUM: LastMetric_.SummaryBuilder.SetSum(value); State_.ToPrev(); @@ -752,22 +752,22 @@ if (Y_UNLIKELY(!(CONDITION))) { \ LastMetric_.SetLastValue(doubleValue); } else { return false; - } + } State_.ToPrev(); break; - + case TState::METRIC_TYPE: LastMetric_.Type = MetricTypeFromStr(value); State_.ToPrev(); break; - + case TState::METRIC_MODE: if (value == TStringBuf("deriv")) { LastMetric_.Type = EMetricType::RATE; } State_.ToPrev(); break; - + case TState::METRIC_DSUMMARY_SUM: if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) { LastMetric_.SummaryBuilder.SetSum(doubleValue); @@ -776,7 +776,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } State_.ToPrev(); break; - + case TState::METRIC_DSUMMARY_MIN: if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) { LastMetric_.SummaryBuilder.SetMin(doubleValue); @@ -785,7 +785,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } State_.ToPrev(); break; - + case TState::METRIC_DSUMMARY_MAX: if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) { LastMetric_.SummaryBuilder.SetMax(doubleValue); @@ -794,7 +794,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } State_.ToPrev(); break; - + case TState::METRIC_DSUMMARY_LAST: if (auto [doubleValue, ok] = ParseSpecDouble(value); ok) { LastMetric_.SummaryBuilder.SetLast(doubleValue); @@ -803,11 +803,11 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } State_.ToPrev(); break; - + default: return false; } - + return true; } @@ -877,7 +877,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ State_.ToNext(TState::METRIC_DSUMMARY); } else if (key == TStringBuf("log_hist")) { State_.ToNext(TState::METRIC_LOG_HIST); - } + } break; case TState::METRIC_HIST: @@ -889,7 +889,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ State_.ToNext(TState::METRIC_HIST_INF); } break; - + case TState::METRIC_LOG_HIST: if (key == TStringBuf("base")) { State_.ToNext(TState::METRIC_LOG_HIST_BASE); @@ -901,7 +901,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ State_.ToNext(TState::METRIC_LOG_HIST_BUCKETS); } break; - + case TState::METRIC_DSUMMARY: if (key == TStringBuf("sum")) { State_.ToNext(TState::METRIC_DSUMMARY_SUM); @@ -914,14 +914,14 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } else if (key == TStringBuf("count")) { State_.ToNext(TState::METRIC_DSUMMARY_COUNT); } - + break; - - + + default: return false; } - + return true; } @@ -945,17 +945,17 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } return true; } - + bool OnCloseMap() override { switch (State_.Current()) { case TState::ROOT_OBJECT: MetricConsumer_->OnStreamEnd(); break; - + case TState::METRIC_LABELS: State_.ToPrev(); break; - + case TState::COMMON_LABELS: MetricConsumer_->OnLabelsEnd(); State_.ToPrev(); @@ -966,22 +966,22 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } break; - + case TState::METRIC_OBJECT: ConsumeMetric(); State_.ToPrev(); break; - + case TState::METRIC_TIMESERIES: LastMetric_.SaveLastPoint(); break; - + case TState::METRIC_HIST: case TState::METRIC_DSUMMARY: case TState::METRIC_LOG_HIST: State_.ToPrev(); break; - + default: break; } @@ -999,7 +999,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ "unexpected array begin"); return true; } - + bool OnCloseArray() override { switch (State_.Current()) { case TState::METRICS_ARRAY: @@ -1009,13 +1009,13 @@ if (Y_UNLIKELY(!(CONDITION))) { \ case TState::METRIC_LOG_HIST_BUCKETS: State_.ToPrev(); break; - + default: return false; } return true; } - + void OnError(size_t off, TStringBuf reason) override { if (IsIntentionallyHalted_) { return; @@ -1023,13 +1023,13 @@ if (Y_UNLIKELY(!(CONDITION))) { \ size_t snippetBeg = (off < 20) ? 0 : (off - 20); TStringBuf snippet = Data_.SubStr(snippetBeg, 40); - + throw TJsonDecodeError() << "cannot parse JSON, error at: " << off << ", reason: " << (ErrorMsg_.empty() ? reason : TStringBuf{ErrorMsg_}) << "\nsnippet: ..." << snippet << "..."; } - + bool OnEnd() override { return true; } @@ -1041,21 +1041,21 @@ if (Y_UNLIKELY(!(CONDITION))) { \ LastMetric_.Type = EMetricType::GAUGE; } else { LastMetric_.Type = EMetricType::HIST; - } + } } - + // (1) begin metric MetricConsumer_->OnMetricBegin(LastMetric_.Type); - + // (2) labels if (!LastMetric_.Labels.empty()) { MetricConsumer_->OnLabelsBegin(); for (auto&& label : LastMetric_.Labels) { MetricConsumer_->OnLabel(label.Name(), label.Value()); - } + } MetricConsumer_->OnLabelsEnd(); } - + // (3) values switch (LastMetric_.Type) { case EMetricType::GAUGE: @@ -1069,14 +1069,14 @@ if (Y_UNLIKELY(!(CONDITION))) { \ MetricConsumer_->OnInt64(time, value.AsInt64(valueType)); }); break; - + case EMetricType::COUNTER: case EMetricType::RATE: LastMetric_.Consume([this](TInstant time, EMetricValueType valueType, TMetricValue value) { MetricConsumer_->OnUint64(time, value.AsUint64(valueType)); }); break; - + case EMetricType::HIST: case EMetricType::HIST_RATE: if (LastMetric_.TimeSeries.empty()) { @@ -1087,10 +1087,10 @@ if (Y_UNLIKELY(!(CONDITION))) { \ for (const auto& p : LastMetric_.TimeSeries) { DECODE_ENSURE(p.GetValueType() == EMetricValueType::HISTOGRAM, "Value is not a histogram"); MetricConsumer_->OnHistogram(p.GetTime(), p.GetValue().AsHistogram()); - } - } + } + } break; - + case EMetricType::DSUMMARY: if (LastMetric_.TimeSeries.empty()) { auto time = LastMetric_.LastPoint.GetTime(); @@ -1103,7 +1103,7 @@ if (Y_UNLIKELY(!(CONDITION))) { \ } } break; - + case EMetricType::LOGHIST: if (LastMetric_.TimeSeries.empty()) { auto time = LastMetric_.LastPoint.GetTime(); @@ -1113,19 +1113,19 @@ if (Y_UNLIKELY(!(CONDITION))) { \ for (const auto& p : LastMetric_.TimeSeries) { DECODE_ENSURE(p.GetValueType() == EMetricValueType::LOGHISTOGRAM, "Value is not a log_histogram"); MetricConsumer_->OnLogHistogram(p.GetTime(), p.GetValue().AsLogHistogram()); - } - } + } + } break; - + case EMetricType::UNKNOWN: // TODO: output metric labels ythrow yexception() << "unknown metric type"; } - + // (4) end metric MetricConsumer_->OnMetricEnd(); } - + private: TStringBuf Data_; IHaltableMetricConsumer* MetricConsumer_; @@ -1136,9 +1136,9 @@ private: TString ErrorMsg_; bool IsIntentionallyHalted_{false}; }; - + } // namespace - + void DecodeJson(TStringBuf data, IMetricConsumer* c, TStringBuf metricNameLabel) { TCommonPartsCollector commonPartsCollector; { @@ -1159,4 +1159,4 @@ void DecodeJson(TStringBuf data, IMetricConsumer* c, TStringBuf metricNameLabel) #undef DECODE_ENSURE -} +} diff --git a/library/cpp/monlib/encode/json/json_encoder.cpp b/library/cpp/monlib/encode/json/json_encoder.cpp index 639177b5d1..20d2bb6283 100644 --- a/library/cpp/monlib/encode/json/json_encoder.cpp +++ b/library/cpp/monlib/encode/json/json_encoder.cpp @@ -1,39 +1,39 @@ -#include "json.h" -#include "typed_point.h" - -#include <library/cpp/monlib/encode/buffered/buffered_encoder_base.h> -#include <library/cpp/monlib/encode/encoder_state.h> -#include <library/cpp/monlib/metrics/metric.h> -#include <library/cpp/monlib/metrics/metric_value.h> -#include <library/cpp/monlib/metrics/labels.h> - +#include "json.h" +#include "typed_point.h" + +#include <library/cpp/monlib/encode/buffered/buffered_encoder_base.h> +#include <library/cpp/monlib/encode/encoder_state.h> +#include <library/cpp/monlib/metrics/metric.h> +#include <library/cpp/monlib/metrics/metric_value.h> +#include <library/cpp/monlib/metrics/labels.h> + #include <library/cpp/json/writer/json.h> - + #include <util/charset/utf8.h> #include <util/generic/algorithm.h> -namespace NMonitoring { - namespace { +namespace NMonitoring { + namespace { enum class EJsonStyle { Solomon, Cloud }; - /////////////////////////////////////////////////////////////////////// - // TJsonWriter - /////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////// + // TJsonWriter + /////////////////////////////////////////////////////////////////////// class TJsonWriter { - public: + public: TJsonWriter(IOutputStream* out, int indentation, EJsonStyle style, TStringBuf metricNameLabel) - : Buf_(NJsonWriter::HEM_UNSAFE, out) + : Buf_(NJsonWriter::HEM_UNSAFE, out) , Style_(style) , MetricNameLabel_(metricNameLabel) , CurrentMetricName_() - { - Buf_.SetIndentSpaces(indentation); - Buf_.SetWriteNanAsString(); - } - + { + Buf_.SetIndentSpaces(indentation); + Buf_.SetWriteNanAsString(); + } + void WriteTime(TInstant time) { if (time != TInstant::Zero()) { Buf_.WriteKey(TStringBuf("ts")); @@ -50,49 +50,49 @@ namespace NMonitoring { Buf_.WriteDouble(value); } - void WriteValue(i64 value) { + void WriteValue(i64 value) { Buf_.WriteKey(TStringBuf("value")); - Buf_.WriteLongLong(value); - } - + Buf_.WriteLongLong(value); + } + void WriteValue(ui64 value) { Buf_.WriteKey(TStringBuf("value")); Buf_.WriteULongLong(value); } - void WriteValue(IHistogramSnapshot* s) { + void WriteValue(IHistogramSnapshot* s) { Y_ENSURE(Style_ == EJsonStyle::Solomon); Buf_.WriteKey(TStringBuf("hist")); - Buf_.BeginObject(); - if (ui32 count = s->Count()) { - bool hasInf = (s->UpperBound(count - 1) == Max<double>()); - if (hasInf) { - count--; - } - + Buf_.BeginObject(); + if (ui32 count = s->Count()) { + bool hasInf = (s->UpperBound(count - 1) == Max<double>()); + if (hasInf) { + count--; + } + Buf_.WriteKey(TStringBuf("bounds")); - Buf_.BeginList(); - for (ui32 i = 0; i < count; i++) { - Buf_.WriteDouble(s->UpperBound(i)); - } - Buf_.EndList(); - + Buf_.BeginList(); + for (ui32 i = 0; i < count; i++) { + Buf_.WriteDouble(s->UpperBound(i)); + } + Buf_.EndList(); + Buf_.WriteKey(TStringBuf("buckets")); - Buf_.BeginList(); - for (ui32 i = 0; i < count; i++) { - Buf_.WriteULongLong(s->Value(i)); - } - Buf_.EndList(); - - if (hasInf) { + Buf_.BeginList(); + for (ui32 i = 0; i < count; i++) { + Buf_.WriteULongLong(s->Value(i)); + } + Buf_.EndList(); + + if (hasInf) { Buf_.WriteKey(TStringBuf("inf")); - Buf_.WriteULongLong(s->Value(count)); - } - } - Buf_.EndObject(); - } - + Buf_.WriteULongLong(s->Value(count)); + } + } + Buf_.EndObject(); + } + void WriteValue(ISummaryDoubleSnapshot* s) { Y_ENSURE(Style_ == EJsonStyle::Solomon); @@ -142,25 +142,25 @@ namespace NMonitoring { Buf_.EndObject(); } - void WriteValue(EMetricValueType type, TMetricValue value) { + void WriteValue(EMetricValueType type, TMetricValue value) { switch (type) { - case EMetricValueType::DOUBLE: - WriteValue(value.AsDouble()); + case EMetricValueType::DOUBLE: + WriteValue(value.AsDouble()); + break; + + case EMetricValueType::INT64: + WriteValue(value.AsInt64()); + break; + + case EMetricValueType::UINT64: + WriteValue(value.AsUint64()); break; - case EMetricValueType::INT64: - WriteValue(value.AsInt64()); - break; - - case EMetricValueType::UINT64: - WriteValue(value.AsUint64()); + case EMetricValueType::HISTOGRAM: + WriteValue(value.AsHistogram()); break; - case EMetricValueType::HISTOGRAM: - WriteValue(value.AsHistogram()); - break; - - case EMetricValueType::SUMMARY: + case EMetricValueType::SUMMARY: WriteValue(value.AsSummaryDouble()); break; @@ -168,7 +168,7 @@ namespace NMonitoring { WriteValue(value.AsLogHistogram()); break; - case EMetricValueType::UNKNOWN: + case EMetricValueType::UNKNOWN: ythrow yexception() << "unknown metric value type"; } } @@ -229,10 +229,10 @@ namespace NMonitoring { TString CurrentMetricName_; }; - /////////////////////////////////////////////////////////////////////// - // TEncoderJson - /////////////////////////////////////////////////////////////////////// - class TEncoderJson final: public IMetricEncoder, public TJsonWriter { + /////////////////////////////////////////////////////////////////////// + // TEncoderJson + /////////////////////////////////////////////////////////////////////// + class TEncoderJson final: public IMetricEncoder, public TJsonWriter { public: TEncoderJson(IOutputStream* out, int indentation, EJsonStyle style, TStringBuf metricNameLabel) : TJsonWriter{out, indentation, style, metricNameLabel} @@ -240,202 +240,202 @@ namespace NMonitoring { } ~TEncoderJson() override { - Close(); - } - - private: - void OnStreamBegin() override { + Close(); + } + + private: + void OnStreamBegin() override { State_.Expect(TEncoderState::EState::ROOT); - Buf_.BeginObject(); - } - - void OnStreamEnd() override { + Buf_.BeginObject(); + } + + void OnStreamEnd() override { State_.Expect(TEncoderState::EState::ROOT); - if (!Buf_.KeyExpected()) { - // not closed metrics array - Buf_.EndList(); - } - Buf_.EndObject(); - } - - void OnCommonTime(TInstant time) override { + if (!Buf_.KeyExpected()) { + // not closed metrics array + Buf_.EndList(); + } + Buf_.EndObject(); + } + + void OnCommonTime(TInstant time) override { State_.Expect(TEncoderState::EState::ROOT); - WriteTime(time); - } - - void OnMetricBegin(EMetricType type) override { - State_.Switch(TEncoderState::EState::ROOT, TEncoderState::EState::METRIC); - if (Buf_.KeyExpected()) { - // first metric, so open metrics array + WriteTime(time); + } + + void OnMetricBegin(EMetricType type) override { + State_.Switch(TEncoderState::EState::ROOT, TEncoderState::EState::METRIC); + if (Buf_.KeyExpected()) { + // first metric, so open metrics array Buf_.WriteKey(TStringBuf(Style_ == EJsonStyle::Solomon ? "sensors" : "metrics")); - Buf_.BeginList(); - } - Buf_.BeginObject(); + Buf_.BeginList(); + } + Buf_.BeginObject(); WriteMetricType(type); - } - - void OnMetricEnd() override { - State_.Switch(TEncoderState::EState::METRIC, TEncoderState::EState::ROOT); - if (!Buf_.KeyExpected()) { - // not closed timeseries array - Buf_.EndList(); - } - - if (!TimeSeries_ && LastPoint_.HasValue()) { - // we have seen only one point between OnMetricBegin() and - // OnMetricEnd() calls - WriteTime(LastPoint_.GetTime()); - WriteValue(LastPoint_.GetValueType(), LastPoint_.GetValue()); - } - Buf_.EndObject(); - - LastPoint_ = {}; - TimeSeries_ = false; - } - - void OnLabelsBegin() override { - if (!Buf_.KeyExpected()) { - // not closed metrics or timeseries array if labels go after values - Buf_.EndList(); - } + } + + void OnMetricEnd() override { + State_.Switch(TEncoderState::EState::METRIC, TEncoderState::EState::ROOT); + if (!Buf_.KeyExpected()) { + // not closed timeseries array + Buf_.EndList(); + } + + if (!TimeSeries_ && LastPoint_.HasValue()) { + // we have seen only one point between OnMetricBegin() and + // OnMetricEnd() calls + WriteTime(LastPoint_.GetTime()); + WriteValue(LastPoint_.GetValueType(), LastPoint_.GetValue()); + } + Buf_.EndObject(); + + LastPoint_ = {}; + TimeSeries_ = false; + } + + void OnLabelsBegin() override { + if (!Buf_.KeyExpected()) { + // not closed metrics or timeseries array if labels go after values + Buf_.EndList(); + } if (State_ == TEncoderState::EState::ROOT) { State_ = TEncoderState::EState::COMMON_LABELS; Buf_.WriteKey(TStringBuf(Style_ == EJsonStyle::Solomon ? "commonLabels" : "labels")); - } else if (State_ == TEncoderState::EState::METRIC) { - State_ = TEncoderState::EState::METRIC_LABELS; + } else if (State_ == TEncoderState::EState::METRIC) { + State_ = TEncoderState::EState::METRIC_LABELS; Buf_.WriteKey(TStringBuf("labels")); - } else { - State_.ThrowInvalid("expected METRIC or ROOT"); - } - Buf_.BeginObject(); + } else { + State_.ThrowInvalid("expected METRIC or ROOT"); + } + Buf_.BeginObject(); EmptyLabels_ = true; - } - - void OnLabelsEnd() override { - if (State_ == TEncoderState::EState::METRIC_LABELS) { - State_ = TEncoderState::EState::METRIC; + } + + void OnLabelsEnd() override { + if (State_ == TEncoderState::EState::METRIC_LABELS) { + State_ = TEncoderState::EState::METRIC; } else if (State_ == TEncoderState::EState::COMMON_LABELS) { State_ = TEncoderState::EState::ROOT; - } else { - State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); - } + } else { + State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); + } Y_ENSURE(!EmptyLabels_, "Labels cannot be empty"); - Buf_.EndObject(); + Buf_.EndObject(); if (State_ == TEncoderState::EState::METRIC) { WriteName(); } - } - - void OnLabel(TStringBuf name, TStringBuf value) override { - if (State_ == TEncoderState::EState::METRIC_LABELS || State_ == TEncoderState::EState::COMMON_LABELS) { + } + + void OnLabel(TStringBuf name, TStringBuf value) override { + if (State_ == TEncoderState::EState::METRIC_LABELS || State_ == TEncoderState::EState::COMMON_LABELS) { WriteLabel(name, value); - } else { - State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); - } + } else { + State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); + } EmptyLabels_ = false; - } - - void OnDouble(TInstant time, double value) override { - State_.Expect(TEncoderState::EState::METRIC); - Write<double>(time, value); - } - - void OnInt64(TInstant time, i64 value) override { - State_.Expect(TEncoderState::EState::METRIC); - Write<i64>(time, value); - } - - void OnUint64(TInstant time, ui64 value) override { - State_.Expect(TEncoderState::EState::METRIC); - Write<ui64>(time, value); - } - - void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { - State_.Expect(TEncoderState::EState::METRIC); - Write<IHistogramSnapshot*>(time, snapshot.Get()); - } - + } + + void OnDouble(TInstant time, double value) override { + State_.Expect(TEncoderState::EState::METRIC); + Write<double>(time, value); + } + + void OnInt64(TInstant time, i64 value) override { + State_.Expect(TEncoderState::EState::METRIC); + Write<i64>(time, value); + } + + void OnUint64(TInstant time, ui64 value) override { + State_.Expect(TEncoderState::EState::METRIC); + Write<ui64>(time, value); + } + + void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { + State_.Expect(TEncoderState::EState::METRIC); + Write<IHistogramSnapshot*>(time, snapshot.Get()); + } + void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override { - State_.Expect(TEncoderState::EState::METRIC); + State_.Expect(TEncoderState::EState::METRIC); Write<ISummaryDoubleSnapshot*>(time, snapshot.Get()); } void OnLogHistogram(TInstant time, TLogHistogramSnapshotPtr snapshot) override { - State_.Expect(TEncoderState::EState::METRIC); + State_.Expect(TEncoderState::EState::METRIC); Write<TLogHistogramSnapshot*>(time, snapshot.Get()); } - template <typename T> - void Write(TInstant time, T value) { - State_.Expect(TEncoderState::EState::METRIC); - - if (!LastPoint_.HasValue()) { - LastPoint_ = {time, value}; - } else { - // second point - // TODO: output types - Y_ENSURE(LastPoint_.GetValueType() == TValueType<T>::Type, - "mixed metric value types in one metric"); - - if (!TimeSeries_) { + template <typename T> + void Write(TInstant time, T value) { + State_.Expect(TEncoderState::EState::METRIC); + + if (!LastPoint_.HasValue()) { + LastPoint_ = {time, value}; + } else { + // second point + // TODO: output types + Y_ENSURE(LastPoint_.GetValueType() == TValueType<T>::Type, + "mixed metric value types in one metric"); + + if (!TimeSeries_) { Buf_.WriteKey(TStringBuf("timeseries")); - Buf_.BeginList(); - Buf_.BeginObject(); - Y_ENSURE(LastPoint_.GetTime() != TInstant::Zero(), + Buf_.BeginList(); + Buf_.BeginObject(); + Y_ENSURE(LastPoint_.GetTime() != TInstant::Zero(), "time cannot be empty or zero in a timeseries point"); - WriteTime(LastPoint_.GetTime()); - WriteValue(LastPoint_.GetValueType(), LastPoint_.GetValue()); - Buf_.EndObject(); - TimeSeries_ = true; - } - - if (TimeSeries_) { - Buf_.BeginObject(); + WriteTime(LastPoint_.GetTime()); + WriteValue(LastPoint_.GetValueType(), LastPoint_.GetValue()); + Buf_.EndObject(); + TimeSeries_ = true; + } + + if (TimeSeries_) { + Buf_.BeginObject(); Y_ENSURE(time != TInstant::Zero(), "time cannot be empty or zero in a timeseries point"); - - WriteTime(time); - WriteValue(value); - Buf_.EndObject(); - } - } - } - - void Close() override { - LastPoint_ = {}; - } - + + WriteTime(time); + WriteValue(value); + Buf_.EndObject(); + } + } + } + + void Close() override { + LastPoint_ = {}; + } + private: TEncoderState State_; - TTypedPoint LastPoint_; + TTypedPoint LastPoint_; bool TimeSeries_ = false; bool EmptyLabels_ = false; }; - /////////////////////////////////////////////////////////////////////// - // TBufferedJsonEncoder - /////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////// + // TBufferedJsonEncoder + /////////////////////////////////////////////////////////////////////// class TBufferedJsonEncoder : public TBufferedEncoderBase, public TJsonWriter { public: TBufferedJsonEncoder(IOutputStream* out, int indentation, EJsonStyle style, TStringBuf metricNameLabel) : TJsonWriter{out, indentation, style, metricNameLabel} { - MetricsMergingMode_ = EMetricsMergingMode::MERGE_METRICS; - } - + MetricsMergingMode_ = EMetricsMergingMode::MERGE_METRICS; + } + ~TBufferedJsonEncoder() override { Close(); - } - + } + void OnLabelsBegin() override { TBufferedEncoderBase::OnLabelsBegin(); EmptyLabels_ = true; } - void OnLabel(TStringBuf name, TStringBuf value) override { + void OnLabel(TStringBuf name, TStringBuf value) override { TBufferedEncoderBase::OnLabel(name, value); EmptyLabels_ = false; } @@ -456,36 +456,36 @@ namespace NMonitoring { } Closed_ = true; - + LabelValuesPool_.Build(); LabelNamesPool_.Build(); - + Buf_.BeginObject(); - + WriteTime(CommonTime_); if (CommonLabels_.size() > 0) { Buf_.WriteKey(TStringBuf(Style_ == EJsonStyle::Solomon ? "commonLabels": "labels")); WriteLabels(CommonLabels_, true); - } + } - if (Metrics_.size() > 0) { + if (Metrics_.size() > 0) { Buf_.WriteKey(TStringBuf(Style_ == EJsonStyle::Solomon ? "sensors" : "metrics")); - WriteMetrics(); + WriteMetrics(); } Buf_.EndObject(); - } - - private: - void WriteMetrics() { + } + + private: + void WriteMetrics() { Buf_.BeginList(); - for (auto&& metric : Metrics_) { - WriteMetric(metric); + for (auto&& metric : Metrics_) { + WriteMetric(metric); } Buf_.EndList(); } - void WriteMetric(TMetric& metric) { + void WriteMetric(TMetric& metric) { Buf_.BeginObject(); WriteMetricType(metric.MetricType); @@ -493,19 +493,19 @@ namespace NMonitoring { Buf_.WriteKey(TStringBuf("labels")); WriteLabels(metric.Labels, false); - metric.TimeSeries.SortByTs(); - if (metric.TimeSeries.Size() == 1) { - const auto& point = metric.TimeSeries[0]; - WriteTime(point.GetTime()); - WriteValue(metric.TimeSeries.GetValueType(), point.GetValue()); - } else if (metric.TimeSeries.Size() > 1) { + metric.TimeSeries.SortByTs(); + if (metric.TimeSeries.Size() == 1) { + const auto& point = metric.TimeSeries[0]; + WriteTime(point.GetTime()); + WriteValue(metric.TimeSeries.GetValueType(), point.GetValue()); + } else if (metric.TimeSeries.Size() > 1) { Buf_.WriteKey(TStringBuf("timeseries")); Buf_.BeginList(); - metric.TimeSeries.ForEach([this](TInstant time, EMetricValueType type, TMetricValue value) { + metric.TimeSeries.ForEach([this](TInstant time, EMetricValueType type, TMetricValue value) { Buf_.BeginObject(); // make gcc 6.1 happy https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61636 - this->WriteTime(time); - this->WriteValue(type, value); + this->WriteTime(time); + this->WriteValue(type, value); Buf_.EndObject(); }); @@ -535,14 +535,14 @@ namespace NMonitoring { private: bool Closed_{false}; bool EmptyLabels_ = false; - }; - } - - IMetricEncoderPtr EncoderJson(IOutputStream* out, int indentation) { + }; + } + + IMetricEncoderPtr EncoderJson(IOutputStream* out, int indentation) { return MakeHolder<TEncoderJson>(out, indentation, EJsonStyle::Solomon, ""); - } - - IMetricEncoderPtr BufferedEncoderJson(IOutputStream* out, int indentation) { + } + + IMetricEncoderPtr BufferedEncoderJson(IOutputStream* out, int indentation) { return MakeHolder<TBufferedJsonEncoder>(out, indentation, EJsonStyle::Solomon, ""); } @@ -553,4 +553,4 @@ namespace NMonitoring { IMetricEncoderPtr BufferedEncoderCloudJson(IOutputStream* out, int indentation, TStringBuf metricNameLabel) { return MakeHolder<TBufferedJsonEncoder>(out, indentation, EJsonStyle::Cloud, metricNameLabel); } -} +} diff --git a/library/cpp/monlib/encode/json/json_ut.cpp b/library/cpp/monlib/encode/json/json_ut.cpp index f80105795b..09e7909289 100644 --- a/library/cpp/monlib/encode/json/json_ut.cpp +++ b/library/cpp/monlib/encode/json/json_ut.cpp @@ -1,19 +1,19 @@ -#include "json.h" - -#include <library/cpp/monlib/encode/protobuf/protobuf.h> -#include <library/cpp/monlib/metrics/labels.h> - +#include "json.h" + +#include <library/cpp/monlib/encode/protobuf/protobuf.h> +#include <library/cpp/monlib/metrics/labels.h> + #include <library/cpp/json/json_reader.h> #include <library/cpp/resource/resource.h> #include <library/cpp/testing/unittest/registar.h> - -#include <util/stream/str.h> + +#include <util/stream/str.h> #include <util/string/builder.h> - -#include <limits> - -using namespace NMonitoring; - + +#include <limits> + +using namespace NMonitoring; + namespace NMonitoring { bool operator<(const TLabel& lhs, const TLabel& rhs) { return lhs.Name() < rhs.Name() || @@ -134,7 +134,7 @@ namespace { Y_UNIT_TEST_SUITE(TJsonTest) { const TInstant now = TInstant::ParseIso8601Deprecated("2017-11-05T01:02:03Z"); - + Y_UNIT_TEST(Encode) { auto check = [](bool cloud, bool buffered, TStringBuf expectedResourceKey) { TString json; @@ -145,12 +145,12 @@ Y_UNIT_TEST_SUITE(TJsonTest) { e->OnStreamBegin(); { // common time e->OnCommonTime(TInstant::Seconds(1500000000)); - } + } { // common labels - e->OnLabelsBegin(); + e->OnLabelsBegin(); e->OnLabel("project", "solomon"); - e->OnLabelsEnd(); - } + e->OnLabelsEnd(); + } { // metric #1 e->OnMetricBegin(EMetricType::COUNTER); { @@ -161,7 +161,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } e->OnUint64(now, 17); e->OnMetricEnd(); - } + } { // metric #2 e->OnMetricBegin(EMetricType::RATE); { @@ -172,7 +172,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } e->OnUint64(now, 17); e->OnMetricEnd(); - } + } { // metric #3 e->OnMetricBegin(EMetricType::GAUGE); e->OnDouble(now, 3.14); @@ -251,7 +251,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { auto emit = [&](IMetricEncoder* encoder, EMetricType metricType) { encoder->OnStreamBegin(); - { + { encoder->OnMetricBegin(metricType); { encoder->OnLabelsBegin(); @@ -280,11 +280,11 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } encoder->OnMetricEnd(); - } + } encoder->OnStreamEnd(); encoder->Close(); }; - + auto doTest = [&](bool buffered, EMetricType metricType) { TString json; TStringOutput out(json); @@ -301,107 +301,107 @@ Y_UNIT_TEST_SUITE(TJsonTest) { doTest(true, EMetricType::HIST); doTest(true, EMetricType::LOGHIST); doTest(true, EMetricType::DSUMMARY); - } - - Y_UNIT_TEST(MetricsWithDifferentLabelOrderGetMerged) { + } + + Y_UNIT_TEST(MetricsWithDifferentLabelOrderGetMerged) { TString json; TStringOutput out(json); auto e = BufferedEncoderJson(&out, 2); - + e->OnStreamBegin(); { - e->OnMetricBegin(EMetricType::RATE); + e->OnMetricBegin(EMetricType::RATE); { e->OnLabelsBegin(); - e->OnLabel("metric", "hello"); + e->OnLabel("metric", "hello"); e->OnLabel("label", "world"); e->OnLabelsEnd(); } e->OnUint64(TInstant::Zero(), 0); - e->OnMetricEnd(); - } + e->OnMetricEnd(); + } { - e->OnMetricBegin(EMetricType::RATE); + e->OnMetricBegin(EMetricType::RATE); { e->OnLabelsBegin(); e->OnLabel("label", "world"); - e->OnLabel("metric", "hello"); + e->OnLabel("metric", "hello"); e->OnLabelsEnd(); } e->OnUint64(TInstant::Zero(), 1); - e->OnMetricEnd(); + e->OnMetricEnd(); } e->OnStreamEnd(); e->Close(); json += "\n"; - + TString expectedJson = NResource::Find("/merged.json"); // we cannot be sure regarding the label order in the result, // so we'll have to parse the expected value and then compare it with actual - + NProto::TMultiSamplesList samples; - IMetricEncoderPtr d = EncoderProtobuf(&samples); + IMetricEncoderPtr d = EncoderProtobuf(&samples); DecodeJson(expectedJson, d.Get()); - + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); { const NProto::TMultiSample& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); - AssertLabels(s, TLabels{{"metric", "hello"}, {"label", "world"}}); - + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); + AssertLabels(s, TLabels{{"metric", "hello"}, {"label", "world"}}); + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); AssertPointEqual(s.GetPoints(0), TInstant::Zero(), ui64(1)); - } - } + } + } Y_UNIT_TEST(Decode1) { - NProto::TMultiSamplesList samples; - { - IMetricEncoderPtr e = EncoderProtobuf(&samples); - - TString testJson = NResource::Find("/expected.json"); - DecodeJson(testJson, e.Get()); - } - - UNIT_ASSERT_VALUES_EQUAL( - TInstant::MilliSeconds(samples.GetCommonTime()), - TInstant::Seconds(1500000000)); - - UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 1); - AssertLabelEqual(samples.GetCommonLabels(0), "project", "solomon"); - + NProto::TMultiSamplesList samples; + { + IMetricEncoderPtr e = EncoderProtobuf(&samples); + + TString testJson = NResource::Find("/expected.json"); + DecodeJson(testJson, e.Get()); + } + + UNIT_ASSERT_VALUES_EQUAL( + TInstant::MilliSeconds(samples.GetCommonTime()), + TInstant::Seconds(1500000000)); + + UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 1); + AssertLabelEqual(samples.GetCommonLabels(0), "project", "solomon"); + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 6); - { - const NProto::TMultiSample& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); - AssertLabelEqual(s.GetLabels(0), "metric", "single"); + { + const NProto::TMultiSample& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); + AssertLabelEqual(s.GetLabels(0), "metric", "single"); AssertLabelEqual(s.GetLabels(1), "labels", "l1"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), now, ui64(17)); - } - { - const NProto::TMultiSample& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); - AssertLabelEqual(s.GetLabels(0), "metric", "single"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), now, ui64(17)); + } + { + const NProto::TMultiSample& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); + AssertLabelEqual(s.GetLabels(0), "metric", "single"); AssertLabelEqual(s.GetLabels(1), "labels", "l2"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), now, ui64(17)); - } - { - const NProto::TMultiSample& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); - AssertLabelEqual(s.GetLabels(0), "metric", "single"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), now, ui64(17)); + } + { + const NProto::TMultiSample& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); + AssertLabelEqual(s.GetLabels(0), "metric", "single"); AssertLabelEqual(s.GetLabels(1), "labels", "l3"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), now, 3.14); - } - { - const NProto::TMultiSample& s = samples.GetSamples(3); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), now, 3.14); + } + { + const NProto::TMultiSample& s = samples.GetSamples(3); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::IGAUGE); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); AssertLabelEqual(s.GetLabels(0), "metric", "single_igauge"); @@ -412,152 +412,152 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } { const NProto::TMultiSample& s = samples.GetSamples(4); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); - AssertLabelEqual(s.GetLabels(0), "metric", "multiple"); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); + AssertLabelEqual(s.GetLabels(0), "metric", "multiple"); AssertLabelEqual(s.GetLabels(1), "labels", "l5"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 3); - AssertPointEqualNan(s.GetPoints(0), now); - AssertPointEqualInf(s.GetPoints(1), now + TDuration::Seconds(15), 1); - AssertPointEqualInf(s.GetPoints(2), now + TDuration::Seconds(30), -11); - } - { + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 3); + AssertPointEqualNan(s.GetPoints(0), now); + AssertPointEqualInf(s.GetPoints(1), now + TDuration::Seconds(15), 1); + AssertPointEqualInf(s.GetPoints(2), now + TDuration::Seconds(30), -11); + } + { const NProto::TMultiSample& s = samples.GetSamples(5); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); - AssertLabelEqual(s.GetLabels(0), "metric", "multiple"); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); + AssertLabelEqual(s.GetLabels(0), "metric", "multiple"); AssertLabelEqual(s.GetLabels(1), "labels", "l6"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); - AssertPointEqual(s.GetPoints(0), now, ui64(1337)); - AssertPointEqual(s.GetPoints(1), now + TDuration::Seconds(15), ui64(1338)); - } - } - - Y_UNIT_TEST(DecodeMetrics) { - NProto::TMultiSamplesList samples; - { - IMetricEncoderPtr e = EncoderProtobuf(&samples); - - TString metricsJson = NResource::Find("/metrics.json"); - DecodeJson(metricsJson, e.Get()); - } - - UNIT_ASSERT_VALUES_EQUAL( - TInstant::MilliSeconds(samples.GetCommonTime()), + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); + AssertPointEqual(s.GetPoints(0), now, ui64(1337)); + AssertPointEqual(s.GetPoints(1), now + TDuration::Seconds(15), ui64(1338)); + } + } + + Y_UNIT_TEST(DecodeMetrics) { + NProto::TMultiSamplesList samples; + { + IMetricEncoderPtr e = EncoderProtobuf(&samples); + + TString metricsJson = NResource::Find("/metrics.json"); + DecodeJson(metricsJson, e.Get()); + } + + UNIT_ASSERT_VALUES_EQUAL( + TInstant::MilliSeconds(samples.GetCommonTime()), TInstant::ParseIso8601Deprecated("2017-08-27T12:34:56Z")); - - UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 3); - AssertLabelEqual(samples.GetCommonLabels(0), "project", "solomon"); - AssertLabelEqual(samples.GetCommonLabels(1), "cluster", "man"); - AssertLabelEqual(samples.GetCommonLabels(2), "service", "stockpile"); - + + UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 3); + AssertLabelEqual(samples.GetCommonLabels(0), "project", "solomon"); + AssertLabelEqual(samples.GetCommonLabels(1), "cluster", "man"); + AssertLabelEqual(samples.GetCommonLabels(2), "service", "stockpile"); + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 4); - { - const NProto::TMultiSample& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "Memory"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), TInstant::Zero(), 10.0); - } - { - const NProto::TMultiSample& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "UserTime"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), TInstant::Zero(), ui64(1)); - } - { - const NProto::TMultiSample& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); - AssertLabelEqual(s.GetLabels(0), "export", "Oxygen"); - AssertLabelEqual(s.GetLabels(1), "metric", "QueueSize"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + { + const NProto::TMultiSample& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "metric", "Memory"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), TInstant::Zero(), 10.0); + } + { + const NProto::TMultiSample& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "metric", "UserTime"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), TInstant::Zero(), ui64(1)); + } + { + const NProto::TMultiSample& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); + AssertLabelEqual(s.GetLabels(0), "export", "Oxygen"); + AssertLabelEqual(s.GetLabels(1), "metric", "QueueSize"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); auto ts = TInstant::ParseIso8601Deprecated("2017-11-05T12:34:56.000Z"); - AssertPointEqual(s.GetPoints(0), ts, 3.14159); - } - { + AssertPointEqual(s.GetPoints(0), ts, 3.14159); + } + { const NProto::TMultiSample& s = samples.GetSamples(3); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "Writes"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "metric", "Writes"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); auto ts1 = TInstant::ParseIso8601Deprecated("2017-08-28T12:32:11Z"); - AssertPointEqual(s.GetPoints(0), ts1, -10.0); - auto ts2 = TInstant::Seconds(1503923187); - AssertPointEqual(s.GetPoints(1), ts2, 20.0); - } - } - - Y_UNIT_TEST(DecodeSensors) { - NProto::TMultiSamplesList samples; - { - IMetricEncoderPtr e = EncoderProtobuf(&samples); - - TString sensorsJson = NResource::Find("/sensors.json"); - DecodeJson(sensorsJson, e.Get()); - } - - UNIT_ASSERT_VALUES_EQUAL( - TInstant::MilliSeconds(samples.GetCommonTime()), - TInstant::ParseIso8601Deprecated("2017-08-27T12:34:56Z")); - - UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 3); - AssertLabelEqual(samples.GetCommonLabels(0), "project", "solomon"); - AssertLabelEqual(samples.GetCommonLabels(1), "cluster", "man"); - AssertLabelEqual(samples.GetCommonLabels(2), "service", "stockpile"); - - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 4); - { - const NProto::TMultiSample& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "Memory"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), TInstant::Zero(), 10.0); - } - { - const NProto::TMultiSample& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "UserTime"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), TInstant::Zero(), ui64(1)); - } - { - const NProto::TMultiSample& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); - AssertLabelEqual(s.GetLabels(0), "export", "Oxygen"); - AssertLabelEqual(s.GetLabels(1), "metric", "QueueSize"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - auto ts = TInstant::ParseIso8601Deprecated("2017-11-05T12:34:56.000Z"); - AssertPointEqual(s.GetPoints(0), ts, 3.14159); - } - { - const NProto::TMultiSample& s = samples.GetSamples(3); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "Writes"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); - auto ts1 = TInstant::ParseIso8601Deprecated("2017-08-28T12:32:11Z"); - AssertPointEqual(s.GetPoints(0), ts1, -10.0); - auto ts2 = TInstant::Seconds(1503923187); - AssertPointEqual(s.GetPoints(1), ts2, 20.0); - } - } + AssertPointEqual(s.GetPoints(0), ts1, -10.0); + auto ts2 = TInstant::Seconds(1503923187); + AssertPointEqual(s.GetPoints(1), ts2, 20.0); + } + } + + Y_UNIT_TEST(DecodeSensors) { + NProto::TMultiSamplesList samples; + { + IMetricEncoderPtr e = EncoderProtobuf(&samples); + + TString sensorsJson = NResource::Find("/sensors.json"); + DecodeJson(sensorsJson, e.Get()); + } + + UNIT_ASSERT_VALUES_EQUAL( + TInstant::MilliSeconds(samples.GetCommonTime()), + TInstant::ParseIso8601Deprecated("2017-08-27T12:34:56Z")); + + UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 3); + AssertLabelEqual(samples.GetCommonLabels(0), "project", "solomon"); + AssertLabelEqual(samples.GetCommonLabels(1), "cluster", "man"); + AssertLabelEqual(samples.GetCommonLabels(2), "service", "stockpile"); + + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 4); + { + const NProto::TMultiSample& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "metric", "Memory"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), TInstant::Zero(), 10.0); + } + { + const NProto::TMultiSample& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "metric", "UserTime"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), TInstant::Zero(), ui64(1)); + } + { + const NProto::TMultiSample& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2); + AssertLabelEqual(s.GetLabels(0), "export", "Oxygen"); + AssertLabelEqual(s.GetLabels(1), "metric", "QueueSize"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + auto ts = TInstant::ParseIso8601Deprecated("2017-11-05T12:34:56.000Z"); + AssertPointEqual(s.GetPoints(0), ts, 3.14159); + } + { + const NProto::TMultiSample& s = samples.GetSamples(3); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "metric", "Writes"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); + auto ts1 = TInstant::ParseIso8601Deprecated("2017-08-28T12:32:11Z"); + AssertPointEqual(s.GetPoints(0), ts1, -10.0); + auto ts2 = TInstant::Seconds(1503923187); + AssertPointEqual(s.GetPoints(1), ts2, 20.0); + } + } Y_UNIT_TEST(DecodeToEncoder) { auto testJson = NResource::Find("/test_decode_to_encode.json"); @@ -574,16 +574,16 @@ Y_UNIT_TEST_SUITE(TJsonTest) { UNIT_ASSERT_VALUES_EQUAL(val1, val2); } - void WriteEmptySeries(const IMetricEncoderPtr& e) { + void WriteEmptySeries(const IMetricEncoderPtr& e) { e->OnStreamBegin(); { - e->OnMetricBegin(EMetricType::COUNTER); + e->OnMetricBegin(EMetricType::COUNTER); { e->OnLabelsBegin(); e->OnLabel("foo", "bar"); e->OnLabelsEnd(); } - e->OnMetricEnd(); + e->OnMetricEnd(); } e->OnStreamEnd(); @@ -602,9 +602,9 @@ Y_UNIT_TEST_SUITE(TJsonTest) { UNIT_ASSERT_NO_DIFF(json, expectedJson); } - void WriteEmptyLabels(IMetricEncoderPtr& e) { + void WriteEmptyLabels(IMetricEncoderPtr& e) { e->OnStreamBegin(); - e->OnMetricBegin(EMetricType::COUNTER); + e->OnMetricBegin(EMetricType::COUNTER); e->OnLabelsBegin(); UNIT_ASSERT_EXCEPTION(e->OnLabelsEnd(), yexception); @@ -638,29 +638,29 @@ Y_UNIT_TEST_SUITE(TJsonTest) { UNIT_ASSERT_NO_DIFF(json, expectedJson); } - Y_UNIT_TEST(BufferedEncoderMergesMetrics) { + Y_UNIT_TEST(BufferedEncoderMergesMetrics) { TString json; TStringOutput out(json); auto e = BufferedEncoderJson(&out, 2); auto ts = 1; - auto writeMetric = [&] (const TString& val) { - e->OnMetricBegin(EMetricType::COUNTER); + auto writeMetric = [&] (const TString& val) { + e->OnMetricBegin(EMetricType::COUNTER); e->OnLabelsBegin(); e->OnLabel("foo", val); e->OnLabelsEnd(); e->OnUint64(TInstant::Seconds(ts++), 42); - e->OnMetricEnd(); + e->OnMetricEnd(); }; e->OnStreamBegin(); - writeMetric("bar"); - writeMetric("bar"); - writeMetric("baz"); - writeMetric("bar"); + writeMetric("bar"); + writeMetric("bar"); + writeMetric("baz"); + writeMetric("bar"); e->OnStreamEnd(); e->Close(); @@ -676,13 +676,13 @@ Y_UNIT_TEST_SUITE(TJsonTest) { auto e = EncoderJson(&out); auto writePreamble = [&] { e->OnStreamBegin(); - e->OnMetricBegin(EMetricType::COUNTER); + e->OnMetricBegin(EMetricType::COUNTER); e->OnLabelsBegin(); e->OnLabel("foo", "bar"); e->OnLabelsEnd(); }; - // writing two values for a metric in a row will trigger + // writing two values for a metric in a row will trigger // timeseries object construction writePreamble(); e->OnUint64(TInstant::Zero(), 42); @@ -705,7 +705,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { { auto e = BufferedEncoderJson(&out, 2); e->OnStreamBegin(); - e->OnMetricBegin(EMetricType::COUNTER); + e->OnMetricBegin(EMetricType::COUNTER); e->OnLabelsBegin(); e->OnLabel("foo", "bar"); e->OnLabelsEnd(); @@ -715,38 +715,38 @@ Y_UNIT_TEST_SUITE(TJsonTest) { e->OnUint64(TInstant::Zero(), 43); e->OnUint64(TInstant::Zero(), 44); e->OnUint64(TInstant::Zero(), 45); - e->OnMetricEnd(); + e->OnMetricEnd(); e->OnStreamEnd(); } out << "\n"; UNIT_ASSERT_NO_DIFF(out.Str(), NResource::Find("/buffered_ts_merge.json")); - } - - template <typename TFactory, typename TConsumer> - TString EncodeToString(TFactory factory, TConsumer consumer) { - TStringStream out; - { - IMetricEncoderPtr e = factory(&out, 2); - consumer(e.Get()); - } - out << '\n'; - return out.Str(); } - + + template <typename TFactory, typename TConsumer> + TString EncodeToString(TFactory factory, TConsumer consumer) { + TStringStream out; + { + IMetricEncoderPtr e = factory(&out, 2); + consumer(e.Get()); + } + out << '\n'; + return out.Str(); + } + Y_UNIT_TEST(SummaryValueEncode) { - auto writeDocument = [](IMetricEncoder* e) { + auto writeDocument = [](IMetricEncoder* e) { e->OnStreamBegin(); { - e->OnMetricBegin(EMetricType::DSUMMARY); + e->OnMetricBegin(EMetricType::DSUMMARY); { e->OnLabelsBegin(); - e->OnLabel("metric", "temperature"); + e->OnLabel("metric", "temperature"); e->OnLabelsEnd(); } e->OnSummaryDouble(now, MakeIntrusive<TSummaryDoubleSnapshot>(10., -0.5, 0.5, 0.3, 30u)); - e->OnMetricEnd(); + e->OnMetricEnd(); } e->OnStreamEnd(); }; @@ -768,18 +768,18 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } Y_UNIT_TEST(SummaryInfEncode) { - auto writeDocument = [](IMetricEncoder* e) { + auto writeDocument = [](IMetricEncoder* e) { e->OnStreamBegin(); { - e->OnMetricBegin(EMetricType::DSUMMARY); + e->OnMetricBegin(EMetricType::DSUMMARY); { e->OnLabelsBegin(); - e->OnLabel("metric", "temperature"); + e->OnLabel("metric", "temperature"); e->OnLabelsEnd(); } e->OnSummaryDouble(now, TestInfSummary()); - e->OnMetricEnd(); + e->OnMetricEnd(); } e->OnStreamEnd(); }; @@ -794,7 +794,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { Y_UNIT_TEST(SummaryInfDecode) { NProto::TMultiSamplesList samples; { - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); TString testJson = NResource::Find("/summary_inf.json"); DecodeJson(testJson, e.Get()); @@ -803,9 +803,9 @@ Y_UNIT_TEST_SUITE(TJsonTest) { UNIT_ASSERT_VALUES_EQUAL(1, samples.SamplesSize()); const NProto::TMultiSample& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "temperature"); + AssertLabelEqual(s.GetLabels(0), "metric", "temperature"); UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); @@ -820,7 +820,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { Y_UNIT_TEST(SummaryValueDecode) { NProto::TMultiSamplesList samples; { - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); TString testJson = NResource::Find("/summary_value.json"); DecodeJson(testJson, e.Get()); @@ -829,9 +829,9 @@ Y_UNIT_TEST_SUITE(TJsonTest) { UNIT_ASSERT_VALUES_EQUAL(1, samples.SamplesSize()); const NProto::TMultiSample& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "temperature"); + AssertLabelEqual(s.GetLabels(0), "metric", "temperature"); UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); @@ -840,13 +840,13 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } Y_UNIT_TEST(SummaryTimeSeriesEncode) { - auto writeDocument = [](IMetricEncoder* e) { + auto writeDocument = [](IMetricEncoder* e) { e->OnStreamBegin(); { - e->OnMetricBegin(EMetricType::DSUMMARY); + e->OnMetricBegin(EMetricType::DSUMMARY); { e->OnLabelsBegin(); - e->OnLabel("metric", "temperature"); + e->OnLabel("metric", "temperature"); e->OnLabelsEnd(); } @@ -862,7 +862,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { e->OnSummaryDouble(now + TDuration::Seconds(15), summary.Snapshot()); - e->OnMetricEnd(); + e->OnMetricEnd(); } e->OnStreamEnd(); }; @@ -877,7 +877,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { Y_UNIT_TEST(SummaryTimeSeriesDecode) { NProto::TMultiSamplesList samples; { - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); TString testJson = NResource::Find("/summary_timeseries.json"); DecodeJson(testJson, e.Get()); @@ -886,9 +886,9 @@ Y_UNIT_TEST_SUITE(TJsonTest) { UNIT_ASSERT_VALUES_EQUAL(1, samples.SamplesSize()); const NProto::TMultiSample& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "temperature"); + AssertLabelEqual(s.GetLabels(0), "metric", "temperature"); UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); @@ -912,7 +912,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { e->OnMetricBegin(EMetricType::LOGHIST); { e->OnLabelsBegin(); - e->OnLabel("metric", "ms"); + e->OnLabel("metric", "ms"); e->OnLabelsEnd(); } @@ -943,7 +943,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::LOGHISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "ms"); + AssertLabelEqual(s.GetLabels(0), "metric", "ms"); UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); @@ -951,36 +951,36 @@ Y_UNIT_TEST_SUITE(TJsonTest) { AssertPointEqual(s.GetPoints(0), now, *snapshot); } - Y_UNIT_TEST(HistogramValueEncode) { - auto writeDocument = [](IMetricEncoder* e) { - e->OnStreamBegin(); - { - e->OnMetricBegin(EMetricType::HIST); - { - e->OnLabelsBegin(); - e->OnLabel("metric", "responseTimeMillis"); - e->OnLabelsEnd(); - } - - // {1: 1, 2: 1, 4: 2, 8: 4, 16: 8, inf: 83} - auto h = ExponentialHistogram(6, 2); - for (i64 i = 1; i < 100; i++) { - h->Collect(i); - } - - e->OnHistogram(now, h->Snapshot()); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }; - - TString result1 = EncodeToString(EncoderJson, writeDocument); - UNIT_ASSERT_NO_DIFF(result1, NResource::Find("/histogram_value.json")); - - TString result2 = EncodeToString(BufferedEncoderJson, writeDocument); - UNIT_ASSERT_NO_DIFF(result2, NResource::Find("/histogram_value.json")); - } - + Y_UNIT_TEST(HistogramValueEncode) { + auto writeDocument = [](IMetricEncoder* e) { + e->OnStreamBegin(); + { + e->OnMetricBegin(EMetricType::HIST); + { + e->OnLabelsBegin(); + e->OnLabel("metric", "responseTimeMillis"); + e->OnLabelsEnd(); + } + + // {1: 1, 2: 1, 4: 2, 8: 4, 16: 8, inf: 83} + auto h = ExponentialHistogram(6, 2); + for (i64 i = 1; i < 100; i++) { + h->Collect(i); + } + + e->OnHistogram(now, h->Snapshot()); + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }; + + TString result1 = EncodeToString(EncoderJson, writeDocument); + UNIT_ASSERT_NO_DIFF(result1, NResource::Find("/histogram_value.json")); + + TString result2 = EncodeToString(BufferedEncoderJson, writeDocument); + UNIT_ASSERT_NO_DIFF(result2, NResource::Find("/histogram_value.json")); + } + Y_UNIT_TEST(LogHistogramTimeSeriesEncode) { auto writeDocument = [](IMetricEncoder* e) { e->OnStreamBegin(); @@ -988,7 +988,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { e->OnMetricBegin(EMetricType::LOGHIST); { e->OnLabelsBegin(); - e->OnLabel("metric", "ms"); + e->OnLabel("metric", "ms"); e->OnLabelsEnd(); } @@ -1022,7 +1022,7 @@ Y_UNIT_TEST_SUITE(TJsonTest) { UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::LOGHISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "ms"); + AssertLabelEqual(s.GetLabels(0), "metric", "ms"); UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); @@ -1034,130 +1034,130 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } void HistogramValueDecode(const TString& filePath) { - NProto::TMultiSamplesList samples; - { - IMetricEncoderPtr e = EncoderProtobuf(&samples); - + NProto::TMultiSamplesList samples; + { + IMetricEncoderPtr e = EncoderProtobuf(&samples); + TString testJson = NResource::Find(filePath); - DecodeJson(testJson, e.Get()); - } - - UNIT_ASSERT_VALUES_EQUAL(1, samples.SamplesSize()); - const NProto::TMultiSample& s = samples.GetSamples(0); - - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HISTOGRAM); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "responseTimeMillis"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - - auto h = ExponentialHistogram(6, 2); - for (i64 i = 1; i < 100; i++) { - h->Collect(i); - } - - AssertPointEqual(s.GetPoints(0), now, *h->Snapshot()); - } - + DecodeJson(testJson, e.Get()); + } + + UNIT_ASSERT_VALUES_EQUAL(1, samples.SamplesSize()); + const NProto::TMultiSample& s = samples.GetSamples(0); + + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HISTOGRAM); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "metric", "responseTimeMillis"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + + auto h = ExponentialHistogram(6, 2); + for (i64 i = 1; i < 100; i++) { + h->Collect(i); + } + + AssertPointEqual(s.GetPoints(0), now, *h->Snapshot()); + } + Y_UNIT_TEST(HistogramValueDecode) { HistogramValueDecode("/histogram_value.json"); HistogramValueDecode("/histogram_value_inf_before_bounds.json"); } - Y_UNIT_TEST(HistogramTimeSeriesEncode) { - auto writeDocument = [](IMetricEncoder* e) { - e->OnStreamBegin(); - { - e->OnMetricBegin(EMetricType::HIST_RATE); - { - e->OnLabelsBegin(); - e->OnLabel("metric", "responseTimeMillis"); - e->OnLabelsEnd(); - } - - // {1: 1, 2: 1, 4: 2, 8: 4, 16: 8, inf: 83} - auto h = ExponentialHistogram(6, 2); - for (i64 i = 1; i < 100; i++) { - h->Collect(i); - } - e->OnHistogram(now, h->Snapshot()); - - // {1: 2, 2: 2, 4: 4, 8: 8, 16: 16, inf: 166} - for (i64 i = 1; i < 100; i++) { - h->Collect(i); - } - e->OnHistogram(now + TDuration::Seconds(15), h->Snapshot()); - - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }; - - TString result1 = EncodeToString(EncoderJson, writeDocument); - UNIT_ASSERT_NO_DIFF(result1, NResource::Find("/histogram_timeseries.json")); - - TString result2 = EncodeToString(BufferedEncoderJson, writeDocument); - UNIT_ASSERT_NO_DIFF(result2, NResource::Find("/histogram_timeseries.json")); - } - - Y_UNIT_TEST(HistogramTimeSeriesDecode) { - NProto::TMultiSamplesList samples; - { - IMetricEncoderPtr e = EncoderProtobuf(&samples); - - TString testJson = NResource::Find("/histogram_timeseries.json"); - DecodeJson(testJson, e.Get()); - } - - UNIT_ASSERT_VALUES_EQUAL(1, samples.SamplesSize()); - const NProto::TMultiSample& s = samples.GetSamples(0); - - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HIST_RATE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "responseTimeMillis"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); - - auto h = ExponentialHistogram(6, 2); - for (i64 i = 1; i < 100; i++) { - h->Collect(i); - } - - AssertPointEqual(s.GetPoints(0), now, *h->Snapshot()); - - for (i64 i = 1; i < 100; i++) { - h->Collect(i); - } - - AssertPointEqual(s.GetPoints(1), now + TDuration::Seconds(15), *h->Snapshot()); - } - - Y_UNIT_TEST(IntGaugeEncode) { - auto writeDocument = [](IMetricEncoder* e) { - e->OnStreamBegin(); - { - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("metric", "a"); - e->OnLabelsEnd(); - } - e->OnInt64(now, Min<i64>()); - e->OnInt64(now + TDuration::Seconds(1), -1); - e->OnInt64(now + TDuration::Seconds(2), 0); - e->OnInt64(now + TDuration::Seconds(3), Max<i64>()); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }; - - TString result1 = EncodeToString(EncoderJson, writeDocument); - UNIT_ASSERT_NO_DIFF(result1, NResource::Find("/int_gauge.json")); - - TString result2 = EncodeToString(BufferedEncoderJson, writeDocument); - UNIT_ASSERT_NO_DIFF(result2, NResource::Find("/int_gauge.json")); - } - + Y_UNIT_TEST(HistogramTimeSeriesEncode) { + auto writeDocument = [](IMetricEncoder* e) { + e->OnStreamBegin(); + { + e->OnMetricBegin(EMetricType::HIST_RATE); + { + e->OnLabelsBegin(); + e->OnLabel("metric", "responseTimeMillis"); + e->OnLabelsEnd(); + } + + // {1: 1, 2: 1, 4: 2, 8: 4, 16: 8, inf: 83} + auto h = ExponentialHistogram(6, 2); + for (i64 i = 1; i < 100; i++) { + h->Collect(i); + } + e->OnHistogram(now, h->Snapshot()); + + // {1: 2, 2: 2, 4: 4, 8: 8, 16: 16, inf: 166} + for (i64 i = 1; i < 100; i++) { + h->Collect(i); + } + e->OnHistogram(now + TDuration::Seconds(15), h->Snapshot()); + + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }; + + TString result1 = EncodeToString(EncoderJson, writeDocument); + UNIT_ASSERT_NO_DIFF(result1, NResource::Find("/histogram_timeseries.json")); + + TString result2 = EncodeToString(BufferedEncoderJson, writeDocument); + UNIT_ASSERT_NO_DIFF(result2, NResource::Find("/histogram_timeseries.json")); + } + + Y_UNIT_TEST(HistogramTimeSeriesDecode) { + NProto::TMultiSamplesList samples; + { + IMetricEncoderPtr e = EncoderProtobuf(&samples); + + TString testJson = NResource::Find("/histogram_timeseries.json"); + DecodeJson(testJson, e.Get()); + } + + UNIT_ASSERT_VALUES_EQUAL(1, samples.SamplesSize()); + const NProto::TMultiSample& s = samples.GetSamples(0); + + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HIST_RATE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "metric", "responseTimeMillis"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); + + auto h = ExponentialHistogram(6, 2); + for (i64 i = 1; i < 100; i++) { + h->Collect(i); + } + + AssertPointEqual(s.GetPoints(0), now, *h->Snapshot()); + + for (i64 i = 1; i < 100; i++) { + h->Collect(i); + } + + AssertPointEqual(s.GetPoints(1), now + TDuration::Seconds(15), *h->Snapshot()); + } + + Y_UNIT_TEST(IntGaugeEncode) { + auto writeDocument = [](IMetricEncoder* e) { + e->OnStreamBegin(); + { + e->OnMetricBegin(EMetricType::IGAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("metric", "a"); + e->OnLabelsEnd(); + } + e->OnInt64(now, Min<i64>()); + e->OnInt64(now + TDuration::Seconds(1), -1); + e->OnInt64(now + TDuration::Seconds(2), 0); + e->OnInt64(now + TDuration::Seconds(3), Max<i64>()); + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }; + + TString result1 = EncodeToString(EncoderJson, writeDocument); + UNIT_ASSERT_NO_DIFF(result1, NResource::Find("/int_gauge.json")); + + TString result2 = EncodeToString(BufferedEncoderJson, writeDocument); + UNIT_ASSERT_NO_DIFF(result2, NResource::Find("/int_gauge.json")); + } + Y_UNIT_TEST(InconsistentMetricTypes) { auto emitMetrics = [](IMetricEncoder& encoder, const TString& expectedError) { encoder.OnMetricBegin(EMetricType::GAUGE); @@ -1213,33 +1213,33 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } } - Y_UNIT_TEST(IntGaugeDecode) { - NProto::TMultiSamplesList samples; - { - IMetricEncoderPtr e = EncoderProtobuf(&samples); - - TString testJson = NResource::Find("/int_gauge.json"); - DecodeJson(testJson, e.Get()); - } - - UNIT_ASSERT_VALUES_EQUAL(1, samples.SamplesSize()); - const NProto::TMultiSample& s = samples.GetSamples(0); - - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::IGAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "metric", "a"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 4); - AssertPointEqual(s.GetPoints(0), now, Min<i64>()); - AssertPointEqual(s.GetPoints(1), now + TDuration::Seconds(1), i64(-1)); - AssertPointEqual(s.GetPoints(2), now + TDuration::Seconds(2), i64(0)); - AssertPointEqual(s.GetPoints(3), now + TDuration::Seconds(3), Max<i64>()); - } + Y_UNIT_TEST(IntGaugeDecode) { + NProto::TMultiSamplesList samples; + { + IMetricEncoderPtr e = EncoderProtobuf(&samples); + + TString testJson = NResource::Find("/int_gauge.json"); + DecodeJson(testJson, e.Get()); + } + + UNIT_ASSERT_VALUES_EQUAL(1, samples.SamplesSize()); + const NProto::TMultiSample& s = samples.GetSamples(0); + + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::IGAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "metric", "a"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 4); + AssertPointEqual(s.GetPoints(0), now, Min<i64>()); + AssertPointEqual(s.GetPoints(1), now + TDuration::Seconds(1), i64(-1)); + AssertPointEqual(s.GetPoints(2), now + TDuration::Seconds(2), i64(0)); + AssertPointEqual(s.GetPoints(3), now + TDuration::Seconds(3), Max<i64>()); + } Y_UNIT_TEST(FuzzerRegression) { NProto::TMultiSamplesList samples; { - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); for (auto f : { "/hist_crash.json", "/crash.json" }) { TString testJson = NResource::Find(f); @@ -1254,13 +1254,13 @@ Y_UNIT_TEST_SUITE(TJsonTest) { { "mode": "deriv", "value": -1, - "labels": { "metric": "SystemTime" } + "labels": { "metric": "SystemTime" } }, } ]}")"; NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); UNIT_ASSERT_EXCEPTION(DecodeJson(input, e.Get()), yexception); } @@ -1287,4 +1287,4 @@ Y_UNIT_TEST_SUITE(TJsonTest) { } } -} +} diff --git a/library/cpp/monlib/encode/json/typed_point.h b/library/cpp/monlib/encode/json/typed_point.h index b606c82924..fbaa840c4b 100644 --- a/library/cpp/monlib/encode/json/typed_point.h +++ b/library/cpp/monlib/encode/json/typed_point.h @@ -1,123 +1,123 @@ -#pragma once - -#include <library/cpp/monlib/metrics/metric_value.h> - - -namespace NMonitoring { - - class TTypedPoint { - public: - TTypedPoint() - : Time_(TInstant::Zero()) - , ValueType_(EMetricValueType::UNKNOWN) - { - } - - template <typename T> - TTypedPoint(TInstant time, T value) - : Time_(time) - , ValueType_(TValueType<T>::Type) - , Value_(value) - { - Ref(); - } - - ~TTypedPoint() { - UnRef(); - } - - TTypedPoint(const TTypedPoint& rhs) - : Time_(rhs.Time_) - , ValueType_(rhs.ValueType_) - , Value_(rhs.Value_) - { - Ref(); - } - - TTypedPoint& operator=(const TTypedPoint& rhs) { - UnRef(); - - Time_ = rhs.Time_; - ValueType_ = rhs.ValueType_; - Value_ = rhs.Value_; - - Ref(); - return *this; - } - +#pragma once + +#include <library/cpp/monlib/metrics/metric_value.h> + + +namespace NMonitoring { + + class TTypedPoint { + public: + TTypedPoint() + : Time_(TInstant::Zero()) + , ValueType_(EMetricValueType::UNKNOWN) + { + } + + template <typename T> + TTypedPoint(TInstant time, T value) + : Time_(time) + , ValueType_(TValueType<T>::Type) + , Value_(value) + { + Ref(); + } + + ~TTypedPoint() { + UnRef(); + } + + TTypedPoint(const TTypedPoint& rhs) + : Time_(rhs.Time_) + , ValueType_(rhs.ValueType_) + , Value_(rhs.Value_) + { + Ref(); + } + + TTypedPoint& operator=(const TTypedPoint& rhs) { + UnRef(); + + Time_ = rhs.Time_; + ValueType_ = rhs.ValueType_; + Value_ = rhs.Value_; + + Ref(); + return *this; + } + TTypedPoint(TTypedPoint&& rhs) noexcept - : Time_(rhs.Time_) - , ValueType_(rhs.ValueType_) - , Value_(rhs.Value_) - { - rhs.ValueType_ = EMetricValueType::UNKNOWN; - rhs.Value_ = {}; - } - + : Time_(rhs.Time_) + , ValueType_(rhs.ValueType_) + , Value_(rhs.Value_) + { + rhs.ValueType_ = EMetricValueType::UNKNOWN; + rhs.Value_ = {}; + } + TTypedPoint& operator=(TTypedPoint&& rhs) noexcept { - UnRef(); - - Time_ = rhs.Time_; - ValueType_ = rhs.ValueType_; - Value_ = rhs.Value_; - - rhs.ValueType_ = EMetricValueType::UNKNOWN; - rhs.Value_ = {}; - - return *this; - } - - TInstant GetTime() const noexcept { - return Time_; - } - - void SetTime(TInstant time) noexcept { - Time_ = time; - } - - TMetricValue GetValue() const noexcept { - return Value_; - } - - EMetricValueType GetValueType() const noexcept { - return ValueType_; - } - - template <typename T> - void SetValue(T value) noexcept { - ValueType_ = TValueType<T>::Type; - Value_ = TMetricValue{value}; - } - - bool HasValue() { - return ValueType_ != EMetricValueType::UNKNOWN; - } - - private: - void Ref() { - if (ValueType_ == EMetricValueType::HISTOGRAM) { - Value_.AsHistogram()->Ref(); - } else if (ValueType_ == EMetricValueType::SUMMARY) { + UnRef(); + + Time_ = rhs.Time_; + ValueType_ = rhs.ValueType_; + Value_ = rhs.Value_; + + rhs.ValueType_ = EMetricValueType::UNKNOWN; + rhs.Value_ = {}; + + return *this; + } + + TInstant GetTime() const noexcept { + return Time_; + } + + void SetTime(TInstant time) noexcept { + Time_ = time; + } + + TMetricValue GetValue() const noexcept { + return Value_; + } + + EMetricValueType GetValueType() const noexcept { + return ValueType_; + } + + template <typename T> + void SetValue(T value) noexcept { + ValueType_ = TValueType<T>::Type; + Value_ = TMetricValue{value}; + } + + bool HasValue() { + return ValueType_ != EMetricValueType::UNKNOWN; + } + + private: + void Ref() { + if (ValueType_ == EMetricValueType::HISTOGRAM) { + Value_.AsHistogram()->Ref(); + } else if (ValueType_ == EMetricValueType::SUMMARY) { Value_.AsSummaryDouble()->Ref(); } else if (ValueType_ == EMetricValueType::LOGHISTOGRAM) { Value_.AsLogHistogram()->Ref(); } - } - - void UnRef() { - if (ValueType_ == EMetricValueType::HISTOGRAM) { - Value_.AsHistogram()->UnRef(); - } else if (ValueType_ == EMetricValueType::SUMMARY) { + } + + void UnRef() { + if (ValueType_ == EMetricValueType::HISTOGRAM) { + Value_.AsHistogram()->UnRef(); + } else if (ValueType_ == EMetricValueType::SUMMARY) { Value_.AsSummaryDouble()->UnRef(); } else if (ValueType_ == EMetricValueType::LOGHISTOGRAM) { Value_.AsLogHistogram()->UnRef(); } - } - - private: - TInstant Time_; - EMetricValueType ValueType_; - TMetricValue Value_; - }; - -} + } + + private: + TInstant Time_; + EMetricValueType ValueType_; + TMetricValue Value_; + }; + +} diff --git a/library/cpp/monlib/encode/json/ut/expected.json b/library/cpp/monlib/encode/json/ut/expected.json index 8541479be6..ead853455b 100644 --- a/library/cpp/monlib/encode/json/ut/expected.json +++ b/library/cpp/monlib/encode/json/ut/expected.json @@ -1,42 +1,42 @@ -{ - "ts":1500000000, - "commonLabels": - { - "project":"solomon" - }, - "sensors": - [ - { - "kind":"COUNTER", - "labels": - { - "metric":"single", +{ + "ts":1500000000, + "commonLabels": + { + "project":"solomon" + }, + "sensors": + [ + { + "kind":"COUNTER", + "labels": + { + "metric":"single", "labels":"l1" - }, - "ts":1509843723, - "value":17 - }, - { - "kind":"RATE", - "labels": - { - "metric":"single", + }, + "ts":1509843723, + "value":17 + }, + { + "kind":"RATE", + "labels": + { + "metric":"single", "labels":"l2" - }, - "ts":1509843723, - "value":17 - }, - { - "kind":"GAUGE", - "labels": - { - "metric":"single", + }, + "ts":1509843723, + "value":17 + }, + { + "kind":"GAUGE", + "labels": + { + "metric":"single", "labels":"l3" - }, - "ts":1509843723, - "value":3.14 - }, - { + }, + "ts":1509843723, + "value":3.14 + }, + { "kind":"IGAUGE", "labels": { @@ -47,46 +47,46 @@ "value":42 }, { - "kind":"GAUGE", - "labels": - { - "metric":"multiple", + "kind":"GAUGE", + "labels": + { + "metric":"multiple", "labels":"l5" - }, - "timeseries": - [ - { - "ts":1509843723, - "value":"nan" - }, - { - "ts":1509843738, - "value":"inf" - }, - { - "ts":1509843753, - "value":"-inf" - } - ] - }, - { - "kind":"COUNTER", - "timeseries": - [ - { - "ts":1509843723, - "value":1337 - }, - { - "ts":1509843738, - "value":1338 - } - ], - "labels": - { - "metric":"multiple", + }, + "timeseries": + [ + { + "ts":1509843723, + "value":"nan" + }, + { + "ts":1509843738, + "value":"inf" + }, + { + "ts":1509843753, + "value":"-inf" + } + ] + }, + { + "kind":"COUNTER", + "timeseries": + [ + { + "ts":1509843723, + "value":1337 + }, + { + "ts":1509843738, + "value":1338 + } + ], + "labels": + { + "metric":"multiple", "labels":"l6" - } - } - ] -} + } + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/expected_buffered.json b/library/cpp/monlib/encode/json/ut/expected_buffered.json index 17c0f06323..9a6a1d6201 100644 --- a/library/cpp/monlib/encode/json/ut/expected_buffered.json +++ b/library/cpp/monlib/encode/json/ut/expected_buffered.json @@ -1,42 +1,42 @@ -{ - "ts":1500000000, - "commonLabels": - { - "project":"solomon" - }, - "sensors": - [ - { - "kind":"COUNTER", - "labels": - { +{ + "ts":1500000000, + "commonLabels": + { + "project":"solomon" + }, + "sensors": + [ + { + "kind":"COUNTER", + "labels": + { "labels":"l1", "metric":"single" - }, - "ts":1509843723, - "value":17 - }, - { - "kind":"RATE", - "labels": - { + }, + "ts":1509843723, + "value":17 + }, + { + "kind":"RATE", + "labels": + { "labels":"l2", "metric":"single" - }, - "ts":1509843723, - "value":17 - }, - { - "kind":"GAUGE", - "labels": - { + }, + "ts":1509843723, + "value":17 + }, + { + "kind":"GAUGE", + "labels": + { "labels":"l3", "metric":"single" - }, - "ts":1509843723, - "value":3.14 - }, - { + }, + "ts":1509843723, + "value":3.14 + }, + { "kind":"IGAUGE", "labels": { @@ -47,46 +47,46 @@ "value":42 }, { - "kind":"GAUGE", - "labels": - { + "kind":"GAUGE", + "labels": + { "labels":"l5", "metric":"multiple" - }, - "timeseries": - [ - { - "ts":1509843723, - "value":"nan" - }, - { - "ts":1509843738, - "value":"inf" - }, - { - "ts":1509843753, - "value":"-inf" - } - ] - }, - { - "kind":"COUNTER", + }, + "timeseries": + [ + { + "ts":1509843723, + "value":"nan" + }, + { + "ts":1509843738, + "value":"inf" + }, + { + "ts":1509843753, + "value":"-inf" + } + ] + }, + { + "kind":"COUNTER", "labels": { "labels":"l6", "metric":"multiple" }, - "timeseries": - [ - { - "ts":1509843723, - "value":1337 - }, - { - "ts":1509843738, - "value":1338 - } + "timeseries": + [ + { + "ts":1509843723, + "value":1337 + }, + { + "ts":1509843738, + "value":1338 + } ] - } - ] -} + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/expected_cloud.json b/library/cpp/monlib/encode/json/ut/expected_cloud.json index 5c4dc65ffc..6184811579 100644 --- a/library/cpp/monlib/encode/json/ut/expected_cloud.json +++ b/library/cpp/monlib/encode/json/ut/expected_cloud.json @@ -1,47 +1,47 @@ -{ +{ "ts":"2017-07-14T02:40:00.000000Z", "labels": - { - "project":"solomon" - }, + { + "project":"solomon" + }, "metrics": - [ - { + [ + { "type":"COUNTER", - "labels": - { + "labels": + { "labels":"l1" - }, + }, "name":"single", "ts":"2017-11-05T01:02:03.000000Z", - "value":17 - }, - { + "value":17 + }, + { "type":"RATE", - "labels": - { + "labels": + { "labels":"l2" - }, + }, "name":"single", "ts":"2017-11-05T01:02:03.000000Z", - "value":17 - }, - { + "value":17 + }, + { "type":"DGAUGE", - "labels": - { + "labels": + { "labels":"l3" - }, + }, "name":"single", "ts":"2017-11-05T01:02:03.000000Z", - "value":3.14 - }, - { + "value":3.14 + }, + { "type":"IGAUGE", - "labels": - { + "labels": + { "labels":"l4" - }, + }, "name":"single_igauge", "ts":"2017-11-05T01:02:03.000000Z", "value":42 @@ -53,40 +53,40 @@ "labels":"l5" }, "name":"multiple", - "timeseries": - [ - { + "timeseries": + [ + { "ts":"2017-11-05T01:02:03.000000Z", - "value":"nan" - }, - { + "value":"nan" + }, + { "ts":"2017-11-05T01:02:18.000000Z", - "value":"inf" - }, - { + "value":"inf" + }, + { "ts":"2017-11-05T01:02:33.000000Z", - "value":"-inf" - } - ] - }, - { + "value":"-inf" + } + ] + }, + { "type":"COUNTER", - "timeseries": - [ - { + "timeseries": + [ + { "ts":"2017-11-05T01:02:03.000000Z", - "value":1337 - }, - { + "value":1337 + }, + { "ts":"2017-11-05T01:02:18.000000Z", - "value":1338 - } - ], - "labels": - { + "value":1338 + } + ], + "labels": + { "labels":"l6" }, "name":"multiple" - } - ] -} + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/histogram_timeseries.json b/library/cpp/monlib/encode/json/ut/histogram_timeseries.json index c3a6f8e8b0..f6131ffded 100644 --- a/library/cpp/monlib/encode/json/ut/histogram_timeseries.json +++ b/library/cpp/monlib/encode/json/ut/histogram_timeseries.json @@ -1,61 +1,61 @@ -{ - "sensors": - [ - { - "kind":"HIST_RATE", - "labels": - { - "metric":"responseTimeMillis" - }, - "timeseries": - [ - { - "ts":1509843723, - "hist": - { - "bounds": - [ - 1, - 2, - 4, - 8, - 16 - ], - "buckets": - [ - 1, - 1, - 2, - 4, - 8 - ], - "inf":83 - } - }, - { - "ts":1509843738, - "hist": - { - "bounds": - [ - 1, - 2, - 4, - 8, - 16 - ], - "buckets": - [ - 2, - 2, - 4, - 8, - 16 - ], - "inf":166 - } - } - ] - } - ] -} +{ + "sensors": + [ + { + "kind":"HIST_RATE", + "labels": + { + "metric":"responseTimeMillis" + }, + "timeseries": + [ + { + "ts":1509843723, + "hist": + { + "bounds": + [ + 1, + 2, + 4, + 8, + 16 + ], + "buckets": + [ + 1, + 1, + 2, + 4, + 8 + ], + "inf":83 + } + }, + { + "ts":1509843738, + "hist": + { + "bounds": + [ + 1, + 2, + 4, + 8, + 16 + ], + "buckets": + [ + 2, + 2, + 4, + 8, + 16 + ], + "inf":166 + } + } + ] + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/histogram_value.json b/library/cpp/monlib/encode/json/ut/histogram_value.json index 91b4ffa3dd..ec1ae5cdec 100644 --- a/library/cpp/monlib/encode/json/ut/histogram_value.json +++ b/library/cpp/monlib/encode/json/ut/histogram_value.json @@ -1,33 +1,33 @@ -{ - "sensors": - [ - { - "kind":"HIST", - "labels": - { - "metric":"responseTimeMillis" - }, - "ts":1509843723, - "hist": - { - "bounds": - [ - 1, - 2, - 4, - 8, - 16 - ], - "buckets": - [ - 1, - 1, - 2, - 4, - 8 - ], - "inf":83 - } - } - ] -} +{ + "sensors": + [ + { + "kind":"HIST", + "labels": + { + "metric":"responseTimeMillis" + }, + "ts":1509843723, + "hist": + { + "bounds": + [ + 1, + 2, + 4, + 8, + 16 + ], + "buckets": + [ + 1, + 1, + 2, + 4, + 8 + ], + "inf":83 + } + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/histogram_value_inf_before_bounds.json b/library/cpp/monlib/encode/json/ut/histogram_value_inf_before_bounds.json index 87dc527985..f8a17c8831 100644 --- a/library/cpp/monlib/encode/json/ut/histogram_value_inf_before_bounds.json +++ b/library/cpp/monlib/encode/json/ut/histogram_value_inf_before_bounds.json @@ -5,7 +5,7 @@ "kind":"HIST", "labels": { - "metric":"responseTimeMillis" + "metric":"responseTimeMillis" }, "ts":1509843723, "hist": diff --git a/library/cpp/monlib/encode/json/ut/int_gauge.json b/library/cpp/monlib/encode/json/ut/int_gauge.json index 95aa12aa52..fbe57f873c 100644 --- a/library/cpp/monlib/encode/json/ut/int_gauge.json +++ b/library/cpp/monlib/encode/json/ut/int_gauge.json @@ -1,31 +1,31 @@ -{ - "sensors": - [ - { - "kind":"IGAUGE", - "labels": - { - "metric":"a" - }, - "timeseries": - [ - { - "ts":1509843723, - "value":-9223372036854775808 - }, - { - "ts":1509843724, - "value":-1 - }, - { - "ts":1509843725, - "value":0 - }, - { - "ts":1509843726, - "value":9223372036854775807 - } - ] - } - ] -} +{ + "sensors": + [ + { + "kind":"IGAUGE", + "labels": + { + "metric":"a" + }, + "timeseries": + [ + { + "ts":1509843723, + "value":-9223372036854775808 + }, + { + "ts":1509843724, + "value":-1 + }, + { + "ts":1509843725, + "value":0 + }, + { + "ts":1509843726, + "value":9223372036854775807 + } + ] + } + ] +} diff --git a/library/cpp/monlib/encode/json/ut/log_histogram_timeseries.json b/library/cpp/monlib/encode/json/ut/log_histogram_timeseries.json index 1e2a4a113c..e811a2cc57 100644 --- a/library/cpp/monlib/encode/json/ut/log_histogram_timeseries.json +++ b/library/cpp/monlib/encode/json/ut/log_histogram_timeseries.json @@ -5,7 +5,7 @@ "kind":"LOGHIST", "labels": { - "metric":"ms" + "metric":"ms" }, "timeseries": [ diff --git a/library/cpp/monlib/encode/json/ut/log_histogram_value.json b/library/cpp/monlib/encode/json/ut/log_histogram_value.json index 9835221116..002478293b 100644 --- a/library/cpp/monlib/encode/json/ut/log_histogram_value.json +++ b/library/cpp/monlib/encode/json/ut/log_histogram_value.json @@ -5,7 +5,7 @@ "kind":"LOGHIST", "labels": { - "metric":"ms" + "metric":"ms" }, "ts":1509843723, "log_hist": diff --git a/library/cpp/monlib/encode/json/ut/merged.json b/library/cpp/monlib/encode/json/ut/merged.json index 15711471f0..ea2c99a33c 100644 --- a/library/cpp/monlib/encode/json/ut/merged.json +++ b/library/cpp/monlib/encode/json/ut/merged.json @@ -5,7 +5,7 @@ "kind":"RATE", "labels": { - "metric":"hello", + "metric":"hello", "label":"world" }, "value":1 diff --git a/library/cpp/monlib/encode/json/ut/metrics.json b/library/cpp/monlib/encode/json/ut/metrics.json index 0dc423d5e9..2be4617d51 100644 --- a/library/cpp/monlib/encode/json/ut/metrics.json +++ b/library/cpp/monlib/encode/json/ut/metrics.json @@ -1,43 +1,43 @@ -{ - "labels": { - "project": "solomon", - "cluster": "man", - "service": "stockpile" - }, - "metrics": [ - { - "type": "DGAUGE", - "labels": { - "metric": "Memory" - }, - "value": 10 - }, - { - "type": "RATE", - "value": 1, - "labels": { "metric": "UserTime" } - }, - { - "type": "GAUGE", - "value": 3.14159, - "labels": { "export": "Oxygen", "metric": "QueueSize" }, - "ts": "2017-11-05T12:34:56.000Z", - "memOnly": true - }, - { - "type": "GAUGE", - "labels": { "metric": "Writes" }, - "timeseries": [ - { - "ts": "2017-08-28T12:32:11Z", - "value": -10 - }, - { - "value": 20, - "ts": 1503923187 - } - ] - } - ], - "ts": "2017-08-27T12:34:56Z" -} +{ + "labels": { + "project": "solomon", + "cluster": "man", + "service": "stockpile" + }, + "metrics": [ + { + "type": "DGAUGE", + "labels": { + "metric": "Memory" + }, + "value": 10 + }, + { + "type": "RATE", + "value": 1, + "labels": { "metric": "UserTime" } + }, + { + "type": "GAUGE", + "value": 3.14159, + "labels": { "export": "Oxygen", "metric": "QueueSize" }, + "ts": "2017-11-05T12:34:56.000Z", + "memOnly": true + }, + { + "type": "GAUGE", + "labels": { "metric": "Writes" }, + "timeseries": [ + { + "ts": "2017-08-28T12:32:11Z", + "value": -10 + }, + { + "value": 20, + "ts": 1503923187 + } + ] + } + ], + "ts": "2017-08-27T12:34:56Z" +} diff --git a/library/cpp/monlib/encode/json/ut/sensors.json b/library/cpp/monlib/encode/json/ut/sensors.json index e128593492..4d979a3c1e 100644 --- a/library/cpp/monlib/encode/json/ut/sensors.json +++ b/library/cpp/monlib/encode/json/ut/sensors.json @@ -1,40 +1,40 @@ -{ - "commonLabels": { - "project": "solomon", - "cluster": "man", - "service": "stockpile" - }, - "sensors": [ - { - "labels": { - "metric": "Memory" - }, - "value": 10 - }, - { - "mode": "deriv", - "value": 1, - "labels": { "metric": "UserTime" } - }, - { - "value": 3.14159, - "labels": { "export": "Oxygen", "metric": "QueueSize" }, - "ts": "2017-11-05T12:34:56.000Z", - "memOnly": true - }, - { - "labels": { "metric": "Writes" }, - "timeseries": [ - { - "ts": "2017-08-28T12:32:11Z", - "value": -10 - }, - { - "value": 20, - "ts": 1503923187 - } - ] - } - ], - "ts": "2017-08-27T12:34:56Z" -} +{ + "commonLabels": { + "project": "solomon", + "cluster": "man", + "service": "stockpile" + }, + "sensors": [ + { + "labels": { + "metric": "Memory" + }, + "value": 10 + }, + { + "mode": "deriv", + "value": 1, + "labels": { "metric": "UserTime" } + }, + { + "value": 3.14159, + "labels": { "export": "Oxygen", "metric": "QueueSize" }, + "ts": "2017-11-05T12:34:56.000Z", + "memOnly": true + }, + { + "labels": { "metric": "Writes" }, + "timeseries": [ + { + "ts": "2017-08-28T12:32:11Z", + "value": -10 + }, + { + "value": 20, + "ts": 1503923187 + } + ] + } + ], + "ts": "2017-08-27T12:34:56Z" +} diff --git a/library/cpp/monlib/encode/json/ut/summary_inf.json b/library/cpp/monlib/encode/json/ut/summary_inf.json index 067102b7da..625a6cd8ad 100644 --- a/library/cpp/monlib/encode/json/ut/summary_inf.json +++ b/library/cpp/monlib/encode/json/ut/summary_inf.json @@ -5,7 +5,7 @@ "kind":"DSUMMARY", "labels": { - "metric":"temperature" + "metric":"temperature" }, "ts":1509843723, "summary": diff --git a/library/cpp/monlib/encode/json/ut/summary_timeseries.json b/library/cpp/monlib/encode/json/ut/summary_timeseries.json index dd06ec8544..92007af3e6 100644 --- a/library/cpp/monlib/encode/json/ut/summary_timeseries.json +++ b/library/cpp/monlib/encode/json/ut/summary_timeseries.json @@ -5,7 +5,7 @@ "kind":"DSUMMARY", "labels": { - "metric":"temperature" + "metric":"temperature" }, "timeseries": [ diff --git a/library/cpp/monlib/encode/json/ut/summary_value.json b/library/cpp/monlib/encode/json/ut/summary_value.json index 2ad9e9ad39..366394c5e1 100644 --- a/library/cpp/monlib/encode/json/ut/summary_value.json +++ b/library/cpp/monlib/encode/json/ut/summary_value.json @@ -5,7 +5,7 @@ "kind":"DSUMMARY", "labels": { - "metric":"temperature" + "metric":"temperature" }, "ts":1509843723, "summary": diff --git a/library/cpp/monlib/encode/json/ut/test_decode_to_encode.json b/library/cpp/monlib/encode/json/ut/test_decode_to_encode.json index db1e00c6e9..65f0c5c6e2 100644 --- a/library/cpp/monlib/encode/json/ut/test_decode_to_encode.json +++ b/library/cpp/monlib/encode/json/ut/test_decode_to_encode.json @@ -7,7 +7,7 @@ "sensors": [ { "kind": "GAUGE", - "labels": { "export": "Oxygen", "metric": "QueueSize" }, + "labels": { "export": "Oxygen", "metric": "QueueSize" }, "ts": 1509885296, "value": 3.14159 } diff --git a/library/cpp/monlib/encode/json/ut/ya.make b/library/cpp/monlib/encode/json/ut/ya.make index 4a24f76650..e50c4f4903 100644 --- a/library/cpp/monlib/encode/json/ut/ya.make +++ b/library/cpp/monlib/encode/json/ut/ya.make @@ -1,30 +1,30 @@ -UNITTEST_FOR(library/cpp/monlib/encode/json) - +UNITTEST_FOR(library/cpp/monlib/encode/json) + OWNER( g:solomon jamel ) - -SRCS( + +SRCS( json_decoder_ut.cpp - json_ut.cpp -) - -RESOURCE( + json_ut.cpp +) + +RESOURCE( buffered_test.json /buffered_test.json buffered_ts_merge.json /buffered_ts_merge.json - empty_series.json /empty_series.json - expected.json /expected.json + empty_series.json /empty_series.json + expected.json /expected.json expected_buffered.json /expected_buffered.json expected_cloud.json /expected_cloud.json expected_cloud_buffered.json /expected_cloud_buffered.json merged.json /merged.json - histogram_timeseries.json /histogram_timeseries.json - histogram_value.json /histogram_value.json + histogram_timeseries.json /histogram_timeseries.json + histogram_value.json /histogram_value.json histogram_value_inf_before_bounds.json /histogram_value_inf_before_bounds.json - int_gauge.json /int_gauge.json - sensors.json /sensors.json - metrics.json /metrics.json + int_gauge.json /int_gauge.json + sensors.json /sensors.json + metrics.json /metrics.json named_metrics.json /named_metrics.json test_decode_to_encode.json /test_decode_to_encode.json crash.json /crash.json @@ -34,13 +34,13 @@ RESOURCE( summary_timeseries.json /summary_timeseries.json log_histogram_value.json /log_histogram_value.json log_histogram_timeseries.json /log_histogram_timeseries.json -) - -PEERDIR( +) + +PEERDIR( library/cpp/json library/cpp/monlib/consumers - library/cpp/monlib/encode/protobuf + library/cpp/monlib/encode/protobuf library/cpp/resource -) - -END() +) + +END() diff --git a/library/cpp/monlib/encode/json/ya.make b/library/cpp/monlib/encode/json/ya.make index 221fbc2a6a..a50fc412a9 100644 --- a/library/cpp/monlib/encode/json/ya.make +++ b/library/cpp/monlib/encode/json/ya.make @@ -1,21 +1,21 @@ -LIBRARY() - +LIBRARY() + OWNER( g:solomon jamel ) - -SRCS( - json_decoder.cpp - json_encoder.cpp -) - -PEERDIR( + +SRCS( + json_decoder.cpp + json_encoder.cpp +) + +PEERDIR( library/cpp/monlib/encode library/cpp/monlib/encode/buffered library/cpp/monlib/exception library/cpp/json library/cpp/json/writer -) - -END() +) + +END() diff --git a/library/cpp/monlib/encode/legacy_protobuf/legacy_proto_decoder.cpp b/library/cpp/monlib/encode/legacy_protobuf/legacy_proto_decoder.cpp index 4a305152e3..f87a2d7e8f 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/legacy_proto_decoder.cpp +++ b/library/cpp/monlib/encode/legacy_protobuf/legacy_proto_decoder.cpp @@ -1,8 +1,8 @@ #include "legacy_protobuf.h" -#include <library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.pb.h> -#include <library/cpp/monlib/metrics/metric_consumer.h> -#include <library/cpp/monlib/metrics/labels.h> +#include <library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.pb.h> +#include <library/cpp/monlib/metrics/metric_consumer.h> +#include <library/cpp/monlib/metrics/labels.h> #include <util/generic/yexception.h> #include <util/generic/maybe.h> @@ -22,7 +22,7 @@ namespace NMonitoring { namespace { - using TMaybeMeta = TMaybe<NMonProto::TMetricMeta>; + using TMaybeMeta = TMaybe<NMonProto::TMetricMeta>; TString ReadLabelValue(const NProtoBuf::Message& msg, const NProtoBuf::FieldDescriptor* d, const NProtoBuf::Reflection& r) { using namespace NProtoBuf; @@ -137,8 +137,8 @@ namespace NMonitoring { } TMaybeMeta MaybeGetMeta(const NProtoBuf::FieldOptions& opts) { - if (opts.HasExtension(NMonProto::Metric)) { - return opts.GetExtension(NMonProto::Metric); + if (opts.HasExtension(NMonProto::Metric)) { + return opts.GetExtension(NMonProto::Metric); } return Nothing(); @@ -218,37 +218,37 @@ namespace NMonitoring { Reflection_ = nullptr; } - TDecoderContext CreateChildFromMeta(const NMonProto::TMetricMeta& metricMeta, const TString& name, i64 repeatedIdx = -1) { + TDecoderContext CreateChildFromMeta(const NMonProto::TMetricMeta& metricMeta, const TString& name, i64 repeatedIdx = -1) { TDecoderContext child{*this}; child.Clear(); - if (metricMeta.HasCustomPath()) { - if (const auto& nodePath = metricMeta.GetCustomPath()) { + if (metricMeta.HasCustomPath()) { + if (const auto& nodePath = metricMeta.GetCustomPath()) { child.AppendPath(nodePath); } - } else if (metricMeta.GetPath()) { + } else if (metricMeta.GetPath()) { child.AppendPath(name); } - if (metricMeta.HasKeys()) { - child.ParseKeys(metricMeta.GetKeys(), repeatedIdx); + if (metricMeta.HasKeys()) { + child.ParseKeys(metricMeta.GetKeys(), repeatedIdx); } return child; } - TDecoderContext CreateChildFromRepeatedScalar(const NMonProto::TMetricMeta& metricMeta, i64 repeatedIdx = -1) { + TDecoderContext CreateChildFromRepeatedScalar(const NMonProto::TMetricMeta& metricMeta, i64 repeatedIdx = -1) { TDecoderContext child{*this}; child.Clear(); - if (metricMeta.HasKeys()) { - child.ParseKeys(metricMeta.GetKeys(), repeatedIdx); + if (metricMeta.HasKeys()) { + child.ParseKeys(metricMeta.GetKeys(), repeatedIdx); } return child; } - TDecoderContext CreateChildFromEls(const TString& name, const NMonProto::TExtraLabelMetrics& metrics, size_t idx, TMaybeMeta maybeMeta) { + TDecoderContext CreateChildFromEls(const TString& name, const NMonProto::TExtraLabelMetrics& metrics, size_t idx, TMaybeMeta maybeMeta) { TDecoderContext child{*this}; child.Clear(); @@ -261,8 +261,8 @@ namespace NMonitoring { } child.Labels_.push_back(::MakeIntrusive<TLazyLabel>( - [ labelName = metrics.GetlabelName(), idx, &metrics ](const auto&) { - const auto& val = metrics.Getvalues(idx); + [ labelName = metrics.GetlabelName(), idx, &metrics ](const auto&) { + const auto& val = metrics.Getvalues(idx); TString labelVal; const auto uintLabel = val.GetlabelValueUint(); @@ -356,7 +356,7 @@ namespace NMonitoring { class TDecoder { public: - TDecoder(IMetricConsumer* consumer, const NProtoBuf::Message& message, TInstant timestamp) + TDecoder(IMetricConsumer* consumer, const NProtoBuf::Message& message, TInstant timestamp) : Consumer_{consumer} , Message_{message} , Timestamp_{timestamp} @@ -374,12 +374,12 @@ namespace NMonitoring { } private: - static const NMonProto::TExtraLabelMetrics& ExtractExtraMetrics(TDecoderContext& ctx, const NProtoBuf::FieldDescriptor& f) { + static const NMonProto::TExtraLabelMetrics& ExtractExtraMetrics(TDecoderContext& ctx, const NProtoBuf::FieldDescriptor& f) { const auto& parent = ctx.Message(); const auto& reflection = ctx.Reflection(); auto& subMessage = reflection.GetMessage(parent, &f); - return dynamic_cast<const NMonProto::TExtraLabelMetrics&>(subMessage); + return dynamic_cast<const NMonProto::TExtraLabelMetrics&>(subMessage); } void DecodeImpl(const NProtoBuf::Message& msg, TDecoderContext ctx) const { @@ -394,68 +394,68 @@ namespace NMonitoring { const auto& opts = f->options(); const auto isMessage = f->type() == NProtoBuf::FieldDescriptor::TYPE_MESSAGE; - const auto isExtraLabelMetrics = isMessage && f->message_type()->full_name() == "NMonProto.TExtraLabelMetrics"; + const auto isExtraLabelMetrics = isMessage && f->message_type()->full_name() == "NMonProto.TExtraLabelMetrics"; const auto maybeMeta = MaybeGetMeta(opts); - if (!(maybeMeta || isExtraLabelMetrics)) { + if (!(maybeMeta || isExtraLabelMetrics)) { continue; } - if (isExtraLabelMetrics) { - const auto& extra = ExtractExtraMetrics(ctx, *f); - RecurseExtraLabelMetrics(ctx, extra, f->name(), maybeMeta); + if (isExtraLabelMetrics) { + const auto& extra = ExtractExtraMetrics(ctx, *f); + RecurseExtraLabelMetrics(ctx, extra, f->name(), maybeMeta); } else if (isMessage) { RecurseMessage(ctx, *maybeMeta, *f); } else if (f->is_repeated()) { RecurseRepeatedScalar(ctx, *maybeMeta, *f); - } else if (maybeMeta->HasType()) { + } else if (maybeMeta->HasType()) { const auto val = ReadFieldAsDouble(msg, f, ctx.Reflection()); - const bool isRate = maybeMeta->GetType() == NMonProto::EMetricType::RATE; - WriteMetric(val, ctx, f->name(), isRate); + const bool isRate = maybeMeta->GetType() == NMonProto::EMetricType::RATE; + WriteMetric(val, ctx, f->name(), isRate); } } } - void RecurseRepeatedScalar(TDecoderContext ctx, const NMonProto::TMetricMeta& meta, const NProtoBuf::FieldDescriptor& f) const { + void RecurseRepeatedScalar(TDecoderContext ctx, const NMonProto::TMetricMeta& meta, const NProtoBuf::FieldDescriptor& f) const { auto&& msg = ctx.Message(); auto&& reflection = ctx.Reflection(); - const bool isRate = meta.GetType() == NMonProto::EMetricType::RATE; + const bool isRate = meta.GetType() == NMonProto::EMetricType::RATE; - // this is a repeated scalar field, which makes metric only if it's indexing + // this is a repeated scalar field, which makes metric only if it's indexing for (auto i = 0; i < reflection.FieldSize(msg, &f); ++i) { auto subCtx = ctx.CreateChildFromRepeatedScalar(meta, i); subCtx.Init(&msg); auto val = ReadRepeatedAsDouble(msg, &f, reflection, i); - WriteMetric(val, subCtx, f.name(), isRate); + WriteMetric(val, subCtx, f.name(), isRate); } } - void RecurseExtraLabelMetrics(TDecoderContext ctx, const NMonProto::TExtraLabelMetrics& msg, const TString& name, const TMaybeMeta& meta) const { + void RecurseExtraLabelMetrics(TDecoderContext ctx, const NMonProto::TExtraLabelMetrics& msg, const TString& name, const TMaybeMeta& meta) const { auto i = 0; for (const auto& val : msg.Getvalues()) { auto subCtx = ctx.CreateChildFromEls(name, msg, i++, meta); subCtx.Init(&val); - const bool isRate = val.Hastype() - ? val.Gettype() == NMonProto::EMetricType::RATE - : meta->GetType() == NMonProto::EMetricType::RATE; + const bool isRate = val.Hastype() + ? val.Gettype() == NMonProto::EMetricType::RATE + : meta->GetType() == NMonProto::EMetricType::RATE; - double metricVal{0}; - if (isRate) { - metricVal = val.GetlongValue(); + double metricVal{0}; + if (isRate) { + metricVal = val.GetlongValue(); } else { - metricVal = val.GetdoubleValue(); + metricVal = val.GetdoubleValue(); } - WriteMetric(metricVal, subCtx, "", isRate); + WriteMetric(metricVal, subCtx, "", isRate); for (const auto& child : val.Getchildren()) { - RecurseExtraLabelMetrics(subCtx, child, "", meta); + RecurseExtraLabelMetrics(subCtx, child, "", meta); } } } - void RecurseMessage(TDecoderContext ctx, const NMonProto::TMetricMeta& metricMeta, const NProtoBuf::FieldDescriptor& f) const { + void RecurseMessage(TDecoderContext ctx, const NMonProto::TMetricMeta& metricMeta, const NProtoBuf::FieldDescriptor& f) const { const auto& msg = ctx.Message(); const auto& reflection = ctx.Reflection(); @@ -463,12 +463,12 @@ namespace NMonitoring { TRACE("recurse into repeated message " << f.name()); for (auto i = 0; i < reflection.FieldSize(msg, &f); ++i) { auto& subMessage = reflection.GetRepeatedMessage(msg, &f, i); - DecodeImpl(subMessage, ctx.CreateChildFromMeta(metricMeta, f.name(), i)); + DecodeImpl(subMessage, ctx.CreateChildFromMeta(metricMeta, f.name(), i)); } } else { TRACE("recurse into message " << f.name()); auto& subMessage = reflection.GetMessage(msg, &f); - DecodeImpl(subMessage, ctx.CreateChildFromMeta(metricMeta, f.name())); + DecodeImpl(subMessage, ctx.CreateChildFromMeta(metricMeta, f.name())); } } @@ -480,12 +480,12 @@ namespace NMonitoring { Consumer_->OnDouble(Timestamp_, value); } - void WriteMetric(double value, const TDecoderContext& ctx, const TString& name, bool isRate) const { - if (isRate) { - Consumer_->OnMetricBegin(EMetricType::RATE); + void WriteMetric(double value, const TDecoderContext& ctx, const TString& name, bool isRate) const { + if (isRate) { + Consumer_->OnMetricBegin(EMetricType::RATE); WriteValue(static_cast<ui64>(value)); } else { - Consumer_->OnMetricBegin(EMetricType::GAUGE); + Consumer_->OnMetricBegin(EMetricType::GAUGE); WriteValue(static_cast<double>(value)); } @@ -504,23 +504,23 @@ namespace NMonitoring { } Consumer_->OnLabelsEnd(); - Consumer_->OnMetricEnd(); + Consumer_->OnMetricEnd(); } private: - IMetricConsumer* Consumer_{nullptr}; + IMetricConsumer* Consumer_{nullptr}; const NProtoBuf::Message& Message_; TInstant Timestamp_; }; } - void DecodeLegacyProto(const NProtoBuf::Message& data, IMetricConsumer* consumer, TInstant ts) { + void DecodeLegacyProto(const NProtoBuf::Message& data, IMetricConsumer* consumer, TInstant ts) { Y_ENSURE(consumer); TDecoder(consumer, data, ts).Decode(); } - void DecodeLegacyProtoToStream(const NProtoBuf::Message& data, IMetricConsumer* consumer, TInstant ts) { + void DecodeLegacyProtoToStream(const NProtoBuf::Message& data, IMetricConsumer* consumer, TInstant ts) { Y_ENSURE(consumer); TDecoder(consumer, data, ts).DecodeToStream(); } diff --git a/library/cpp/monlib/encode/legacy_protobuf/legacy_protobuf.h b/library/cpp/monlib/encode/legacy_protobuf/legacy_protobuf.h index 50f65bf2c8..7cf8985d65 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/legacy_protobuf.h +++ b/library/cpp/monlib/encode/legacy_protobuf/legacy_protobuf.h @@ -9,8 +9,8 @@ namespace NMonitoring { // - memOnly; // - dropHost/ignorePath - void DecodeLegacyProto(const NProtoBuf::Message& data, class IMetricConsumer* c, TInstant ts = TInstant::Zero()); + void DecodeLegacyProto(const NProtoBuf::Message& data, class IMetricConsumer* c, TInstant ts = TInstant::Zero()); /// Does not open/close consumer stream unlike the above function. - void DecodeLegacyProtoToStream(const NProtoBuf::Message& data, class IMetricConsumer* c, TInstant ts = TInstant::Zero()); + void DecodeLegacyProtoToStream(const NProtoBuf::Message& data, class IMetricConsumer* c, TInstant ts = TInstant::Zero()); } diff --git a/library/cpp/monlib/encode/legacy_protobuf/legacy_protobuf_ut.cpp b/library/cpp/monlib/encode/legacy_protobuf/legacy_protobuf_ut.cpp index a751f8fb14..53683cb39c 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/legacy_protobuf_ut.cpp +++ b/library/cpp/monlib/encode/legacy_protobuf/legacy_protobuf_ut.cpp @@ -2,12 +2,12 @@ #include <library/cpp/testing/unittest/registar.h> -#include <library/cpp/monlib/encode/legacy_protobuf/ut/test_cases.pb.h> -#include <library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.pb.h> +#include <library/cpp/monlib/encode/legacy_protobuf/ut/test_cases.pb.h> +#include <library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.pb.h> -#include <library/cpp/monlib/encode/protobuf/protobuf.h> -#include <library/cpp/monlib/encode/text/text.h> -#include <library/cpp/monlib/metrics/labels.h> +#include <library/cpp/monlib/encode/protobuf/protobuf.h> +#include <library/cpp/monlib/encode/text/text.h> +#include <library/cpp/monlib/metrics/labels.h> #include <util/generic/algorithm.h> #include <util/generic/hash_set.h> @@ -24,7 +24,7 @@ TSimple MakeSimpleMessage() { return msg; } -IMetricEncoderPtr debugPrinter = EncoderText(&Cerr); +IMetricEncoderPtr debugPrinter = EncoderText(&Cerr); namespace NMonitoring { inline bool operator<(const TLabel& lhs, const TLabel& rhs) { @@ -34,20 +34,20 @@ namespace NMonitoring { } -void SetLabelValue(NMonProto::TExtraLabelMetrics::TValue& val, TString s) { +void SetLabelValue(NMonProto::TExtraLabelMetrics::TValue& val, TString s) { val.SetlabelValue(s); } -void SetLabelValue(NMonProto::TExtraLabelMetrics::TValue& val, ui64 u) { +void SetLabelValue(NMonProto::TExtraLabelMetrics::TValue& val, ui64 u) { val.SetlabelValueUint(u); } template <typename T, typename V> -NMonProto::TExtraLabelMetrics MakeExtra(TString labelName, V labelValue, T value, bool isDeriv) { - NMonProto::TExtraLabelMetrics metric; - auto* val = metric.Addvalues(); +NMonProto::TExtraLabelMetrics MakeExtra(TString labelName, V labelValue, T value, bool isDeriv) { + NMonProto::TExtraLabelMetrics metric; + auto* val = metric.Addvalues(); - metric.SetlabelName(labelName); + metric.SetlabelName(labelName); SetLabelValue(*val, labelValue); if (isDeriv) { @@ -56,7 +56,7 @@ NMonProto::TExtraLabelMetrics MakeExtra(TString labelName, V labelValue, T value val->SetdoubleValue(value); } - return metric; + return metric; } void AssertLabels(const TLabels& expected, const NProto::TMultiSample& actual) { @@ -100,13 +100,13 @@ void AssertSimpleMessage(const NProto::TMultiSamplesList& samples, TString pathP UNIT_ASSERT(expectedValues.contains(labelVal)); if (labelVal == pathPrefix + "Foo") { - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_DOUBLES_EQUAL(s.GetPoints(0).GetFloat64(), 1, 1e-6); } else if (labelVal == pathPrefix + "Bar") { - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_DOUBLES_EQUAL(s.GetPoints(0).GetFloat64(), 2, 1e-6); } else if (labelVal == pathPrefix + "Baz") { - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); UNIT_ASSERT_EQUAL(s.GetPoints(0).GetUint64(), 42); } } @@ -115,7 +115,7 @@ void AssertSimpleMessage(const NProto::TMultiSamplesList& samples, TString pathP Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(SimpleProto) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); auto msg = MakeSimpleMessage(); DecodeLegacyProto(msg, e.Get()); @@ -125,7 +125,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(RepeatedProto) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); TRepeated msg; @@ -138,7 +138,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(RepeatedProtoWithPath) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); TRepeatedWithPath msg; @@ -151,7 +151,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(DeepNesting) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); TRepeatedWithPath internal; @@ -167,7 +167,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(Keys) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); simple.SetLabel("my_label_value"); @@ -206,7 +206,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(NonStringKeys) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); TNonStringKeys msg; msg.SetFoo(42); @@ -241,7 +241,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(KeysFromNonLeafNodes) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); simple.SetLabel("label_value"); @@ -260,7 +260,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(SpacesAreGetReplaced) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); auto simple = MakeSimpleMessage(); simple.SetLabel("my label_value"); @@ -288,7 +288,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(ExtraLabels) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); TExtraLabels msg; msg.MutableExtraAsIs()->CopyFrom(MakeExtra("label", "foo", 42, false)); @@ -318,14 +318,14 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(NestedExtraLabels) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); TExtraLabels msg; auto extra = MakeExtra("label", "foo", 42, false); auto* val = extra.Mutablevalues(0); { auto child = MakeExtra("child1", "label1", 24, true); - child.Mutablevalues(0)->Settype(NMonProto::EMetricType::RATE); + child.Mutablevalues(0)->Settype(NMonProto::EMetricType::RATE); val->Addchildren()->CopyFrom(child); } @@ -368,7 +368,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(RobotLabels) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); TNamedCounter responses; responses.SetName("responses"); @@ -397,7 +397,7 @@ Y_UNIT_TEST_SUITE(TLegacyProtoDecoderTest) { Y_UNIT_TEST(ZoraLabels) { NProto::TMultiSamplesList samples; - IMetricEncoderPtr e = EncoderProtobuf(&samples); + IMetricEncoderPtr e = EncoderProtobuf(&samples); TTimeLogHist hist; hist.AddBuckets(42); diff --git a/library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto b/library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto index a8c5a2b93d..fd23eb372b 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto +++ b/library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto @@ -1,23 +1,23 @@ import "google/protobuf/descriptor.proto"; -package NMonProto; +package NMonProto; -option java_package = "ru.yandex.monlib.proto"; -option java_outer_classname = "MetricMetaProto"; +option java_package = "ru.yandex.monlib.proto"; +option java_outer_classname = "MetricMetaProto"; -enum EMetricType { - GAUGE = 1; - RATE = 2; +enum EMetricType { + GAUGE = 1; + RATE = 2; } -enum EMemOnly { +enum EMemOnly { DEFAULT = 0; STORE = 1; MEM_ONLY = 2; } -message TMetricMeta { - optional EMetricType Type = 1; +message TMetricMeta { + optional EMetricType Type = 1; optional bool Path = 2; optional string Keys = 3; optional bool MemOnly = 4; @@ -45,7 +45,7 @@ message THistogram { } // field of this type is recognized by Solomon -message TExtraLabelMetrics { +message TExtraLabelMetrics { optional string labelName = 1; message TValue { @@ -57,17 +57,17 @@ message TExtraLabelMetrics { optional double doubleValue = 3; optional THistogram histogramValue = 4; - optional EMetricType type = 7; - optional EMemOnly memOnly = 8; + optional EMetricType type = 7; + optional EMemOnly memOnly = 8; optional bool dropHost = 9; - repeated TExtraLabelMetrics children = 17; + repeated TExtraLabelMetrics children = 17; } repeated TValue values = 2; } extend google.protobuf.FieldOptions { - optional TMetricMeta Metric = 1719; + optional TMetricMeta Metric = 1719; } diff --git a/library/cpp/monlib/encode/legacy_protobuf/protos/python/ya.make b/library/cpp/monlib/encode/legacy_protobuf/protos/python/ya.make index ea96eaa950..095b307b01 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/protos/python/ya.make +++ b/library/cpp/monlib/encode/legacy_protobuf/protos/python/ya.make @@ -1,3 +1,3 @@ OWNER(g:solomon) -PY_PROTOS_FOR(library/cpp/monlib/encode/legacy_protobuf/protos) +PY_PROTOS_FOR(library/cpp/monlib/encode/legacy_protobuf/protos) diff --git a/library/cpp/monlib/encode/legacy_protobuf/protos/ya.make b/library/cpp/monlib/encode/legacy_protobuf/protos/ya.make index b5f1098a48..489f361ab1 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/protos/ya.make +++ b/library/cpp/monlib/encode/legacy_protobuf/protos/ya.make @@ -3,7 +3,7 @@ PROTO_LIBRARY() OWNER(g:solomon) SRCS( - metric_meta.proto + metric_meta.proto ) IF (NOT PY_PROTOS_FOR) diff --git a/library/cpp/monlib/encode/legacy_protobuf/ut/test_cases.proto b/library/cpp/monlib/encode/legacy_protobuf/ut/test_cases.proto index c51d870e07..37e901de48 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/ut/test_cases.proto +++ b/library/cpp/monlib/encode/legacy_protobuf/ut/test_cases.proto @@ -1,26 +1,26 @@ -import "library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto"; +import "library/cpp/monlib/encode/legacy_protobuf/protos/metric_meta.proto"; message TSimple { - optional uint64 Foo = 1 [ (NMonProto.Metric).Type = GAUGE ]; - optional double Bar = 2 [ (NMonProto.Metric).Type = GAUGE ]; - optional double Baz = 3 [ (NMonProto.Metric).Type = RATE ]; + optional uint64 Foo = 1 [ (NMonProto.Metric).Type = GAUGE ]; + optional double Bar = 2 [ (NMonProto.Metric).Type = GAUGE ]; + optional double Baz = 3 [ (NMonProto.Metric).Type = RATE ]; optional string Label = 4; } message TRepeated { - repeated TSimple Messages = 1 [ (NMonProto.Metric).Path = false ]; + repeated TSimple Messages = 1 [ (NMonProto.Metric).Path = false ]; }; message TRepeatedWithPath { - repeated TSimple Namespace = 1 [ (NMonProto.Metric).Path = true ]; + repeated TSimple Namespace = 1 [ (NMonProto.Metric).Path = true ]; }; message TNestedWithKeys { - repeated TSimple Namespace = 1 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "my_label:Label fixed_label=fixed_value numbered:#" ]; + repeated TSimple Namespace = 1 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "my_label:Label fixed_label=fixed_value numbered:#" ]; }; message TDeepNesting { - optional TRepeatedWithPath Nested = 1 [ (NMonProto.Metric).Path = false ]; + optional TRepeatedWithPath Nested = 1 [ (NMonProto.Metric).Path = false ]; }; enum EEnum { @@ -29,43 +29,43 @@ enum EEnum { }; message TNonStringKeys { - optional uint32 Foo = 1 [ (NMonProto.Metric).Type = GAUGE ]; + optional uint32 Foo = 1 [ (NMonProto.Metric).Type = GAUGE ]; optional EEnum Enum = 2; optional uint32 Int = 3; }; message TRepeatedNonStringKeys { - repeated TNonStringKeys Nested = 1 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "enum:Enum int:Int" ]; + repeated TNonStringKeys Nested = 1 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "enum:Enum int:Int" ]; }; message TExtraLabels { - optional NMonProto.TExtraLabelMetrics ExtraAsIs = 1 [ (NMonProto.Metric).Type = GAUGE ]; - optional NMonProto.TExtraLabelMetrics ExtraDeriv = 2 [ (NMonProto.Metric).Type = RATE ]; + optional NMonProto.TExtraLabelMetrics ExtraAsIs = 1 [ (NMonProto.Metric).Type = GAUGE ]; + optional NMonProto.TExtraLabelMetrics ExtraDeriv = 2 [ (NMonProto.Metric).Type = RATE ]; }; message TRepeatedWithName { optional string Name = 1; - repeated TSimple Nested = 2 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "my_label:Label" ]; + repeated TSimple Nested = 2 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "my_label:Label" ]; }; message TKeysFromNonLeaf { - repeated TRepeatedWithName Nested = 1 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "name:Name" ]; + repeated TRepeatedWithName Nested = 1 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "name:Name" ]; }; message TNamedCounter { optional string Name = 1; - optional uint64 Count = 2 [ (NMonProto.Metric).Type = RATE ]; + optional uint64 Count = 2 [ (NMonProto.Metric).Type = RATE ]; } message TCrawlerCounters { message TStatusCounters { - repeated TNamedCounter ZoraResponses = 3 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "ZoraResponse:Name" ]; - repeated TNamedCounter FetcherResponses = 4 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "SpiderResponse:Name" ]; - repeated TNamedCounter RotorResponses = 5 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "SpiderResponse:Name" ]; - repeated TNamedCounter PDFetchResponses = 6 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "PDFetchResponse:Name" ]; - repeated TNamedCounter CalcResponses = 7 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "CalcResponse:Name" ]; - repeated TNamedCounter Responses = 8 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "AggregatedResponse:Name" ]; + repeated TNamedCounter ZoraResponses = 3 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "ZoraResponse:Name" ]; + repeated TNamedCounter FetcherResponses = 4 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "SpiderResponse:Name" ]; + repeated TNamedCounter RotorResponses = 5 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "SpiderResponse:Name" ]; + repeated TNamedCounter PDFetchResponses = 6 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "PDFetchResponse:Name" ]; + repeated TNamedCounter CalcResponses = 7 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "CalcResponse:Name" ]; + repeated TNamedCounter Responses = 8 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "AggregatedResponse:Name" ]; } message TPolicyCounters { @@ -73,18 +73,18 @@ message TCrawlerCounters { optional string Name = 2; optional string Zone = 3; - optional TStatusCounters StatusCounters = 4 [ (NMonProto.Metric).Path = true ]; + optional TStatusCounters StatusCounters = 4 [ (NMonProto.Metric).Path = true ]; } optional string Component = 1; - repeated TPolicyCounters PoliciesCounters = 3 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "SubComponent:SubComponent Policy:Name Zone:Zone" ]; + repeated TPolicyCounters PoliciesCounters = 3 [ (NMonProto.Metric).Path = true, (NMonProto.Metric).Keys = "SubComponent:SubComponent Policy:Name Zone:Zone" ]; } message TTimeLogHist { optional uint32 MinBucketMillisec = 1; - repeated uint64 Buckets = 2 [ (NMonProto.Metric).Type = RATE, (NMonProto.Metric).Keys = "slot:#" ]; + repeated uint64 Buckets = 2 [ (NMonProto.Metric).Type = RATE, (NMonProto.Metric).Keys = "slot:#" ]; } message TKiwiCounters { - optional TTimeLogHist Times = 22 [ (NMonProto.Metric).Path = true ]; + optional TTimeLogHist Times = 22 [ (NMonProto.Metric).Path = true ]; } diff --git a/library/cpp/monlib/encode/legacy_protobuf/ut/ya.make b/library/cpp/monlib/encode/legacy_protobuf/ut/ya.make index fa9b4ebb1a..479a0c46c9 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/ut/ya.make +++ b/library/cpp/monlib/encode/legacy_protobuf/ut/ya.make @@ -1,4 +1,4 @@ -UNITTEST_FOR(library/cpp/monlib/encode/legacy_protobuf) +UNITTEST_FOR(library/cpp/monlib/encode/legacy_protobuf) OWNER( g:solomon @@ -11,8 +11,8 @@ SRCS( ) PEERDIR( - library/cpp/monlib/encode/protobuf - library/cpp/monlib/encode/text + library/cpp/monlib/encode/protobuf + library/cpp/monlib/encode/text ) END() diff --git a/library/cpp/monlib/encode/legacy_protobuf/ya.make b/library/cpp/monlib/encode/legacy_protobuf/ya.make index 5750032537..74c82aac93 100644 --- a/library/cpp/monlib/encode/legacy_protobuf/ya.make +++ b/library/cpp/monlib/encode/legacy_protobuf/ya.make @@ -10,7 +10,7 @@ SRCS( ) PEERDIR( - library/cpp/monlib/encode/legacy_protobuf/protos + library/cpp/monlib/encode/legacy_protobuf/protos ) END() diff --git a/library/cpp/monlib/encode/prometheus/fuzz/main.cpp b/library/cpp/monlib/encode/prometheus/fuzz/main.cpp index a9ed0afc45..24bda2d32e 100644 --- a/library/cpp/monlib/encode/prometheus/fuzz/main.cpp +++ b/library/cpp/monlib/encode/prometheus/fuzz/main.cpp @@ -1,18 +1,18 @@ -#include <library/cpp/monlib/encode/prometheus/prometheus.h> -#include <library/cpp/monlib/encode/fake/fake.h> - -#include <util/stream/mem.h> - - -extern "C" int LLVMFuzzerTestOneInput(const ui8* buf, size_t size) { - using namespace NMonitoring; - - try { - TStringBuf data(reinterpret_cast<const char*>(buf), size); - auto encoder = EncoderFake(); - DecodePrometheus(data, encoder.Get()); - } catch (...) { - } - - return 0; -} +#include <library/cpp/monlib/encode/prometheus/prometheus.h> +#include <library/cpp/monlib/encode/fake/fake.h> + +#include <util/stream/mem.h> + + +extern "C" int LLVMFuzzerTestOneInput(const ui8* buf, size_t size) { + using namespace NMonitoring; + + try { + TStringBuf data(reinterpret_cast<const char*>(buf), size); + auto encoder = EncoderFake(); + DecodePrometheus(data, encoder.Get()); + } catch (...) { + } + + return 0; +} diff --git a/library/cpp/monlib/encode/prometheus/fuzz/ya.make b/library/cpp/monlib/encode/prometheus/fuzz/ya.make index 0fc3845718..4a6c796ed5 100644 --- a/library/cpp/monlib/encode/prometheus/fuzz/ya.make +++ b/library/cpp/monlib/encode/prometheus/fuzz/ya.make @@ -1,16 +1,16 @@ -FUZZ() - -OWNER(g:solomon jamel) - -PEERDIR( - library/cpp/monlib/encode/prometheus - library/cpp/monlib/encode/fake -) - -SIZE(MEDIUM) - -SRCS( - main.cpp -) - -END() +FUZZ() + +OWNER(g:solomon jamel) + +PEERDIR( + library/cpp/monlib/encode/prometheus + library/cpp/monlib/encode/fake +) + +SIZE(MEDIUM) + +SRCS( + main.cpp +) + +END() diff --git a/library/cpp/monlib/encode/prometheus/prometheus.h b/library/cpp/monlib/encode/prometheus/prometheus.h index f031f5e933..2e7fa31c28 100644 --- a/library/cpp/monlib/encode/prometheus/prometheus.h +++ b/library/cpp/monlib/encode/prometheus/prometheus.h @@ -1,18 +1,18 @@ -#pragma once - -#include <library/cpp/monlib/encode/encoder.h> -#include <library/cpp/monlib/encode/format.h> - -#include <util/generic/yexception.h> - - -namespace NMonitoring { - - class TPrometheusDecodeException: public yexception { - }; - +#pragma once + +#include <library/cpp/monlib/encode/encoder.h> +#include <library/cpp/monlib/encode/format.h> + +#include <util/generic/yexception.h> + + +namespace NMonitoring { + + class TPrometheusDecodeException: public yexception { + }; + IMetricEncoderPtr EncoderPrometheus(IOutputStream* out, TStringBuf metricNameLabel = "sensor"); - + void DecodePrometheus(TStringBuf data, IMetricConsumer* c, TStringBuf metricNameLabel = "sensor"); - -} + +} diff --git a/library/cpp/monlib/encode/prometheus/prometheus_decoder.cpp b/library/cpp/monlib/encode/prometheus/prometheus_decoder.cpp index f11dd33e31..7e81357dbd 100644 --- a/library/cpp/monlib/encode/prometheus/prometheus_decoder.cpp +++ b/library/cpp/monlib/encode/prometheus/prometheus_decoder.cpp @@ -1,51 +1,51 @@ -#include "prometheus.h" -#include "prometheus_model.h" - -#include <library/cpp/monlib/metrics/histogram_snapshot.h> -#include <library/cpp/monlib/metrics/metric.h> - -#include <util/datetime/base.h> -#include <util/generic/hash.h> -#include <util/string/cast.h> -#include <util/string/builder.h> -#include <util/generic/maybe.h> -#include <util/string/ascii.h> - -#include <cmath> - -#define Y_PARSER_FAIL(message) \ - ythrow ::NMonitoring::TPrometheusDecodeException() << message << " at line #" << CurrentLine_ - -#define Y_PARSER_ENSURE(cond, message) \ - Y_ENSURE_EX(cond, ::NMonitoring::TPrometheusDecodeException() << message << " at line #" << CurrentLine_) - - -namespace NMonitoring { - namespace { +#include "prometheus.h" +#include "prometheus_model.h" + +#include <library/cpp/monlib/metrics/histogram_snapshot.h> +#include <library/cpp/monlib/metrics/metric.h> + +#include <util/datetime/base.h> +#include <util/generic/hash.h> +#include <util/string/cast.h> +#include <util/string/builder.h> +#include <util/generic/maybe.h> +#include <util/string/ascii.h> + +#include <cmath> + +#define Y_PARSER_FAIL(message) \ + ythrow ::NMonitoring::TPrometheusDecodeException() << message << " at line #" << CurrentLine_ + +#define Y_PARSER_ENSURE(cond, message) \ + Y_ENSURE_EX(cond, ::NMonitoring::TPrometheusDecodeException() << message << " at line #" << CurrentLine_) + + +namespace NMonitoring { + namespace { constexpr ui32 MAX_LABEL_VALUE_LEN = 256; - - using TLabelsMap = THashMap<TString, TString>; - - TString LabelsToStr(const TLabelsMap& labels) { - TStringBuilder sb; - auto it = labels.begin(); - auto end = labels.end(); - - sb << '{'; - while (it != end) { - sb << it->first; - sb << '='; - sb << '"' << it->second << '"'; - - ++it; - if (it != end) { - sb << ", "; - } - } - sb << '}'; - return sb; - } - + + using TLabelsMap = THashMap<TString, TString>; + + TString LabelsToStr(const TLabelsMap& labels) { + TStringBuilder sb; + auto it = labels.begin(); + auto end = labels.end(); + + sb << '{'; + while (it != end) { + sb << it->first; + sb << '='; + sb << '"' << it->second << '"'; + + ++it; + if (it != end) { + sb << ", "; + } + } + sb << '}'; + return sb; + } + template <typename T, typename U> bool TryStaticCast(U val, T& out) { static_assert(std::is_arithmetic_v<U>); @@ -64,534 +64,534 @@ namespace NMonitoring { return true; } - /////////////////////////////////////////////////////////////////////// - // THistogramBuilder - /////////////////////////////////////////////////////////////////////// - class THistogramBuilder { - using TBucketData = std::pair<TBucketBound, TBucketValue>; - constexpr static TBucketData ZERO_BUCKET = { -std::numeric_limits<TBucketBound>::max(), 0 }; - public: - TStringBuf GetName() const noexcept { - return Name_; - } - - void SetName(TStringBuf name) noexcept { - Name_ = name; - } - - const TLabelsMap& GetLabels() const noexcept { - return *Labels_; - } - - void SetLabels(TLabelsMap&& labels) { - if (Labels_.Defined()) { - Y_ENSURE(Labels_ == labels, - "mixed labels in one histogram, prev: " << LabelsToStr(*Labels_) << - ", current: " << LabelsToStr(labels)); - } else { - Labels_.ConstructInPlace(std::move(labels)); - } - } - - TInstant GetTime() const noexcept { - return Time_; - } - - void SetTime(TInstant time) noexcept { - Time_ = time; - } - - bool Empty() const noexcept { - return Bounds_.empty(); - } - - bool Same(TStringBuf name, const TLabelsMap& labels) const noexcept { - return Name_ == name && Labels_ == labels; - } - - void AddBucket(TBucketBound bound, TBucketValue value) { - Y_ENSURE_EX(PrevBucket_.first < bound, TPrometheusDecodeException() << - "invalid order of histogram bounds " << PrevBucket_.first << - " >= " << bound); - - Y_ENSURE_EX(PrevBucket_.second <= value, TPrometheusDecodeException() << - "invalid order of histogram bucket values " << PrevBucket_.second << - " > " << value); - - // convert infinite bound value - if (bound == std::numeric_limits<TBucketBound>::infinity()) { - bound = HISTOGRAM_INF_BOUND; - } - - Bounds_.push_back(bound); - Values_.push_back(value - PrevBucket_.second); // keep only delta between buckets - - PrevBucket_ = { bound, value }; - } - - // will clear builder state - IHistogramSnapshotPtr ToSnapshot() { - Y_ENSURE_EX(!Empty(), TPrometheusDecodeException() << "histogram cannot be empty"); - Time_ = TInstant::Zero(); - PrevBucket_ = ZERO_BUCKET; - Labels_.Clear(); + /////////////////////////////////////////////////////////////////////// + // THistogramBuilder + /////////////////////////////////////////////////////////////////////// + class THistogramBuilder { + using TBucketData = std::pair<TBucketBound, TBucketValue>; + constexpr static TBucketData ZERO_BUCKET = { -std::numeric_limits<TBucketBound>::max(), 0 }; + public: + TStringBuf GetName() const noexcept { + return Name_; + } + + void SetName(TStringBuf name) noexcept { + Name_ = name; + } + + const TLabelsMap& GetLabels() const noexcept { + return *Labels_; + } + + void SetLabels(TLabelsMap&& labels) { + if (Labels_.Defined()) { + Y_ENSURE(Labels_ == labels, + "mixed labels in one histogram, prev: " << LabelsToStr(*Labels_) << + ", current: " << LabelsToStr(labels)); + } else { + Labels_.ConstructInPlace(std::move(labels)); + } + } + + TInstant GetTime() const noexcept { + return Time_; + } + + void SetTime(TInstant time) noexcept { + Time_ = time; + } + + bool Empty() const noexcept { + return Bounds_.empty(); + } + + bool Same(TStringBuf name, const TLabelsMap& labels) const noexcept { + return Name_ == name && Labels_ == labels; + } + + void AddBucket(TBucketBound bound, TBucketValue value) { + Y_ENSURE_EX(PrevBucket_.first < bound, TPrometheusDecodeException() << + "invalid order of histogram bounds " << PrevBucket_.first << + " >= " << bound); + + Y_ENSURE_EX(PrevBucket_.second <= value, TPrometheusDecodeException() << + "invalid order of histogram bucket values " << PrevBucket_.second << + " > " << value); + + // convert infinite bound value + if (bound == std::numeric_limits<TBucketBound>::infinity()) { + bound = HISTOGRAM_INF_BOUND; + } + + Bounds_.push_back(bound); + Values_.push_back(value - PrevBucket_.second); // keep only delta between buckets + + PrevBucket_ = { bound, value }; + } + + // will clear builder state + IHistogramSnapshotPtr ToSnapshot() { + Y_ENSURE_EX(!Empty(), TPrometheusDecodeException() << "histogram cannot be empty"); + Time_ = TInstant::Zero(); + PrevBucket_ = ZERO_BUCKET; + Labels_.Clear(); auto snapshot = ExplicitHistogramSnapshot(Bounds_, Values_); Bounds_.clear(); Values_.clear(); return snapshot; - } - - private: - TStringBuf Name_; - TMaybe<TLabelsMap> Labels_; - TInstant Time_; - TBucketBounds Bounds_; - TBucketValues Values_; - TBucketData PrevBucket_ = ZERO_BUCKET; - }; - - /////////////////////////////////////////////////////////////////////// - // EPrometheusMetricType - /////////////////////////////////////////////////////////////////////// - enum class EPrometheusMetricType { - GAUGE, - COUNTER, - SUMMARY, - UNTYPED, - HISTOGRAM, - }; - - /////////////////////////////////////////////////////////////////////// - // TPrometheusReader - /////////////////////////////////////////////////////////////////////// - class TPrometheusReader { - public: + } + + private: + TStringBuf Name_; + TMaybe<TLabelsMap> Labels_; + TInstant Time_; + TBucketBounds Bounds_; + TBucketValues Values_; + TBucketData PrevBucket_ = ZERO_BUCKET; + }; + + /////////////////////////////////////////////////////////////////////// + // EPrometheusMetricType + /////////////////////////////////////////////////////////////////////// + enum class EPrometheusMetricType { + GAUGE, + COUNTER, + SUMMARY, + UNTYPED, + HISTOGRAM, + }; + + /////////////////////////////////////////////////////////////////////// + // TPrometheusReader + /////////////////////////////////////////////////////////////////////// + class TPrometheusReader { + public: TPrometheusReader(TStringBuf data, IMetricConsumer* c, TStringBuf metricNameLabel) - : Data_(data) - , Consumer_(c) + : Data_(data) + , Consumer_(c) , MetricNameLabel_(metricNameLabel) - { - } - - void Read() { - Consumer_->OnStreamBegin(); - - if (HasRemaining()) { - ReadNextByte(); - SkipSpaces(); - - try { - while (HasRemaining()) { - switch (CurrentByte_) { - case '\n': - ReadNextByte(); // skip '\n' - CurrentLine_++; - SkipSpaces(); - break; - case '#': - ParseComment(); - break; - default: - ParseMetric(); - break; - } - } - - if (!HistogramBuilder_.Empty()) { - ConsumeHistogram(); - } - } catch (const TPrometheusDecodeException& e) { - throw e; - } catch (...) { - Y_PARSER_FAIL("unexpected error " << CurrentExceptionMessage()); - } - } - - Consumer_->OnStreamEnd(); - } - - private: - bool HasRemaining() const noexcept { - return CurrentPos_ < Data_.Size(); - } - - // # 'TYPE' metric_name {counter|gauge|histogram|summary|untyped} - // # 'HELP' metric_name some help info - // # general comment message - void ParseComment() { - SkipExpectedChar('#'); - SkipSpaces(); - - TStringBuf keyword = ReadToken(); + { + } + + void Read() { + Consumer_->OnStreamBegin(); + + if (HasRemaining()) { + ReadNextByte(); + SkipSpaces(); + + try { + while (HasRemaining()) { + switch (CurrentByte_) { + case '\n': + ReadNextByte(); // skip '\n' + CurrentLine_++; + SkipSpaces(); + break; + case '#': + ParseComment(); + break; + default: + ParseMetric(); + break; + } + } + + if (!HistogramBuilder_.Empty()) { + ConsumeHistogram(); + } + } catch (const TPrometheusDecodeException& e) { + throw e; + } catch (...) { + Y_PARSER_FAIL("unexpected error " << CurrentExceptionMessage()); + } + } + + Consumer_->OnStreamEnd(); + } + + private: + bool HasRemaining() const noexcept { + return CurrentPos_ < Data_.Size(); + } + + // # 'TYPE' metric_name {counter|gauge|histogram|summary|untyped} + // # 'HELP' metric_name some help info + // # general comment message + void ParseComment() { + SkipExpectedChar('#'); + SkipSpaces(); + + TStringBuf keyword = ReadToken(); if (keyword == TStringBuf("TYPE")) { - SkipSpaces(); - - TStringBuf nextName = ReadTokenAsMetricName(); - Y_PARSER_ENSURE(!nextName.Empty(), "invalid metric name"); - - SkipSpaces(); - EPrometheusMetricType nextType = ReadType(); - - bool inserted = SeenTypes_.emplace(nextName, nextType).second; - Y_PARSER_ENSURE(inserted, "second TYPE line for metric " << nextName); - - if (nextType == EPrometheusMetricType::HISTOGRAM) { - if (!HistogramBuilder_.Empty()) { - ConsumeHistogram(); - } - HistogramBuilder_.SetName(nextName); - } - } else { - // skip HELP and general comments - SkipUntilEol(); - } - - Y_PARSER_ENSURE(CurrentByte_ == '\n', "expected '\\n', found '" << CurrentByte_ << '\''); - } - - // metric_name [labels] value [timestamp] - void ParseMetric() { - TStringBuf name = ReadTokenAsMetricName(); - SkipSpaces(); - - TLabelsMap labels = ReadLabels(); - SkipSpaces(); - - double value = ParseGoDouble(ReadToken()); - SkipSpaces(); - - TInstant time = TInstant::Zero(); - if (CurrentByte_ != '\n') { - time = TInstant::MilliSeconds(FromString<ui64>(ReadToken())); - } - - TStringBuf baseName = name; - EPrometheusMetricType type = EPrometheusMetricType::UNTYPED; - - if (auto* seenType = SeenTypes_.FindPtr(name)) { - type = *seenType; - } else { - baseName = NPrometheus::ToBaseName(name); - if (auto* baseType = SeenTypes_.FindPtr(baseName)) { - type = *baseType; - } - } - - switch (type) { - case EPrometheusMetricType::HISTOGRAM: - if (NPrometheus::IsBucket(name)) { - double bound = 0.0; - auto it = labels.find(NPrometheus::BUCKET_LABEL); - if (it != labels.end()) { - bound = ParseGoDouble(it->second); - labels.erase(it); - } else { - Y_PARSER_FAIL( - "metric " << name << "has no " << NPrometheus::BUCKET_LABEL << - " label at line #" << CurrentLine_); - } - - if (!HistogramBuilder_.Empty() && !HistogramBuilder_.Same(baseName, labels)) { - ConsumeHistogram(); - HistogramBuilder_.SetName(baseName); - } - + SkipSpaces(); + + TStringBuf nextName = ReadTokenAsMetricName(); + Y_PARSER_ENSURE(!nextName.Empty(), "invalid metric name"); + + SkipSpaces(); + EPrometheusMetricType nextType = ReadType(); + + bool inserted = SeenTypes_.emplace(nextName, nextType).second; + Y_PARSER_ENSURE(inserted, "second TYPE line for metric " << nextName); + + if (nextType == EPrometheusMetricType::HISTOGRAM) { + if (!HistogramBuilder_.Empty()) { + ConsumeHistogram(); + } + HistogramBuilder_.SetName(nextName); + } + } else { + // skip HELP and general comments + SkipUntilEol(); + } + + Y_PARSER_ENSURE(CurrentByte_ == '\n', "expected '\\n', found '" << CurrentByte_ << '\''); + } + + // metric_name [labels] value [timestamp] + void ParseMetric() { + TStringBuf name = ReadTokenAsMetricName(); + SkipSpaces(); + + TLabelsMap labels = ReadLabels(); + SkipSpaces(); + + double value = ParseGoDouble(ReadToken()); + SkipSpaces(); + + TInstant time = TInstant::Zero(); + if (CurrentByte_ != '\n') { + time = TInstant::MilliSeconds(FromString<ui64>(ReadToken())); + } + + TStringBuf baseName = name; + EPrometheusMetricType type = EPrometheusMetricType::UNTYPED; + + if (auto* seenType = SeenTypes_.FindPtr(name)) { + type = *seenType; + } else { + baseName = NPrometheus::ToBaseName(name); + if (auto* baseType = SeenTypes_.FindPtr(baseName)) { + type = *baseType; + } + } + + switch (type) { + case EPrometheusMetricType::HISTOGRAM: + if (NPrometheus::IsBucket(name)) { + double bound = 0.0; + auto it = labels.find(NPrometheus::BUCKET_LABEL); + if (it != labels.end()) { + bound = ParseGoDouble(it->second); + labels.erase(it); + } else { + Y_PARSER_FAIL( + "metric " << name << "has no " << NPrometheus::BUCKET_LABEL << + " label at line #" << CurrentLine_); + } + + if (!HistogramBuilder_.Empty() && !HistogramBuilder_.Same(baseName, labels)) { + ConsumeHistogram(); + HistogramBuilder_.SetName(baseName); + } + TBucketValue bucketVal; Y_PARSER_ENSURE(TryStaticCast(value, bucketVal), "Cannot convert " << value << " to bucket value type"); HistogramBuilder_.AddBucket(bound, bucketVal); - HistogramBuilder_.SetTime(time); - HistogramBuilder_.SetLabels(std::move(labels)); - } else if (NPrometheus::IsCount(name)) { - // translate x_count metric as COUNTER metric - ConsumeCounter(name, labels, time, value); - } else if (NPrometheus::IsSum(name)) { - // translate x_sum metric as GAUGE metric - ConsumeGauge(name, labels, time, value); - } else { - Y_PARSER_FAIL( - "metric " << name << - " should be part of HISTOGRAM " << baseName); - } - break; - - case EPrometheusMetricType::SUMMARY: - if (NPrometheus::IsCount(name)) { - // translate x_count metric as COUNTER metric - ConsumeCounter(name, labels, time, value); - } else if (NPrometheus::IsSum(name)) { - // translate x_sum metric as GAUGE metric - ConsumeGauge(name, labels, time, value); - } else { - ConsumeGauge(name, labels, time, value); - } - break; - - case EPrometheusMetricType::COUNTER: - ConsumeCounter(name, labels, time, value); - break; - - case EPrometheusMetricType::GAUGE: - ConsumeGauge(name, labels, time, value); - break; - - case EPrometheusMetricType::UNTYPED: - ConsumeGauge(name, labels, time, value); - break; - } - - Y_PARSER_ENSURE(CurrentByte_ == '\n', "expected '\\n', found '" << CurrentByte_ << '\''); - } - - // { name = "value", name2 = "value2", } - TLabelsMap ReadLabels() { - TLabelsMap labels; - if (CurrentByte_ != '{') { - return labels; - } - - SkipExpectedChar('{'); - SkipSpaces(); - - while (CurrentByte_ != '}') { - TStringBuf name = ReadTokenAsLabelName(); - SkipSpaces(); - - SkipExpectedChar('='); - SkipSpaces(); - - TString value = ReadTokenAsLabelValue(); - SkipSpaces(); - labels.emplace(name, value); - - if (CurrentByte_ == ',') { - SkipExpectedChar(','); - SkipSpaces(); - } - } - - SkipExpectedChar('}'); - return labels; - } - - EPrometheusMetricType ReadType() { - TStringBuf keyword = ReadToken(); - if (AsciiEqualsIgnoreCase(keyword, "GAUGE")) { - return EPrometheusMetricType::GAUGE; - } else if (AsciiEqualsIgnoreCase(keyword, "COUNTER")) { - return EPrometheusMetricType::COUNTER; - } else if (AsciiEqualsIgnoreCase(keyword, "SUMMARY")) { - return EPrometheusMetricType::SUMMARY; - } else if (AsciiEqualsIgnoreCase(keyword, "HISTOGRAM")) { - return EPrometheusMetricType::HISTOGRAM; - } else if (AsciiEqualsIgnoreCase(keyword, "UNTYPED")) { - return EPrometheusMetricType::UNTYPED; - } - - Y_PARSER_FAIL( - "unknown metric type: " << keyword << - " at line #" << CurrentLine_); - } - - Y_FORCE_INLINE void ReadNextByteUnsafe() { - CurrentByte_ = Data_[CurrentPos_++]; - } - + HistogramBuilder_.SetTime(time); + HistogramBuilder_.SetLabels(std::move(labels)); + } else if (NPrometheus::IsCount(name)) { + // translate x_count metric as COUNTER metric + ConsumeCounter(name, labels, time, value); + } else if (NPrometheus::IsSum(name)) { + // translate x_sum metric as GAUGE metric + ConsumeGauge(name, labels, time, value); + } else { + Y_PARSER_FAIL( + "metric " << name << + " should be part of HISTOGRAM " << baseName); + } + break; + + case EPrometheusMetricType::SUMMARY: + if (NPrometheus::IsCount(name)) { + // translate x_count metric as COUNTER metric + ConsumeCounter(name, labels, time, value); + } else if (NPrometheus::IsSum(name)) { + // translate x_sum metric as GAUGE metric + ConsumeGauge(name, labels, time, value); + } else { + ConsumeGauge(name, labels, time, value); + } + break; + + case EPrometheusMetricType::COUNTER: + ConsumeCounter(name, labels, time, value); + break; + + case EPrometheusMetricType::GAUGE: + ConsumeGauge(name, labels, time, value); + break; + + case EPrometheusMetricType::UNTYPED: + ConsumeGauge(name, labels, time, value); + break; + } + + Y_PARSER_ENSURE(CurrentByte_ == '\n', "expected '\\n', found '" << CurrentByte_ << '\''); + } + + // { name = "value", name2 = "value2", } + TLabelsMap ReadLabels() { + TLabelsMap labels; + if (CurrentByte_ != '{') { + return labels; + } + + SkipExpectedChar('{'); + SkipSpaces(); + + while (CurrentByte_ != '}') { + TStringBuf name = ReadTokenAsLabelName(); + SkipSpaces(); + + SkipExpectedChar('='); + SkipSpaces(); + + TString value = ReadTokenAsLabelValue(); + SkipSpaces(); + labels.emplace(name, value); + + if (CurrentByte_ == ',') { + SkipExpectedChar(','); + SkipSpaces(); + } + } + + SkipExpectedChar('}'); + return labels; + } + + EPrometheusMetricType ReadType() { + TStringBuf keyword = ReadToken(); + if (AsciiEqualsIgnoreCase(keyword, "GAUGE")) { + return EPrometheusMetricType::GAUGE; + } else if (AsciiEqualsIgnoreCase(keyword, "COUNTER")) { + return EPrometheusMetricType::COUNTER; + } else if (AsciiEqualsIgnoreCase(keyword, "SUMMARY")) { + return EPrometheusMetricType::SUMMARY; + } else if (AsciiEqualsIgnoreCase(keyword, "HISTOGRAM")) { + return EPrometheusMetricType::HISTOGRAM; + } else if (AsciiEqualsIgnoreCase(keyword, "UNTYPED")) { + return EPrometheusMetricType::UNTYPED; + } + + Y_PARSER_FAIL( + "unknown metric type: " << keyword << + " at line #" << CurrentLine_); + } + + Y_FORCE_INLINE void ReadNextByteUnsafe() { + CurrentByte_ = Data_[CurrentPos_++]; + } + Y_FORCE_INLINE bool IsSpace(char ch) { - return ch == ' ' || ch == '\t'; - } - - void ReadNextByte() { - Y_PARSER_ENSURE(HasRemaining(), "unexpected end of file"); - ReadNextByteUnsafe(); - } - - void SkipExpectedChar(char ch) { - Y_PARSER_ENSURE(CurrentByte_ == ch, - "expected '" << CurrentByte_ << "', found '" << ch << '\''); - ReadNextByte(); - } - - void SkipSpaces() { + return ch == ' ' || ch == '\t'; + } + + void ReadNextByte() { + Y_PARSER_ENSURE(HasRemaining(), "unexpected end of file"); + ReadNextByteUnsafe(); + } + + void SkipExpectedChar(char ch) { + Y_PARSER_ENSURE(CurrentByte_ == ch, + "expected '" << CurrentByte_ << "', found '" << ch << '\''); + ReadNextByte(); + } + + void SkipSpaces() { while (HasRemaining() && IsSpace(CurrentByte_)) { - ReadNextByteUnsafe(); - } - } - - void SkipUntilEol() { - while (HasRemaining() && CurrentByte_ != '\n') { - ReadNextByteUnsafe(); - } - } - - TStringBuf ReadToken() { - Y_VERIFY_DEBUG(CurrentPos_ > 0); - size_t begin = CurrentPos_ - 1; // read first byte again + ReadNextByteUnsafe(); + } + } + + void SkipUntilEol() { + while (HasRemaining() && CurrentByte_ != '\n') { + ReadNextByteUnsafe(); + } + } + + TStringBuf ReadToken() { + Y_VERIFY_DEBUG(CurrentPos_ > 0); + size_t begin = CurrentPos_ - 1; // read first byte again while (HasRemaining() && !IsSpace(CurrentByte_) && CurrentByte_ != '\n') { - ReadNextByteUnsafe(); - } - return TokenFromPos(begin); - } - - TStringBuf ReadTokenAsMetricName() { - if (!NPrometheus::IsValidMetricNameStart(CurrentByte_)) { - return ""; - } - - Y_VERIFY_DEBUG(CurrentPos_ > 0); - size_t begin = CurrentPos_ - 1; // read first byte again - while (HasRemaining()) { - ReadNextByteUnsafe(); - if (!NPrometheus::IsValidMetricNameContinuation(CurrentByte_)) { - break; - } - } - return TokenFromPos(begin); - } - - TStringBuf ReadTokenAsLabelName() { - if (!NPrometheus::IsValidLabelNameStart(CurrentByte_)) { - return ""; - } - - Y_VERIFY_DEBUG(CurrentPos_ > 0); - size_t begin = CurrentPos_ - 1; // read first byte again - while (HasRemaining()) { - ReadNextByteUnsafe(); - if (!NPrometheus::IsValidLabelNameContinuation(CurrentByte_)) { - break; - } - } - return TokenFromPos(begin); - } - - TString ReadTokenAsLabelValue() { - TString labelValue; - - SkipExpectedChar('"'); - for (ui32 i = 0; i < MAX_LABEL_VALUE_LEN; i++) { - switch (CurrentByte_) { - case '"': - SkipExpectedChar('"'); - return labelValue; - - case '\n': - Y_PARSER_FAIL("label value contains unescaped new-line"); - - case '\\': - ReadNextByte(); - switch (CurrentByte_) { - case '"': - case '\\': - labelValue.append(CurrentByte_); - break; - case 'n': - labelValue.append('\n'); - break; - default: - Y_PARSER_FAIL("invalid escape sequence '" << CurrentByte_ << '\''); - } - break; - - default: - labelValue.append(CurrentByte_); - break; - } - - ReadNextByte(); - } - - Y_PARSER_FAIL("trying to parse too long label value, size >= " << MAX_LABEL_VALUE_LEN); - } - - TStringBuf TokenFromPos(size_t begin) { - Y_VERIFY_DEBUG(CurrentPos_ > begin); - size_t len = CurrentPos_ - begin - 1; - if (len == 0) { - return {}; - } - - return Data_.SubString(begin, len); - } - - void ConsumeLabels(TStringBuf name, const TLabelsMap& labels) { + ReadNextByteUnsafe(); + } + return TokenFromPos(begin); + } + + TStringBuf ReadTokenAsMetricName() { + if (!NPrometheus::IsValidMetricNameStart(CurrentByte_)) { + return ""; + } + + Y_VERIFY_DEBUG(CurrentPos_ > 0); + size_t begin = CurrentPos_ - 1; // read first byte again + while (HasRemaining()) { + ReadNextByteUnsafe(); + if (!NPrometheus::IsValidMetricNameContinuation(CurrentByte_)) { + break; + } + } + return TokenFromPos(begin); + } + + TStringBuf ReadTokenAsLabelName() { + if (!NPrometheus::IsValidLabelNameStart(CurrentByte_)) { + return ""; + } + + Y_VERIFY_DEBUG(CurrentPos_ > 0); + size_t begin = CurrentPos_ - 1; // read first byte again + while (HasRemaining()) { + ReadNextByteUnsafe(); + if (!NPrometheus::IsValidLabelNameContinuation(CurrentByte_)) { + break; + } + } + return TokenFromPos(begin); + } + + TString ReadTokenAsLabelValue() { + TString labelValue; + + SkipExpectedChar('"'); + for (ui32 i = 0; i < MAX_LABEL_VALUE_LEN; i++) { + switch (CurrentByte_) { + case '"': + SkipExpectedChar('"'); + return labelValue; + + case '\n': + Y_PARSER_FAIL("label value contains unescaped new-line"); + + case '\\': + ReadNextByte(); + switch (CurrentByte_) { + case '"': + case '\\': + labelValue.append(CurrentByte_); + break; + case 'n': + labelValue.append('\n'); + break; + default: + Y_PARSER_FAIL("invalid escape sequence '" << CurrentByte_ << '\''); + } + break; + + default: + labelValue.append(CurrentByte_); + break; + } + + ReadNextByte(); + } + + Y_PARSER_FAIL("trying to parse too long label value, size >= " << MAX_LABEL_VALUE_LEN); + } + + TStringBuf TokenFromPos(size_t begin) { + Y_VERIFY_DEBUG(CurrentPos_ > begin); + size_t len = CurrentPos_ - begin - 1; + if (len == 0) { + return {}; + } + + return Data_.SubString(begin, len); + } + + void ConsumeLabels(TStringBuf name, const TLabelsMap& labels) { Y_PARSER_ENSURE(labels.count(MetricNameLabel_) == 0, "label name '" << MetricNameLabel_ << "' is reserved, but is used with metric: " << name << LabelsToStr(labels)); - - Consumer_->OnLabelsBegin(); + + Consumer_->OnLabelsBegin(); Consumer_->OnLabel(MetricNameLabel_, TString(name)); // TODO: remove this string allocation - for (const auto& it: labels) { - Consumer_->OnLabel(it.first, it.second); - } - Consumer_->OnLabelsEnd(); - } - - void ConsumeCounter(TStringBuf name, const TLabelsMap& labels, TInstant time, double value) { + for (const auto& it: labels) { + Consumer_->OnLabel(it.first, it.second); + } + Consumer_->OnLabelsEnd(); + } + + void ConsumeCounter(TStringBuf name, const TLabelsMap& labels, TInstant time, double value) { i64 intValue{0}; // not nan if (value == value) { Y_PARSER_ENSURE(TryStaticCast(value, intValue), "value " << value << " is out of range"); } - - // see https://st.yandex-team.ru/SOLOMON-4142 for more details - // why we convert Prometheus COUNTER into Solomon RATE - // TODO: need to fix after server-side aggregation become correct for COUNTERs - Consumer_->OnMetricBegin(EMetricType::RATE); - ConsumeLabels(name, labels); - Consumer_->OnUint64(time, intValue); - Consumer_->OnMetricEnd(); - } - - void ConsumeGauge(TStringBuf name, const TLabelsMap& labels, TInstant time, double value) { - Consumer_->OnMetricBegin(EMetricType::GAUGE); - ConsumeLabels(name, labels); - Consumer_->OnDouble(time, value); - Consumer_->OnMetricEnd(); - } - - void ConsumeHistogram() { - Consumer_->OnMetricBegin(EMetricType::HIST_RATE); - ConsumeLabels(HistogramBuilder_.GetName(), HistogramBuilder_.GetLabels()); - auto time = HistogramBuilder_.GetTime(); - auto hist = HistogramBuilder_.ToSnapshot(); - Consumer_->OnHistogram(time, std::move(hist)); - Consumer_->OnMetricEnd(); - } - - double ParseGoDouble(TStringBuf str) { + + // see https://st.yandex-team.ru/SOLOMON-4142 for more details + // why we convert Prometheus COUNTER into Solomon RATE + // TODO: need to fix after server-side aggregation become correct for COUNTERs + Consumer_->OnMetricBegin(EMetricType::RATE); + ConsumeLabels(name, labels); + Consumer_->OnUint64(time, intValue); + Consumer_->OnMetricEnd(); + } + + void ConsumeGauge(TStringBuf name, const TLabelsMap& labels, TInstant time, double value) { + Consumer_->OnMetricBegin(EMetricType::GAUGE); + ConsumeLabels(name, labels); + Consumer_->OnDouble(time, value); + Consumer_->OnMetricEnd(); + } + + void ConsumeHistogram() { + Consumer_->OnMetricBegin(EMetricType::HIST_RATE); + ConsumeLabels(HistogramBuilder_.GetName(), HistogramBuilder_.GetLabels()); + auto time = HistogramBuilder_.GetTime(); + auto hist = HistogramBuilder_.ToSnapshot(); + Consumer_->OnHistogram(time, std::move(hist)); + Consumer_->OnMetricEnd(); + } + + double ParseGoDouble(TStringBuf str) { if (str == TStringBuf("+Inf")) { - return std::numeric_limits<double>::infinity(); + return std::numeric_limits<double>::infinity(); } else if (str == TStringBuf("-Inf")) { - return -std::numeric_limits<double>::infinity(); + return -std::numeric_limits<double>::infinity(); } else if (str == TStringBuf("NaN")) { - return NAN; - } - - double r = 0.0; - if (TryFromString(str, r)) { - return r; - } - Y_PARSER_FAIL("cannot parse double value from '" << str << "\' at line #" << CurrentLine_); - } - - private: - TStringBuf Data_; - IMetricConsumer* Consumer_; + return NAN; + } + + double r = 0.0; + if (TryFromString(str, r)) { + return r; + } + Y_PARSER_FAIL("cannot parse double value from '" << str << "\' at line #" << CurrentLine_); + } + + private: + TStringBuf Data_; + IMetricConsumer* Consumer_; TStringBuf MetricNameLabel_; - THashMap<TString, EPrometheusMetricType> SeenTypes_; - THistogramBuilder HistogramBuilder_; - - ui32 CurrentLine_ = 1; - ui32 CurrentPos_ = 0; - char CurrentByte_ = 0; - }; - } // namespace - + THashMap<TString, EPrometheusMetricType> SeenTypes_; + THistogramBuilder HistogramBuilder_; + + ui32 CurrentLine_ = 1; + ui32 CurrentPos_ = 0; + char CurrentByte_ = 0; + }; + } // namespace + void DecodePrometheus(TStringBuf data, IMetricConsumer* c, TStringBuf metricNameLabel) { TPrometheusReader reader(data, c, metricNameLabel); - reader.Read(); -} - -} // namespace NMonitoring + reader.Read(); +} + +} // namespace NMonitoring diff --git a/library/cpp/monlib/encode/prometheus/prometheus_decoder_ut.cpp b/library/cpp/monlib/encode/prometheus/prometheus_decoder_ut.cpp index 580b9c6617..49c2244fb4 100644 --- a/library/cpp/monlib/encode/prometheus/prometheus_decoder_ut.cpp +++ b/library/cpp/monlib/encode/prometheus/prometheus_decoder_ut.cpp @@ -1,478 +1,478 @@ -#include "prometheus.h" - -#include <library/cpp/monlib/encode/protobuf/protobuf.h> - +#include "prometheus.h" + +#include <library/cpp/monlib/encode/protobuf/protobuf.h> + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - -#define ASSERT_LABEL_EQUAL(label, name, value) do { \ - UNIT_ASSERT_STRINGS_EQUAL((label).GetName(), name); \ - UNIT_ASSERT_STRINGS_EQUAL((label).GetValue(), value); \ - } while (false) - -#define ASSERT_DOUBLE_POINT(s, time, value) do { \ - UNIT_ASSERT_VALUES_EQUAL((s).GetTime(), (time).MilliSeconds()); \ - UNIT_ASSERT_EQUAL((s).GetValueCase(), NProto::TSingleSample::kFloat64); \ - UNIT_ASSERT_DOUBLES_EQUAL((s).GetFloat64(), value, std::numeric_limits<double>::epsilon()); \ - } while (false) - -#define ASSERT_UINT_POINT(s, time, value) do { \ - UNIT_ASSERT_VALUES_EQUAL((s).GetTime(), (time).MilliSeconds()); \ - UNIT_ASSERT_EQUAL((s).GetValueCase(), NProto::TSingleSample::kUint64); \ - UNIT_ASSERT_VALUES_EQUAL((s).GetUint64(), value); \ - } while (false) - -#define ASSERT_HIST_POINT(s, time, expected) do { \ - UNIT_ASSERT_VALUES_EQUAL((s).GetTime(), time.MilliSeconds()); \ - UNIT_ASSERT_EQUAL((s).GetValueCase(), NProto::TSingleSample::kHistogram);\ - UNIT_ASSERT_VALUES_EQUAL((s).GetHistogram().BoundsSize(), (expected).Count()); \ - UNIT_ASSERT_VALUES_EQUAL((s).GetHistogram().ValuesSize(), (expected).Count()); \ - for (size_t i = 0; i < (s).GetHistogram().BoundsSize(); i++) { \ - UNIT_ASSERT_DOUBLES_EQUAL((s).GetHistogram().GetBounds(i), (expected).UpperBound(i), Min<double>()); \ - UNIT_ASSERT_VALUES_EQUAL((s).GetHistogram().GetValues(i), (expected).Value(i)); \ - } \ - } while (false) - -Y_UNIT_TEST_SUITE(TPrometheusDecoderTest) { - - NProto::TSingleSamplesList Decode(TStringBuf data) { - NProto::TSingleSamplesList samples; - { - IMetricEncoderPtr e = EncoderProtobuf(&samples); - DecodePrometheus(data, e.Get()); - } - return samples; - } - - Y_UNIT_TEST(Empty) { - { - auto samples = Decode(""); - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0); - } - { - auto samples = Decode("\n"); - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0); - } - { - auto samples = Decode("\n \n \n"); - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0); - } - { - auto samples = Decode("\t\n\t\n"); - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0); - } - } - - Y_UNIT_TEST(Minimal) { - auto samples = Decode( - "minimal_metric 1.234\n" - "another_metric -3e3 103948\n" - "# Even that:\n" - "no_labels{} 3\n" - "# HELP line for non-existing metric will be ignored.\n"); - - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3); - { - auto& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(1, s.LabelsSize()); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "minimal_metric"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 1.234); - } - { - auto& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "another_metric"); - ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(103948), -3000.0); - } - { - auto& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(1, s.LabelsSize()); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "no_labels"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 3.0); - } - } - - Y_UNIT_TEST(Counter) { - auto samples = Decode( - "# A normal comment.\n" - "#\n" - "# TYPE name counter\n" - "name{labelname=\"val1\",basename=\"basevalue\"} NaN\n" - "name {labelname=\"val2\",basename=\"basevalue\"} 2.3 1234567890\n" - "# HELP name two-line\\n doc str\\\\ing\n"); - - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 2); - - { - auto& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue"); - ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val1"); - ASSERT_UINT_POINT(s, TInstant::Zero(), ui64(0)); - } - { - auto& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue"); - ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val2"); - ASSERT_UINT_POINT(s, TInstant::MilliSeconds(1234567890), i64(2)); - } - } - - Y_UNIT_TEST(Gauge) { - auto samples = Decode( - "# A normal comment.\n" - "#\n" - " # HELP name2 \tdoc str\"ing 2\n" - " # TYPE name2 gauge\n" - "name2{labelname=\"val2\"\t,basename = \"basevalue2\"\t\t} +Inf 54321\n" - "name2{ labelname = \"val1\" , }-Inf\n"); - - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 2); - - { - auto& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name2"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue2"); - ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val2"); - ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(54321), INFINITY); - } - { - auto& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name2"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "labelname", "val1"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), -INFINITY); - } - } - - Y_UNIT_TEST(Summary) { - auto samples = Decode( - "# HELP \n" - "# TYPE my_summary summary\n" - "my_summary{n1=\"val1\",quantile=\"0.5\"} 110\n" - "my_summary{n1=\"val1\",quantile=\"0.9\"} 140 1\n" - "my_summary_count{n1=\"val1\"} 42\n" - "my_summary_sum{n1=\"val1\"} 08 15\n" - "# some\n" - "# funny comments\n" - "# HELP\n" - "# HELP my_summary\n" - "# HELP my_summary \n"); - - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 4); - - { - auto& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.5"); - ASSERT_LABEL_EQUAL(s.GetLabels(2), "n1", "val1"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 110.0); - } - { - auto& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.9"); - ASSERT_LABEL_EQUAL(s.GetLabels(2), "n1", "val1"); - ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(1), 140.0); - } - { - auto& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary_count"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "n1", "val1"); - ASSERT_UINT_POINT(s, TInstant::Zero(), 42); - } - { - auto& s = samples.GetSamples(3); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary_sum"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "n1", "val1"); - ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(15), 8.0); - } - } - - Y_UNIT_TEST(Histogram) { - auto samples = Decode( - "# HELP request_duration_microseconds The response latency.\n" - "# TYPE request_duration_microseconds histogram\n" - "request_duration_microseconds_bucket{le=\"0\"} 0\n" - "request_duration_microseconds_bucket{le=\"100\"} 123\n" - "request_duration_microseconds_bucket{le=\"120\"} 412\n" - "request_duration_microseconds_bucket{le=\"144\"} 592\n" - "request_duration_microseconds_bucket{le=\"172.8\"} 1524\n" - "request_duration_microseconds_bucket{le=\"+Inf\"} 2693\n" - "request_duration_microseconds_sum 1.7560473e+06\n" - "request_duration_microseconds_count 2693\n"); - - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3); - - { - auto& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds_sum"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 1756047.3); - } - { - auto& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds_count"); - ASSERT_UINT_POINT(s, TInstant::Zero(), 2693); - } - { - auto& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds"); - auto hist = ExplicitHistogramSnapshot( - { 0, 100, 120, 144, 172.8, HISTOGRAM_INF_BOUND }, - { 0, 123, 289, 180, 932, 1169 }); - ASSERT_HIST_POINT(s, TInstant::Zero(), *hist); - } - } - - Y_UNIT_TEST(HistogramWithLabels) { - auto samples = Decode( - "# A histogram, which has a pretty complex representation in the text format:\n" - "# HELP http_request_duration_seconds A histogram of the request duration.\n" - "# TYPE http_request_duration_seconds histogram\n" - "http_request_duration_seconds_bucket{le=\"0.05\", method=\"POST\"} 24054\n" - "http_request_duration_seconds_bucket{method=\"POST\", le=\"0.1\"} 33444\n" - "http_request_duration_seconds_bucket{le=\"0.2\", method=\"POST\", } 100392\n" - "http_request_duration_seconds_bucket{le=\"0.5\",method=\"POST\",} 129389\n" - "http_request_duration_seconds_bucket{ method=\"POST\", le=\"1\", } 133988\n" - "http_request_duration_seconds_bucket{ le=\"+Inf\", method=\"POST\", } 144320\n" - "http_request_duration_seconds_sum{method=\"POST\"} 53423\n" - "http_request_duration_seconds_count{ method=\"POST\", } 144320\n"); - - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3); - - { - auto& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_request_duration_seconds_sum"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "POST"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 53423.0); - } - { - auto& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_request_duration_seconds_count"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "POST"); - ASSERT_UINT_POINT(s, TInstant::Zero(), 144320); - } - { - auto& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_request_duration_seconds"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "POST"); - auto hist = ExplicitHistogramSnapshot( - { 0.05, 0.1, 0.2, 0.5, 1, HISTOGRAM_INF_BOUND }, - { 24054, 9390, 66948, 28997, 4599, 10332 }); - ASSERT_HIST_POINT(s, TInstant::Zero(), *hist); - } - } - - Y_UNIT_TEST(MultipleHistograms) { - auto samples = Decode( - "# TYPE inboundBytesPerSec histogram\n" - "inboundBytesPerSec_bucket{client=\"mbus\", le=\"10.0\"} 1.0\n" - "inboundBytesPerSec_bucket{client=\"mbus\", le=\"20.0\"} 5.0\n" - "inboundBytesPerSec_bucket{client=\"mbus\", le=\"+Inf\"} 5.0\n" - "inboundBytesPerSec_count{client=\"mbus\"} 5.0\n" - "inboundBytesPerSec_bucket{client=\"grpc\", le=\"10.0\"} 1.0\n" - "inboundBytesPerSec_bucket{client=\"grpc\", le=\"20.0\"} 5.0\n" - "inboundBytesPerSec_bucket{client=\"grpc\", le=\"30.0\"} 5.0\n" - "inboundBytesPerSec_count{client=\"grpc\"} 5.0\n" - "# TYPE outboundBytesPerSec histogram\n" - "outboundBytesPerSec_bucket{client=\"grpc\", le=\"100.0\"} 1.0 1512216000000\n" - "outboundBytesPerSec_bucket{client=\"grpc\", le=\"200.0\"} 1.0 1512216000000\n" - "outboundBytesPerSec_bucket{client=\"grpc\", le=\"+Inf\"} 1.0 1512216000000\n" - "outboundBytesPerSec_count{client=\"grpc\"} 1.0 1512216000000\n"); - - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 6); - - { - auto& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec_count"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "mbus"); - ASSERT_UINT_POINT(s, TInstant::Zero(), 5); - } - { - auto& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "mbus"); - auto hist = ExplicitHistogramSnapshot( - { 10, 20, HISTOGRAM_INF_BOUND }, - { 1, 4, 0 }); - ASSERT_HIST_POINT(s, TInstant::Zero(), *hist); - } - { - auto& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec_count"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc"); - ASSERT_UINT_POINT(s, TInstant::Zero(), 5); - } - { - auto& s = samples.GetSamples(3); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc"); - auto hist = ExplicitHistogramSnapshot( - { 10, 20, 30 }, - { 1, 4, 0 }); - ASSERT_HIST_POINT(s, TInstant::Zero(), *hist); - } - { - auto& s = samples.GetSamples(4); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "outboundBytesPerSec_count"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc"); - ASSERT_UINT_POINT(s, TInstant::Seconds(1512216000), 1) ; - } - { - auto& s = samples.GetSamples(5); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "outboundBytesPerSec"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc"); - auto hist = ExplicitHistogramSnapshot( - { 100, 200, HISTOGRAM_INF_BOUND }, - { 1, 0, 0 }); - ASSERT_HIST_POINT(s, TInstant::Seconds(1512216000), *hist); - } - } - - Y_UNIT_TEST(MixedTypes) { - auto samples = Decode( - "# HELP http_requests_total The total number of HTTP requests.\n" - "# TYPE http_requests_total counter\n" - "http_requests_total { } 1027 1395066363000\n" - "http_requests_total{method=\"post\",code=\"200\"} 1027 1395066363000\n" - "http_requests_total{method=\"post\",code=\"400\"} 3 1395066363000\n" - "\n" - "# Minimalistic line:\n" - "metric_without_timestamp_and_labels 12.47\n" - "\n" - "# HELP rpc_duration_seconds A summary of the RPC duration in seconds.\n" - "# TYPE rpc_duration_seconds summary\n" - "rpc_duration_seconds{quantile=\"0.01\"} 3102\n" - "rpc_duration_seconds{quantile=\"0.5\"} 4773\n" - "rpc_duration_seconds{quantile=\"0.9\"} 9001\n" - "rpc_duration_seconds_sum 1.7560473e+07\n" - "rpc_duration_seconds_count 2693\n" - "\n" - "# Another mMinimalistic line:\n" - "metric_with_timestamp 12.47 1234567890\n"); - - UNIT_ASSERT_EQUAL(samples.SamplesSize(), 10); - - { - auto& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_requests_total"); - ASSERT_UINT_POINT(s, TInstant::Seconds(1395066363), 1027); - } - { - auto& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_requests_total"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "post"); - ASSERT_LABEL_EQUAL(s.GetLabels(2), "code", "200"); - ASSERT_UINT_POINT(s, TInstant::Seconds(1395066363), 1027); - } - { - auto& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_requests_total"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "post"); - ASSERT_LABEL_EQUAL(s.GetLabels(2), "code", "400"); - ASSERT_UINT_POINT(s, TInstant::Seconds(1395066363), 3); - } - { - auto& s = samples.GetSamples(3); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "metric_without_timestamp_and_labels"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 12.47); - } - { - auto& s = samples.GetSamples(4); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.01"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 3102); - } - { - auto& s = samples.GetSamples(5); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.5"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 4773); - } - { - auto& s = samples.GetSamples(6); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds"); - ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.9"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 9001); - } - { - auto& s = samples.GetSamples(7); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds_sum"); - ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 17560473); - } - { - auto& s = samples.GetSamples(8); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds_count"); - ASSERT_UINT_POINT(s, TInstant::Zero(), 2693); - } - { - auto& s = samples.GetSamples(9); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); - UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); - ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "metric_with_timestamp"); - ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(1234567890), 12.47); - } - } -} + +using namespace NMonitoring; + +#define ASSERT_LABEL_EQUAL(label, name, value) do { \ + UNIT_ASSERT_STRINGS_EQUAL((label).GetName(), name); \ + UNIT_ASSERT_STRINGS_EQUAL((label).GetValue(), value); \ + } while (false) + +#define ASSERT_DOUBLE_POINT(s, time, value) do { \ + UNIT_ASSERT_VALUES_EQUAL((s).GetTime(), (time).MilliSeconds()); \ + UNIT_ASSERT_EQUAL((s).GetValueCase(), NProto::TSingleSample::kFloat64); \ + UNIT_ASSERT_DOUBLES_EQUAL((s).GetFloat64(), value, std::numeric_limits<double>::epsilon()); \ + } while (false) + +#define ASSERT_UINT_POINT(s, time, value) do { \ + UNIT_ASSERT_VALUES_EQUAL((s).GetTime(), (time).MilliSeconds()); \ + UNIT_ASSERT_EQUAL((s).GetValueCase(), NProto::TSingleSample::kUint64); \ + UNIT_ASSERT_VALUES_EQUAL((s).GetUint64(), value); \ + } while (false) + +#define ASSERT_HIST_POINT(s, time, expected) do { \ + UNIT_ASSERT_VALUES_EQUAL((s).GetTime(), time.MilliSeconds()); \ + UNIT_ASSERT_EQUAL((s).GetValueCase(), NProto::TSingleSample::kHistogram);\ + UNIT_ASSERT_VALUES_EQUAL((s).GetHistogram().BoundsSize(), (expected).Count()); \ + UNIT_ASSERT_VALUES_EQUAL((s).GetHistogram().ValuesSize(), (expected).Count()); \ + for (size_t i = 0; i < (s).GetHistogram().BoundsSize(); i++) { \ + UNIT_ASSERT_DOUBLES_EQUAL((s).GetHistogram().GetBounds(i), (expected).UpperBound(i), Min<double>()); \ + UNIT_ASSERT_VALUES_EQUAL((s).GetHistogram().GetValues(i), (expected).Value(i)); \ + } \ + } while (false) + +Y_UNIT_TEST_SUITE(TPrometheusDecoderTest) { + + NProto::TSingleSamplesList Decode(TStringBuf data) { + NProto::TSingleSamplesList samples; + { + IMetricEncoderPtr e = EncoderProtobuf(&samples); + DecodePrometheus(data, e.Get()); + } + return samples; + } + + Y_UNIT_TEST(Empty) { + { + auto samples = Decode(""); + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0); + } + { + auto samples = Decode("\n"); + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0); + } + { + auto samples = Decode("\n \n \n"); + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0); + } + { + auto samples = Decode("\t\n\t\n"); + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0); + } + } + + Y_UNIT_TEST(Minimal) { + auto samples = Decode( + "minimal_metric 1.234\n" + "another_metric -3e3 103948\n" + "# Even that:\n" + "no_labels{} 3\n" + "# HELP line for non-existing metric will be ignored.\n"); + + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3); + { + auto& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(1, s.LabelsSize()); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "minimal_metric"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 1.234); + } + { + auto& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "another_metric"); + ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(103948), -3000.0); + } + { + auto& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(1, s.LabelsSize()); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "no_labels"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 3.0); + } + } + + Y_UNIT_TEST(Counter) { + auto samples = Decode( + "# A normal comment.\n" + "#\n" + "# TYPE name counter\n" + "name{labelname=\"val1\",basename=\"basevalue\"} NaN\n" + "name {labelname=\"val2\",basename=\"basevalue\"} 2.3 1234567890\n" + "# HELP name two-line\\n doc str\\\\ing\n"); + + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 2); + + { + auto& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue"); + ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val1"); + ASSERT_UINT_POINT(s, TInstant::Zero(), ui64(0)); + } + { + auto& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue"); + ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val2"); + ASSERT_UINT_POINT(s, TInstant::MilliSeconds(1234567890), i64(2)); + } + } + + Y_UNIT_TEST(Gauge) { + auto samples = Decode( + "# A normal comment.\n" + "#\n" + " # HELP name2 \tdoc str\"ing 2\n" + " # TYPE name2 gauge\n" + "name2{labelname=\"val2\"\t,basename = \"basevalue2\"\t\t} +Inf 54321\n" + "name2{ labelname = \"val1\" , }-Inf\n"); + + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 2); + + { + auto& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name2"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue2"); + ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val2"); + ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(54321), INFINITY); + } + { + auto& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name2"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "labelname", "val1"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), -INFINITY); + } + } + + Y_UNIT_TEST(Summary) { + auto samples = Decode( + "# HELP \n" + "# TYPE my_summary summary\n" + "my_summary{n1=\"val1\",quantile=\"0.5\"} 110\n" + "my_summary{n1=\"val1\",quantile=\"0.9\"} 140 1\n" + "my_summary_count{n1=\"val1\"} 42\n" + "my_summary_sum{n1=\"val1\"} 08 15\n" + "# some\n" + "# funny comments\n" + "# HELP\n" + "# HELP my_summary\n" + "# HELP my_summary \n"); + + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 4); + + { + auto& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.5"); + ASSERT_LABEL_EQUAL(s.GetLabels(2), "n1", "val1"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 110.0); + } + { + auto& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.9"); + ASSERT_LABEL_EQUAL(s.GetLabels(2), "n1", "val1"); + ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(1), 140.0); + } + { + auto& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary_count"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "n1", "val1"); + ASSERT_UINT_POINT(s, TInstant::Zero(), 42); + } + { + auto& s = samples.GetSamples(3); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary_sum"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "n1", "val1"); + ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(15), 8.0); + } + } + + Y_UNIT_TEST(Histogram) { + auto samples = Decode( + "# HELP request_duration_microseconds The response latency.\n" + "# TYPE request_duration_microseconds histogram\n" + "request_duration_microseconds_bucket{le=\"0\"} 0\n" + "request_duration_microseconds_bucket{le=\"100\"} 123\n" + "request_duration_microseconds_bucket{le=\"120\"} 412\n" + "request_duration_microseconds_bucket{le=\"144\"} 592\n" + "request_duration_microseconds_bucket{le=\"172.8\"} 1524\n" + "request_duration_microseconds_bucket{le=\"+Inf\"} 2693\n" + "request_duration_microseconds_sum 1.7560473e+06\n" + "request_duration_microseconds_count 2693\n"); + + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3); + + { + auto& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds_sum"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 1756047.3); + } + { + auto& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds_count"); + ASSERT_UINT_POINT(s, TInstant::Zero(), 2693); + } + { + auto& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds"); + auto hist = ExplicitHistogramSnapshot( + { 0, 100, 120, 144, 172.8, HISTOGRAM_INF_BOUND }, + { 0, 123, 289, 180, 932, 1169 }); + ASSERT_HIST_POINT(s, TInstant::Zero(), *hist); + } + } + + Y_UNIT_TEST(HistogramWithLabels) { + auto samples = Decode( + "# A histogram, which has a pretty complex representation in the text format:\n" + "# HELP http_request_duration_seconds A histogram of the request duration.\n" + "# TYPE http_request_duration_seconds histogram\n" + "http_request_duration_seconds_bucket{le=\"0.05\", method=\"POST\"} 24054\n" + "http_request_duration_seconds_bucket{method=\"POST\", le=\"0.1\"} 33444\n" + "http_request_duration_seconds_bucket{le=\"0.2\", method=\"POST\", } 100392\n" + "http_request_duration_seconds_bucket{le=\"0.5\",method=\"POST\",} 129389\n" + "http_request_duration_seconds_bucket{ method=\"POST\", le=\"1\", } 133988\n" + "http_request_duration_seconds_bucket{ le=\"+Inf\", method=\"POST\", } 144320\n" + "http_request_duration_seconds_sum{method=\"POST\"} 53423\n" + "http_request_duration_seconds_count{ method=\"POST\", } 144320\n"); + + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3); + + { + auto& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_request_duration_seconds_sum"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "POST"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 53423.0); + } + { + auto& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_request_duration_seconds_count"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "POST"); + ASSERT_UINT_POINT(s, TInstant::Zero(), 144320); + } + { + auto& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_request_duration_seconds"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "POST"); + auto hist = ExplicitHistogramSnapshot( + { 0.05, 0.1, 0.2, 0.5, 1, HISTOGRAM_INF_BOUND }, + { 24054, 9390, 66948, 28997, 4599, 10332 }); + ASSERT_HIST_POINT(s, TInstant::Zero(), *hist); + } + } + + Y_UNIT_TEST(MultipleHistograms) { + auto samples = Decode( + "# TYPE inboundBytesPerSec histogram\n" + "inboundBytesPerSec_bucket{client=\"mbus\", le=\"10.0\"} 1.0\n" + "inboundBytesPerSec_bucket{client=\"mbus\", le=\"20.0\"} 5.0\n" + "inboundBytesPerSec_bucket{client=\"mbus\", le=\"+Inf\"} 5.0\n" + "inboundBytesPerSec_count{client=\"mbus\"} 5.0\n" + "inboundBytesPerSec_bucket{client=\"grpc\", le=\"10.0\"} 1.0\n" + "inboundBytesPerSec_bucket{client=\"grpc\", le=\"20.0\"} 5.0\n" + "inboundBytesPerSec_bucket{client=\"grpc\", le=\"30.0\"} 5.0\n" + "inboundBytesPerSec_count{client=\"grpc\"} 5.0\n" + "# TYPE outboundBytesPerSec histogram\n" + "outboundBytesPerSec_bucket{client=\"grpc\", le=\"100.0\"} 1.0 1512216000000\n" + "outboundBytesPerSec_bucket{client=\"grpc\", le=\"200.0\"} 1.0 1512216000000\n" + "outboundBytesPerSec_bucket{client=\"grpc\", le=\"+Inf\"} 1.0 1512216000000\n" + "outboundBytesPerSec_count{client=\"grpc\"} 1.0 1512216000000\n"); + + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 6); + + { + auto& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec_count"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "mbus"); + ASSERT_UINT_POINT(s, TInstant::Zero(), 5); + } + { + auto& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "mbus"); + auto hist = ExplicitHistogramSnapshot( + { 10, 20, HISTOGRAM_INF_BOUND }, + { 1, 4, 0 }); + ASSERT_HIST_POINT(s, TInstant::Zero(), *hist); + } + { + auto& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec_count"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc"); + ASSERT_UINT_POINT(s, TInstant::Zero(), 5); + } + { + auto& s = samples.GetSamples(3); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc"); + auto hist = ExplicitHistogramSnapshot( + { 10, 20, 30 }, + { 1, 4, 0 }); + ASSERT_HIST_POINT(s, TInstant::Zero(), *hist); + } + { + auto& s = samples.GetSamples(4); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "outboundBytesPerSec_count"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc"); + ASSERT_UINT_POINT(s, TInstant::Seconds(1512216000), 1) ; + } + { + auto& s = samples.GetSamples(5); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "outboundBytesPerSec"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc"); + auto hist = ExplicitHistogramSnapshot( + { 100, 200, HISTOGRAM_INF_BOUND }, + { 1, 0, 0 }); + ASSERT_HIST_POINT(s, TInstant::Seconds(1512216000), *hist); + } + } + + Y_UNIT_TEST(MixedTypes) { + auto samples = Decode( + "# HELP http_requests_total The total number of HTTP requests.\n" + "# TYPE http_requests_total counter\n" + "http_requests_total { } 1027 1395066363000\n" + "http_requests_total{method=\"post\",code=\"200\"} 1027 1395066363000\n" + "http_requests_total{method=\"post\",code=\"400\"} 3 1395066363000\n" + "\n" + "# Minimalistic line:\n" + "metric_without_timestamp_and_labels 12.47\n" + "\n" + "# HELP rpc_duration_seconds A summary of the RPC duration in seconds.\n" + "# TYPE rpc_duration_seconds summary\n" + "rpc_duration_seconds{quantile=\"0.01\"} 3102\n" + "rpc_duration_seconds{quantile=\"0.5\"} 4773\n" + "rpc_duration_seconds{quantile=\"0.9\"} 9001\n" + "rpc_duration_seconds_sum 1.7560473e+07\n" + "rpc_duration_seconds_count 2693\n" + "\n" + "# Another mMinimalistic line:\n" + "metric_with_timestamp 12.47 1234567890\n"); + + UNIT_ASSERT_EQUAL(samples.SamplesSize(), 10); + + { + auto& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_requests_total"); + ASSERT_UINT_POINT(s, TInstant::Seconds(1395066363), 1027); + } + { + auto& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_requests_total"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "post"); + ASSERT_LABEL_EQUAL(s.GetLabels(2), "code", "200"); + ASSERT_UINT_POINT(s, TInstant::Seconds(1395066363), 1027); + } + { + auto& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 3); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_requests_total"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "post"); + ASSERT_LABEL_EQUAL(s.GetLabels(2), "code", "400"); + ASSERT_UINT_POINT(s, TInstant::Seconds(1395066363), 3); + } + { + auto& s = samples.GetSamples(3); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "metric_without_timestamp_and_labels"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 12.47); + } + { + auto& s = samples.GetSamples(4); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.01"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 3102); + } + { + auto& s = samples.GetSamples(5); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.5"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 4773); + } + { + auto& s = samples.GetSamples(6); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 2); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds"); + ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.9"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 9001); + } + { + auto& s = samples.GetSamples(7); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds_sum"); + ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 17560473); + } + { + auto& s = samples.GetSamples(8); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds_count"); + ASSERT_UINT_POINT(s, TInstant::Zero(), 2693); + } + { + auto& s = samples.GetSamples(9); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE); + UNIT_ASSERT_EQUAL(s.LabelsSize(), 1); + ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "metric_with_timestamp"); + ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(1234567890), 12.47); + } + } +} diff --git a/library/cpp/monlib/encode/prometheus/prometheus_encoder.cpp b/library/cpp/monlib/encode/prometheus/prometheus_encoder.cpp index 3baf90fa2e..15efeb8c03 100644 --- a/library/cpp/monlib/encode/prometheus/prometheus_encoder.cpp +++ b/library/cpp/monlib/encode/prometheus/prometheus_encoder.cpp @@ -1,95 +1,95 @@ -#include "prometheus.h" -#include "prometheus_model.h" - -#include <library/cpp/monlib/encode/encoder_state.h> -#include <library/cpp/monlib/metrics/labels.h> -#include <library/cpp/monlib/metrics/metric_value.h> - -#include <util/string/cast.h> -#include <util/generic/hash_set.h> - - -namespace NMonitoring { - namespace { - /////////////////////////////////////////////////////////////////////// - // TPrometheusWriter - /////////////////////////////////////////////////////////////////////// - class TPrometheusWriter { - public: - explicit TPrometheusWriter(IOutputStream* out) - : Out_(out) - { - } - - void WriteType(EMetricType type, const TString& name) { - auto r = WrittenTypes_.insert(name); - if (!r.second) { - // type for this metric was already written - return; - } - - Out_->Write("# TYPE "); - WriteMetricName(name); - Out_->Write(' '); - - switch (type) { - case EMetricType::GAUGE: - case EMetricType::IGAUGE: - Out_->Write("gauge"); - break; - case EMetricType::RATE: - case EMetricType::COUNTER: - Out_->Write("counter"); - break; - case EMetricType::HIST: - case EMetricType::HIST_RATE: - Out_->Write("histogram"); - break; +#include "prometheus.h" +#include "prometheus_model.h" + +#include <library/cpp/monlib/encode/encoder_state.h> +#include <library/cpp/monlib/metrics/labels.h> +#include <library/cpp/monlib/metrics/metric_value.h> + +#include <util/string/cast.h> +#include <util/generic/hash_set.h> + + +namespace NMonitoring { + namespace { + /////////////////////////////////////////////////////////////////////// + // TPrometheusWriter + /////////////////////////////////////////////////////////////////////// + class TPrometheusWriter { + public: + explicit TPrometheusWriter(IOutputStream* out) + : Out_(out) + { + } + + void WriteType(EMetricType type, const TString& name) { + auto r = WrittenTypes_.insert(name); + if (!r.second) { + // type for this metric was already written + return; + } + + Out_->Write("# TYPE "); + WriteMetricName(name); + Out_->Write(' '); + + switch (type) { + case EMetricType::GAUGE: + case EMetricType::IGAUGE: + Out_->Write("gauge"); + break; + case EMetricType::RATE: + case EMetricType::COUNTER: + Out_->Write("counter"); + break; + case EMetricType::HIST: + case EMetricType::HIST_RATE: + Out_->Write("histogram"); + break; case EMetricType::LOGHIST: // TODO(@kbalakirev): implement this case break; - case EMetricType::DSUMMARY: + case EMetricType::DSUMMARY: ythrow yexception() << "writing summary type is forbiden"; - case EMetricType::UNKNOWN: - ythrow yexception() << "unknown metric type: " << MetricTypeToStr(type) - << ", name: " << name; - } - Out_->Write('\n'); - } - - void WriteDouble(TStringBuf name, const TLabels& labels, TInstant time, double value) { - WriteValue(name, "", labels, "", "", time, value); - } - - void WriteHistogram(TStringBuf name, const TLabels& labels, TInstant time, IHistogramSnapshot* h) { - Y_ENSURE(!labels.Has(NPrometheus::BUCKET_LABEL), - "histogram metric " << name << " has label '" << - NPrometheus::BUCKET_LABEL << "' which is reserved in Prometheus"); - - double totalCount = 0; - for (ui32 i = 0, count = h->Count(); i < count; i++) { - TBucketBound bound = h->UpperBound(i); - TStringBuf boundStr; - if (bound == HISTOGRAM_INF_BOUND) { + case EMetricType::UNKNOWN: + ythrow yexception() << "unknown metric type: " << MetricTypeToStr(type) + << ", name: " << name; + } + Out_->Write('\n'); + } + + void WriteDouble(TStringBuf name, const TLabels& labels, TInstant time, double value) { + WriteValue(name, "", labels, "", "", time, value); + } + + void WriteHistogram(TStringBuf name, const TLabels& labels, TInstant time, IHistogramSnapshot* h) { + Y_ENSURE(!labels.Has(NPrometheus::BUCKET_LABEL), + "histogram metric " << name << " has label '" << + NPrometheus::BUCKET_LABEL << "' which is reserved in Prometheus"); + + double totalCount = 0; + for (ui32 i = 0, count = h->Count(); i < count; i++) { + TBucketBound bound = h->UpperBound(i); + TStringBuf boundStr; + if (bound == HISTOGRAM_INF_BOUND) { boundStr = TStringBuf("+Inf"); - } else { - size_t len = FloatToString(bound, TmpBuf_, Y_ARRAY_SIZE(TmpBuf_)); - boundStr = TStringBuf(TmpBuf_, len); - } - - TBucketValue value = h->Value(i); - totalCount += static_cast<double>(value); - - WriteValue( - name, NPrometheus::BUCKET_SUFFIX, - labels, NPrometheus::BUCKET_LABEL, boundStr, - time, - totalCount); - } - - WriteValue(name, NPrometheus::COUNT_SUFFIX, labels, "", "", time, totalCount); - } - + } else { + size_t len = FloatToString(bound, TmpBuf_, Y_ARRAY_SIZE(TmpBuf_)); + boundStr = TStringBuf(TmpBuf_, len); + } + + TBucketValue value = h->Value(i); + totalCount += static_cast<double>(value); + + WriteValue( + name, NPrometheus::BUCKET_SUFFIX, + labels, NPrometheus::BUCKET_LABEL, boundStr, + time, + totalCount); + } + + WriteValue(name, NPrometheus::COUNT_SUFFIX, labels, "", "", time, totalCount); + } + void WriteSummaryDouble(TStringBuf name, const TLabels& labels, TInstant time, ISummaryDoubleSnapshot* s) { WriteValue(name, NPrometheus::SUM_SUFFIX, labels, "", "", time, s->GetSum()); WriteValue(name, NPrometheus::MIN_SUFFIX, labels, "", "", time, s->GetMin()); @@ -98,316 +98,316 @@ namespace NMonitoring { WriteValue(name, NPrometheus::COUNT_SUFFIX, labels, "", "", time, s->GetCount()); } - void WriteLn() { - Out_->Write('\n'); - } - - private: - // will replace invalid chars with '_' - void WriteMetricName(TStringBuf name) { - Y_ENSURE(!name.Empty(), "trying to write metric with empty name"); - - char ch = name[0]; - if (NPrometheus::IsValidMetricNameStart(ch)) { - Out_->Write(ch); - } else { - Out_->Write('_'); - } - - for (size_t i = 1, len = name.length(); i < len; i++) { - ch = name[i]; - if (NPrometheus::IsValidMetricNameContinuation(ch)) { - Out_->Write(ch); - } else { - Out_->Write('_'); - } - } - } - - void WriteLabels(const TLabels& labels, TStringBuf addLabelKey, TStringBuf addLabelValue) { - Out_->Write('{'); + void WriteLn() { + Out_->Write('\n'); + } + + private: + // will replace invalid chars with '_' + void WriteMetricName(TStringBuf name) { + Y_ENSURE(!name.Empty(), "trying to write metric with empty name"); + + char ch = name[0]; + if (NPrometheus::IsValidMetricNameStart(ch)) { + Out_->Write(ch); + } else { + Out_->Write('_'); + } + + for (size_t i = 1, len = name.length(); i < len; i++) { + ch = name[i]; + if (NPrometheus::IsValidMetricNameContinuation(ch)) { + Out_->Write(ch); + } else { + Out_->Write('_'); + } + } + } + + void WriteLabels(const TLabels& labels, TStringBuf addLabelKey, TStringBuf addLabelValue) { + Out_->Write('{'); for (auto&& l: labels) { - Out_->Write(l.Name()); - Out_->Write('='); - WriteLabelValue(l.Value()); - Out_->Write(", "); // trailign comma is supported in parsers - } - if (!addLabelKey.Empty() && !addLabelValue.Empty()) { - Out_->Write(addLabelKey); - Out_->Write('='); - WriteLabelValue(addLabelValue); - } - Out_->Write('}'); - } - - void WriteLabelValue(TStringBuf value) { - Out_->Write('"'); - for (char ch: value) { - if (ch == '"') { - Out_->Write("\\\""); - } else if (ch == '\\') { - Out_->Write("\\\\"); - } else if (ch == '\n') { - Out_->Write("\\n"); - } else { - Out_->Write(ch); - } - } - Out_->Write('"'); - } - - void WriteValue( - TStringBuf name, TStringBuf suffix, - const TLabels& labels, TStringBuf addLabelKey, TStringBuf addLabelValue, - TInstant time, double value) - { - // (1) name - WriteMetricName(name); - if (!suffix.Empty()) { - Out_->Write(suffix); - } - - // (2) labels - if (!labels.Empty() || !addLabelKey.Empty()) { - WriteLabels(labels, addLabelKey, addLabelValue); - } - Out_->Write(' '); - - // (3) value - { - size_t len = FloatToString(value, TmpBuf_, Y_ARRAY_SIZE(TmpBuf_)); - Out_->Write(TmpBuf_, len); - } - - // (4) time - if (ui64 timeMillis = time.MilliSeconds()) { - Out_->Write(' '); - size_t len = IntToString<10>(timeMillis, TmpBuf_, Y_ARRAY_SIZE(TmpBuf_)); - Out_->Write(TmpBuf_, len); - } - Out_->Write('\n'); - } - - private: - IOutputStream* Out_; - THashSet<TString> WrittenTypes_; - char TmpBuf_[512]; // used to convert doubles to strings - }; - - /////////////////////////////////////////////////////////////////////// - // TMetricState - /////////////////////////////////////////////////////////////////////// - struct TMetricState { - EMetricType Type = EMetricType::UNKNOWN; - TLabels Labels; - TInstant Time = TInstant::Zero(); - EMetricValueType ValueType = EMetricValueType::UNKNOWN; - TMetricValue Value; - - ~TMetricState() { - ClearValue(); - } - - void Clear() { - Type = EMetricType::UNKNOWN; - Labels.Clear(); - Time = TInstant::Zero(); - ClearValue(); - } - - void ClearValue() { - // TMetricValue does not keep ownership of histogram - if (ValueType == EMetricValueType::HISTOGRAM) { - Value.AsHistogram()->UnRef(); - } else if (ValueType == EMetricValueType::SUMMARY) { + Out_->Write(l.Name()); + Out_->Write('='); + WriteLabelValue(l.Value()); + Out_->Write(", "); // trailign comma is supported in parsers + } + if (!addLabelKey.Empty() && !addLabelValue.Empty()) { + Out_->Write(addLabelKey); + Out_->Write('='); + WriteLabelValue(addLabelValue); + } + Out_->Write('}'); + } + + void WriteLabelValue(TStringBuf value) { + Out_->Write('"'); + for (char ch: value) { + if (ch == '"') { + Out_->Write("\\\""); + } else if (ch == '\\') { + Out_->Write("\\\\"); + } else if (ch == '\n') { + Out_->Write("\\n"); + } else { + Out_->Write(ch); + } + } + Out_->Write('"'); + } + + void WriteValue( + TStringBuf name, TStringBuf suffix, + const TLabels& labels, TStringBuf addLabelKey, TStringBuf addLabelValue, + TInstant time, double value) + { + // (1) name + WriteMetricName(name); + if (!suffix.Empty()) { + Out_->Write(suffix); + } + + // (2) labels + if (!labels.Empty() || !addLabelKey.Empty()) { + WriteLabels(labels, addLabelKey, addLabelValue); + } + Out_->Write(' '); + + // (3) value + { + size_t len = FloatToString(value, TmpBuf_, Y_ARRAY_SIZE(TmpBuf_)); + Out_->Write(TmpBuf_, len); + } + + // (4) time + if (ui64 timeMillis = time.MilliSeconds()) { + Out_->Write(' '); + size_t len = IntToString<10>(timeMillis, TmpBuf_, Y_ARRAY_SIZE(TmpBuf_)); + Out_->Write(TmpBuf_, len); + } + Out_->Write('\n'); + } + + private: + IOutputStream* Out_; + THashSet<TString> WrittenTypes_; + char TmpBuf_[512]; // used to convert doubles to strings + }; + + /////////////////////////////////////////////////////////////////////// + // TMetricState + /////////////////////////////////////////////////////////////////////// + struct TMetricState { + EMetricType Type = EMetricType::UNKNOWN; + TLabels Labels; + TInstant Time = TInstant::Zero(); + EMetricValueType ValueType = EMetricValueType::UNKNOWN; + TMetricValue Value; + + ~TMetricState() { + ClearValue(); + } + + void Clear() { + Type = EMetricType::UNKNOWN; + Labels.Clear(); + Time = TInstant::Zero(); + ClearValue(); + } + + void ClearValue() { + // TMetricValue does not keep ownership of histogram + if (ValueType == EMetricValueType::HISTOGRAM) { + Value.AsHistogram()->UnRef(); + } else if (ValueType == EMetricValueType::SUMMARY) { Value.AsSummaryDouble()->UnRef(); - } - ValueType = EMetricValueType::UNKNOWN; - Value = {}; - } - - template <typename T> - void SetValue(T value) { - // TMetricValue does not keep ownership of histogram - if (ValueType == EMetricValueType::HISTOGRAM) { - Value.AsHistogram()->UnRef(); - } else if (ValueType == EMetricValueType::SUMMARY) { + } + ValueType = EMetricValueType::UNKNOWN; + Value = {}; + } + + template <typename T> + void SetValue(T value) { + // TMetricValue does not keep ownership of histogram + if (ValueType == EMetricValueType::HISTOGRAM) { + Value.AsHistogram()->UnRef(); + } else if (ValueType == EMetricValueType::SUMMARY) { Value.AsSummaryDouble()->UnRef(); - } - ValueType = TValueType<T>::Type; - Value = TMetricValue(value); - if (ValueType == EMetricValueType::HISTOGRAM) { - Value.AsHistogram()->Ref(); - } else if (ValueType == EMetricValueType::SUMMARY) { + } + ValueType = TValueType<T>::Type; + Value = TMetricValue(value); + if (ValueType == EMetricValueType::HISTOGRAM) { + Value.AsHistogram()->Ref(); + } else if (ValueType == EMetricValueType::SUMMARY) { Value.AsSummaryDouble()->Ref(); - } - } - }; - - /////////////////////////////////////////////////////////////////////// - // TPrometheusEncoder - /////////////////////////////////////////////////////////////////////// - class TPrometheusEncoder final: public IMetricEncoder { - public: + } + } + }; + + /////////////////////////////////////////////////////////////////////// + // TPrometheusEncoder + /////////////////////////////////////////////////////////////////////// + class TPrometheusEncoder final: public IMetricEncoder { + public: explicit TPrometheusEncoder(IOutputStream* out, TStringBuf metricNameLabel) - : Writer_(out) + : Writer_(out) , MetricNameLabel_(metricNameLabel) - { - } - - private: - void OnStreamBegin() override { + { + } + + private: + void OnStreamBegin() override { State_.Expect(TEncoderState::EState::ROOT); - } - - void OnStreamEnd() override { + } + + void OnStreamEnd() override { State_.Expect(TEncoderState::EState::ROOT); - Writer_.WriteLn(); - } - - void OnCommonTime(TInstant time) override { + Writer_.WriteLn(); + } + + void OnCommonTime(TInstant time) override { State_.Expect(TEncoderState::EState::ROOT); - CommonTime_ = time; - } - - void OnMetricBegin(EMetricType type) override { - State_.Switch(TEncoderState::EState::ROOT, TEncoderState::EState::METRIC); - MetricState_.Clear(); - MetricState_.Type = type; - } - - void OnMetricEnd() override { - State_.Switch(TEncoderState::EState::METRIC, TEncoderState::EState::ROOT); - WriteMetric(); - } - - void OnLabelsBegin() override { - if (State_ == TEncoderState::EState::METRIC) { - State_ = TEncoderState::EState::METRIC_LABELS; + CommonTime_ = time; + } + + void OnMetricBegin(EMetricType type) override { + State_.Switch(TEncoderState::EState::ROOT, TEncoderState::EState::METRIC); + MetricState_.Clear(); + MetricState_.Type = type; + } + + void OnMetricEnd() override { + State_.Switch(TEncoderState::EState::METRIC, TEncoderState::EState::ROOT); + WriteMetric(); + } + + void OnLabelsBegin() override { + if (State_ == TEncoderState::EState::METRIC) { + State_ = TEncoderState::EState::METRIC_LABELS; } else if (State_ == TEncoderState::EState::ROOT) { State_ = TEncoderState::EState::COMMON_LABELS; - } else { - State_.ThrowInvalid("expected METRIC or ROOT"); - } - } - - void OnLabelsEnd() override { - if (State_ == TEncoderState::EState::METRIC_LABELS) { - State_ = TEncoderState::EState::METRIC; + } else { + State_.ThrowInvalid("expected METRIC or ROOT"); + } + } + + void OnLabelsEnd() override { + if (State_ == TEncoderState::EState::METRIC_LABELS) { + State_ = TEncoderState::EState::METRIC; } else if (State_ == TEncoderState::EState::COMMON_LABELS) { State_ = TEncoderState::EState::ROOT; - } else { - State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); - } - } - - void OnLabel(TStringBuf name, TStringBuf value) override { - if (State_ == TEncoderState::EState::METRIC_LABELS) { - MetricState_.Labels.Add(name, value); + } else { + State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); + } + } + + void OnLabel(TStringBuf name, TStringBuf value) override { + if (State_ == TEncoderState::EState::METRIC_LABELS) { + MetricState_.Labels.Add(name, value); } else if (State_ == TEncoderState::EState::COMMON_LABELS) { - CommonLabels_.Add(name, value); - } else { - State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); - } - } - - void OnDouble(TInstant time, double value) override { - State_.Expect(TEncoderState::EState::METRIC); - MetricState_.Time = time; - MetricState_.SetValue(value); - } - - void OnInt64(TInstant time, i64 value) override { - State_.Expect(TEncoderState::EState::METRIC); - MetricState_.Time = time; - MetricState_.SetValue(value); - } - - void OnUint64(TInstant time, ui64 value) override { - State_.Expect(TEncoderState::EState::METRIC); - MetricState_.Time = time; - MetricState_.SetValue(value); - } - - void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { - State_.Expect(TEncoderState::EState::METRIC); - MetricState_.Time = time; - MetricState_.SetValue(snapshot.Get()); - } - + CommonLabels_.Add(name, value); + } else { + State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); + } + } + + void OnDouble(TInstant time, double value) override { + State_.Expect(TEncoderState::EState::METRIC); + MetricState_.Time = time; + MetricState_.SetValue(value); + } + + void OnInt64(TInstant time, i64 value) override { + State_.Expect(TEncoderState::EState::METRIC); + MetricState_.Time = time; + MetricState_.SetValue(value); + } + + void OnUint64(TInstant time, ui64 value) override { + State_.Expect(TEncoderState::EState::METRIC); + MetricState_.Time = time; + MetricState_.SetValue(value); + } + + void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { + State_.Expect(TEncoderState::EState::METRIC); + MetricState_.Time = time; + MetricState_.SetValue(snapshot.Get()); + } + void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override { - State_.Expect(TEncoderState::EState::METRIC); - MetricState_.Time = time; - MetricState_.SetValue(snapshot.Get()); + State_.Expect(TEncoderState::EState::METRIC); + MetricState_.Time = time; + MetricState_.SetValue(snapshot.Get()); } void OnLogHistogram(TInstant, TLogHistogramSnapshotPtr) override { // TODO(@kbalakirev): implement this function } - void Close() override { - } - - void WriteMetric() { - if (MetricState_.ValueType == EMetricValueType::UNKNOWN) { - return; - } - - // XXX: poor performace + void Close() override { + } + + void WriteMetric() { + if (MetricState_.ValueType == EMetricValueType::UNKNOWN) { + return; + } + + // XXX: poor performace for (auto&& l: CommonLabels_) { - MetricState_.Labels.Add(l.Name(), l.Value()); - } - + MetricState_.Labels.Add(l.Name(), l.Value()); + } + TMaybe<TLabel> nameLabel = MetricState_.Labels.Extract(MetricNameLabel_); - Y_ENSURE(nameLabel, - "labels " << MetricState_.Labels << + Y_ENSURE(nameLabel, + "labels " << MetricState_.Labels << " does not contain label '" << MetricNameLabel_ << '\''); - + const TString& metricName = ToString(nameLabel->Value()); - if (MetricState_.Type != EMetricType::DSUMMARY) { - Writer_.WriteType(MetricState_.Type, metricName); + if (MetricState_.Type != EMetricType::DSUMMARY) { + Writer_.WriteType(MetricState_.Type, metricName); } - - if (MetricState_.Time == TInstant::Zero()) { - MetricState_.Time = CommonTime_; - } - - EMetricType type = MetricState_.Type; - if (type == EMetricType::HIST || type == EMetricType::HIST_RATE) { - Y_ENSURE(MetricState_.ValueType == EMetricValueType::HISTOGRAM, - "invalid value type for histogram: " << int(MetricState_.ValueType)); // TODO: to string conversion - Writer_.WriteHistogram( - metricName, - MetricState_.Labels, - MetricState_.Time, - MetricState_.Value.AsHistogram()); - } else if (type == EMetricType::DSUMMARY) { + + if (MetricState_.Time == TInstant::Zero()) { + MetricState_.Time = CommonTime_; + } + + EMetricType type = MetricState_.Type; + if (type == EMetricType::HIST || type == EMetricType::HIST_RATE) { + Y_ENSURE(MetricState_.ValueType == EMetricValueType::HISTOGRAM, + "invalid value type for histogram: " << int(MetricState_.ValueType)); // TODO: to string conversion + Writer_.WriteHistogram( + metricName, + MetricState_.Labels, + MetricState_.Time, + MetricState_.Value.AsHistogram()); + } else if (type == EMetricType::DSUMMARY) { Writer_.WriteSummaryDouble( metricName, - MetricState_.Labels, - MetricState_.Time, - MetricState_.Value.AsSummaryDouble()); - } else { - Writer_.WriteDouble( - metricName, - MetricState_.Labels, - MetricState_.Time, - MetricState_.Value.AsDouble(MetricState_.ValueType)); - } - } - - private: - TEncoderState State_; - TPrometheusWriter Writer_; + MetricState_.Labels, + MetricState_.Time, + MetricState_.Value.AsSummaryDouble()); + } else { + Writer_.WriteDouble( + metricName, + MetricState_.Labels, + MetricState_.Time, + MetricState_.Value.AsDouble(MetricState_.ValueType)); + } + } + + private: + TEncoderState State_; + TPrometheusWriter Writer_; TString MetricNameLabel_; - TInstant CommonTime_ = TInstant::Zero(); - TLabels CommonLabels_; - TMetricState MetricState_; - }; - } - + TInstant CommonTime_ = TInstant::Zero(); + TLabels CommonLabels_; + TMetricState MetricState_; + }; + } + IMetricEncoderPtr EncoderPrometheus(IOutputStream* out, TStringBuf metricNameLabel) { return MakeHolder<TPrometheusEncoder>(out, metricNameLabel); - } - -} // namespace NMonitoring + } + +} // namespace NMonitoring diff --git a/library/cpp/monlib/encode/prometheus/prometheus_encoder_ut.cpp b/library/cpp/monlib/encode/prometheus/prometheus_encoder_ut.cpp index 6820aa9ba6..fd9debb060 100644 --- a/library/cpp/monlib/encode/prometheus/prometheus_encoder_ut.cpp +++ b/library/cpp/monlib/encode/prometheus/prometheus_encoder_ut.cpp @@ -1,119 +1,119 @@ -#include "prometheus.h" - -#include <library/cpp/monlib/encode/protobuf/protobuf.h> -#include <library/cpp/monlib/metrics/metric_value.h> -#include <library/cpp/monlib/metrics/histogram_snapshot.h> - +#include "prometheus.h" + +#include <library/cpp/monlib/encode/protobuf/protobuf.h> +#include <library/cpp/monlib/metrics/metric_value.h> +#include <library/cpp/monlib/metrics/histogram_snapshot.h> + #include <library/cpp/testing/unittest/registar.h> - -#include <util/stream/str.h> - -using namespace NMonitoring; - -Y_UNIT_TEST_SUITE(TPrometheusEncoderTest) { - - template <typename TFunc> - TString EncodeToString(TFunc fn) { - TStringStream ss; - IMetricEncoderPtr encoder = EncoderPrometheus(&ss); - fn(encoder.Get()); - return ss.Str(); - } - + +#include <util/stream/str.h> + +using namespace NMonitoring; + +Y_UNIT_TEST_SUITE(TPrometheusEncoderTest) { + + template <typename TFunc> + TString EncodeToString(TFunc fn) { + TStringStream ss; + IMetricEncoderPtr encoder = EncoderPrometheus(&ss); + fn(encoder.Get()); + return ss.Str(); + } + ISummaryDoubleSnapshotPtr TestSummaryDouble() { return MakeIntrusive<TSummaryDoubleSnapshot>(10.1, -0.45, 0.478, 0.3, 30u); } - Y_UNIT_TEST(Empty) { - auto result = EncodeToString([](IMetricEncoder* e) { - e->OnStreamBegin(); - e->OnStreamEnd(); - }); - UNIT_ASSERT_STRINGS_EQUAL(result, "\n"); - } - - Y_UNIT_TEST(DoubleGauge) { - auto result = EncodeToString([](IMetricEncoder* e) { - e->OnStreamBegin(); - { // no values - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "cpuUsage"); - e->OnLabelsEnd(); - } - e->OnMetricEnd(); - } - { // one value no ts - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "diskUsage"); - e->OnLabel("disk", "sda1"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::Zero(), 1000); - e->OnMetricEnd(); - } - { // one value with ts - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "memoryUsage"); - e->OnLabel("host", "solomon-man-00"); - e->OnLabel("dc", "man"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); - e->OnMetricEnd(); - } - { // many values - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "bytesRx"); - e->OnLabel("host", "solomon-sas-01"); - e->OnLabel("dc", "sas"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); - e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); - e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); - e->OnMetricEnd(); - } - { // already seen metric name - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "diskUsage"); - e->OnLabel("disk", "sdb1"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::Zero(), 1001); - e->OnMetricEnd(); - } - { // NaN - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "nanValue"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::Zero(), NAN); - e->OnMetricEnd(); - } - { // Inf - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "infValue"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::Zero(), INFINITY); - e->OnMetricEnd(); - } + Y_UNIT_TEST(Empty) { + auto result = EncodeToString([](IMetricEncoder* e) { + e->OnStreamBegin(); + e->OnStreamEnd(); + }); + UNIT_ASSERT_STRINGS_EQUAL(result, "\n"); + } + + Y_UNIT_TEST(DoubleGauge) { + auto result = EncodeToString([](IMetricEncoder* e) { + e->OnStreamBegin(); + { // no values + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "cpuUsage"); + e->OnLabelsEnd(); + } + e->OnMetricEnd(); + } + { // one value no ts + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "diskUsage"); + e->OnLabel("disk", "sda1"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::Zero(), 1000); + e->OnMetricEnd(); + } + { // one value with ts + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "memoryUsage"); + e->OnLabel("host", "solomon-man-00"); + e->OnLabel("dc", "man"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); + e->OnMetricEnd(); + } + { // many values + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "bytesRx"); + e->OnLabel("host", "solomon-sas-01"); + e->OnLabel("dc", "sas"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); + e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); + e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); + e->OnMetricEnd(); + } + { // already seen metric name + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "diskUsage"); + e->OnLabel("disk", "sdb1"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::Zero(), 1001); + e->OnMetricEnd(); + } + { // NaN + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "nanValue"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::Zero(), NAN); + e->OnMetricEnd(); + } + { // Inf + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "infValue"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::Zero(), INFINITY); + e->OnMetricEnd(); + } { - e->OnMetricBegin(EMetricType::DSUMMARY); + e->OnMetricBegin(EMetricType::DSUMMARY); { e->OnLabelsBegin(); e->OnLabel("sensor", "seconds"); @@ -121,252 +121,252 @@ Y_UNIT_TEST_SUITE(TPrometheusEncoderTest) { e->OnLabelsEnd(); } e->OnSummaryDouble(TInstant::Zero(), TestSummaryDouble()); - e->OnMetricEnd(); + e->OnMetricEnd(); } - e->OnStreamEnd(); - }); - - UNIT_ASSERT_STRINGS_EQUAL(result, - "# TYPE diskUsage gauge\n" - "diskUsage{disk=\"sda1\", } 1000\n" - "# TYPE memoryUsage gauge\n" - "memoryUsage{host=\"solomon-man-00\", dc=\"man\", } 1000 1512216000000\n" - "# TYPE bytesRx gauge\n" - "bytesRx{host=\"solomon-sas-01\", dc=\"sas\", } 8 1512216010000\n" - "diskUsage{disk=\"sdb1\", } 1001\n" - "# TYPE nanValue gauge\n" - "nanValue nan\n" - "# TYPE infValue gauge\n" - "infValue inf\n" + e->OnStreamEnd(); + }); + + UNIT_ASSERT_STRINGS_EQUAL(result, + "# TYPE diskUsage gauge\n" + "diskUsage{disk=\"sda1\", } 1000\n" + "# TYPE memoryUsage gauge\n" + "memoryUsage{host=\"solomon-man-00\", dc=\"man\", } 1000 1512216000000\n" + "# TYPE bytesRx gauge\n" + "bytesRx{host=\"solomon-sas-01\", dc=\"sas\", } 8 1512216010000\n" + "diskUsage{disk=\"sdb1\", } 1001\n" + "# TYPE nanValue gauge\n" + "nanValue nan\n" + "# TYPE infValue gauge\n" + "infValue inf\n" "seconds_sum{disk=\"sdb1\", } 10.1\n" "seconds_min{disk=\"sdb1\", } -0.45\n" "seconds_max{disk=\"sdb1\", } 0.478\n" "seconds_last{disk=\"sdb1\", } 0.3\n" "seconds_count{disk=\"sdb1\", } 30\n" - "\n"); - } - - Y_UNIT_TEST(IntGauges) { - auto result = EncodeToString([](IMetricEncoder* e) { - e->OnStreamBegin(); - { // no values - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "cpuUsage"); - e->OnLabelsEnd(); - } - e->OnMetricEnd(); - } - { // one value no ts - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "diskUsage"); - e->OnLabel("disk", "sda1"); - e->OnLabelsEnd(); - } - e->OnInt64(TInstant::Zero(), 1000); - e->OnMetricEnd(); - } - { // one value with ts - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "memoryUsage"); - e->OnLabel("dc", "man"); - e->OnLabel("host", "solomon-man-00"); - e->OnLabelsEnd(); - } - e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); - e->OnMetricEnd(); - } - { // many values - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "bytesRx"); - e->OnLabel("dc", "sas"); - e->OnLabel("host", "solomon-sas-01"); - e->OnLabelsEnd(); - } - e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); - e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); - e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }); - - UNIT_ASSERT_STRINGS_EQUAL(result, - "# TYPE diskUsage gauge\n" - "diskUsage{disk=\"sda1\", } 1000\n" - "# TYPE memoryUsage gauge\n" - "memoryUsage{dc=\"man\", host=\"solomon-man-00\", } 1000 1512216000000\n" - "# TYPE bytesRx gauge\n" - "bytesRx{dc=\"sas\", host=\"solomon-sas-01\", } 8 1512216010000\n" - "\n"); - } - - Y_UNIT_TEST(Counters) { - auto result = EncodeToString([](IMetricEncoder* e) { - e->OnStreamBegin(); - { // no values - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "cpuUsage"); - e->OnLabelsEnd(); - } - e->OnMetricEnd(); - } - { // one value no ts - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "diskUsage"); - e->OnLabel("disk", "sda1"); - e->OnLabelsEnd(); - } - e->OnInt64(TInstant::Zero(), 1000); - e->OnMetricEnd(); - } - { // one value with ts - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "memoryUsage"); - e->OnLabel("host", "solomon-man-00"); - e->OnLabel("dc", "man"); - e->OnLabelsEnd(); - } - e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); - e->OnMetricEnd(); - } - { // many values - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "bytesRx"); - e->OnLabel("host", "solomon-sas-01"); - e->OnLabel("dc", "sas"); - e->OnLabelsEnd(); - } - e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); - e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); - e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }); - - UNIT_ASSERT_STRINGS_EQUAL(result, - "# TYPE diskUsage counter\n" - "diskUsage{disk=\"sda1\", } 1000\n" - "# TYPE memoryUsage counter\n" - "memoryUsage{host=\"solomon-man-00\", dc=\"man\", } 1000 1512216000000\n" - "# TYPE bytesRx counter\n" - "bytesRx{host=\"solomon-sas-01\", dc=\"sas\", } 8 1512216010000\n" - "\n"); - } - - Y_UNIT_TEST(Histograms) { - auto result = EncodeToString([](IMetricEncoder* e) { - e->OnStreamBegin(); - { // no values histogram - e->OnMetricBegin(EMetricType::HIST); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "cpuUsage"); - e->OnLabelsEnd(); - } - e->OnMetricEnd(); - } - { // one value no ts - e->OnMetricBegin(EMetricType::HIST); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "inboundBytesPerSec"); - e->OnLabel("client", "mbus"); - e->OnLabelsEnd(); - } - e->OnHistogram( - TInstant::Zero(), - ExplicitHistogramSnapshot({10, 20, HISTOGRAM_INF_BOUND}, {1, 4, 0})); - e->OnMetricEnd(); - } - { // one value no ts no +inf bucket - e->OnMetricBegin(EMetricType::HIST); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "inboundBytesPerSec"); - e->OnLabel("client", "grpc"); - e->OnLabelsEnd(); - } - e->OnHistogram( - TInstant::Zero(), - ExplicitHistogramSnapshot({10, 20, 30}, {1, 4, 0})); - e->OnMetricEnd(); - } - { // one value with ts - e->OnMetricBegin(EMetricType::HIST_RATE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "outboundBytesPerSec"); - e->OnLabel("client", "grps"); - e->OnLabelsEnd(); - } - e->OnHistogram( - TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), - ExplicitHistogramSnapshot({100, 200, HISTOGRAM_INF_BOUND}, {1, 0, 0})); - e->OnMetricEnd(); - } - { // many values - e->OnMetricBegin(EMetricType::HIST); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "bytesRx"); - e->OnLabel("host", "solomon-sas-01"); - e->OnLabel("dc", "sas"); - e->OnLabelsEnd(); - } - TBucketBounds bounds = {100, 200, HISTOGRAM_INF_BOUND}; - e->OnHistogram( - TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), - ExplicitHistogramSnapshot(bounds, {10, 0, 0})); - e->OnHistogram( - TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), - ExplicitHistogramSnapshot(bounds, {10, 2, 0})); - e->OnHistogram( - TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), - ExplicitHistogramSnapshot(bounds, {10, 2, 5})); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }); - - UNIT_ASSERT_STRINGS_EQUAL(result, - "# TYPE inboundBytesPerSec histogram\n" - "inboundBytesPerSec_bucket{client=\"mbus\", le=\"10\"} 1\n" - "inboundBytesPerSec_bucket{client=\"mbus\", le=\"20\"} 5\n" - "inboundBytesPerSec_bucket{client=\"mbus\", le=\"+Inf\"} 5\n" - "inboundBytesPerSec_count{client=\"mbus\", } 5\n" - "inboundBytesPerSec_bucket{client=\"grpc\", le=\"10\"} 1\n" - "inboundBytesPerSec_bucket{client=\"grpc\", le=\"20\"} 5\n" - "inboundBytesPerSec_bucket{client=\"grpc\", le=\"30\"} 5\n" - "inboundBytesPerSec_count{client=\"grpc\", } 5\n" - "# TYPE outboundBytesPerSec histogram\n" - "outboundBytesPerSec_bucket{client=\"grps\", le=\"100\"} 1 1512216000000\n" - "outboundBytesPerSec_bucket{client=\"grps\", le=\"200\"} 1 1512216000000\n" - "outboundBytesPerSec_bucket{client=\"grps\", le=\"+Inf\"} 1 1512216000000\n" - "outboundBytesPerSec_count{client=\"grps\", } 1 1512216000000\n" - "# TYPE bytesRx histogram\n" - "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"100\"} 10 1512216010000\n" - "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"200\"} 12 1512216010000\n" - "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"+Inf\"} 17 1512216010000\n" - "bytesRx_count{host=\"solomon-sas-01\", dc=\"sas\", } 17 1512216010000\n" - "\n"); - } + "\n"); + } + + Y_UNIT_TEST(IntGauges) { + auto result = EncodeToString([](IMetricEncoder* e) { + e->OnStreamBegin(); + { // no values + e->OnMetricBegin(EMetricType::IGAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "cpuUsage"); + e->OnLabelsEnd(); + } + e->OnMetricEnd(); + } + { // one value no ts + e->OnMetricBegin(EMetricType::IGAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "diskUsage"); + e->OnLabel("disk", "sda1"); + e->OnLabelsEnd(); + } + e->OnInt64(TInstant::Zero(), 1000); + e->OnMetricEnd(); + } + { // one value with ts + e->OnMetricBegin(EMetricType::IGAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "memoryUsage"); + e->OnLabel("dc", "man"); + e->OnLabel("host", "solomon-man-00"); + e->OnLabelsEnd(); + } + e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); + e->OnMetricEnd(); + } + { // many values + e->OnMetricBegin(EMetricType::IGAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "bytesRx"); + e->OnLabel("dc", "sas"); + e->OnLabel("host", "solomon-sas-01"); + e->OnLabelsEnd(); + } + e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); + e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); + e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }); + + UNIT_ASSERT_STRINGS_EQUAL(result, + "# TYPE diskUsage gauge\n" + "diskUsage{disk=\"sda1\", } 1000\n" + "# TYPE memoryUsage gauge\n" + "memoryUsage{dc=\"man\", host=\"solomon-man-00\", } 1000 1512216000000\n" + "# TYPE bytesRx gauge\n" + "bytesRx{dc=\"sas\", host=\"solomon-sas-01\", } 8 1512216010000\n" + "\n"); + } + + Y_UNIT_TEST(Counters) { + auto result = EncodeToString([](IMetricEncoder* e) { + e->OnStreamBegin(); + { // no values + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "cpuUsage"); + e->OnLabelsEnd(); + } + e->OnMetricEnd(); + } + { // one value no ts + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "diskUsage"); + e->OnLabel("disk", "sda1"); + e->OnLabelsEnd(); + } + e->OnInt64(TInstant::Zero(), 1000); + e->OnMetricEnd(); + } + { // one value with ts + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "memoryUsage"); + e->OnLabel("host", "solomon-man-00"); + e->OnLabel("dc", "man"); + e->OnLabelsEnd(); + } + e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); + e->OnMetricEnd(); + } + { // many values + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "bytesRx"); + e->OnLabel("host", "solomon-sas-01"); + e->OnLabel("dc", "sas"); + e->OnLabelsEnd(); + } + e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); + e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); + e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }); + + UNIT_ASSERT_STRINGS_EQUAL(result, + "# TYPE diskUsage counter\n" + "diskUsage{disk=\"sda1\", } 1000\n" + "# TYPE memoryUsage counter\n" + "memoryUsage{host=\"solomon-man-00\", dc=\"man\", } 1000 1512216000000\n" + "# TYPE bytesRx counter\n" + "bytesRx{host=\"solomon-sas-01\", dc=\"sas\", } 8 1512216010000\n" + "\n"); + } + + Y_UNIT_TEST(Histograms) { + auto result = EncodeToString([](IMetricEncoder* e) { + e->OnStreamBegin(); + { // no values histogram + e->OnMetricBegin(EMetricType::HIST); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "cpuUsage"); + e->OnLabelsEnd(); + } + e->OnMetricEnd(); + } + { // one value no ts + e->OnMetricBegin(EMetricType::HIST); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "inboundBytesPerSec"); + e->OnLabel("client", "mbus"); + e->OnLabelsEnd(); + } + e->OnHistogram( + TInstant::Zero(), + ExplicitHistogramSnapshot({10, 20, HISTOGRAM_INF_BOUND}, {1, 4, 0})); + e->OnMetricEnd(); + } + { // one value no ts no +inf bucket + e->OnMetricBegin(EMetricType::HIST); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "inboundBytesPerSec"); + e->OnLabel("client", "grpc"); + e->OnLabelsEnd(); + } + e->OnHistogram( + TInstant::Zero(), + ExplicitHistogramSnapshot({10, 20, 30}, {1, 4, 0})); + e->OnMetricEnd(); + } + { // one value with ts + e->OnMetricBegin(EMetricType::HIST_RATE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "outboundBytesPerSec"); + e->OnLabel("client", "grps"); + e->OnLabelsEnd(); + } + e->OnHistogram( + TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), + ExplicitHistogramSnapshot({100, 200, HISTOGRAM_INF_BOUND}, {1, 0, 0})); + e->OnMetricEnd(); + } + { // many values + e->OnMetricBegin(EMetricType::HIST); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "bytesRx"); + e->OnLabel("host", "solomon-sas-01"); + e->OnLabel("dc", "sas"); + e->OnLabelsEnd(); + } + TBucketBounds bounds = {100, 200, HISTOGRAM_INF_BOUND}; + e->OnHistogram( + TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), + ExplicitHistogramSnapshot(bounds, {10, 0, 0})); + e->OnHistogram( + TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), + ExplicitHistogramSnapshot(bounds, {10, 2, 0})); + e->OnHistogram( + TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), + ExplicitHistogramSnapshot(bounds, {10, 2, 5})); + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }); + + UNIT_ASSERT_STRINGS_EQUAL(result, + "# TYPE inboundBytesPerSec histogram\n" + "inboundBytesPerSec_bucket{client=\"mbus\", le=\"10\"} 1\n" + "inboundBytesPerSec_bucket{client=\"mbus\", le=\"20\"} 5\n" + "inboundBytesPerSec_bucket{client=\"mbus\", le=\"+Inf\"} 5\n" + "inboundBytesPerSec_count{client=\"mbus\", } 5\n" + "inboundBytesPerSec_bucket{client=\"grpc\", le=\"10\"} 1\n" + "inboundBytesPerSec_bucket{client=\"grpc\", le=\"20\"} 5\n" + "inboundBytesPerSec_bucket{client=\"grpc\", le=\"30\"} 5\n" + "inboundBytesPerSec_count{client=\"grpc\", } 5\n" + "# TYPE outboundBytesPerSec histogram\n" + "outboundBytesPerSec_bucket{client=\"grps\", le=\"100\"} 1 1512216000000\n" + "outboundBytesPerSec_bucket{client=\"grps\", le=\"200\"} 1 1512216000000\n" + "outboundBytesPerSec_bucket{client=\"grps\", le=\"+Inf\"} 1 1512216000000\n" + "outboundBytesPerSec_count{client=\"grps\", } 1 1512216000000\n" + "# TYPE bytesRx histogram\n" + "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"100\"} 10 1512216010000\n" + "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"200\"} 12 1512216010000\n" + "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"+Inf\"} 17 1512216010000\n" + "bytesRx_count{host=\"solomon-sas-01\", dc=\"sas\", } 17 1512216010000\n" + "\n"); + } Y_UNIT_TEST(CommonLables) { auto result = EncodeToString([](IMetricEncoder* e) { @@ -411,4 +411,4 @@ two{labels="l2", project="solomon", } 42 1500000000000 )"); } -} +} diff --git a/library/cpp/monlib/encode/prometheus/prometheus_model.h b/library/cpp/monlib/encode/prometheus/prometheus_model.h index f8e55868e7..cb7f2cb15b 100644 --- a/library/cpp/monlib/encode/prometheus/prometheus_model.h +++ b/library/cpp/monlib/encode/prometheus/prometheus_model.h @@ -1,70 +1,70 @@ -#pragma once - -#include <util/generic/strbuf.h> - - -namespace NMonitoring { -namespace NPrometheus { - - // - // Prometheus specific names and validation rules. - // - // See https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md - // and https://github.com/prometheus/common/blob/master/expfmt/text_parse.go - // - +#pragma once + +#include <util/generic/strbuf.h> + + +namespace NMonitoring { +namespace NPrometheus { + + // + // Prometheus specific names and validation rules. + // + // See https://github.com/prometheus/docs/blob/master/content/docs/instrumenting/exposition_formats.md + // and https://github.com/prometheus/common/blob/master/expfmt/text_parse.go + // + inline constexpr TStringBuf BUCKET_SUFFIX = "_bucket"; inline constexpr TStringBuf COUNT_SUFFIX = "_count"; inline constexpr TStringBuf SUM_SUFFIX = "_sum"; inline constexpr TStringBuf MIN_SUFFIX = "_min"; inline constexpr TStringBuf MAX_SUFFIX = "_max"; inline constexpr TStringBuf LAST_SUFFIX = "_last"; - - // Used for the label that defines the upper bound of a bucket of a - // histogram ("le" -> "less or equal"). + + // Used for the label that defines the upper bound of a bucket of a + // histogram ("le" -> "less or equal"). inline constexpr TStringBuf BUCKET_LABEL = "le"; - - - inline bool IsValidLabelNameStart(char ch) { - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_'; - } - - inline bool IsValidLabelNameContinuation(char ch) { - return IsValidLabelNameStart(ch) || (ch >= '0' && ch <= '9'); - } - - inline bool IsValidMetricNameStart(char ch) { - return IsValidLabelNameStart(ch) || ch == ':'; - } - - inline bool IsValidMetricNameContinuation(char ch) { - return IsValidLabelNameContinuation(ch) || ch == ':'; - } - - inline bool IsSum(TStringBuf name) { - return name.EndsWith(SUM_SUFFIX); - } - - inline bool IsCount(TStringBuf name) { - return name.EndsWith(COUNT_SUFFIX); - } - - inline bool IsBucket(TStringBuf name) { - return name.EndsWith(BUCKET_SUFFIX); - } - - inline TStringBuf ToBaseName(TStringBuf name) { - if (IsBucket(name)) { - return name.SubString(0, name.length() - BUCKET_SUFFIX.length()); - } - if (IsCount(name)) { - return name.SubString(0, name.length() - COUNT_SUFFIX.length()); - } - if (IsSum(name)) { - return name.SubString(0, name.length() - SUM_SUFFIX.length()); - } - return name; - } - -} // namespace NPrometheus -} // namespace NMonitoring + + + inline bool IsValidLabelNameStart(char ch) { + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || ch == '_'; + } + + inline bool IsValidLabelNameContinuation(char ch) { + return IsValidLabelNameStart(ch) || (ch >= '0' && ch <= '9'); + } + + inline bool IsValidMetricNameStart(char ch) { + return IsValidLabelNameStart(ch) || ch == ':'; + } + + inline bool IsValidMetricNameContinuation(char ch) { + return IsValidLabelNameContinuation(ch) || ch == ':'; + } + + inline bool IsSum(TStringBuf name) { + return name.EndsWith(SUM_SUFFIX); + } + + inline bool IsCount(TStringBuf name) { + return name.EndsWith(COUNT_SUFFIX); + } + + inline bool IsBucket(TStringBuf name) { + return name.EndsWith(BUCKET_SUFFIX); + } + + inline TStringBuf ToBaseName(TStringBuf name) { + if (IsBucket(name)) { + return name.SubString(0, name.length() - BUCKET_SUFFIX.length()); + } + if (IsCount(name)) { + return name.SubString(0, name.length() - COUNT_SUFFIX.length()); + } + if (IsSum(name)) { + return name.SubString(0, name.length() - SUM_SUFFIX.length()); + } + return name; + } + +} // namespace NPrometheus +} // namespace NMonitoring diff --git a/library/cpp/monlib/encode/prometheus/ut/ya.make b/library/cpp/monlib/encode/prometheus/ut/ya.make index 4d4070d194..fc468ffb68 100644 --- a/library/cpp/monlib/encode/prometheus/ut/ya.make +++ b/library/cpp/monlib/encode/prometheus/ut/ya.make @@ -1,17 +1,17 @@ -UNITTEST_FOR(library/cpp/monlib/encode/prometheus) - -OWNER( - g:solomon - jamel -) - -SRCS( - prometheus_encoder_ut.cpp - prometheus_decoder_ut.cpp -) - -PEERDIR( - library/cpp/monlib/encode/protobuf -) - -END() +UNITTEST_FOR(library/cpp/monlib/encode/prometheus) + +OWNER( + g:solomon + jamel +) + +SRCS( + prometheus_encoder_ut.cpp + prometheus_decoder_ut.cpp +) + +PEERDIR( + library/cpp/monlib/encode/protobuf +) + +END() diff --git a/library/cpp/monlib/encode/prometheus/ya.make b/library/cpp/monlib/encode/prometheus/ya.make index 03f18f78a4..7f2483b166 100644 --- a/library/cpp/monlib/encode/prometheus/ya.make +++ b/library/cpp/monlib/encode/prometheus/ya.make @@ -1,17 +1,17 @@ -LIBRARY() - -OWNER( - jamel - g:solomon -) - -SRCS( - prometheus_decoder.cpp - prometheus_encoder.cpp -) - -PEERDIR( - library/cpp/monlib/encode -) - -END() +LIBRARY() + +OWNER( + jamel + g:solomon +) + +SRCS( + prometheus_decoder.cpp + prometheus_encoder.cpp +) + +PEERDIR( + library/cpp/monlib/encode +) + +END() diff --git a/library/cpp/monlib/encode/protobuf/protobuf.h b/library/cpp/monlib/encode/protobuf/protobuf.h index 219b94bee4..3f82cbdd84 100644 --- a/library/cpp/monlib/encode/protobuf/protobuf.h +++ b/library/cpp/monlib/encode/protobuf/protobuf.h @@ -1,16 +1,16 @@ -#pragma once - -#include <library/cpp/monlib/encode/encoder.h> - -#include <library/cpp/monlib/encode/protobuf/protos/samples.pb.h> - -namespace NMonitoring { - namespace NProto { - class TSingleSamplesList; - class TMultiSamplesList; - } - - IMetricEncoderPtr EncoderProtobuf(NProto::TSingleSamplesList* samples); - IMetricEncoderPtr EncoderProtobuf(NProto::TMultiSamplesList* samples); - -} +#pragma once + +#include <library/cpp/monlib/encode/encoder.h> + +#include <library/cpp/monlib/encode/protobuf/protos/samples.pb.h> + +namespace NMonitoring { + namespace NProto { + class TSingleSamplesList; + class TMultiSamplesList; + } + + IMetricEncoderPtr EncoderProtobuf(NProto::TSingleSamplesList* samples); + IMetricEncoderPtr EncoderProtobuf(NProto::TMultiSamplesList* samples); + +} diff --git a/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp b/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp index 57fbbba605..2d11b9d5ba 100644 --- a/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp +++ b/library/cpp/monlib/encode/protobuf/protobuf_encoder.cpp @@ -1,42 +1,42 @@ -#include "protobuf.h" - -#include <util/datetime/base.h> - -namespace NMonitoring { - namespace { - NProto::EMetricType ConvertMetricType(EMetricType type) { - switch (type) { - case EMetricType::GAUGE: - return NProto::GAUGE; - case EMetricType::COUNTER: - return NProto::COUNTER; - case EMetricType::RATE: - return NProto::RATE; - case EMetricType::IGAUGE: - return NProto::IGAUGE; - case EMetricType::HIST: +#include "protobuf.h" + +#include <util/datetime/base.h> + +namespace NMonitoring { + namespace { + NProto::EMetricType ConvertMetricType(EMetricType type) { + switch (type) { + case EMetricType::GAUGE: + return NProto::GAUGE; + case EMetricType::COUNTER: + return NProto::COUNTER; + case EMetricType::RATE: + return NProto::RATE; + case EMetricType::IGAUGE: + return NProto::IGAUGE; + case EMetricType::HIST: return NProto::HISTOGRAM; - case EMetricType::HIST_RATE: + case EMetricType::HIST_RATE: return NProto::HIST_RATE; - case EMetricType::DSUMMARY: + case EMetricType::DSUMMARY: return NProto::DSUMMARY; case EMetricType::LOGHIST: return NProto::LOGHISTOGRAM; - case EMetricType::UNKNOWN: - return NProto::UNKNOWN; - } - } - - void FillHistogram( - const IHistogramSnapshot& snapshot, - NProto::THistogram* histogram) - { - for (ui32 i = 0; i < snapshot.Count(); i++) { - histogram->AddBounds(snapshot.UpperBound(i)); - histogram->AddValues(snapshot.Value(i)); - } - } - + case EMetricType::UNKNOWN: + return NProto::UNKNOWN; + } + } + + void FillHistogram( + const IHistogramSnapshot& snapshot, + NProto::THistogram* histogram) + { + for (ui32 i = 0; i < snapshot.Count(); i++) { + histogram->AddBounds(snapshot.UpperBound(i)); + histogram->AddValues(snapshot.Value(i)); + } + } + void FillSummaryDouble(const ISummaryDoubleSnapshot& snapshot, NProto::TSummaryDouble* summary) { summary->SetSum(snapshot.GetSum()); summary->SetMin(snapshot.GetMin()); @@ -54,195 +54,195 @@ namespace NMonitoring { } } - /////////////////////////////////////////////////////////////////////////////// - // TSingleamplesEncoder - /////////////////////////////////////////////////////////////////////////////// - class TSingleSamplesEncoder final: public IMetricEncoder { - public: - TSingleSamplesEncoder(NProto::TSingleSamplesList* samples) - : Samples_(samples) - , Sample_(nullptr) - { - } - - private: - void OnStreamBegin() override { - } - void OnStreamEnd() override { - } - - void OnCommonTime(TInstant time) override { - Samples_->SetCommonTime(time.MilliSeconds()); - } - - void OnMetricBegin(EMetricType type) override { - Sample_ = Samples_->AddSamples(); - Sample_->SetMetricType(ConvertMetricType(type)); - } - - void OnMetricEnd() override { - Sample_ = nullptr; - } - - void OnLabelsBegin() override { - } - void OnLabelsEnd() override { - } - - void OnLabel(TStringBuf name, TStringBuf value) override { - NProto::TLabel* label = (Sample_ == nullptr) - ? Samples_->AddCommonLabels() - : Sample_->AddLabels(); + /////////////////////////////////////////////////////////////////////////////// + // TSingleamplesEncoder + /////////////////////////////////////////////////////////////////////////////// + class TSingleSamplesEncoder final: public IMetricEncoder { + public: + TSingleSamplesEncoder(NProto::TSingleSamplesList* samples) + : Samples_(samples) + , Sample_(nullptr) + { + } + + private: + void OnStreamBegin() override { + } + void OnStreamEnd() override { + } + + void OnCommonTime(TInstant time) override { + Samples_->SetCommonTime(time.MilliSeconds()); + } + + void OnMetricBegin(EMetricType type) override { + Sample_ = Samples_->AddSamples(); + Sample_->SetMetricType(ConvertMetricType(type)); + } + + void OnMetricEnd() override { + Sample_ = nullptr; + } + + void OnLabelsBegin() override { + } + void OnLabelsEnd() override { + } + + void OnLabel(TStringBuf name, TStringBuf value) override { + NProto::TLabel* label = (Sample_ == nullptr) + ? Samples_->AddCommonLabels() + : Sample_->AddLabels(); label->SetName(TString{name}); label->SetValue(TString{value}); - } - - void OnDouble(TInstant time, double value) override { - Y_ENSURE(Sample_, "metric not started"); - Sample_->SetTime(time.MilliSeconds()); - Sample_->SetFloat64(value); - } - - void OnInt64(TInstant time, i64 value) override { - Y_ENSURE(Sample_, "metric not started"); - Sample_->SetTime(time.MilliSeconds()); - Sample_->SetInt64(value); - } - - void OnUint64(TInstant time, ui64 value) override { - Y_ENSURE(Sample_, "metric not started"); - Sample_->SetTime(time.MilliSeconds()); - Sample_->SetUint64(value); - } - - void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { - Y_ENSURE(Sample_, "metric not started"); - Sample_->SetTime(time.MilliSeconds()); - FillHistogram(*snapshot, Sample_->MutableHistogram()); - } - + } + + void OnDouble(TInstant time, double value) override { + Y_ENSURE(Sample_, "metric not started"); + Sample_->SetTime(time.MilliSeconds()); + Sample_->SetFloat64(value); + } + + void OnInt64(TInstant time, i64 value) override { + Y_ENSURE(Sample_, "metric not started"); + Sample_->SetTime(time.MilliSeconds()); + Sample_->SetInt64(value); + } + + void OnUint64(TInstant time, ui64 value) override { + Y_ENSURE(Sample_, "metric not started"); + Sample_->SetTime(time.MilliSeconds()); + Sample_->SetUint64(value); + } + + void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { + Y_ENSURE(Sample_, "metric not started"); + Sample_->SetTime(time.MilliSeconds()); + FillHistogram(*snapshot, Sample_->MutableHistogram()); + } + void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override { - Y_ENSURE(Sample_, "metric not started"); + Y_ENSURE(Sample_, "metric not started"); Sample_->SetTime(time.MilliSeconds()); FillSummaryDouble(*snapshot, Sample_->MutableSummaryDouble()); } void OnLogHistogram(TInstant time, TLogHistogramSnapshotPtr snapshot) override { - Y_ENSURE(Sample_, "metric not started"); + Y_ENSURE(Sample_, "metric not started"); Sample_->SetTime(time.MilliSeconds()); FillLogHistogram(*snapshot, Sample_->MutableLogHistogram()); } - void Close() override { - } - - private: - NProto::TSingleSamplesList* Samples_; - NProto::TSingleSample* Sample_; - }; - - /////////////////////////////////////////////////////////////////////////////// - // TMultiSamplesEncoder - /////////////////////////////////////////////////////////////////////////////// - class TMultiSamplesEncoder final: public IMetricEncoder { - public: - TMultiSamplesEncoder(NProto::TMultiSamplesList* samples) - : Samples_(samples) - , Sample_(nullptr) - { - } - - private: - void OnStreamBegin() override { - } - void OnStreamEnd() override { - } - - void OnCommonTime(TInstant time) override { - Samples_->SetCommonTime(time.MilliSeconds()); - } - - void OnMetricBegin(EMetricType type) override { - Sample_ = Samples_->AddSamples(); - Sample_->SetMetricType(ConvertMetricType(type)); - } - - void OnMetricEnd() override { - Sample_ = nullptr; - } - - void OnLabelsBegin() override { - } - void OnLabelsEnd() override { - } - - void OnLabel(TStringBuf name, TStringBuf value) override { - NProto::TLabel* label = (Sample_ == nullptr) - ? Samples_->AddCommonLabels() - : Sample_->AddLabels(); - + void Close() override { + } + + private: + NProto::TSingleSamplesList* Samples_; + NProto::TSingleSample* Sample_; + }; + + /////////////////////////////////////////////////////////////////////////////// + // TMultiSamplesEncoder + /////////////////////////////////////////////////////////////////////////////// + class TMultiSamplesEncoder final: public IMetricEncoder { + public: + TMultiSamplesEncoder(NProto::TMultiSamplesList* samples) + : Samples_(samples) + , Sample_(nullptr) + { + } + + private: + void OnStreamBegin() override { + } + void OnStreamEnd() override { + } + + void OnCommonTime(TInstant time) override { + Samples_->SetCommonTime(time.MilliSeconds()); + } + + void OnMetricBegin(EMetricType type) override { + Sample_ = Samples_->AddSamples(); + Sample_->SetMetricType(ConvertMetricType(type)); + } + + void OnMetricEnd() override { + Sample_ = nullptr; + } + + void OnLabelsBegin() override { + } + void OnLabelsEnd() override { + } + + void OnLabel(TStringBuf name, TStringBuf value) override { + NProto::TLabel* label = (Sample_ == nullptr) + ? Samples_->AddCommonLabels() + : Sample_->AddLabels(); + label->SetName(TString{name}); label->SetValue(TString{value}); - } - - void OnDouble(TInstant time, double value) override { - Y_ENSURE(Sample_, "metric not started"); - NProto::TPoint* point = Sample_->AddPoints(); - point->SetTime(time.MilliSeconds()); - point->SetFloat64(value); - } - - void OnInt64(TInstant time, i64 value) override { - Y_ENSURE(Sample_, "metric not started"); - NProto::TPoint* point = Sample_->AddPoints(); - point->SetTime(time.MilliSeconds()); - point->SetInt64(value); - } - - void OnUint64(TInstant time, ui64 value) override { - Y_ENSURE(Sample_, "metric not started"); - NProto::TPoint* point = Sample_->AddPoints(); - point->SetTime(time.MilliSeconds()); - point->SetUint64(value); - } - - void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { - Y_ENSURE(Sample_, "metric not started"); - NProto::TPoint* point = Sample_->AddPoints(); - point->SetTime(time.MilliSeconds()); - FillHistogram(*snapshot, point->MutableHistogram()); - } - + } + + void OnDouble(TInstant time, double value) override { + Y_ENSURE(Sample_, "metric not started"); + NProto::TPoint* point = Sample_->AddPoints(); + point->SetTime(time.MilliSeconds()); + point->SetFloat64(value); + } + + void OnInt64(TInstant time, i64 value) override { + Y_ENSURE(Sample_, "metric not started"); + NProto::TPoint* point = Sample_->AddPoints(); + point->SetTime(time.MilliSeconds()); + point->SetInt64(value); + } + + void OnUint64(TInstant time, ui64 value) override { + Y_ENSURE(Sample_, "metric not started"); + NProto::TPoint* point = Sample_->AddPoints(); + point->SetTime(time.MilliSeconds()); + point->SetUint64(value); + } + + void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { + Y_ENSURE(Sample_, "metric not started"); + NProto::TPoint* point = Sample_->AddPoints(); + point->SetTime(time.MilliSeconds()); + FillHistogram(*snapshot, point->MutableHistogram()); + } + void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override { - Y_ENSURE(Sample_, "metric not started"); + Y_ENSURE(Sample_, "metric not started"); NProto::TPoint* point = Sample_->AddPoints(); point->SetTime(time.MilliSeconds()); FillSummaryDouble(*snapshot, point->MutableSummaryDouble()); } void OnLogHistogram(TInstant time, TLogHistogramSnapshotPtr snapshot) override { - Y_ENSURE(Sample_, "metric not started"); + Y_ENSURE(Sample_, "metric not started"); NProto::TPoint* point = Sample_->AddPoints(); point->SetTime(time.MilliSeconds()); FillLogHistogram(*snapshot, point->MutableLogHistogram()); } - void Close() override { - } - - private: - NProto::TMultiSamplesList* Samples_; - NProto::TMultiSample* Sample_; - }; - - } - - IMetricEncoderPtr EncoderProtobuf(NProto::TSingleSamplesList* samples) { + void Close() override { + } + + private: + NProto::TMultiSamplesList* Samples_; + NProto::TMultiSample* Sample_; + }; + + } + + IMetricEncoderPtr EncoderProtobuf(NProto::TSingleSamplesList* samples) { return MakeHolder<TSingleSamplesEncoder>(samples); - } - - IMetricEncoderPtr EncoderProtobuf(NProto::TMultiSamplesList* samples) { + } + + IMetricEncoderPtr EncoderProtobuf(NProto::TMultiSamplesList* samples) { return MakeHolder<TMultiSamplesEncoder>(samples); - } - -} + } + +} diff --git a/library/cpp/monlib/encode/protobuf/protos/samples.proto b/library/cpp/monlib/encode/protobuf/protos/samples.proto index d5f0c6403e..371f4181d2 100644 --- a/library/cpp/monlib/encode/protobuf/protos/samples.proto +++ b/library/cpp/monlib/encode/protobuf/protos/samples.proto @@ -1,33 +1,33 @@ -syntax = 'proto3'; - -package NMonitoring.NProto; - -option java_package = "ru.yandex.solomon.protos"; -option java_multiple_files = true; -option cc_enable_arenas = true; - -message TLabel { - string Name = 1; - string Value = 2; -} - -enum EMetricType { - UNKNOWN = 0; - GAUGE = 1; - IGAUGE = 2; - COUNTER = 3; - RATE = 4; - HISTOGRAM = 5; +syntax = 'proto3'; + +package NMonitoring.NProto; + +option java_package = "ru.yandex.solomon.protos"; +option java_multiple_files = true; +option cc_enable_arenas = true; + +message TLabel { + string Name = 1; + string Value = 2; +} + +enum EMetricType { + UNKNOWN = 0; + GAUGE = 1; + IGAUGE = 2; + COUNTER = 3; + RATE = 4; + HISTOGRAM = 5; HIST_RATE = 6; DSUMMARY = 7; LOGHISTOGRAM = 8; -} - -message THistogram { - repeated double Bounds = 1; // upper bounds of each bucket - repeated uint64 Values = 2; // values stored in each bucket -} - +} + +message THistogram { + repeated double Bounds = 1; // upper bounds of each bucket + repeated uint64 Values = 2; // values stored in each bucket +} + message TLogHistogram { double Base = 1; uint64 ZerosCount = 2; @@ -43,49 +43,49 @@ message TSummaryDouble { uint64 Count = 5; } -// see TSingleSample -message TPoint { - uint64 Time = 1; - oneof Value { - sfixed64 Int64 = 2; - fixed64 Uint64 = 3; - double Float64 = 4; - THistogram Histogram = 5; +// see TSingleSample +message TPoint { + uint64 Time = 1; + oneof Value { + sfixed64 Int64 = 2; + fixed64 Uint64 = 3; + double Float64 = 4; + THistogram Histogram = 5; TSummaryDouble SummaryDouble = 6; TLogHistogram LogHistogram = 7; - } -} - -message TSingleSample { - repeated TLabel Labels = 1; - EMetricType MetricType = 2; - - // inlined TPoint - uint64 Time = 3; - oneof Value { - sfixed64 Int64 = 4; - fixed64 Uint64 = 5; - double Float64 = 6; - THistogram Histogram = 7; + } +} + +message TSingleSample { + repeated TLabel Labels = 1; + EMetricType MetricType = 2; + + // inlined TPoint + uint64 Time = 3; + oneof Value { + sfixed64 Int64 = 4; + fixed64 Uint64 = 5; + double Float64 = 6; + THistogram Histogram = 7; TSummaryDouble SummaryDouble = 8; TLogHistogram LogHistogram = 9; - } -} - -message TMultiSample { - repeated TLabel Labels = 1; - EMetricType MetricType = 2; - repeated TPoint Points = 3; -} - -message TSingleSamplesList { - uint64 CommonTime = 1; - repeated TLabel CommonLabels = 2; - repeated TSingleSample Samples = 3; -} - -message TMultiSamplesList { - uint64 CommonTime = 1; - repeated TLabel CommonLabels = 2; - repeated TMultiSample Samples = 3; -} + } +} + +message TMultiSample { + repeated TLabel Labels = 1; + EMetricType MetricType = 2; + repeated TPoint Points = 3; +} + +message TSingleSamplesList { + uint64 CommonTime = 1; + repeated TLabel CommonLabels = 2; + repeated TSingleSample Samples = 3; +} + +message TMultiSamplesList { + uint64 CommonTime = 1; + repeated TLabel CommonLabels = 2; + repeated TMultiSample Samples = 3; +} diff --git a/library/cpp/monlib/encode/protobuf/protos/ya.make b/library/cpp/monlib/encode/protobuf/protos/ya.make index 29a87a0b21..88ff3ddf88 100644 --- a/library/cpp/monlib/encode/protobuf/protos/ya.make +++ b/library/cpp/monlib/encode/protobuf/protos/ya.make @@ -1,14 +1,14 @@ -PROTO_LIBRARY() - +PROTO_LIBRARY() + OWNER( jamel g:solomon ) - -SRCS( - samples.proto -) - + +SRCS( + samples.proto +) + EXCLUDE_TAGS(GO_PROTO) -END() +END() diff --git a/library/cpp/monlib/encode/protobuf/ya.make b/library/cpp/monlib/encode/protobuf/ya.make index fd575ef731..9354958b6f 100644 --- a/library/cpp/monlib/encode/protobuf/ya.make +++ b/library/cpp/monlib/encode/protobuf/ya.make @@ -1,17 +1,17 @@ -LIBRARY() - +LIBRARY() + OWNER( jamel g:solomon ) - -SRCS( - protobuf_encoder.cpp -) - -PEERDIR( - library/cpp/monlib/encode - library/cpp/monlib/encode/protobuf/protos -) - -END() + +SRCS( + protobuf_encoder.cpp +) + +PEERDIR( + library/cpp/monlib/encode + library/cpp/monlib/encode/protobuf/protos +) + +END() diff --git a/library/cpp/monlib/encode/spack/compression.cpp b/library/cpp/monlib/encode/spack/compression.cpp index 0ad1eee866..0d2152fc85 100644 --- a/library/cpp/monlib/encode/spack/compression.cpp +++ b/library/cpp/monlib/encode/spack/compression.cpp @@ -1,213 +1,213 @@ -#include "compression.h" - +#include "compression.h" + #include <util/generic/buffer.h> -#include <util/generic/cast.h> -#include <util/generic/ptr.h> +#include <util/generic/cast.h> +#include <util/generic/ptr.h> #include <util/generic/scope.h> #include <util/generic/size_literals.h> #include <util/stream/format.h> #include <util/stream/output.h> -#include <util/stream/walk.h> - -#include <contrib/libs/lz4/lz4.h> +#include <util/stream/walk.h> + +#include <contrib/libs/lz4/lz4.h> #include <contrib/libs/xxhash/xxhash.h> -#include <contrib/libs/zlib/zlib.h> -#define ZSTD_STATIC_LINKING_ONLY +#include <contrib/libs/zlib/zlib.h> +#define ZSTD_STATIC_LINKING_ONLY #include <contrib/libs/zstd/include/zstd.h> - -namespace NMonitoring { - namespace { - /////////////////////////////////////////////////////////////////////////////// - // Frame - /////////////////////////////////////////////////////////////////////////////// - using TCompressedSize = ui32; - using TUncompressedSize = ui32; - using TCheckSum = ui32; - + +namespace NMonitoring { + namespace { + /////////////////////////////////////////////////////////////////////////////// + // Frame + /////////////////////////////////////////////////////////////////////////////// + using TCompressedSize = ui32; + using TUncompressedSize = ui32; + using TCheckSum = ui32; + constexpr size_t COMPRESSED_FRAME_SIZE_LIMIT = 512_KB; constexpr size_t UNCOMPRESSED_FRAME_SIZE_LIMIT = COMPRESSED_FRAME_SIZE_LIMIT; constexpr size_t FRAME_SIZE_LIMIT = 2_MB; constexpr size_t DEFAULT_FRAME_LEN = 64_KB; - + struct Y_PACKED TFrameHeader { - TCompressedSize CompressedSize; - TUncompressedSize UncompressedSize; - }; - + TCompressedSize CompressedSize; + TUncompressedSize UncompressedSize; + }; + struct Y_PACKED TFrameFooter { - TCheckSum CheckSum; - }; - - /////////////////////////////////////////////////////////////////////////////// - // TBlock - /////////////////////////////////////////////////////////////////////////////// - struct TBlock: public TStringBuf { - template <typename T> - TBlock(T&& t) + TCheckSum CheckSum; + }; + + /////////////////////////////////////////////////////////////////////////////// + // TBlock + /////////////////////////////////////////////////////////////////////////////// + struct TBlock: public TStringBuf { + template <typename T> + TBlock(T&& t) : TStringBuf(t.data(), t.size()) - { + { Y_ENSURE(t.data() != nullptr); - } - + } + char* data() noexcept { return const_cast<char*>(TStringBuf::data()); - } - }; - - /////////////////////////////////////////////////////////////////////////////// - // XXHASH - /////////////////////////////////////////////////////////////////////////////// - struct TXxHash32 { - static TCheckSum Calc(TBlock in) { - static const ui32 SEED = 0x1337c0de; + } + }; + + /////////////////////////////////////////////////////////////////////////////// + // XXHASH + /////////////////////////////////////////////////////////////////////////////// + struct TXxHash32 { + static TCheckSum Calc(TBlock in) { + static const ui32 SEED = 0x1337c0de; return XXH32(in.data(), in.size(), SEED); - } - - static bool Check(TBlock in, TCheckSum checksum) { - return Calc(in) == checksum; - } - }; - - /////////////////////////////////////////////////////////////////////////////// - // Adler32 - /////////////////////////////////////////////////////////////////////////////// - struct TAdler32 { - static TCheckSum Calc(TBlock in) { + } + + static bool Check(TBlock in, TCheckSum checksum) { + return Calc(in) == checksum; + } + }; + + /////////////////////////////////////////////////////////////////////////////// + // Adler32 + /////////////////////////////////////////////////////////////////////////////// + struct TAdler32 { + static TCheckSum Calc(TBlock in) { return adler32(1L, reinterpret_cast<const Bytef*>(in.data()), in.size()); - } - - static bool Check(TBlock in, TCheckSum checksum) { - return Calc(in) == checksum; - } - }; - - /////////////////////////////////////////////////////////////////////////////// - // LZ4 - /////////////////////////////////////////////////////////////////////////////// - struct TLz4Codec { - static size_t MaxCompressedLength(size_t in) { - int result = LZ4_compressBound(static_cast<int>(in)); - Y_ENSURE(result != 0, "lz4 input size is too large"); - return result; - } - - static size_t Compress(TBlock in, TBlock out) { - int rc = LZ4_compress_default( + } + + static bool Check(TBlock in, TCheckSum checksum) { + return Calc(in) == checksum; + } + }; + + /////////////////////////////////////////////////////////////////////////////// + // LZ4 + /////////////////////////////////////////////////////////////////////////////// + struct TLz4Codec { + static size_t MaxCompressedLength(size_t in) { + int result = LZ4_compressBound(static_cast<int>(in)); + Y_ENSURE(result != 0, "lz4 input size is too large"); + return result; + } + + static size_t Compress(TBlock in, TBlock out) { + int rc = LZ4_compress_default( in.data(), out.data(), SafeIntegerCast<int>(in.size()), SafeIntegerCast<int>(out.size())); - Y_ENSURE(rc != 0, "lz4 compression failed"); - return rc; - } - - static void Decompress(TBlock in, TBlock out) { - int rc = LZ4_decompress_safe( + Y_ENSURE(rc != 0, "lz4 compression failed"); + return rc; + } + + static void Decompress(TBlock in, TBlock out) { + int rc = LZ4_decompress_safe( in.data(), out.data(), SafeIntegerCast<int>(in.size()), SafeIntegerCast<int>(out.size())); - Y_ENSURE(rc >= 0, "the lz4 stream is detected malformed"); - } - }; - - /////////////////////////////////////////////////////////////////////////////// - // ZSTD - /////////////////////////////////////////////////////////////////////////////// - struct TZstdCodec { - static const int LEVEL = 11; - - static size_t MaxCompressedLength(size_t in) { - return ZSTD_compressBound(in); - } - - static size_t Compress(TBlock in, TBlock out) { + Y_ENSURE(rc >= 0, "the lz4 stream is detected malformed"); + } + }; + + /////////////////////////////////////////////////////////////////////////////// + // ZSTD + /////////////////////////////////////////////////////////////////////////////// + struct TZstdCodec { + static const int LEVEL = 11; + + static size_t MaxCompressedLength(size_t in) { + return ZSTD_compressBound(in); + } + + static size_t Compress(TBlock in, TBlock out) { size_t rc = ZSTD_compress(out.data(), out.size(), in.data(), in.size(), LEVEL); - if (Y_UNLIKELY(ZSTD_isError(rc))) { + if (Y_UNLIKELY(ZSTD_isError(rc))) { ythrow yexception() << TStringBuf("zstd compression failed: ") - << ZSTD_getErrorName(rc); - } - return rc; - } - - static void Decompress(TBlock in, TBlock out) { + << ZSTD_getErrorName(rc); + } + return rc; + } + + static void Decompress(TBlock in, TBlock out) { size_t rc = ZSTD_decompress(out.data(), out.size(), in.data(), in.size()); - if (Y_UNLIKELY(ZSTD_isError(rc))) { + if (Y_UNLIKELY(ZSTD_isError(rc))) { ythrow yexception() << TStringBuf("zstd decompression failed: ") - << ZSTD_getErrorName(rc); - } + << ZSTD_getErrorName(rc); + } Y_ENSURE(rc == out.size(), "zstd decompressed wrong size"); - } - }; - - /////////////////////////////////////////////////////////////////////////////// - // ZLIB - /////////////////////////////////////////////////////////////////////////////// - struct TZlibCodec { - static const int LEVEL = 6; - - static size_t MaxCompressedLength(size_t in) { - return compressBound(in); - } - - static size_t Compress(TBlock in, TBlock out) { + } + }; + + /////////////////////////////////////////////////////////////////////////////// + // ZLIB + /////////////////////////////////////////////////////////////////////////////// + struct TZlibCodec { + static const int LEVEL = 6; + + static size_t MaxCompressedLength(size_t in) { + return compressBound(in); + } + + static size_t Compress(TBlock in, TBlock out) { uLong ret = out.size(); - int rc = compress2( + int rc = compress2( reinterpret_cast<Bytef*>(out.data()), - &ret, + &ret, reinterpret_cast<const Bytef*>(in.data()), in.size(), - LEVEL); - Y_ENSURE(rc == Z_OK, "zlib compression failed"); - return ret; - } - - static void Decompress(TBlock in, TBlock out) { + LEVEL); + Y_ENSURE(rc == Z_OK, "zlib compression failed"); + return ret; + } + + static void Decompress(TBlock in, TBlock out) { uLong ret = out.size(); - int rc = uncompress( + int rc = uncompress( reinterpret_cast<Bytef*>(out.data()), - &ret, + &ret, reinterpret_cast<const Bytef*>(in.data()), in.size()); - Y_ENSURE(rc == Z_OK, "zlib decompression failed"); + Y_ENSURE(rc == Z_OK, "zlib decompression failed"); Y_ENSURE(ret == out.size(), "zlib decompressed wrong size"); - } - }; - - // - // Framed streams use next frame structure: - // - // +-----------------+-------------------+============+------------------+ - // | compressed size | uncompressed size | data | check sum | - // +-----------------+-------------------+============+------------------+ - // 4 bytes 4 bytes var len 4 bytes - // - - /////////////////////////////////////////////////////////////////////////////// - // TFramedInputStream - /////////////////////////////////////////////////////////////////////////////// - template <typename TCodecAlg, typename TCheckSumAlg> - class TFramedDecompressStream final: public IWalkInput { - public: - explicit TFramedDecompressStream(IInputStream* in) - : In_(in) - { - } - - private: - size_t DoUnboundedNext(const void** ptr) override { - if (!In_) { - return 0; - } - - TFrameHeader header; - In_->LoadOrFail(&header, sizeof(header)); - - if (header.CompressedSize == 0) { - In_ = nullptr; - return 0; - } - + } + }; + + // + // Framed streams use next frame structure: + // + // +-----------------+-------------------+============+------------------+ + // | compressed size | uncompressed size | data | check sum | + // +-----------------+-------------------+============+------------------+ + // 4 bytes 4 bytes var len 4 bytes + // + + /////////////////////////////////////////////////////////////////////////////// + // TFramedInputStream + /////////////////////////////////////////////////////////////////////////////// + template <typename TCodecAlg, typename TCheckSumAlg> + class TFramedDecompressStream final: public IWalkInput { + public: + explicit TFramedDecompressStream(IInputStream* in) + : In_(in) + { + } + + private: + size_t DoUnboundedNext(const void** ptr) override { + if (!In_) { + return 0; + } + + TFrameHeader header; + In_->LoadOrFail(&header, sizeof(header)); + + if (header.CompressedSize == 0) { + In_ = nullptr; + return 0; + } + Y_ENSURE(header.CompressedSize <= COMPRESSED_FRAME_SIZE_LIMIT, "Compressed frame size is limited to " << HumanReadableSize(COMPRESSED_FRAME_SIZE_LIMIT, SF_BYTES) << " but is " << HumanReadableSize(header.CompressedSize, SF_BYTES)); @@ -216,87 +216,87 @@ namespace NMonitoring { << HumanReadableSize(UNCOMPRESSED_FRAME_SIZE_LIMIT, SF_BYTES) << " but is " << HumanReadableSize(header.UncompressedSize, SF_BYTES)); - Compressed_.Resize(header.CompressedSize); - In_->LoadOrFail(Compressed_.Data(), header.CompressedSize); - - TFrameFooter footer; - In_->LoadOrFail(&footer, sizeof(footer)); - Y_ENSURE(TCheckSumAlg::Check(Compressed_, footer.CheckSum), - "corrupted stream: check sum mismatch"); - - Uncompressed_.Resize(header.UncompressedSize); - TCodecAlg::Decompress(Compressed_, Uncompressed_); - - *ptr = Uncompressed_.Data(); - return Uncompressed_.Size(); - } - - private: - IInputStream* In_; - TBuffer Compressed_; - TBuffer Uncompressed_; - }; - - /////////////////////////////////////////////////////////////////////////////// - // TFramedOutputStream - /////////////////////////////////////////////////////////////////////////////// - template <typename TCodecAlg, typename TCheckSumAlg> + Compressed_.Resize(header.CompressedSize); + In_->LoadOrFail(Compressed_.Data(), header.CompressedSize); + + TFrameFooter footer; + In_->LoadOrFail(&footer, sizeof(footer)); + Y_ENSURE(TCheckSumAlg::Check(Compressed_, footer.CheckSum), + "corrupted stream: check sum mismatch"); + + Uncompressed_.Resize(header.UncompressedSize); + TCodecAlg::Decompress(Compressed_, Uncompressed_); + + *ptr = Uncompressed_.Data(); + return Uncompressed_.Size(); + } + + private: + IInputStream* In_; + TBuffer Compressed_; + TBuffer Uncompressed_; + }; + + /////////////////////////////////////////////////////////////////////////////// + // TFramedOutputStream + /////////////////////////////////////////////////////////////////////////////// + template <typename TCodecAlg, typename TCheckSumAlg> class TFramedCompressStream final: public IFramedCompressStream { - public: - explicit TFramedCompressStream(IOutputStream* out) - : Out_(out) - , Uncompressed_(DEFAULT_FRAME_LEN) - { - } - + public: + explicit TFramedCompressStream(IOutputStream* out) + : Out_(out) + , Uncompressed_(DEFAULT_FRAME_LEN) + { + } + ~TFramedCompressStream() override { - try { - Finish(); - } catch (...) { - } - } - - private: - void DoWrite(const void* buf, size_t len) override { - const char* in = static_cast<const char*>(buf); - - while (len != 0) { - const size_t avail = Uncompressed_.Avail(); - if (len < avail) { - Uncompressed_.Append(in, len); - return; - } - - Uncompressed_.Append(in, avail); - Y_ASSERT(Uncompressed_.Avail() == 0); - - in += avail; - len -= avail; - - WriteCompressedFrame(); - } - } - + try { + Finish(); + } catch (...) { + } + } + + private: + void DoWrite(const void* buf, size_t len) override { + const char* in = static_cast<const char*>(buf); + + while (len != 0) { + const size_t avail = Uncompressed_.Avail(); + if (len < avail) { + Uncompressed_.Append(in, len); + return; + } + + Uncompressed_.Append(in, avail); + Y_ASSERT(Uncompressed_.Avail() == 0); + + in += avail; + len -= avail; + + WriteCompressedFrame(); + } + } + void FlushWithoutEmptyFrame() override { - if (Out_ && !Uncompressed_.Empty()) { - WriteCompressedFrame(); - } - } - + if (Out_ && !Uncompressed_.Empty()) { + WriteCompressedFrame(); + } + } + void FinishAndWriteEmptyFrame() override { - if (Out_) { + if (Out_) { Y_DEFER { - Out_ = nullptr; + Out_ = nullptr; }; if (!Uncompressed_.Empty()) { WriteCompressedFrame(); - } + } WriteEmptyFrame(); - } - } - + } + } + void DoFlush() override { FlushWithoutEmptyFrame(); } @@ -305,79 +305,79 @@ namespace NMonitoring { FinishAndWriteEmptyFrame(); } - void WriteCompressedFrame() { - static const auto framePayload = sizeof(TFrameHeader) + sizeof(TFrameFooter); + void WriteCompressedFrame() { + static const auto framePayload = sizeof(TFrameHeader) + sizeof(TFrameFooter); const auto maxFrameSize = ui64(TCodecAlg::MaxCompressedLength(Uncompressed_.Size())) + framePayload; Y_ENSURE(maxFrameSize <= FRAME_SIZE_LIMIT, "Frame size in encoder is limited to " << HumanReadableSize(FRAME_SIZE_LIMIT, SF_BYTES) << " but is " << HumanReadableSize(maxFrameSize, SF_BYTES)); - + Frame_.Resize(maxFrameSize); - // compress - TBlock compressedBlock = Frame_; - compressedBlock.Skip(sizeof(TFrameHeader)); - compressedBlock.Trunc(TCodecAlg::Compress(Uncompressed_, compressedBlock)); - - // add header - auto header = reinterpret_cast<TFrameHeader*>(Frame_.Data()); + // compress + TBlock compressedBlock = Frame_; + compressedBlock.Skip(sizeof(TFrameHeader)); + compressedBlock.Trunc(TCodecAlg::Compress(Uncompressed_, compressedBlock)); + + // add header + auto header = reinterpret_cast<TFrameHeader*>(Frame_.Data()); header->CompressedSize = SafeIntegerCast<TCompressedSize>(compressedBlock.size()); - header->UncompressedSize = SafeIntegerCast<TUncompressedSize>(Uncompressed_.Size()); - - // add footer - auto footer = reinterpret_cast<TFrameFooter*>( - Frame_.Data() + sizeof(TFrameHeader) + header->CompressedSize); - footer->CheckSum = TCheckSumAlg::Calc(compressedBlock); - - // write - Out_->Write(Frame_.Data(), header->CompressedSize + framePayload); - Uncompressed_.Clear(); - } - - void WriteEmptyFrame() { - static const auto framePayload = sizeof(TFrameHeader) + sizeof(TFrameFooter); - char buf[framePayload] = {0}; - Out_->Write(buf, sizeof(buf)); - } - - private: - IOutputStream* Out_; - TBuffer Uncompressed_; - TBuffer Frame_; - }; - - } - - THolder<IInputStream> CompressedInput(IInputStream* in, ECompression alg) { - switch (alg) { - case ECompression::IDENTITY: - return nullptr; - case ECompression::ZLIB: + header->UncompressedSize = SafeIntegerCast<TUncompressedSize>(Uncompressed_.Size()); + + // add footer + auto footer = reinterpret_cast<TFrameFooter*>( + Frame_.Data() + sizeof(TFrameHeader) + header->CompressedSize); + footer->CheckSum = TCheckSumAlg::Calc(compressedBlock); + + // write + Out_->Write(Frame_.Data(), header->CompressedSize + framePayload); + Uncompressed_.Clear(); + } + + void WriteEmptyFrame() { + static const auto framePayload = sizeof(TFrameHeader) + sizeof(TFrameFooter); + char buf[framePayload] = {0}; + Out_->Write(buf, sizeof(buf)); + } + + private: + IOutputStream* Out_; + TBuffer Uncompressed_; + TBuffer Frame_; + }; + + } + + THolder<IInputStream> CompressedInput(IInputStream* in, ECompression alg) { + switch (alg) { + case ECompression::IDENTITY: + return nullptr; + case ECompression::ZLIB: return MakeHolder<TFramedDecompressStream<TZlibCodec, TAdler32>>(in); - case ECompression::ZSTD: + case ECompression::ZSTD: return MakeHolder<TFramedDecompressStream<TZstdCodec, TXxHash32>>(in); - case ECompression::LZ4: + case ECompression::LZ4: return MakeHolder<TFramedDecompressStream<TLz4Codec, TXxHash32>>(in); - case ECompression::UNKNOWN: - return nullptr; - } - Y_FAIL("invalid compression algorithm"); - } - + case ECompression::UNKNOWN: + return nullptr; + } + Y_FAIL("invalid compression algorithm"); + } + THolder<IFramedCompressStream> CompressedOutput(IOutputStream* out, ECompression alg) { - switch (alg) { - case ECompression::IDENTITY: - return nullptr; - case ECompression::ZLIB: + switch (alg) { + case ECompression::IDENTITY: + return nullptr; + case ECompression::ZLIB: return MakeHolder<TFramedCompressStream<TZlibCodec, TAdler32>>(out); - case ECompression::ZSTD: + case ECompression::ZSTD: return MakeHolder<TFramedCompressStream<TZstdCodec, TXxHash32>>(out); - case ECompression::LZ4: + case ECompression::LZ4: return MakeHolder<TFramedCompressStream<TLz4Codec, TXxHash32>>(out); - case ECompression::UNKNOWN: - return nullptr; - } - Y_FAIL("invalid compression algorithm"); - } - -} + case ECompression::UNKNOWN: + return nullptr; + } + Y_FAIL("invalid compression algorithm"); + } + +} diff --git a/library/cpp/monlib/encode/spack/compression.h b/library/cpp/monlib/encode/spack/compression.h index 1f99b0f5a0..f74d8b424e 100644 --- a/library/cpp/monlib/encode/spack/compression.h +++ b/library/cpp/monlib/encode/spack/compression.h @@ -1,12 +1,12 @@ -#pragma once - -#include "spack_v1.h" - -#include <util/stream/input.h> -#include <util/stream/output.h> - -namespace NMonitoring { - +#pragma once + +#include "spack_v1.h" + +#include <util/stream/input.h> +#include <util/stream/output.h> + +namespace NMonitoring { + class IFramedCompressStream: public IOutputStream { public: virtual void FlushWithoutEmptyFrame() = 0; diff --git a/library/cpp/monlib/encode/spack/fuzz/main.cpp b/library/cpp/monlib/encode/spack/fuzz/main.cpp index ac64b8b232..6a14afe71c 100644 --- a/library/cpp/monlib/encode/spack/fuzz/main.cpp +++ b/library/cpp/monlib/encode/spack/fuzz/main.cpp @@ -1,5 +1,5 @@ -#include <library/cpp/monlib/encode/spack/spack_v1.h> -#include <library/cpp/monlib/encode/fake/fake.h> +#include <library/cpp/monlib/encode/spack/spack_v1.h> +#include <library/cpp/monlib/encode/fake/fake.h> #include <util/stream/mem.h> diff --git a/library/cpp/monlib/encode/spack/fuzz/ya.make b/library/cpp/monlib/encode/spack/fuzz/ya.make index c43ee84f36..99b63eadd5 100644 --- a/library/cpp/monlib/encode/spack/fuzz/ya.make +++ b/library/cpp/monlib/encode/spack/fuzz/ya.make @@ -10,8 +10,8 @@ FUZZ_OPTS(-rss_limit_mb=1024) SIZE(MEDIUM) PEERDIR( - library/cpp/monlib/encode/spack - library/cpp/monlib/encode/fake + library/cpp/monlib/encode/spack + library/cpp/monlib/encode/fake ) SRCS( diff --git a/library/cpp/monlib/encode/spack/spack_v1.h b/library/cpp/monlib/encode/spack/spack_v1.h index 628f07de5c..cf1c9417b9 100644 --- a/library/cpp/monlib/encode/spack/spack_v1.h +++ b/library/cpp/monlib/encode/spack/spack_v1.h @@ -1,107 +1,107 @@ -#pragma once - -#include <library/cpp/monlib/encode/encoder.h> -#include <library/cpp/monlib/encode/format.h> -#include <library/cpp/monlib/metrics/metric.h> - -#include <util/generic/yexception.h> - -// -// format specification available here: -// https://wiki.yandex-team.ru/solomon/api/dataformat/spackv1/ -// - -class IInputStream; -class IOutputStream; - -namespace NMonitoring { +#pragma once + +#include <library/cpp/monlib/encode/encoder.h> +#include <library/cpp/monlib/encode/format.h> +#include <library/cpp/monlib/metrics/metric.h> + +#include <util/generic/yexception.h> + +// +// format specification available here: +// https://wiki.yandex-team.ru/solomon/api/dataformat/spackv1/ +// + +class IInputStream; +class IOutputStream; + +namespace NMonitoring { class TSpackDecodeError: public yexception { }; - constexpr auto EncodeMetricType(EMetricType mt) noexcept { - return static_cast<std::underlying_type_t<EMetricType>>(mt); - } - - EMetricType DecodeMetricType(ui8 byte); - + constexpr auto EncodeMetricType(EMetricType mt) noexcept { + return static_cast<std::underlying_type_t<EMetricType>>(mt); + } + + EMetricType DecodeMetricType(ui8 byte); + [[nodiscard]] bool TryDecodeMetricType(ui8 byte, EMetricType* result); - /////////////////////////////////////////////////////////////////////////////// - // EValueType - /////////////////////////////////////////////////////////////////////////////// - enum class EValueType : ui8 { - NONE = 0x00, - ONE_WITHOUT_TS = 0x01, - ONE_WITH_TS = 0x02, - MANY_WITH_TS = 0x03, - }; - - constexpr auto EncodeValueType(EValueType vt) noexcept { - return static_cast<std::underlying_type_t<EValueType>>(vt); - } - - EValueType DecodeValueType(ui8 byte); - + /////////////////////////////////////////////////////////////////////////////// + // EValueType + /////////////////////////////////////////////////////////////////////////////// + enum class EValueType : ui8 { + NONE = 0x00, + ONE_WITHOUT_TS = 0x01, + ONE_WITH_TS = 0x02, + MANY_WITH_TS = 0x03, + }; + + constexpr auto EncodeValueType(EValueType vt) noexcept { + return static_cast<std::underlying_type_t<EValueType>>(vt); + } + + EValueType DecodeValueType(ui8 byte); + [[nodiscard]] bool TryDecodeValueType(ui8 byte, EValueType* result); - /////////////////////////////////////////////////////////////////////////////// - // ETimePrecision - /////////////////////////////////////////////////////////////////////////////// - enum class ETimePrecision : ui8 { - SECONDS = 0x00, - MILLIS = 0x01, - }; - - constexpr auto EncodeTimePrecision(ETimePrecision tp) noexcept { - return static_cast<std::underlying_type_t<ETimePrecision>>(tp); - } - - ETimePrecision DecodeTimePrecision(ui8 byte); - + /////////////////////////////////////////////////////////////////////////////// + // ETimePrecision + /////////////////////////////////////////////////////////////////////////////// + enum class ETimePrecision : ui8 { + SECONDS = 0x00, + MILLIS = 0x01, + }; + + constexpr auto EncodeTimePrecision(ETimePrecision tp) noexcept { + return static_cast<std::underlying_type_t<ETimePrecision>>(tp); + } + + ETimePrecision DecodeTimePrecision(ui8 byte); + [[nodiscard]] bool TryDecodeTimePrecision(ui8 byte, ETimePrecision* result); - /////////////////////////////////////////////////////////////////////////////// - // ECompression - /////////////////////////////////////////////////////////////////////////////// - ui8 EncodeCompression(ECompression c) noexcept; - - ECompression DecodeCompression(ui8 byte); - + /////////////////////////////////////////////////////////////////////////////// + // ECompression + /////////////////////////////////////////////////////////////////////////////// + ui8 EncodeCompression(ECompression c) noexcept; + + ECompression DecodeCompression(ui8 byte); + [[nodiscard]] bool TryDecodeCompression(ui8 byte, ECompression* result); - /////////////////////////////////////////////////////////////////////////////// - // TSpackHeader - /////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// + // TSpackHeader + /////////////////////////////////////////////////////////////////////////////// struct Y_PACKED TSpackHeader { - ui16 Magic = 0x5053; // "SP" + ui16 Magic = 0x5053; // "SP" ui16 Version; // MSB - major version, LSB - minor version - ui16 HeaderSize = sizeof(TSpackHeader); - ui8 TimePrecision; - ui8 Compression; - ui32 LabelNamesSize; - ui32 LabelValuesSize; - ui32 MetricCount; - ui32 PointsCount; - // add new fields here - }; - + ui16 HeaderSize = sizeof(TSpackHeader); + ui8 TimePrecision; + ui8 Compression; + ui32 LabelNamesSize; + ui32 LabelValuesSize; + ui32 MetricCount; + ui32 PointsCount; + // add new fields here + }; + enum ESpackV1Version: ui16 { SV1_00 = 0x0100, SV1_01 = 0x0101, SV1_02 = 0x0102 }; - IMetricEncoderPtr EncoderSpackV1( - IOutputStream* out, - ETimePrecision timePrecision, + IMetricEncoderPtr EncoderSpackV1( + IOutputStream* out, + ETimePrecision timePrecision, ECompression compression, - EMetricsMergingMode mergingMode = EMetricsMergingMode::DEFAULT + EMetricsMergingMode mergingMode = EMetricsMergingMode::DEFAULT ); - + IMetricEncoderPtr EncoderSpackV12( IOutputStream* out, ETimePrecision timePrecision, @@ -109,7 +109,7 @@ namespace NMonitoring { EMetricsMergingMode mergingMode = EMetricsMergingMode::DEFAULT, TStringBuf metricNameLabel = "name" ); - + void DecodeSpackV1(IInputStream* in, IMetricConsumer* c, TStringBuf metricNameLabel = "name"); -} +} diff --git a/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp b/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp index a6dadc08a8..1f445fc80d 100644 --- a/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp +++ b/library/cpp/monlib/encode/spack/spack_v1_decoder.cpp @@ -1,189 +1,189 @@ -#include "spack_v1.h" -#include "varint.h" -#include "compression.h" - -#include <library/cpp/monlib/encode/buffered/string_pool.h> +#include "spack_v1.h" +#include "varint.h" +#include "compression.h" + +#include <library/cpp/monlib/encode/buffered/string_pool.h> #include <library/cpp/monlib/exception/exception.h> -#include <library/cpp/monlib/metrics/histogram_collector.h> +#include <library/cpp/monlib/metrics/histogram_collector.h> #include <library/cpp/monlib/metrics/metric.h> - -#include <util/generic/yexception.h> -#include <util/generic/buffer.h> + +#include <util/generic/yexception.h> +#include <util/generic/buffer.h> #include <util/generic/size_literals.h> #include <util/stream/format.h> - -#ifndef _little_endian_ -#error Unsupported platform -#endif - -namespace NMonitoring { - namespace { + +#ifndef _little_endian_ +#error Unsupported platform +#endif + +namespace NMonitoring { + namespace { #define DECODE_ENSURE(COND, ...) MONLIB_ENSURE_EX(COND, TSpackDecodeError() << __VA_ARGS__) constexpr ui64 LABEL_SIZE_LIMIT = 128_MB; - /////////////////////////////////////////////////////////////////////// - // TDecoderSpackV1 - /////////////////////////////////////////////////////////////////////// - class TDecoderSpackV1 { - public: + /////////////////////////////////////////////////////////////////////// + // TDecoderSpackV1 + /////////////////////////////////////////////////////////////////////// + class TDecoderSpackV1 { + public: TDecoderSpackV1(IInputStream* in, TStringBuf metricNameLabel) - : In_(in) + : In_(in) , MetricNameLabel_(metricNameLabel) - { - } - - void Decode(IMetricConsumer* c) { - c->OnStreamBegin(); - - // (1) read header + { + } + + void Decode(IMetricConsumer* c) { + c->OnStreamBegin(); + + // (1) read header size_t readBytes = In_->Read(&Header_, sizeof(Header_)); DECODE_ENSURE(readBytes == sizeof(Header_), "not enough data in input stream to read header"); - + ui8 version = ((Header_.Version >> 8) & 0xff); DECODE_ENSURE(version == 1, "versions mismatch (expected: 1, got: " << +version << ')'); - + DECODE_ENSURE(Header_.HeaderSize >= sizeof(Header_), "invalid header size"); if (size_t skipBytes = Header_.HeaderSize - sizeof(Header_)) { DECODE_ENSURE(In_->Skip(skipBytes) == skipBytes, "input stream unexpectedly ended"); - } - - if (Header_.MetricCount == 0) { - // emulate empty stream - c->OnStreamEnd(); - return; - } - - // if compression enabled all below reads must go throught decompressor + } + + if (Header_.MetricCount == 0) { + // emulate empty stream + c->OnStreamEnd(); + return; + } + + // if compression enabled all below reads must go throught decompressor auto compressedIn = CompressedInput(In_, DecodeCompression(Header_.Compression)); - if (compressedIn) { - In_ = compressedIn.Get(); - } - + if (compressedIn) { + In_ = compressedIn.Get(); + } + TimePrecision_ = DecodeTimePrecision(Header_.TimePrecision); - + const ui64 labelSizeTotal = ui64(Header_.LabelNamesSize) + Header_.LabelValuesSize; DECODE_ENSURE(labelSizeTotal <= LABEL_SIZE_LIMIT, "Label names & values size of " << HumanReadableSize(labelSizeTotal, SF_BYTES) << " exceeds the limit which is " << HumanReadableSize(LABEL_SIZE_LIMIT, SF_BYTES)); - // (2) read string pools + // (2) read string pools TVector<char> namesBuf(Header_.LabelNamesSize); readBytes = In_->Load(namesBuf.data(), namesBuf.size()); DECODE_ENSURE(readBytes == Header_.LabelNamesSize, "not enough data to read label names pool"); TStringPool labelNames(namesBuf.data(), namesBuf.size()); - + TVector<char> valuesBuf(Header_.LabelValuesSize); readBytes = In_->Load(valuesBuf.data(), valuesBuf.size()); DECODE_ENSURE(readBytes == Header_.LabelValuesSize, "not enough data to read label values pool"); TStringPool labelValues(valuesBuf.data(), valuesBuf.size()); - - // (3) read common time - c->OnCommonTime(ReadTime()); - - // (4) read common labels - if (ui32 commonLabelsCount = ReadVarint()) { + + // (3) read common time + c->OnCommonTime(ReadTime()); + + // (4) read common labels + if (ui32 commonLabelsCount = ReadVarint()) { c->OnLabelsBegin(); - ReadLabels(labelNames, labelValues, commonLabelsCount, c); + ReadLabels(labelNames, labelValues, commonLabelsCount, c); c->OnLabelsEnd(); - } - - // (5) read metrics - ReadMetrics(labelNames, labelValues, c); - c->OnStreamEnd(); - } - - private: - void ReadMetrics( - const TStringPool& labelNames, - const TStringPool& labelValues, - IMetricConsumer* c) - { - for (ui32 i = 0; i < Header_.MetricCount; i++) { - // (5.1) types byte - ui8 typesByte = ReadFixed<ui8>(); - EMetricType metricType = DecodeMetricType(typesByte >> 2); - EValueType valueType = DecodeValueType(typesByte & 0x03); - - c->OnMetricBegin(metricType); - - // TODO: use it - ReadFixed<ui8>(); // skip flags byte - + } + + // (5) read metrics + ReadMetrics(labelNames, labelValues, c); + c->OnStreamEnd(); + } + + private: + void ReadMetrics( + const TStringPool& labelNames, + const TStringPool& labelValues, + IMetricConsumer* c) + { + for (ui32 i = 0; i < Header_.MetricCount; i++) { + // (5.1) types byte + ui8 typesByte = ReadFixed<ui8>(); + EMetricType metricType = DecodeMetricType(typesByte >> 2); + EValueType valueType = DecodeValueType(typesByte & 0x03); + + c->OnMetricBegin(metricType); + + // TODO: use it + ReadFixed<ui8>(); // skip flags byte + auto metricNameValueIndex = std::numeric_limits<ui32>::max(); if (Header_.Version >= SV1_02) { metricNameValueIndex = ReadVarint(); } - // (5.2) labels - ui32 labelsCount = ReadVarint(); + // (5.2) labels + ui32 labelsCount = ReadVarint(); DECODE_ENSURE(Header_.Version >= SV1_02 || labelsCount > 0, "metric #" << i << " has no labels"); c->OnLabelsBegin(); if (Header_.Version >= SV1_02) { c->OnLabel(MetricNameLabel_, labelValues.Get(metricNameValueIndex)); } - ReadLabels(labelNames, labelValues, labelsCount, c); + ReadLabels(labelNames, labelValues, labelsCount, c); c->OnLabelsEnd(); - - // (5.3) values - switch (valueType) { - case EValueType::NONE: - break; - case EValueType::ONE_WITHOUT_TS: - ReadValue(metricType, TInstant::Zero(), c); - break; - case EValueType::ONE_WITH_TS: { - TInstant time = ReadTime(); - ReadValue(metricType, time, c); - break; - } - case EValueType::MANY_WITH_TS: { - ui32 pointsCount = ReadVarint(); - for (ui32 i = 0; i < pointsCount; i++) { - TInstant time = ReadTime(); - ReadValue(metricType, time, c); - } - break; - } - } - - c->OnMetricEnd(); - } - } - - void ReadValue(EMetricType metricType, TInstant time, IMetricConsumer* c) { - switch (metricType) { - case EMetricType::GAUGE: - c->OnDouble(time, ReadFixed<double>()); - break; - - case EMetricType::IGAUGE: - c->OnInt64(time, ReadFixed<i64>()); - break; - - case EMetricType::COUNTER: - case EMetricType::RATE: - c->OnUint64(time, ReadFixed<ui64>()); - break; - - case EMetricType::DSUMMARY: + + // (5.3) values + switch (valueType) { + case EValueType::NONE: + break; + case EValueType::ONE_WITHOUT_TS: + ReadValue(metricType, TInstant::Zero(), c); + break; + case EValueType::ONE_WITH_TS: { + TInstant time = ReadTime(); + ReadValue(metricType, time, c); + break; + } + case EValueType::MANY_WITH_TS: { + ui32 pointsCount = ReadVarint(); + for (ui32 i = 0; i < pointsCount; i++) { + TInstant time = ReadTime(); + ReadValue(metricType, time, c); + } + break; + } + } + + c->OnMetricEnd(); + } + } + + void ReadValue(EMetricType metricType, TInstant time, IMetricConsumer* c) { + switch (metricType) { + case EMetricType::GAUGE: + c->OnDouble(time, ReadFixed<double>()); + break; + + case EMetricType::IGAUGE: + c->OnInt64(time, ReadFixed<i64>()); + break; + + case EMetricType::COUNTER: + case EMetricType::RATE: + c->OnUint64(time, ReadFixed<ui64>()); + break; + + case EMetricType::DSUMMARY: c->OnSummaryDouble(time, ReadSummaryDouble()); break; - case EMetricType::HIST: - case EMetricType::HIST_RATE: - c->OnHistogram(time, ReadHistogram()); - break; - + case EMetricType::HIST: + case EMetricType::HIST_RATE: + c->OnHistogram(time, ReadHistogram()); + break; + case EMetricType::LOGHIST: c->OnLogHistogram(time, ReadLogHistogram()); break; - default: + default: throw TSpackDecodeError() << "Unsupported metric type: " << metricType; - } - } - + } + } + ISummaryDoubleSnapshotPtr ReadSummaryDouble() { ui64 count = ReadFixed<ui64>(); double sum = ReadFixed<double>(); @@ -198,10 +198,10 @@ namespace NMonitoring { ui64 zerosCount = ReadFixed<ui64>(); int startPower = static_cast<int>(ReadVarint()); ui32 count = ReadVarint(); - // see https://a.yandex-team.ru/arc/trunk/arcadia/infra/yasm/stockpile_client/points.cpp?rev=r8593154#L31 - // and https://a.yandex-team.ru/arc/trunk/arcadia/infra/yasm/common/points/hgram/normal/normal.h?rev=r8268697#L9 - // TODO: share this constant value - Y_ENSURE(count <= 100u, "more than 100 buckets in log histogram: " << count); + // see https://a.yandex-team.ru/arc/trunk/arcadia/infra/yasm/stockpile_client/points.cpp?rev=r8593154#L31 + // and https://a.yandex-team.ru/arc/trunk/arcadia/infra/yasm/common/points/hgram/normal/normal.h?rev=r8268697#L9 + // TODO: share this constant value + Y_ENSURE(count <= 100u, "more than 100 buckets in log histogram: " << count); TVector<double> buckets; buckets.reserve(count); for (ui32 i = 0; i < count; ++i) { @@ -210,17 +210,17 @@ namespace NMonitoring { return MakeIntrusive<TLogHistogramSnapshot>(base, zerosCount, startPower, std::move(buckets)); } - IHistogramSnapshotPtr ReadHistogram() { - ui32 bucketsCount = ReadVarint(); + IHistogramSnapshotPtr ReadHistogram() { + ui32 bucketsCount = ReadVarint(); auto s = TExplicitHistogramSnapshot::New(bucketsCount); - + if (SV1_00 == Header_.Version) { // v1.0 for (ui32 i = 0; i < bucketsCount; i++) { i64 bound = ReadFixed<i64>(); double doubleBound = (bound != Max<i64>()) ? static_cast<double>(bound) : Max<double>(); - + (*s)[i].first = doubleBound; } } else { @@ -228,62 +228,62 @@ namespace NMonitoring { double doubleBound = ReadFixed<double>(); (*s)[i].first = doubleBound; } - } - - - // values - for (ui32 i = 0; i < bucketsCount; i++) { - (*s)[i].second = ReadFixed<ui64>(); - } - return s; - } - - void ReadLabels( - const TStringPool& labelNames, - const TStringPool& labelValues, - ui32 count, - IMetricConsumer* c) - { - for (ui32 i = 0; i < count; i++) { + } + + + // values + for (ui32 i = 0; i < bucketsCount; i++) { + (*s)[i].second = ReadFixed<ui64>(); + } + return s; + } + + void ReadLabels( + const TStringPool& labelNames, + const TStringPool& labelValues, + ui32 count, + IMetricConsumer* c) + { + for (ui32 i = 0; i < count; i++) { auto nameIdx = ReadVarint(); auto valueIdx = ReadVarint(); c->OnLabel(labelNames.Get(nameIdx), labelValues.Get(valueIdx)); - } - } - - TInstant ReadTime() { - switch (TimePrecision_) { - case ETimePrecision::SECONDS: - return TInstant::Seconds(ReadFixed<ui32>()); - case ETimePrecision::MILLIS: - return TInstant::MilliSeconds(ReadFixed<ui64>()); - } - Y_FAIL("invalid time precision"); - } - - template <typename T> - inline T ReadFixed() { - T value; - size_t readBytes = In_->Load(&value, sizeof(T)); + } + } + + TInstant ReadTime() { + switch (TimePrecision_) { + case ETimePrecision::SECONDS: + return TInstant::Seconds(ReadFixed<ui32>()); + case ETimePrecision::MILLIS: + return TInstant::MilliSeconds(ReadFixed<ui64>()); + } + Y_FAIL("invalid time precision"); + } + + template <typename T> + inline T ReadFixed() { + T value; + size_t readBytes = In_->Load(&value, sizeof(T)); DECODE_ENSURE(readBytes == sizeof(T), "no enough data to read " << TypeName<T>()); - return value; - } - - inline ui32 ReadVarint() { - return ReadVarUInt32(In_); - } - - private: - IInputStream* In_; + return value; + } + + inline ui32 ReadVarint() { + return ReadVarUInt32(In_); + } + + private: + IInputStream* In_; TString MetricNameLabel_; - ETimePrecision TimePrecision_; + ETimePrecision TimePrecision_; TSpackHeader Header_; }; // class TDecoderSpackV1 - + #undef DECODE_ENSURE } // namespace - - EValueType DecodeValueType(ui8 byte) { + + EValueType DecodeValueType(ui8 byte) { EValueType result; if (!TryDecodeValueType(byte, &result)) { throw TSpackDecodeError() << "unknown value type: " << byte; @@ -292,32 +292,32 @@ namespace NMonitoring { } bool TryDecodeValueType(ui8 byte, EValueType* result) { - if (byte == EncodeValueType(EValueType::NONE)) { + if (byte == EncodeValueType(EValueType::NONE)) { if (result) { *result = EValueType::NONE; } return true; - } else if (byte == EncodeValueType(EValueType::ONE_WITHOUT_TS)) { + } else if (byte == EncodeValueType(EValueType::ONE_WITHOUT_TS)) { if (result) { *result = EValueType::ONE_WITHOUT_TS; } return true; - } else if (byte == EncodeValueType(EValueType::ONE_WITH_TS)) { + } else if (byte == EncodeValueType(EValueType::ONE_WITH_TS)) { if (result) { *result = EValueType::ONE_WITH_TS; } return true; - } else if (byte == EncodeValueType(EValueType::MANY_WITH_TS)) { + } else if (byte == EncodeValueType(EValueType::MANY_WITH_TS)) { if (result) { *result = EValueType::MANY_WITH_TS; } return true; - } else { + } else { return false; - } - } - - ETimePrecision DecodeTimePrecision(ui8 byte) { + } + } + + ETimePrecision DecodeTimePrecision(ui8 byte) { ETimePrecision result; if (!TryDecodeTimePrecision(byte, &result)) { throw TSpackDecodeError() << "unknown time precision: " << byte; @@ -326,22 +326,22 @@ namespace NMonitoring { } bool TryDecodeTimePrecision(ui8 byte, ETimePrecision* result) { - if (byte == EncodeTimePrecision(ETimePrecision::SECONDS)) { + if (byte == EncodeTimePrecision(ETimePrecision::SECONDS)) { if (result) { *result = ETimePrecision::SECONDS; } return true; - } else if (byte == EncodeTimePrecision(ETimePrecision::MILLIS)) { + } else if (byte == EncodeTimePrecision(ETimePrecision::MILLIS)) { if (result) { *result = ETimePrecision::MILLIS; } return true; - } else { + } else { return false; - } - } - - EMetricType DecodeMetricType(ui8 byte) { + } + } + + EMetricType DecodeMetricType(ui8 byte) { EMetricType result; if (!TryDecodeMetricType(byte, &result)) { throw TSpackDecodeError() << "unknown metric type: " << byte; @@ -350,37 +350,37 @@ namespace NMonitoring { } bool TryDecodeMetricType(ui8 byte, EMetricType* result) { - if (byte == EncodeMetricType(EMetricType::GAUGE)) { + if (byte == EncodeMetricType(EMetricType::GAUGE)) { if (result) { *result = EMetricType::GAUGE; } return true; - } else if (byte == EncodeMetricType(EMetricType::COUNTER)) { + } else if (byte == EncodeMetricType(EMetricType::COUNTER)) { if (result) { *result = EMetricType::COUNTER; } return true; - } else if (byte == EncodeMetricType(EMetricType::RATE)) { + } else if (byte == EncodeMetricType(EMetricType::RATE)) { if (result) { *result = EMetricType::RATE; } return true; - } else if (byte == EncodeMetricType(EMetricType::IGAUGE)) { + } else if (byte == EncodeMetricType(EMetricType::IGAUGE)) { if (result) { *result = EMetricType::IGAUGE; } return true; - } else if (byte == EncodeMetricType(EMetricType::HIST)) { + } else if (byte == EncodeMetricType(EMetricType::HIST)) { if (result) { *result = EMetricType::HIST; } return true; - } else if (byte == EncodeMetricType(EMetricType::HIST_RATE)) { + } else if (byte == EncodeMetricType(EMetricType::HIST_RATE)) { if (result) { *result = EMetricType::HIST_RATE; } return true; - } else if (byte == EncodeMetricType(EMetricType::DSUMMARY)) { + } else if (byte == EncodeMetricType(EMetricType::DSUMMARY)) { if (result) { *result = EMetricType::DSUMMARY; } @@ -390,33 +390,33 @@ namespace NMonitoring { *result = EMetricType::LOGHIST; } return true; - } else if (byte == EncodeMetricType(EMetricType::UNKNOWN)) { + } else if (byte == EncodeMetricType(EMetricType::UNKNOWN)) { if (result) { *result = EMetricType::UNKNOWN; } return true; - } else { + } else { return false; - } - } - - ui8 EncodeCompression(ECompression c) noexcept { - switch (c) { - case ECompression::IDENTITY: - return 0x00; - case ECompression::ZLIB: - return 0x01; - case ECompression::ZSTD: - return 0x02; - case ECompression::LZ4: - return 0x03; - case ECompression::UNKNOWN: - return Max<ui8>(); - } - Y_FAIL(); // for GCC - } - - ECompression DecodeCompression(ui8 byte) { + } + } + + ui8 EncodeCompression(ECompression c) noexcept { + switch (c) { + case ECompression::IDENTITY: + return 0x00; + case ECompression::ZLIB: + return 0x01; + case ECompression::ZSTD: + return 0x02; + case ECompression::LZ4: + return 0x03; + case ECompression::UNKNOWN: + return Max<ui8>(); + } + Y_FAIL(); // for GCC + } + + ECompression DecodeCompression(ui8 byte) { ECompression result; if (!TryDecodeCompression(byte, &result)) { throw TSpackDecodeError() << "unknown compression alg: " << byte; @@ -425,34 +425,34 @@ namespace NMonitoring { } bool TryDecodeCompression(ui8 byte, ECompression* result) { - if (byte == EncodeCompression(ECompression::IDENTITY)) { + if (byte == EncodeCompression(ECompression::IDENTITY)) { if (result) { *result = ECompression::IDENTITY; } return true; - } else if (byte == EncodeCompression(ECompression::ZLIB)) { + } else if (byte == EncodeCompression(ECompression::ZLIB)) { if (result) { *result = ECompression::ZLIB; } return true; - } else if (byte == EncodeCompression(ECompression::ZSTD)) { + } else if (byte == EncodeCompression(ECompression::ZSTD)) { if (result) { *result = ECompression::ZSTD; } return true; - } else if (byte == EncodeCompression(ECompression::LZ4)) { + } else if (byte == EncodeCompression(ECompression::LZ4)) { if (result) { *result = ECompression::LZ4; } return true; - } else { + } else { return false; - } - } - + } + } + void DecodeSpackV1(IInputStream* in, IMetricConsumer* c, TStringBuf metricNameLabel) { TDecoderSpackV1 decoder(in, metricNameLabel); - decoder.Decode(c); - } - -} + decoder.Decode(c); + } + +} diff --git a/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp b/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp index f4f5b88073..a2b0bb5f50 100644 --- a/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp +++ b/library/cpp/monlib/encode/spack/spack_v1_encoder.cpp @@ -1,65 +1,65 @@ -#include "spack_v1.h" -#include "compression.h" -#include "varint.h" - -#include <library/cpp/monlib/encode/buffered/buffered_encoder_base.h> - -#include <util/generic/cast.h> -#include <util/datetime/base.h> -#include <util/string/builder.h> - -#ifndef _little_endian_ -#error Unsupported platform -#endif - -namespace NMonitoring { - namespace { - /////////////////////////////////////////////////////////////////////// - // TEncoderSpackV1 - /////////////////////////////////////////////////////////////////////// +#include "spack_v1.h" +#include "compression.h" +#include "varint.h" + +#include <library/cpp/monlib/encode/buffered/buffered_encoder_base.h> + +#include <util/generic/cast.h> +#include <util/datetime/base.h> +#include <util/string/builder.h> + +#ifndef _little_endian_ +#error Unsupported platform +#endif + +namespace NMonitoring { + namespace { + /////////////////////////////////////////////////////////////////////// + // TEncoderSpackV1 + /////////////////////////////////////////////////////////////////////// class TEncoderSpackV1 final: public TBufferedEncoderBase { - public: - TEncoderSpackV1( - IOutputStream* out, - ETimePrecision timePrecision, + public: + TEncoderSpackV1( + IOutputStream* out, + ETimePrecision timePrecision, ECompression compression, EMetricsMergingMode mergingMode, ESpackV1Version version, TStringBuf metricNameLabel ) - : Out_(out) - , TimePrecision_(timePrecision) - , Compression_(compression) + : Out_(out) + , TimePrecision_(timePrecision) + , Compression_(compression) , Version_(version) , MetricName_(Version_ >= SV1_02 ? LabelNamesPool_.PutIfAbsent(metricNameLabel) : nullptr) - { - MetricsMergingMode_ = mergingMode; + { + MetricsMergingMode_ = mergingMode; LabelNamesPool_.SetSorted(true); LabelValuesPool_.SetSorted(true); - } - + } + ~TEncoderSpackV1() override { - Close(); - } - - private: - void OnDouble(TInstant time, double value) override { + Close(); + } + + private: + void OnDouble(TInstant time, double value) override { TBufferedEncoderBase::OnDouble(time, value); - } - - void OnInt64(TInstant time, i64 value) override { - TBufferedEncoderBase::OnInt64(time, value); - } - - void OnUint64(TInstant time, ui64 value) override { + } + + void OnInt64(TInstant time, i64 value) override { + TBufferedEncoderBase::OnInt64(time, value); + } + + void OnUint64(TInstant time, ui64 value) override { TBufferedEncoderBase::OnUint64(time, value); - } - - void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { - TBufferedEncoderBase::OnHistogram(time, snapshot); - } - + } + + void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { + TBufferedEncoderBase::OnHistogram(time, snapshot); + } + void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override { TBufferedEncoderBase::OnSummaryDouble(time, snapshot); } @@ -68,70 +68,70 @@ namespace NMonitoring { TBufferedEncoderBase::OnLogHistogram(time, snapshot); } - void Close() override { - if (Closed_) { - return; - } - Closed_ = true; - + void Close() override { + if (Closed_) { + return; + } + Closed_ = true; + LabelNamesPool_.Build(); LabelValuesPool_.Build(); - + // Sort all points uniquely by ts -- the size can decrease ui64 pointsCount = 0; - for (TMetric& metric : Metrics_) { - if (metric.TimeSeries.Size() > 1) { - metric.TimeSeries.SortByTs(); + for (TMetric& metric : Metrics_) { + if (metric.TimeSeries.Size() > 1) { + metric.TimeSeries.SortByTs(); } - pointsCount += metric.TimeSeries.Size(); + pointsCount += metric.TimeSeries.Size(); } - // (1) write header - TSpackHeader header; + // (1) write header + TSpackHeader header; header.Version = Version_; - header.TimePrecision = EncodeTimePrecision(TimePrecision_); - header.Compression = EncodeCompression(Compression_); - header.LabelNamesSize = static_cast<ui32>( - LabelNamesPool_.BytesSize() + LabelNamesPool_.Count()); - header.LabelValuesSize = static_cast<ui32>( - LabelValuesPool_.BytesSize() + LabelValuesPool_.Count()); - header.MetricCount = Metrics_.size(); + header.TimePrecision = EncodeTimePrecision(TimePrecision_); + header.Compression = EncodeCompression(Compression_); + header.LabelNamesSize = static_cast<ui32>( + LabelNamesPool_.BytesSize() + LabelNamesPool_.Count()); + header.LabelValuesSize = static_cast<ui32>( + LabelValuesPool_.BytesSize() + LabelValuesPool_.Count()); + header.MetricCount = Metrics_.size(); header.PointsCount = pointsCount; - Out_->Write(&header, sizeof(header)); - - // if compression enabled all below writes must go throught compressor - auto compressedOut = CompressedOutput(Out_, Compression_); - if (compressedOut) { - Out_ = compressedOut.Get(); - } - - // (2) write string pools - auto strPoolWrite = [this](TStringBuf str, ui32, ui32) { - Out_->Write(str); - Out_->Write('\0'); - }; - - LabelNamesPool_.ForEach(strPoolWrite); - LabelValuesPool_.ForEach(strPoolWrite); - - // (3) write common time - WriteTime(CommonTime_); - - // (4) write common labels' indexes + Out_->Write(&header, sizeof(header)); + + // if compression enabled all below writes must go throught compressor + auto compressedOut = CompressedOutput(Out_, Compression_); + if (compressedOut) { + Out_ = compressedOut.Get(); + } + + // (2) write string pools + auto strPoolWrite = [this](TStringBuf str, ui32, ui32) { + Out_->Write(str); + Out_->Write('\0'); + }; + + LabelNamesPool_.ForEach(strPoolWrite); + LabelValuesPool_.ForEach(strPoolWrite); + + // (3) write common time + WriteTime(CommonTime_); + + // (4) write common labels' indexes WriteLabels(CommonLabels_, nullptr); - - // (5) write metrics - // metrics count already written in header - for (TMetric& metric : Metrics_) { - // (5.1) types byte - ui8 typesByte = PackTypes(metric); - Out_->Write(&typesByte, sizeof(typesByte)); - - // TODO: implement - ui8 flagsByte = 0x00; - Out_->Write(&flagsByte, sizeof(flagsByte)); - + + // (5) write metrics + // metrics count already written in header + for (TMetric& metric : Metrics_) { + // (5.1) types byte + ui8 typesByte = PackTypes(metric); + Out_->Write(&typesByte, sizeof(typesByte)); + + // TODO: implement + ui8 flagsByte = 0x00; + Out_->Write(&flagsByte, sizeof(flagsByte)); + // v1.2 format addition — metric name if (Version_ >= SV1_02) { const auto it = FindIf(metric.Labels, [&](const auto& l) { @@ -143,53 +143,53 @@ namespace NMonitoring { WriteVarUInt32(Out_, it->Value->Index); } - // (5.2) labels + // (5.2) labels WriteLabels(metric.Labels, MetricName_); - - // (5.3) values - switch (metric.TimeSeries.Size()) { - case 0: - break; - case 1: { - const auto& point = metric.TimeSeries[0]; - if (point.GetTime() != TInstant::Zero()) { - WriteTime(point.GetTime()); - } - EMetricValueType valueType = metric.TimeSeries.GetValueType(); - WriteValue(metric.MetricType, valueType, point.GetValue()); - break; - } - default: - WriteVarUInt32(Out_, static_cast<ui32>(metric.TimeSeries.Size())); - const TMetricTimeSeries& ts = metric.TimeSeries; - EMetricType metricType = metric.MetricType; - ts.ForEach([this, metricType](TInstant time, EMetricValueType valueType, TMetricValue value) { - // workaround for GCC bug - // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61636 - this->WriteTime(time); - this->WriteValue(metricType, valueType, value); - }); - break; - } - } - } - - // store metric type and values type in one byte - ui8 PackTypes(const TMetric& metric) { - EValueType valueType; - if (metric.TimeSeries.Empty()) { - valueType = EValueType::NONE; - } else if (metric.TimeSeries.Size() == 1) { - TInstant time = metric.TimeSeries[0].GetTime(); - valueType = (time == TInstant::Zero()) - ? EValueType::ONE_WITHOUT_TS - : EValueType::ONE_WITH_TS; - } else { - valueType = EValueType::MANY_WITH_TS; - } - return (static_cast<ui8>(metric.MetricType) << 2) | static_cast<ui8>(valueType); - } - + + // (5.3) values + switch (metric.TimeSeries.Size()) { + case 0: + break; + case 1: { + const auto& point = metric.TimeSeries[0]; + if (point.GetTime() != TInstant::Zero()) { + WriteTime(point.GetTime()); + } + EMetricValueType valueType = metric.TimeSeries.GetValueType(); + WriteValue(metric.MetricType, valueType, point.GetValue()); + break; + } + default: + WriteVarUInt32(Out_, static_cast<ui32>(metric.TimeSeries.Size())); + const TMetricTimeSeries& ts = metric.TimeSeries; + EMetricType metricType = metric.MetricType; + ts.ForEach([this, metricType](TInstant time, EMetricValueType valueType, TMetricValue value) { + // workaround for GCC bug + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61636 + this->WriteTime(time); + this->WriteValue(metricType, valueType, value); + }); + break; + } + } + } + + // store metric type and values type in one byte + ui8 PackTypes(const TMetric& metric) { + EValueType valueType; + if (metric.TimeSeries.Empty()) { + valueType = EValueType::NONE; + } else if (metric.TimeSeries.Size() == 1) { + TInstant time = metric.TimeSeries[0].GetTime(); + valueType = (time == TInstant::Zero()) + ? EValueType::ONE_WITHOUT_TS + : EValueType::ONE_WITH_TS; + } else { + valueType = EValueType::MANY_WITH_TS; + } + return (static_cast<ui8>(metric.MetricType) << 2) | static_cast<ui8>(valueType); + } + void WriteLabels(const TPooledLabels& labels, const TPooledStr* skipKey) { WriteVarUInt32(Out_, static_cast<ui32>(skipKey ? labels.size() - 1 : labels.size())); for (auto&& label : labels) { @@ -198,30 +198,30 @@ namespace NMonitoring { } WriteVarUInt32(Out_, label.Key->Index); WriteVarUInt32(Out_, label.Value->Index); - } - } - - void WriteValue(EMetricType metricType, EMetricValueType valueType, TMetricValue value) { - switch (metricType) { - case EMetricType::GAUGE: - WriteFixed(value.AsDouble(valueType)); - break; - - case EMetricType::IGAUGE: - WriteFixed(value.AsInt64(valueType)); - break; - - case EMetricType::COUNTER: - case EMetricType::RATE: - WriteFixed(value.AsUint64(valueType)); - break; - - case EMetricType::HIST: - case EMetricType::HIST_RATE: - WriteHistogram(*value.AsHistogram()); - break; - - case EMetricType::DSUMMARY: + } + } + + void WriteValue(EMetricType metricType, EMetricValueType valueType, TMetricValue value) { + switch (metricType) { + case EMetricType::GAUGE: + WriteFixed(value.AsDouble(valueType)); + break; + + case EMetricType::IGAUGE: + WriteFixed(value.AsInt64(valueType)); + break; + + case EMetricType::COUNTER: + case EMetricType::RATE: + WriteFixed(value.AsUint64(valueType)); + break; + + case EMetricType::HIST: + case EMetricType::HIST_RATE: + WriteHistogram(*value.AsHistogram()); + break; + + case EMetricType::DSUMMARY: WriteSummaryDouble(*value.AsSummaryDouble()); break; @@ -229,44 +229,44 @@ namespace NMonitoring { WriteLogHistogram(*value.AsLogHistogram()); break; - default: - ythrow yexception() << "unsupported metric type: " << metricType; - } - } - - void WriteTime(TInstant instant) { - switch (TimePrecision_) { - case ETimePrecision::SECONDS: { - ui32 time = static_cast<ui32>(instant.Seconds()); - Out_->Write(&time, sizeof(time)); - break; - } - case ETimePrecision::MILLIS: { - ui64 time = static_cast<ui64>(instant.MilliSeconds()); - Out_->Write(&time, sizeof(time)); - } - } - } - - template <typename T> - void WriteFixed(T value) { - Out_->Write(&value, sizeof(value)); - } - - void WriteHistogram(const IHistogramSnapshot& histogram) { - ui32 count = histogram.Count(); - WriteVarUInt32(Out_, count); - - for (ui32 i = 0; i < count; i++) { + default: + ythrow yexception() << "unsupported metric type: " << metricType; + } + } + + void WriteTime(TInstant instant) { + switch (TimePrecision_) { + case ETimePrecision::SECONDS: { + ui32 time = static_cast<ui32>(instant.Seconds()); + Out_->Write(&time, sizeof(time)); + break; + } + case ETimePrecision::MILLIS: { + ui64 time = static_cast<ui64>(instant.MilliSeconds()); + Out_->Write(&time, sizeof(time)); + } + } + } + + template <typename T> + void WriteFixed(T value) { + Out_->Write(&value, sizeof(value)); + } + + void WriteHistogram(const IHistogramSnapshot& histogram) { + ui32 count = histogram.Count(); + WriteVarUInt32(Out_, count); + + for (ui32 i = 0; i < count; i++) { double bound = histogram.UpperBound(i); - Out_->Write(&bound, sizeof(bound)); - } - for (ui32 i = 0; i < count; i++) { - ui64 value = histogram.Value(i); - Out_->Write(&value, sizeof(value)); - } - } - + Out_->Write(&bound, sizeof(bound)); + } + for (ui32 i = 0; i < count; i++) { + ui64 value = histogram.Value(i); + Out_->Write(&value, sizeof(value)); + } + } + void WriteLogHistogram(const TLogHistogramSnapshot& logHist) { WriteFixed(logHist.Base()); WriteFixed(logHist.ZerosCount()); @@ -285,26 +285,26 @@ namespace NMonitoring { WriteFixed(summary.GetLast()); } - private: - IOutputStream* Out_; - ETimePrecision TimePrecision_; - ECompression Compression_; + private: + IOutputStream* Out_; + ETimePrecision TimePrecision_; + ECompression Compression_; ESpackV1Version Version_; const TPooledStr* MetricName_; - bool Closed_ = false; - }; - - } - - IMetricEncoderPtr EncoderSpackV1( - IOutputStream* out, - ETimePrecision timePrecision, + bool Closed_ = false; + }; + + } + + IMetricEncoderPtr EncoderSpackV1( + IOutputStream* out, + ETimePrecision timePrecision, ECompression compression, - EMetricsMergingMode mergingMode + EMetricsMergingMode mergingMode ) { return MakeHolder<TEncoderSpackV1>(out, timePrecision, compression, mergingMode, SV1_01, ""); - } - + } + IMetricEncoderPtr EncoderSpackV12( IOutputStream* out, ETimePrecision timePrecision, @@ -315,4 +315,4 @@ namespace NMonitoring { Y_ENSURE(!metricNameLabel.Empty(), "metricNameLabel can't be empty"); return MakeHolder<TEncoderSpackV1>(out, timePrecision, compression, mergingMode, SV1_02, metricNameLabel); } -} +} diff --git a/library/cpp/monlib/encode/spack/spack_v1_ut.cpp b/library/cpp/monlib/encode/spack/spack_v1_ut.cpp index 0981ac90e2..fe778eb7e0 100644 --- a/library/cpp/monlib/encode/spack/spack_v1_ut.cpp +++ b/library/cpp/monlib/encode/spack/spack_v1_ut.cpp @@ -1,67 +1,67 @@ -#include "spack_v1.h" - -#include <library/cpp/monlib/encode/protobuf/protobuf.h> -#include <library/cpp/monlib/metrics/labels.h> -#include <library/cpp/monlib/metrics/metric.h> - +#include "spack_v1.h" + +#include <library/cpp/monlib/encode/protobuf/protobuf.h> +#include <library/cpp/monlib/metrics/labels.h> +#include <library/cpp/monlib/metrics/metric.h> + #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/buffer.h> -#include <util/stream/buffer.h> -#include <util/string/hex.h> - -#include <utility> - -using namespace NMonitoring; - -#define UNIT_ASSERT_BINARY_EQUALS(a, b) \ - do { \ - auto size = Y_ARRAY_SIZE(b); \ - if (Y_UNLIKELY(::memcmp(a, b, size) != 0)) { \ - auto as = HexEncode(a, size); \ - auto bs = HexEncode(b, size); \ - UNIT_FAIL_IMPL("equal assertion failed " #a " == " #b, \ - "\n actual: " << as << "\nexpected: " << bs); \ - } \ - } while (0) - -void AssertLabelEqual(const NProto::TLabel& l, TStringBuf name, TStringBuf value) { - UNIT_ASSERT_STRINGS_EQUAL(l.GetName(), name); - UNIT_ASSERT_STRINGS_EQUAL(l.GetValue(), value); -} - -void AssertPointEqual(const NProto::TPoint& p, TInstant time, double value) { - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kFloat64); - UNIT_ASSERT_DOUBLES_EQUAL(p.GetFloat64(), value, std::numeric_limits<double>::epsilon()); -} - -void AssertPointEqual(const NProto::TPoint& p, TInstant time, ui64 value) { - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kUint64); - UNIT_ASSERT_VALUES_EQUAL(p.GetUint64(), value); -} - -void AssertPointEqual(const NProto::TPoint& p, TInstant time, i64 value) { - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kInt64); - UNIT_ASSERT_VALUES_EQUAL(p.GetInt64(), value); -} - + +#include <util/generic/buffer.h> +#include <util/stream/buffer.h> +#include <util/string/hex.h> + +#include <utility> + +using namespace NMonitoring; + +#define UNIT_ASSERT_BINARY_EQUALS(a, b) \ + do { \ + auto size = Y_ARRAY_SIZE(b); \ + if (Y_UNLIKELY(::memcmp(a, b, size) != 0)) { \ + auto as = HexEncode(a, size); \ + auto bs = HexEncode(b, size); \ + UNIT_FAIL_IMPL("equal assertion failed " #a " == " #b, \ + "\n actual: " << as << "\nexpected: " << bs); \ + } \ + } while (0) + +void AssertLabelEqual(const NProto::TLabel& l, TStringBuf name, TStringBuf value) { + UNIT_ASSERT_STRINGS_EQUAL(l.GetName(), name); + UNIT_ASSERT_STRINGS_EQUAL(l.GetValue(), value); +} + +void AssertPointEqual(const NProto::TPoint& p, TInstant time, double value) { + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kFloat64); + UNIT_ASSERT_DOUBLES_EQUAL(p.GetFloat64(), value, std::numeric_limits<double>::epsilon()); +} + +void AssertPointEqual(const NProto::TPoint& p, TInstant time, ui64 value) { + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kUint64); + UNIT_ASSERT_VALUES_EQUAL(p.GetUint64(), value); +} + +void AssertPointEqual(const NProto::TPoint& p, TInstant time, i64 value) { + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), time.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kInt64); + UNIT_ASSERT_VALUES_EQUAL(p.GetInt64(), value); +} + Y_UNIT_TEST_SUITE(TSpackTest) { ui8 expectedHeader_v1_0[] = { - 0x53, 0x50, // magic "SP" (fixed ui16) + 0x53, 0x50, // magic "SP" (fixed ui16) // minor, major - 0x00, 0x01, // version (fixed ui16) - 0x18, 0x00, // header size (fixed ui16) - 0x00, // time precision (fixed ui8) - 0x00, // compression algorithm (fixed ui8) - 0x0d, 0x00, 0x00, 0x00, // label names size (fixed ui32) + 0x00, 0x01, // version (fixed ui16) + 0x18, 0x00, // header size (fixed ui16) + 0x00, // time precision (fixed ui8) + 0x00, // compression algorithm (fixed ui8) + 0x0d, 0x00, 0x00, 0x00, // label names size (fixed ui32) 0x40, 0x00, 0x00, 0x00, // labels values size (fixed ui32) - 0x08, 0x00, 0x00, 0x00, // metric count (fixed ui32) + 0x08, 0x00, 0x00, 0x00, // metric count (fixed ui32) 0x08, 0x00, 0x00, 0x00, // points count (fixed ui32) - }; - + }; + ui8 expectedHeader[] = { 0x53, 0x50, // magic "SP" (fixed ui16) // minor, major @@ -69,105 +69,105 @@ Y_UNIT_TEST_SUITE(TSpackTest) { 0x18, 0x00, // header size (fixed ui16) 0x00, // time precision (fixed ui8) 0x00, // compression algorithm (fixed ui8) - 0x0d, 0x00, 0x00, 0x00, // label names size (fixed ui32) + 0x0d, 0x00, 0x00, 0x00, // label names size (fixed ui32) 0x40, 0x00, 0x00, 0x00, // labels values size (fixed ui32) - 0x08, 0x00, 0x00, 0x00, // metric count (fixed ui32) + 0x08, 0x00, 0x00, 0x00, // metric count (fixed ui32) 0x08, 0x00, 0x00, 0x00, // points count (fixed ui32) }; - ui8 expectedStringPools[] = { - 0x6e, 0x61, 0x6d, 0x65, 0x00, // "name\0" - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x00, // "project\0" + ui8 expectedStringPools[] = { + 0x6e, 0x61, 0x6d, 0x65, 0x00, // "name\0" + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x00, // "project\0" 0x73, 0x6f, 0x6c, 0x6f, 0x6d, 0x6f, 0x6e, 0x00, // "solomon\0" 0x71, 0x31, 0x00, // "q1\0" 0x71, 0x32, 0x00, // "q2\0" 0x71, 0x33, 0x00, // "q3\0" 0x61, 0x6e, 0x73, 0x77, 0x65, 0x72, 0x00, // "answer\0" - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, // "responseTimeMillis\0" - 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x6c, 0x6c, - 0x69, 0x73, 0x00, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, // "responseTimeMillis\0" + 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x69, 0x6c, 0x6c, + 0x69, 0x73, 0x00, 0x62, 0x79, 0x74, 0x65, 0x73, 0x00, // "bytes\0" 0x74, 0x65, 0x6D, 0x70, 0x65, 0x72, 0x61, 0x74, // "temperature\0" 0x75, 0x72, 0x65, 0x00, 0x6d, 0x73, 0x00, // "ms\0" - }; - - ui8 expectedCommonTime[] = { - 0x00, 0x2f, 0x68, 0x59, // common time in seconds (fixed ui32) - }; - - ui8 expectedCommonLabels[] = { - 0x01, // common labels count (varint) - 0x01, // label name index (varint) + }; + + ui8 expectedCommonTime[] = { + 0x00, 0x2f, 0x68, 0x59, // common time in seconds (fixed ui32) + }; + + ui8 expectedCommonLabels[] = { + 0x01, // common labels count (varint) + 0x01, // label name index (varint) 0x00, // label value index (varint) - }; - - ui8 expectedMetric1[] = { - 0x0C, // types (RATE | NONE) (fixed ui8) - 0x00, // flags (fixed ui8) - 0x01, // metric labels count (varint) - 0x00, // label name index (varint) + }; + + ui8 expectedMetric1[] = { + 0x0C, // types (RATE | NONE) (fixed ui8) + 0x00, // flags (fixed ui8) + 0x01, // metric labels count (varint) + 0x00, // label name index (varint) 0x01, // label value index (varint) - }; - - ui8 expectedMetric2[] = { - 0x09, // types (COUNTER | ONE_WITHOUT_TS) (fixed ui8) - 0x00, // flags (fixed ui8) - 0x01, // metric labels count (varint) - 0x00, // label name index (varint) + }; + + ui8 expectedMetric2[] = { + 0x09, // types (COUNTER | ONE_WITHOUT_TS) (fixed ui8) + 0x00, // flags (fixed ui8) + 0x01, // metric labels count (varint) + 0x00, // label name index (varint) 0x02, // label value index (varint) - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value (fixed ui64) - }; - - ui8 expectedMetric3[] = { - 0x0a, // types (COUNTER | ONE_WITH_TS) (fixed ui8) - 0x00, // flags (fixed ui8) - 0x01, // metric labels count (varint) - 0x00, // label name index (varint) - 0x03, // label value index (varint) - 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value (fixed ui64) - }; - - ui8 expectedMetric4[] = { - 0x07, // types (GAUGE | MANY_WITH_TS) (fixed ui8) - 0x00, // flags (fixed ui8) - 0x01, // metric labels count (varint) - 0x00, // label name index (varint) - 0x04, // label value index (varint) - 0x02, // points count (varint) - 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, // value (double IEEE754) - 0x1a, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4d, 0x40 // value (double IEEE754) - }; - - ui8 expectedMetric5_v1_0[] = { - 0x16, // types (HIST | ONE_WITH_TS) (fixed ui8) - 0x00, // flags (fixed ui8) - 0x01, // metric labels count (varint) - 0x00, // label name index (varint) + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value (fixed ui64) + }; + + ui8 expectedMetric3[] = { + 0x0a, // types (COUNTER | ONE_WITH_TS) (fixed ui8) + 0x00, // flags (fixed ui8) + 0x01, // metric labels count (varint) + 0x00, // label name index (varint) + 0x03, // label value index (varint) + 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value (fixed ui64) + }; + + ui8 expectedMetric4[] = { + 0x07, // types (GAUGE | MANY_WITH_TS) (fixed ui8) + 0x00, // flags (fixed ui8) + 0x01, // metric labels count (varint) + 0x00, // label name index (varint) + 0x04, // label value index (varint) + 0x02, // points count (varint) + 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, // value (double IEEE754) + 0x1a, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4d, 0x40 // value (double IEEE754) + }; + + ui8 expectedMetric5_v1_0[] = { + 0x16, // types (HIST | ONE_WITH_TS) (fixed ui8) + 0x00, // flags (fixed ui8) + 0x01, // metric labels count (varint) + 0x00, // label name index (varint) 0x05, // label value index (varint) - 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) - 0x06, // histogram buckets count (varint) + 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) + 0x06, // histogram buckets count (varint) 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // histogram bucket bounds (array of fixed ui64) - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // histogram bucket values - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - - ui8 expectedMetric5[] = { + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // histogram bucket values + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + ui8 expectedMetric5[] = { 0x16, // types (HIST | ONE_WITH_TS) (fixed ui8) 0x00, // flags (fixed ui8) - 0x01, // metric labels count (varint) + 0x01, // metric labels count (varint) 0x00, // label name index (varint) 0x05, // label value index (varint) 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) @@ -186,20 +186,20 @@ Y_UNIT_TEST_SUITE(TSpackTest) { 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; - ui8 expectedMetric6[] = { - 0x12, // types (IGAUGE | ONE_WITH_TS) (fixed ui8) - 0x00, // flags (fixed ui8) - 0x01, // metric labels count (varint) - 0x00, // label name index (varint) + ui8 expectedMetric6[] = { + 0x12, // types (IGAUGE | ONE_WITH_TS) (fixed ui8) + 0x00, // flags (fixed ui8) + 0x01, // metric labels count (varint) + 0x00, // label name index (varint) 0x06, // label value index (varint) - 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) - 0x39, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value (fixed i64) - }; - - ui8 expectedMetric7[] = { + 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) + 0x39, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // value (fixed i64) + }; + + ui8 expectedMetric7[] = { 0x1e, // types (DSUMMARY | ONE_WITH_TS) (fixed ui8) 0x00, // flags (fixed ui8) - 0x01, // metric labels count (varint) + 0x01, // metric labels count (varint) 0x00, // label name index (varint) 0x07, // label value index (varint) 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) @@ -210,10 +210,10 @@ Y_UNIT_TEST_SUITE(TSpackTest) { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xd3, 0x3f, // last (fixed double) }; - ui8 expectedMetric8[] = { + ui8 expectedMetric8[] = { 0x26, // types (LOGHIST | ONE_WITH_TS) (fixed ui8) 0x00, // flags (fixed ui8) - 0x01, // metric labels count (variant) + 0x01, // metric labels count (variant) 0x00, // label name index (variant) 0x08, // label value index (variant) 0x0b, 0x63, 0xfe, 0x59, // time in seconds (fixed ui32) @@ -227,31 +227,31 @@ Y_UNIT_TEST_SUITE(TSpackTest) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x3F, }; - const size_t expectedSize = - Y_ARRAY_SIZE(expectedHeader) + - Y_ARRAY_SIZE(expectedStringPools) + - Y_ARRAY_SIZE(expectedCommonTime) + - Y_ARRAY_SIZE(expectedCommonLabels) + - Y_ARRAY_SIZE(expectedMetric1) + - Y_ARRAY_SIZE(expectedMetric2) + - Y_ARRAY_SIZE(expectedMetric3) + - Y_ARRAY_SIZE(expectedMetric4) + - Y_ARRAY_SIZE(expectedMetric5) + - Y_ARRAY_SIZE(expectedMetric6) + - Y_ARRAY_SIZE(expectedMetric7) + - Y_ARRAY_SIZE(expectedMetric8); - + const size_t expectedSize = + Y_ARRAY_SIZE(expectedHeader) + + Y_ARRAY_SIZE(expectedStringPools) + + Y_ARRAY_SIZE(expectedCommonTime) + + Y_ARRAY_SIZE(expectedCommonLabels) + + Y_ARRAY_SIZE(expectedMetric1) + + Y_ARRAY_SIZE(expectedMetric2) + + Y_ARRAY_SIZE(expectedMetric3) + + Y_ARRAY_SIZE(expectedMetric4) + + Y_ARRAY_SIZE(expectedMetric5) + + Y_ARRAY_SIZE(expectedMetric6) + + Y_ARRAY_SIZE(expectedMetric7) + + Y_ARRAY_SIZE(expectedMetric8); + const TInstant now = TInstant::ParseIso8601Deprecated("2017-11-05T01:02:03Z"); - - // {1: 1, 2: 1, 4: 2, 8: 4, 16: 8, inf: 83} - IHistogramSnapshotPtr TestHistogram() { - auto h = ExponentialHistogram(6, 2); - for (i64 i = 1; i < 100; i++) { - h->Collect(i); - } - return h->Snapshot(); - } - + + // {1: 1, 2: 1, 4: 2, 8: 4, 16: 8, inf: 83} + IHistogramSnapshotPtr TestHistogram() { + auto h = ExponentialHistogram(6, 2); + for (i64 i = 1; i < 100; i++) { + h->Collect(i); + } + return h->Snapshot(); + } + TLogHistogramSnapshotPtr TestLogHistogram() { TVector buckets{0.5, 0.25, 0.25, 0.5}; return MakeIntrusive<TLogHistogramSnapshot>(1.5, 1u, 0, std::move(buckets)); @@ -262,154 +262,154 @@ Y_UNIT_TEST_SUITE(TSpackTest) { } Y_UNIT_TEST(Encode) { - TBuffer buffer; - TBufferOutput out(buffer); - auto e = EncoderSpackV1( - &out, ETimePrecision::SECONDS, ECompression::IDENTITY); - - e->OnStreamBegin(); - { // common time - e->OnCommonTime(TInstant::Seconds(1500000000)); - } - { // common labels - e->OnLabelsBegin(); - e->OnLabel("project", "solomon"); - e->OnLabelsEnd(); - } - { // metric #1 - e->OnMetricBegin(EMetricType::RATE); - { - e->OnLabelsBegin(); - e->OnLabel("name", "q1"); - e->OnLabelsEnd(); - } - e->OnMetricEnd(); - } - { // metric #2 - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("name", "q2"); - e->OnLabelsEnd(); - } + TBuffer buffer; + TBufferOutput out(buffer); + auto e = EncoderSpackV1( + &out, ETimePrecision::SECONDS, ECompression::IDENTITY); + + e->OnStreamBegin(); + { // common time + e->OnCommonTime(TInstant::Seconds(1500000000)); + } + { // common labels + e->OnLabelsBegin(); + e->OnLabel("project", "solomon"); + e->OnLabelsEnd(); + } + { // metric #1 + e->OnMetricBegin(EMetricType::RATE); + { + e->OnLabelsBegin(); + e->OnLabel("name", "q1"); + e->OnLabelsEnd(); + } + e->OnMetricEnd(); + } + { // metric #2 + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("name", "q2"); + e->OnLabelsEnd(); + } // Only the last value will be encoded e->OnUint64(TInstant::Zero(), 10); e->OnUint64(TInstant::Zero(), 13); - e->OnUint64(TInstant::Zero(), 17); - e->OnMetricEnd(); - } - { // metric #3 - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("name", "q3"); - e->OnLabelsEnd(); - } + e->OnUint64(TInstant::Zero(), 17); + e->OnMetricEnd(); + } + { // metric #3 + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("name", "q3"); + e->OnLabelsEnd(); + } e->OnUint64(now, 10); e->OnUint64(now, 13); - e->OnUint64(now, 17); - e->OnMetricEnd(); - } - { // metric #4 - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("name", "answer"); - e->OnLabelsEnd(); - } - e->OnDouble(now, 42); - e->OnDouble(now + TDuration::Seconds(15), 59); - e->OnMetricEnd(); - } - { // metric #5 - e->OnMetricBegin(EMetricType::HIST); - { - e->OnLabelsBegin(); - e->OnLabel("name", "responseTimeMillis"); - e->OnLabelsEnd(); - } - - auto histogram = TestHistogram(); - e->OnHistogram(now, histogram); - e->OnMetricEnd(); - } - { // metric #6 - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("name", "bytes"); - e->OnLabelsEnd(); - } - e->OnInt64(now, 1337); - e->OnMetricEnd(); - } - { // metric 7 - e->OnMetricBegin(EMetricType::DSUMMARY); + e->OnUint64(now, 17); + e->OnMetricEnd(); + } + { // metric #4 + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("name", "answer"); + e->OnLabelsEnd(); + } + e->OnDouble(now, 42); + e->OnDouble(now + TDuration::Seconds(15), 59); + e->OnMetricEnd(); + } + { // metric #5 + e->OnMetricBegin(EMetricType::HIST); + { + e->OnLabelsBegin(); + e->OnLabel("name", "responseTimeMillis"); + e->OnLabelsEnd(); + } + + auto histogram = TestHistogram(); + e->OnHistogram(now, histogram); + e->OnMetricEnd(); + } + { // metric #6 + e->OnMetricBegin(EMetricType::IGAUGE); { e->OnLabelsBegin(); - e->OnLabel("name", "temperature"); + e->OnLabel("name", "bytes"); + e->OnLabelsEnd(); + } + e->OnInt64(now, 1337); + e->OnMetricEnd(); + } + { // metric 7 + e->OnMetricBegin(EMetricType::DSUMMARY); + { + e->OnLabelsBegin(); + e->OnLabel("name", "temperature"); e->OnLabelsEnd(); } e->OnSummaryDouble(now, TestSummaryDouble()); - e->OnMetricEnd(); + e->OnMetricEnd(); } - { // metric 8 + { // metric 8 e->OnMetricBegin(EMetricType::LOGHIST); { e->OnLabelsBegin(); - e->OnLabel("name", "ms"); + e->OnLabel("name", "ms"); e->OnLabelsEnd(); } e->OnLogHistogram(now, TestLogHistogram()); e->OnMetricEnd(); } - e->OnStreamEnd(); - e->Close(); - + e->OnStreamEnd(); + e->Close(); + // Cout << "encoded: " << HexEncode(buffer.Data(), buffer.Size()) << Endl; // Cout << "size: " << buffer.Size() << Endl; - - UNIT_ASSERT_VALUES_EQUAL(buffer.Size(), expectedSize); - - ui8* p = reinterpret_cast<ui8*>(buffer.Data()); - UNIT_ASSERT_BINARY_EQUALS(p, expectedHeader); - p += Y_ARRAY_SIZE(expectedHeader); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedStringPools); - p += Y_ARRAY_SIZE(expectedStringPools); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedCommonTime); - p += Y_ARRAY_SIZE(expectedCommonTime); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedCommonLabels); - p += Y_ARRAY_SIZE(expectedCommonLabels); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric1); - p += Y_ARRAY_SIZE(expectedMetric1); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric2); - p += Y_ARRAY_SIZE(expectedMetric2); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric3); - p += Y_ARRAY_SIZE(expectedMetric3); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric4); - p += Y_ARRAY_SIZE(expectedMetric4); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric5); - p += Y_ARRAY_SIZE(expectedMetric5); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric6); - p += Y_ARRAY_SIZE(expectedMetric6); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric7); - p += Y_ARRAY_SIZE(expectedMetric7); - - UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric8); - p += Y_ARRAY_SIZE(expectedMetric8); - } - - NProto::TMultiSamplesList GetMergingMetricSamples(EMetricsMergingMode mergingMode) { + + UNIT_ASSERT_VALUES_EQUAL(buffer.Size(), expectedSize); + + ui8* p = reinterpret_cast<ui8*>(buffer.Data()); + UNIT_ASSERT_BINARY_EQUALS(p, expectedHeader); + p += Y_ARRAY_SIZE(expectedHeader); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedStringPools); + p += Y_ARRAY_SIZE(expectedStringPools); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedCommonTime); + p += Y_ARRAY_SIZE(expectedCommonTime); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedCommonLabels); + p += Y_ARRAY_SIZE(expectedCommonLabels); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric1); + p += Y_ARRAY_SIZE(expectedMetric1); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric2); + p += Y_ARRAY_SIZE(expectedMetric2); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric3); + p += Y_ARRAY_SIZE(expectedMetric3); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric4); + p += Y_ARRAY_SIZE(expectedMetric4); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric5); + p += Y_ARRAY_SIZE(expectedMetric5); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric6); + p += Y_ARRAY_SIZE(expectedMetric6); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric7); + p += Y_ARRAY_SIZE(expectedMetric7); + + UNIT_ASSERT_BINARY_EQUALS(p, expectedMetric8); + p += Y_ARRAY_SIZE(expectedMetric8); + } + + NProto::TMultiSamplesList GetMergingMetricSamples(EMetricsMergingMode mergingMode) { TBuffer buffer; TBufferOutput out(buffer); @@ -422,29 +422,29 @@ Y_UNIT_TEST_SUITE(TSpackTest) { e->OnStreamBegin(); for (size_t i = 0; i != 3; ++i) { - e->OnMetricBegin(EMetricType::COUNTER); + e->OnMetricBegin(EMetricType::COUNTER); { e->OnLabelsBegin(); - e->OnLabel("name", "my_counter"); + e->OnLabel("name", "my_counter"); e->OnLabelsEnd(); } e->OnUint64(TInstant::Zero() + TDuration::Seconds(i), i + 1); - e->OnMetricEnd(); + e->OnMetricEnd(); } e->OnStreamEnd(); e->Close(); NProto::TMultiSamplesList samples; - IMetricEncoderPtr eProto = EncoderProtobuf(&samples); + IMetricEncoderPtr eProto = EncoderProtobuf(&samples); TBufferInput in(buffer); DecodeSpackV1(&in, eProto.Get()); return samples; } - Y_UNIT_TEST(SpackEncoderMergesMetrics) { + Y_UNIT_TEST(SpackEncoderMergesMetrics) { { - NProto::TMultiSamplesList samples = GetMergingMetricSamples(EMetricsMergingMode::DEFAULT); + NProto::TMultiSamplesList samples = GetMergingMetricSamples(EMetricsMergingMode::DEFAULT); UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3); UNIT_ASSERT_EQUAL(samples.GetSamples(0).GetPoints(0).GetUint64(), 1); @@ -453,7 +453,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { } { - NProto::TMultiSamplesList samples = GetMergingMetricSamples(EMetricsMergingMode::MERGE_METRICS); + NProto::TMultiSamplesList samples = GetMergingMetricSamples(EMetricsMergingMode::MERGE_METRICS); UNIT_ASSERT_EQUAL(samples.SamplesSize(), 1); @@ -465,29 +465,29 @@ Y_UNIT_TEST_SUITE(TSpackTest) { } void DecodeDataToSamples(NProto::TMultiSamplesList & samples, ui16 version) { - IMetricEncoderPtr e = EncoderProtobuf(&samples); - + IMetricEncoderPtr e = EncoderProtobuf(&samples); + TBuffer data(expectedSize); if (SV1_00 == version) { // v1.0 data.Append(reinterpret_cast<char*>(expectedHeader_v1_0), Y_ARRAY_SIZE(expectedHeader_v1_0)); } else { - data.Append(reinterpret_cast<char*>(expectedHeader), Y_ARRAY_SIZE(expectedHeader)); + data.Append(reinterpret_cast<char*>(expectedHeader), Y_ARRAY_SIZE(expectedHeader)); } data.Append(reinterpret_cast<char*>(expectedStringPools), Y_ARRAY_SIZE(expectedStringPools)); data.Append(reinterpret_cast<char*>(expectedCommonTime), Y_ARRAY_SIZE(expectedCommonTime)); data.Append(reinterpret_cast<char*>(expectedCommonLabels), Y_ARRAY_SIZE(expectedCommonLabels)); - data.Append(reinterpret_cast<char*>(expectedMetric1), Y_ARRAY_SIZE(expectedMetric1)); - data.Append(reinterpret_cast<char*>(expectedMetric2), Y_ARRAY_SIZE(expectedMetric2)); - data.Append(reinterpret_cast<char*>(expectedMetric3), Y_ARRAY_SIZE(expectedMetric3)); - data.Append(reinterpret_cast<char*>(expectedMetric4), Y_ARRAY_SIZE(expectedMetric4)); + data.Append(reinterpret_cast<char*>(expectedMetric1), Y_ARRAY_SIZE(expectedMetric1)); + data.Append(reinterpret_cast<char*>(expectedMetric2), Y_ARRAY_SIZE(expectedMetric2)); + data.Append(reinterpret_cast<char*>(expectedMetric3), Y_ARRAY_SIZE(expectedMetric3)); + data.Append(reinterpret_cast<char*>(expectedMetric4), Y_ARRAY_SIZE(expectedMetric4)); if (SV1_00 == version) { // v1.0 - data.Append(reinterpret_cast<char*>(expectedMetric5_v1_0), Y_ARRAY_SIZE(expectedMetric5_v1_0)); + data.Append(reinterpret_cast<char*>(expectedMetric5_v1_0), Y_ARRAY_SIZE(expectedMetric5_v1_0)); } else { - data.Append(reinterpret_cast<char*>(expectedMetric5), Y_ARRAY_SIZE(expectedMetric5)); - } - data.Append(reinterpret_cast<char*>(expectedMetric6), Y_ARRAY_SIZE(expectedMetric6)); - data.Append(reinterpret_cast<char*>(expectedMetric7), Y_ARRAY_SIZE(expectedMetric7)); - data.Append(reinterpret_cast<char*>(expectedMetric8), Y_ARRAY_SIZE(expectedMetric8)); + data.Append(reinterpret_cast<char*>(expectedMetric5), Y_ARRAY_SIZE(expectedMetric5)); + } + data.Append(reinterpret_cast<char*>(expectedMetric6), Y_ARRAY_SIZE(expectedMetric6)); + data.Append(reinterpret_cast<char*>(expectedMetric7), Y_ARRAY_SIZE(expectedMetric7)); + data.Append(reinterpret_cast<char*>(expectedMetric8), Y_ARRAY_SIZE(expectedMetric8)); TBufferInput in(data); DecodeSpackV1(&in, e.Get()); } @@ -502,85 +502,85 @@ Y_UNIT_TEST_SUITE(TSpackTest) { NProto::TMultiSamplesList samples; DecodeDataToSamples(samples); - UNIT_ASSERT_VALUES_EQUAL( - TInstant::MilliSeconds(samples.GetCommonTime()), - TInstant::Seconds(1500000000)); - - UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 1); - AssertLabelEqual(samples.GetCommonLabels(0), "project", "solomon"); - + UNIT_ASSERT_VALUES_EQUAL( + TInstant::MilliSeconds(samples.GetCommonTime()), + TInstant::Seconds(1500000000)); + + UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 1); + AssertLabelEqual(samples.GetCommonLabels(0), "project", "solomon"); + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 8); - { - const NProto::TMultiSample& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "name", "q1"); - } - { - const NProto::TMultiSample& s = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "name", "q2"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), TInstant::Zero(), ui64(17)); - } - { - const NProto::TMultiSample& s = samples.GetSamples(2); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "name", "q3"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), now, ui64(17)); - } - { - const NProto::TMultiSample& s = samples.GetSamples(3); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "name", "answer"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); - AssertPointEqual(s.GetPoints(0), now, double(42)); - AssertPointEqual(s.GetPoints(1), now + TDuration::Seconds(15), double(59)); - } - { - const NProto::TMultiSample& s = samples.GetSamples(4); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HISTOGRAM); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "name", "responseTimeMillis"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - - const NProto::TPoint& p = s.GetPoints(0); - UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), now.MilliSeconds()); - UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kHistogram); - - auto histogram = TestHistogram(); - - const NProto::THistogram& pointHistogram = p.GetHistogram(); - UNIT_ASSERT_VALUES_EQUAL(pointHistogram.BoundsSize(), histogram->Count()); - UNIT_ASSERT_VALUES_EQUAL(pointHistogram.ValuesSize(), histogram->Count()); - - for (size_t i = 0; i < pointHistogram.BoundsSize(); i++) { - UNIT_ASSERT_DOUBLES_EQUAL(pointHistogram.GetBounds(i), histogram->UpperBound(i), Min<double>()); - UNIT_ASSERT_VALUES_EQUAL(pointHistogram.GetValues(i), histogram->Value(i)); - } - } - { - const NProto::TMultiSample& s = samples.GetSamples(5); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::IGAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "name", "bytes"); - - UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); - AssertPointEqual(s.GetPoints(0), now, i64(1337)); - } + { + const NProto::TMultiSample& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::RATE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "name", "q1"); + } + { + const NProto::TMultiSample& s = samples.GetSamples(1); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "name", "q2"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), TInstant::Zero(), ui64(17)); + } + { + const NProto::TMultiSample& s = samples.GetSamples(2); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::COUNTER); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "name", "q3"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), now, ui64(17)); + } + { + const NProto::TMultiSample& s = samples.GetSamples(3); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "name", "answer"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 2); + AssertPointEqual(s.GetPoints(0), now, double(42)); + AssertPointEqual(s.GetPoints(1), now + TDuration::Seconds(15), double(59)); + } + { + const NProto::TMultiSample& s = samples.GetSamples(4); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::HISTOGRAM); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "name", "responseTimeMillis"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + + const NProto::TPoint& p = s.GetPoints(0); + UNIT_ASSERT_VALUES_EQUAL(p.GetTime(), now.MilliSeconds()); + UNIT_ASSERT_EQUAL(p.GetValueCase(), NProto::TPoint::kHistogram); + + auto histogram = TestHistogram(); + + const NProto::THistogram& pointHistogram = p.GetHistogram(); + UNIT_ASSERT_VALUES_EQUAL(pointHistogram.BoundsSize(), histogram->Count()); + UNIT_ASSERT_VALUES_EQUAL(pointHistogram.ValuesSize(), histogram->Count()); + + for (size_t i = 0; i < pointHistogram.BoundsSize(); i++) { + UNIT_ASSERT_DOUBLES_EQUAL(pointHistogram.GetBounds(i), histogram->UpperBound(i), Min<double>()); + UNIT_ASSERT_VALUES_EQUAL(pointHistogram.GetValues(i), histogram->Value(i)); + } + } + { + const NProto::TMultiSample& s = samples.GetSamples(5); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::IGAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "name", "bytes"); + + UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); + AssertPointEqual(s.GetPoints(0), now, i64(1337)); + } { const NProto::TMultiSample& s = samples.GetSamples(6); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::DSUMMARY); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "name", "temperature"); + AssertLabelEqual(s.GetLabels(0), "name", "temperature"); UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); @@ -602,7 +602,7 @@ Y_UNIT_TEST_SUITE(TSpackTest) { const NProto::TMultiSample& s = samples.GetSamples(7); UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::LOGHISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "name", "ms"); + AssertLabelEqual(s.GetLabels(0), "name", "ms"); UNIT_ASSERT_VALUES_EQUAL(s.PointsSize(), 1); @@ -621,69 +621,69 @@ Y_UNIT_TEST_SUITE(TSpackTest) { UNIT_ASSERT_VALUES_EQUAL(expected->Bucket(i), actual.GetBuckets(i)); } } - } - - void TestCompression(ECompression alg) { - TBuffer buffer; - { - TBufferOutput out(buffer); - auto e = EncoderSpackV1(&out, ETimePrecision::MILLIS, alg); - e->OnStreamBegin(); - { - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("name", "answer"); - e->OnLabelsEnd(); - } - e->OnDouble(now, 42); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - e->Close(); - } - - auto* header = reinterpret_cast<const TSpackHeader*>(buffer.Data()); - UNIT_ASSERT_EQUAL(DecodeCompression(header->Compression), alg); - - NProto::TMultiSamplesList samples; - { - IMetricEncoderPtr e = EncoderProtobuf(&samples); - TBufferInput in(buffer); - DecodeSpackV1(&in, e.Get()); - } - - UNIT_ASSERT_VALUES_EQUAL( - TInstant::MilliSeconds(samples.GetCommonTime()), - TInstant::Zero()); - - UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 0); - - UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); - { - const NProto::TMultiSample& s = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); - UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); - AssertLabelEqual(s.GetLabels(0), "name", "answer"); - AssertPointEqual(s.GetPoints(0), now, 42.0); - } - } - + } + + void TestCompression(ECompression alg) { + TBuffer buffer; + { + TBufferOutput out(buffer); + auto e = EncoderSpackV1(&out, ETimePrecision::MILLIS, alg); + e->OnStreamBegin(); + { + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("name", "answer"); + e->OnLabelsEnd(); + } + e->OnDouble(now, 42); + e->OnMetricEnd(); + } + e->OnStreamEnd(); + e->Close(); + } + + auto* header = reinterpret_cast<const TSpackHeader*>(buffer.Data()); + UNIT_ASSERT_EQUAL(DecodeCompression(header->Compression), alg); + + NProto::TMultiSamplesList samples; + { + IMetricEncoderPtr e = EncoderProtobuf(&samples); + TBufferInput in(buffer); + DecodeSpackV1(&in, e.Get()); + } + + UNIT_ASSERT_VALUES_EQUAL( + TInstant::MilliSeconds(samples.GetCommonTime()), + TInstant::Zero()); + + UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 0); + + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); + { + const NProto::TMultiSample& s = samples.GetSamples(0); + UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 1); + AssertLabelEqual(s.GetLabels(0), "name", "answer"); + AssertPointEqual(s.GetPoints(0), now, 42.0); + } + } + Y_UNIT_TEST(CompressionIdentity) { - TestCompression(ECompression::IDENTITY); - } - + TestCompression(ECompression::IDENTITY); + } + Y_UNIT_TEST(CompressionZlib) { - TestCompression(ECompression::ZLIB); - } - + TestCompression(ECompression::ZLIB); + } + Y_UNIT_TEST(CompressionZstd) { - TestCompression(ECompression::ZSTD); - } - + TestCompression(ECompression::ZSTD); + } + Y_UNIT_TEST(CompressionLz4) { - TestCompression(ECompression::LZ4); - } + TestCompression(ECompression::LZ4); + } Y_UNIT_TEST(Decode_v1_0_histograms) { // Check that histogram bounds decoded from different versions are the same @@ -842,4 +842,4 @@ Y_UNIT_TEST_SUITE(TSpackTest) { yexception, "metric name label 's' not found, all metric labels '{m=v, project=solomon}'"); } -} +} diff --git a/library/cpp/monlib/encode/spack/ut/ya.make b/library/cpp/monlib/encode/spack/ut/ya.make index 6f27ddf43c..980bf54667 100644 --- a/library/cpp/monlib/encode/spack/ut/ya.make +++ b/library/cpp/monlib/encode/spack/ut/ya.make @@ -1,16 +1,16 @@ -UNITTEST_FOR(library/cpp/monlib/encode/spack) - +UNITTEST_FOR(library/cpp/monlib/encode/spack) + OWNER( g:solomon jamel ) - -SRCS( - spack_v1_ut.cpp -) - -PEERDIR( - library/cpp/monlib/encode/protobuf -) - -END() + +SRCS( + spack_v1_ut.cpp +) + +PEERDIR( + library/cpp/monlib/encode/protobuf +) + +END() diff --git a/library/cpp/monlib/encode/spack/varint.cpp b/library/cpp/monlib/encode/spack/varint.cpp index dabfaa9afe..051cf17380 100644 --- a/library/cpp/monlib/encode/spack/varint.cpp +++ b/library/cpp/monlib/encode/spack/varint.cpp @@ -1,79 +1,79 @@ -#include "varint.h" - -#include <util/generic/yexception.h> -#include <util/stream/input.h> -#include <util/stream/output.h> - -namespace NMonitoring { - ui32 WriteVarUInt32(IOutputStream* output, ui32 value) { - bool stop = false; - ui32 written = 0; - while (!stop) { - ui8 byte = static_cast<ui8>(value | 0x80); - value >>= 7; - if (value == 0) { - stop = true; - byte &= 0x7F; - } - output->Write(byte); - written++; - } - return written; - } - - ui32 ReadVarUInt32(IInputStream* input) { +#include "varint.h" + +#include <util/generic/yexception.h> +#include <util/stream/input.h> +#include <util/stream/output.h> + +namespace NMonitoring { + ui32 WriteVarUInt32(IOutputStream* output, ui32 value) { + bool stop = false; + ui32 written = 0; + while (!stop) { + ui8 byte = static_cast<ui8>(value | 0x80); + value >>= 7; + if (value == 0) { + stop = true; + byte &= 0x7F; + } + output->Write(byte); + written++; + } + return written; + } + + ui32 ReadVarUInt32(IInputStream* input) { ui32 value = 0; switch (TryReadVarUInt32(input, &value)) { case EReadResult::OK: return value; case EReadResult::ERR_OVERFLOW: - ythrow yexception() << "the data is too long to read ui32"; + ythrow yexception() << "the data is too long to read ui32"; case EReadResult::ERR_UNEXPECTED_EOF: - ythrow yexception() << "the data unexpectedly ended"; + ythrow yexception() << "the data unexpectedly ended"; default: ythrow yexception() << "unknown error while reading varint"; } - } - - size_t ReadVarUInt32(const ui8* buf, size_t len, ui32* result) { - size_t count = 0; - ui32 value = 0; - - ui8 byte = 0; - do { - if (7 * count > 8 * sizeof(ui32)) { - ythrow yexception() << "the data is too long to read ui32"; - } - if (count == len) { - ythrow yexception() << "the data unexpectedly ended"; - } - byte = buf[count]; - value |= (static_cast<ui32>(byte & 0x7F)) << (7 * count); - ++count; - } while (byte & 0x80); - - *result = value; - return count; - } - + } + + size_t ReadVarUInt32(const ui8* buf, size_t len, ui32* result) { + size_t count = 0; + ui32 value = 0; + + ui8 byte = 0; + do { + if (7 * count > 8 * sizeof(ui32)) { + ythrow yexception() << "the data is too long to read ui32"; + } + if (count == len) { + ythrow yexception() << "the data unexpectedly ended"; + } + byte = buf[count]; + value |= (static_cast<ui32>(byte & 0x7F)) << (7 * count); + ++count; + } while (byte & 0x80); + + *result = value; + return count; + } + EReadResult TryReadVarUInt32(IInputStream* input, ui32* value) { - size_t count = 0; - ui32 result = 0; - - ui8 byte = 0; - do { - if (7 * count > 8 * sizeof(ui32)) { + size_t count = 0; + ui32 result = 0; + + ui8 byte = 0; + do { + if (7 * count > 8 * sizeof(ui32)) { return EReadResult::ERR_OVERFLOW; - } - if (input->Read(&byte, 1) != 1) { + } + if (input->Read(&byte, 1) != 1) { return EReadResult::ERR_UNEXPECTED_EOF; - } - result |= (static_cast<ui32>(byte & 0x7F)) << (7 * count); - ++count; - } while (byte & 0x80); - - *value = result; + } + result |= (static_cast<ui32>(byte & 0x7F)) << (7 * count); + ++count; + } while (byte & 0x80); + + *value = result; return EReadResult::OK; - } - -} + } + +} diff --git a/library/cpp/monlib/encode/spack/varint.h b/library/cpp/monlib/encode/spack/varint.h index 7bce244b20..7ac522dd6c 100644 --- a/library/cpp/monlib/encode/spack/varint.h +++ b/library/cpp/monlib/encode/spack/varint.h @@ -1,16 +1,16 @@ -#pragma once - -#include <util/system/types.h> - -class IInputStream; -class IOutputStream; - -namespace NMonitoring { - ui32 WriteVarUInt32(IOutputStream* output, ui32 value); - - ui32 ReadVarUInt32(IInputStream* input); - size_t ReadVarUInt32(const ui8* buf, size_t len, ui32* result); - +#pragma once + +#include <util/system/types.h> + +class IInputStream; +class IOutputStream; + +namespace NMonitoring { + ui32 WriteVarUInt32(IOutputStream* output, ui32 value); + + ui32 ReadVarUInt32(IInputStream* input); + size_t ReadVarUInt32(const ui8* buf, size_t len, ui32* result); + enum class EReadResult { OK, ERR_OVERFLOW, @@ -20,4 +20,4 @@ namespace NMonitoring { [[nodiscard]] EReadResult TryReadVarUInt32(IInputStream* input, ui32* value); -} +} diff --git a/library/cpp/monlib/encode/spack/ya.make b/library/cpp/monlib/encode/spack/ya.make index 1b1a27e7e2..78d3061291 100644 --- a/library/cpp/monlib/encode/spack/ya.make +++ b/library/cpp/monlib/encode/spack/ya.make @@ -1,25 +1,25 @@ -LIBRARY() - +LIBRARY() + OWNER( g:solomon jamel ) - -SRCS( - spack_v1_decoder.cpp - spack_v1_encoder.cpp - varint.cpp - compression.cpp -) - -PEERDIR( + +SRCS( + spack_v1_decoder.cpp + spack_v1_encoder.cpp + varint.cpp + compression.cpp +) + +PEERDIR( library/cpp/monlib/encode/buffered library/cpp/monlib/exception - contrib/libs/lz4 + contrib/libs/lz4 contrib/libs/xxhash - contrib/libs/zlib - contrib/libs/zstd -) - -END() + contrib/libs/zlib + contrib/libs/zstd +) + +END() diff --git a/library/cpp/monlib/encode/text/text.h b/library/cpp/monlib/encode/text/text.h index 8efc2b18a2..6b2be3937b 100644 --- a/library/cpp/monlib/encode/text/text.h +++ b/library/cpp/monlib/encode/text/text.h @@ -1,9 +1,9 @@ -#pragma once - -#include <library/cpp/monlib/encode/encoder.h> - -class IOutputStream; - -namespace NMonitoring { - IMetricEncoderPtr EncoderText(IOutputStream* out, bool humanReadableTs = true); -} +#pragma once + +#include <library/cpp/monlib/encode/encoder.h> + +class IOutputStream; + +namespace NMonitoring { + IMetricEncoderPtr EncoderText(IOutputStream* out, bool humanReadableTs = true); +} diff --git a/library/cpp/monlib/encode/text/text_encoder.cpp b/library/cpp/monlib/encode/text/text_encoder.cpp index cfddcb2405..10336261f0 100644 --- a/library/cpp/monlib/encode/text/text_encoder.cpp +++ b/library/cpp/monlib/encode/text/text_encoder.cpp @@ -1,148 +1,148 @@ -#include "text.h" - -#include <library/cpp/monlib/encode/encoder_state.h> -#include <library/cpp/monlib/metrics/labels.h> -#include <library/cpp/monlib/metrics/metric_value.h> - -#include <util/datetime/base.h> -#include <util/stream/format.h> - -namespace NMonitoring { - namespace { - class TEncoderText final: public IMetricEncoder { - public: - TEncoderText(IOutputStream* out, bool humanReadableTs) - : Out_(out) - , HumanReadableTs_(humanReadableTs) - { - } - - private: - void OnStreamBegin() override { +#include "text.h" + +#include <library/cpp/monlib/encode/encoder_state.h> +#include <library/cpp/monlib/metrics/labels.h> +#include <library/cpp/monlib/metrics/metric_value.h> + +#include <util/datetime/base.h> +#include <util/stream/format.h> + +namespace NMonitoring { + namespace { + class TEncoderText final: public IMetricEncoder { + public: + TEncoderText(IOutputStream* out, bool humanReadableTs) + : Out_(out) + , HumanReadableTs_(humanReadableTs) + { + } + + private: + void OnStreamBegin() override { State_.Expect(TEncoderState::EState::ROOT); - } - - void OnStreamEnd() override { + } + + void OnStreamEnd() override { State_.Expect(TEncoderState::EState::ROOT); - } - - void OnCommonTime(TInstant time) override { + } + + void OnCommonTime(TInstant time) override { State_.Expect(TEncoderState::EState::ROOT); - CommonTime_ = time; - if (time != TInstant::Zero()) { + CommonTime_ = time; + if (time != TInstant::Zero()) { Out_->Write(TStringBuf("common time: ")); - WriteTime(time); - Out_->Write('\n'); - } - } - - void OnMetricBegin(EMetricType type) override { - State_.Switch(TEncoderState::EState::ROOT, TEncoderState::EState::METRIC); - ClearLastMetricState(); - MetricType_ = type; - } - - void OnMetricEnd() override { - State_.Switch(TEncoderState::EState::METRIC, TEncoderState::EState::ROOT); - WriteMetric(); - } - - void OnLabelsBegin() override { - if (State_ == TEncoderState::EState::METRIC) { - State_ = TEncoderState::EState::METRIC_LABELS; + WriteTime(time); + Out_->Write('\n'); + } + } + + void OnMetricBegin(EMetricType type) override { + State_.Switch(TEncoderState::EState::ROOT, TEncoderState::EState::METRIC); + ClearLastMetricState(); + MetricType_ = type; + } + + void OnMetricEnd() override { + State_.Switch(TEncoderState::EState::METRIC, TEncoderState::EState::ROOT); + WriteMetric(); + } + + void OnLabelsBegin() override { + if (State_ == TEncoderState::EState::METRIC) { + State_ = TEncoderState::EState::METRIC_LABELS; } else if (State_ == TEncoderState::EState::ROOT) { State_ = TEncoderState::EState::COMMON_LABELS; - } else { - State_.ThrowInvalid("expected METRIC or ROOT"); - } - } - - void OnLabelsEnd() override { - if (State_ == TEncoderState::EState::METRIC_LABELS) { - State_ = TEncoderState::EState::METRIC; + } else { + State_.ThrowInvalid("expected METRIC or ROOT"); + } + } + + void OnLabelsEnd() override { + if (State_ == TEncoderState::EState::METRIC_LABELS) { + State_ = TEncoderState::EState::METRIC; } else if (State_ == TEncoderState::EState::COMMON_LABELS) { State_ = TEncoderState::EState::ROOT; Out_->Write(TStringBuf("common labels: ")); - WriteLabels(); - Out_->Write('\n'); - } else { - State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); - } - } - - void OnLabel(TStringBuf name, TStringBuf value) override { - Labels_.Add(name, value); - } - - void OnDouble(TInstant time, double value) override { - State_.Expect(TEncoderState::EState::METRIC); - TimeSeries_.Add(time, value); - } - - void OnInt64(TInstant time, i64 value) override { - State_.Expect(TEncoderState::EState::METRIC); - TimeSeries_.Add(time, value); - } - - void OnUint64(TInstant time, ui64 value) override { - State_.Expect(TEncoderState::EState::METRIC); - TimeSeries_.Add(time, value); - } - - void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { - State_.Expect(TEncoderState::EState::METRIC); - TimeSeries_.Add(time, snapshot.Get()); - } - + WriteLabels(); + Out_->Write('\n'); + } else { + State_.ThrowInvalid("expected LABELS or COMMON_LABELS"); + } + } + + void OnLabel(TStringBuf name, TStringBuf value) override { + Labels_.Add(name, value); + } + + void OnDouble(TInstant time, double value) override { + State_.Expect(TEncoderState::EState::METRIC); + TimeSeries_.Add(time, value); + } + + void OnInt64(TInstant time, i64 value) override { + State_.Expect(TEncoderState::EState::METRIC); + TimeSeries_.Add(time, value); + } + + void OnUint64(TInstant time, ui64 value) override { + State_.Expect(TEncoderState::EState::METRIC); + TimeSeries_.Add(time, value); + } + + void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) override { + State_.Expect(TEncoderState::EState::METRIC); + TimeSeries_.Add(time, snapshot.Get()); + } + void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) override { - State_.Expect(TEncoderState::EState::METRIC); + State_.Expect(TEncoderState::EState::METRIC); TimeSeries_.Add(time, snapshot.Get()); } void OnLogHistogram(TInstant ts, TLogHistogramSnapshotPtr snapshot) override { - State_.Expect(TEncoderState::EState::METRIC); + State_.Expect(TEncoderState::EState::METRIC); TimeSeries_.Add(ts, snapshot.Get()); } - void Close() override { - } - - void WriteTime(TInstant time) { - if (HumanReadableTs_) { - char buf[64]; - auto len = FormatDate8601(buf, sizeof(buf), time.TimeT()); - Out_->Write(buf, len); - } else { - (*Out_) << time.Seconds(); - } - } - - void WriteValue(EMetricValueType type, TMetricValue value) { - switch (type) { - case EMetricValueType::DOUBLE: - (*Out_) << value.AsDouble(); - break; - case EMetricValueType::INT64: - (*Out_) << value.AsInt64(); - break; - case EMetricValueType::UINT64: - (*Out_) << value.AsUint64(); - break; - case EMetricValueType::HISTOGRAM: - (*Out_) << *value.AsHistogram(); - break; - case EMetricValueType::SUMMARY: + void Close() override { + } + + void WriteTime(TInstant time) { + if (HumanReadableTs_) { + char buf[64]; + auto len = FormatDate8601(buf, sizeof(buf), time.TimeT()); + Out_->Write(buf, len); + } else { + (*Out_) << time.Seconds(); + } + } + + void WriteValue(EMetricValueType type, TMetricValue value) { + switch (type) { + case EMetricValueType::DOUBLE: + (*Out_) << value.AsDouble(); + break; + case EMetricValueType::INT64: + (*Out_) << value.AsInt64(); + break; + case EMetricValueType::UINT64: + (*Out_) << value.AsUint64(); + break; + case EMetricValueType::HISTOGRAM: + (*Out_) << *value.AsHistogram(); + break; + case EMetricValueType::SUMMARY: (*Out_) << *value.AsSummaryDouble(); break; case EMetricValueType::LOGHISTOGRAM: (*Out_) << *value.AsLogHistogram(); break; - case EMetricValueType::UNKNOWN: - ythrow yexception() << "unknown metric value type"; - } - } - - void WriteLabels() { + case EMetricValueType::UNKNOWN: + ythrow yexception() << "unknown metric value type"; + } + } + + void WriteLabels() { auto& out = *Out_; const auto size = Labels_.Size(); size_t i = 0; @@ -154,73 +154,73 @@ namespace NMonitoring { ++i; if (i < size) { out << TStringBuf(", "); - } + } }; out << '}'; - } - - void WriteMetric() { - // (1) type - TStringBuf typeStr = MetricTypeToStr(MetricType_); - (*Out_) << LeftPad(typeStr, MaxMetricTypeNameLength) << ' '; - - // (2) name and labels + } + + void WriteMetric() { + // (1) type + TStringBuf typeStr = MetricTypeToStr(MetricType_); + (*Out_) << LeftPad(typeStr, MaxMetricTypeNameLength) << ' '; + + // (2) name and labels auto name = Labels_.Extract(TStringBuf("sensor")); - if (name) { - if (name->Value().find(' ') != TString::npos) { - (*Out_) << '"' << name->Value() << '"'; - } else { - (*Out_) << name->Value(); - } - } - WriteLabels(); - - // (3) values - if (!TimeSeries_.Empty()) { - TimeSeries_.SortByTs(); + if (name) { + if (name->Value().find(' ') != TString::npos) { + (*Out_) << '"' << name->Value() << '"'; + } else { + (*Out_) << name->Value(); + } + } + WriteLabels(); + + // (3) values + if (!TimeSeries_.Empty()) { + TimeSeries_.SortByTs(); Out_->Write(TStringBuf(" [")); - for (size_t i = 0; i < TimeSeries_.Size(); i++) { - if (i > 0) { + for (size_t i = 0; i < TimeSeries_.Size(); i++) { + if (i > 0) { Out_->Write(TStringBuf(", ")); - } - - const auto& point = TimeSeries_[i]; - if (point.GetTime() == CommonTime_ || point.GetTime() == TInstant::Zero()) { - WriteValue(TimeSeries_.GetValueType(), point.GetValue()); - } else { - Out_->Write('('); - WriteTime(point.GetTime()); + } + + const auto& point = TimeSeries_[i]; + if (point.GetTime() == CommonTime_ || point.GetTime() == TInstant::Zero()) { + WriteValue(TimeSeries_.GetValueType(), point.GetValue()); + } else { + Out_->Write('('); + WriteTime(point.GetTime()); Out_->Write(TStringBuf(", ")); - WriteValue(TimeSeries_.GetValueType(), point.GetValue()); - Out_->Write(')'); - } - } - Out_->Write(']'); - } - Out_->Write('\n'); - } - - void ClearLastMetricState() { - MetricType_ = EMetricType::UNKNOWN; - Labels_.Clear(); - TimeSeries_.Clear(); - } - - private: - TEncoderState State_; - IOutputStream* Out_; - bool HumanReadableTs_; - TInstant CommonTime_ = TInstant::Zero(); - EMetricType MetricType_ = EMetricType::UNKNOWN; - TLabels Labels_; - TMetricTimeSeries TimeSeries_; - }; - - } - - IMetricEncoderPtr EncoderText(IOutputStream* out, bool humanReadableTs) { + WriteValue(TimeSeries_.GetValueType(), point.GetValue()); + Out_->Write(')'); + } + } + Out_->Write(']'); + } + Out_->Write('\n'); + } + + void ClearLastMetricState() { + MetricType_ = EMetricType::UNKNOWN; + Labels_.Clear(); + TimeSeries_.Clear(); + } + + private: + TEncoderState State_; + IOutputStream* Out_; + bool HumanReadableTs_; + TInstant CommonTime_ = TInstant::Zero(); + EMetricType MetricType_ = EMetricType::UNKNOWN; + TLabels Labels_; + TMetricTimeSeries TimeSeries_; + }; + + } + + IMetricEncoderPtr EncoderText(IOutputStream* out, bool humanReadableTs) { return MakeHolder<TEncoderText>(out, humanReadableTs); - } - -} + } + +} diff --git a/library/cpp/monlib/encode/text/text_encoder_ut.cpp b/library/cpp/monlib/encode/text/text_encoder_ut.cpp index b817b38285..554b6f5fa9 100644 --- a/library/cpp/monlib/encode/text/text_encoder_ut.cpp +++ b/library/cpp/monlib/encode/text/text_encoder_ut.cpp @@ -1,283 +1,283 @@ -#include "text.h" - -#include <library/cpp/monlib/metrics/histogram_collector.h> - +#include "text.h" + +#include <library/cpp/monlib/metrics/histogram_collector.h> + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - + +using namespace NMonitoring; + Y_UNIT_TEST_SUITE(TTextText) { - template <typename TFunc> - TString EncodeToString(bool humanReadableTs, TFunc fn) { - TStringStream ss; - IMetricEncoderPtr encoder = EncoderText(&ss, humanReadableTs); - fn(encoder.Get()); - return ss.Str(); - } - + template <typename TFunc> + TString EncodeToString(bool humanReadableTs, TFunc fn) { + TStringStream ss; + IMetricEncoderPtr encoder = EncoderText(&ss, humanReadableTs); + fn(encoder.Get()); + return ss.Str(); + } + Y_UNIT_TEST(Empty) { - auto result = EncodeToString(true, [](IMetricEncoder* e) { - e->OnStreamBegin(); - e->OnStreamEnd(); - }); - UNIT_ASSERT_STRINGS_EQUAL(result, ""); - } - + auto result = EncodeToString(true, [](IMetricEncoder* e) { + e->OnStreamBegin(); + e->OnStreamEnd(); + }); + UNIT_ASSERT_STRINGS_EQUAL(result, ""); + } + Y_UNIT_TEST(CommonPart) { - auto result = EncodeToString(true, [](IMetricEncoder* e) { - e->OnStreamBegin(); + auto result = EncodeToString(true, [](IMetricEncoder* e) { + e->OnStreamBegin(); e->OnCommonTime(TInstant::ParseIso8601Deprecated("2017-01-02T03:04:05.006Z")); - { - e->OnLabelsBegin(); - e->OnLabel("project", "solomon"); - e->OnLabel("cluster", "man"); - e->OnLabel("service", "stockpile"); - e->OnLabelsEnd(); - } - e->OnStreamEnd(); - }); - UNIT_ASSERT_STRINGS_EQUAL(result, - "common time: 2017-01-02T03:04:05Z\n" - "common labels: {project='solomon', cluster='man', service='stockpile'}\n"); - } - + { + e->OnLabelsBegin(); + e->OnLabel("project", "solomon"); + e->OnLabel("cluster", "man"); + e->OnLabel("service", "stockpile"); + e->OnLabelsEnd(); + } + e->OnStreamEnd(); + }); + UNIT_ASSERT_STRINGS_EQUAL(result, + "common time: 2017-01-02T03:04:05Z\n" + "common labels: {project='solomon', cluster='man', service='stockpile'}\n"); + } + Y_UNIT_TEST(Gauges) { - auto result = EncodeToString(true, [](IMetricEncoder* e) { - e->OnStreamBegin(); - { // no values - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "cpuUsage"); - e->OnLabelsEnd(); - } - e->OnMetricEnd(); - } - { // one value no ts - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "diskUsage"); - e->OnLabel("disk", "sda1"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::Zero(), 1000); - e->OnMetricEnd(); - } - { // one value with ts - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "memoryUsage"); - e->OnLabel("host", "solomon-man-00"); - e->OnLabel("dc", "man"); - e->OnLabelsEnd(); - } + auto result = EncodeToString(true, [](IMetricEncoder* e) { + e->OnStreamBegin(); + { // no values + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "cpuUsage"); + e->OnLabelsEnd(); + } + e->OnMetricEnd(); + } + { // one value no ts + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "diskUsage"); + e->OnLabel("disk", "sda1"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::Zero(), 1000); + e->OnMetricEnd(); + } + { // one value with ts + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "memoryUsage"); + e->OnLabel("host", "solomon-man-00"); + e->OnLabel("dc", "man"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); + e->OnMetricEnd(); + } + { // many values + e->OnMetricBegin(EMetricType::GAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "bytesRx"); + e->OnLabel("host", "solomon-sas-01"); + e->OnLabel("dc", "sas"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); + e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); + e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }); + UNIT_ASSERT_STRINGS_EQUAL(result, + " GAUGE cpuUsage{}\n" + " GAUGE diskUsage{disk='sda1'} [1000]\n" + " GAUGE memoryUsage{host='solomon-man-00', dc='man'} [(2017-12-02T12:00:00Z, 1000)]\n" + " GAUGE bytesRx{host='solomon-sas-01', dc='sas'} [(2017-12-02T12:00:00Z, 2), (2017-12-02T12:00:05Z, 4), (2017-12-02T12:00:10Z, 8)]\n"); + } + + Y_UNIT_TEST(IntGauges) { + auto result = EncodeToString(true, [](IMetricEncoder* e) { + e->OnStreamBegin(); + { // no values + e->OnMetricBegin(EMetricType::IGAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "cpuUsage"); + e->OnLabelsEnd(); + } + e->OnMetricEnd(); + } + { // one value no ts + e->OnMetricBegin(EMetricType::IGAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "diskUsage"); + e->OnLabel("disk", "sda1"); + e->OnLabelsEnd(); + } + e->OnDouble(TInstant::Zero(), 1000); + e->OnMetricEnd(); + } + { // one value with ts + e->OnMetricBegin(EMetricType::IGAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "memoryUsage"); + e->OnLabel("host", "solomon-man-00"); + e->OnLabel("dc", "man"); + e->OnLabelsEnd(); + } e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); - e->OnMetricEnd(); - } - { // many values - e->OnMetricBegin(EMetricType::GAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "bytesRx"); - e->OnLabel("host", "solomon-sas-01"); - e->OnLabel("dc", "sas"); - e->OnLabelsEnd(); - } + e->OnMetricEnd(); + } + { // many values + e->OnMetricBegin(EMetricType::IGAUGE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "bytesRx"); + e->OnLabel("host", "solomon-sas-01"); + e->OnLabel("dc", "sas"); + e->OnLabelsEnd(); + } e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }); - UNIT_ASSERT_STRINGS_EQUAL(result, - " GAUGE cpuUsage{}\n" - " GAUGE diskUsage{disk='sda1'} [1000]\n" - " GAUGE memoryUsage{host='solomon-man-00', dc='man'} [(2017-12-02T12:00:00Z, 1000)]\n" - " GAUGE bytesRx{host='solomon-sas-01', dc='sas'} [(2017-12-02T12:00:00Z, 2), (2017-12-02T12:00:05Z, 4), (2017-12-02T12:00:10Z, 8)]\n"); - } - - Y_UNIT_TEST(IntGauges) { - auto result = EncodeToString(true, [](IMetricEncoder* e) { - e->OnStreamBegin(); - { // no values - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "cpuUsage"); - e->OnLabelsEnd(); - } - e->OnMetricEnd(); - } - { // one value no ts - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "diskUsage"); - e->OnLabel("disk", "sda1"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::Zero(), 1000); - e->OnMetricEnd(); - } - { // one value with ts - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "memoryUsage"); - e->OnLabel("host", "solomon-man-00"); - e->OnLabel("dc", "man"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); - e->OnMetricEnd(); - } - { // many values - e->OnMetricBegin(EMetricType::IGAUGE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "bytesRx"); - e->OnLabel("host", "solomon-sas-01"); - e->OnLabel("dc", "sas"); - e->OnLabelsEnd(); - } - e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); - e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); - e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }); - UNIT_ASSERT_STRINGS_EQUAL(result, - " IGAUGE cpuUsage{}\n" - " IGAUGE diskUsage{disk='sda1'} [1000]\n" - " IGAUGE memoryUsage{host='solomon-man-00', dc='man'} [(2017-12-02T12:00:00Z, 1000)]\n" - " IGAUGE bytesRx{host='solomon-sas-01', dc='sas'} [(2017-12-02T12:00:00Z, 2), (2017-12-02T12:00:05Z, 4), (2017-12-02T12:00:10Z, 8)]\n"); - } - + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }); + UNIT_ASSERT_STRINGS_EQUAL(result, + " IGAUGE cpuUsage{}\n" + " IGAUGE diskUsage{disk='sda1'} [1000]\n" + " IGAUGE memoryUsage{host='solomon-man-00', dc='man'} [(2017-12-02T12:00:00Z, 1000)]\n" + " IGAUGE bytesRx{host='solomon-sas-01', dc='sas'} [(2017-12-02T12:00:00Z, 2), (2017-12-02T12:00:05Z, 4), (2017-12-02T12:00:10Z, 8)]\n"); + } + Y_UNIT_TEST(Counters) { - auto doEncode = [](IMetricEncoder* e) { - e->OnStreamBegin(); - { // no values - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "cpuUsage"); - e->OnLabelsEnd(); - } - e->OnMetricEnd(); - } - { // one value no ts - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "diskUsage"); - e->OnLabel("disk", "sda1"); - e->OnLabelsEnd(); - } - e->OnUint64(TInstant::Zero(), 1000); - e->OnMetricEnd(); - } - { // one value with ts - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "memoryUsage"); - e->OnLabel("host", "solomon-man-00"); - e->OnLabel("dc", "man"); - e->OnLabelsEnd(); - } + auto doEncode = [](IMetricEncoder* e) { + e->OnStreamBegin(); + { // no values + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "cpuUsage"); + e->OnLabelsEnd(); + } + e->OnMetricEnd(); + } + { // one value no ts + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "diskUsage"); + e->OnLabel("disk", "sda1"); + e->OnLabelsEnd(); + } + e->OnUint64(TInstant::Zero(), 1000); + e->OnMetricEnd(); + } + { // one value with ts + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "memoryUsage"); + e->OnLabel("host", "solomon-man-00"); + e->OnLabel("dc", "man"); + e->OnLabelsEnd(); + } e->OnUint64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000); - e->OnMetricEnd(); - } - { // many values - e->OnMetricBegin(EMetricType::COUNTER); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "bytesRx"); - e->OnLabel("host", "solomon-sas-01"); - e->OnLabel("dc", "sas"); - e->OnLabelsEnd(); - } + e->OnMetricEnd(); + } + { // many values + e->OnMetricBegin(EMetricType::COUNTER); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "bytesRx"); + e->OnLabel("host", "solomon-sas-01"); + e->OnLabel("dc", "sas"); + e->OnLabelsEnd(); + } e->OnUint64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2); e->OnUint64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4); e->OnUint64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }; - - auto result1 = EncodeToString(false, doEncode); - UNIT_ASSERT_STRINGS_EQUAL(result1, - " COUNTER cpuUsage{}\n" - " COUNTER diskUsage{disk='sda1'} [1000]\n" - " COUNTER memoryUsage{host='solomon-man-00', dc='man'} [(1512216000, 1000)]\n" - " COUNTER bytesRx{host='solomon-sas-01', dc='sas'} [(1512216000, 2), (1512216005, 4), (1512216010, 8)]\n"); - - auto result2 = EncodeToString(true, doEncode); - UNIT_ASSERT_STRINGS_EQUAL(result2, - " COUNTER cpuUsage{}\n" - " COUNTER diskUsage{disk='sda1'} [1000]\n" - " COUNTER memoryUsage{host='solomon-man-00', dc='man'} [(2017-12-02T12:00:00Z, 1000)]\n" - " COUNTER bytesRx{host='solomon-sas-01', dc='sas'} [(2017-12-02T12:00:00Z, 2), (2017-12-02T12:00:05Z, 4), (2017-12-02T12:00:10Z, 8)]\n"); - } - - Y_UNIT_TEST(Histograms) { - auto h = ExplicitHistogram({1, 2, 3, 4, 5}); - h->Collect(3); - h->Collect(5, 7); - h->Collect(13); - auto s = h->Snapshot(); - - TString result = EncodeToString(true, [s](IMetricEncoder* e) { - e->OnStreamBegin(); - { - e->OnMetricBegin(EMetricType::HIST); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "readTimeMillis"); - e->OnLabelsEnd(); - } - e->OnHistogram(TInstant::Zero(), s); - e->OnMetricEnd(); - } - { - e->OnMetricBegin(EMetricType::HIST_RATE); - { - e->OnLabelsBegin(); - e->OnLabel("sensor", "writeTimeMillis"); - e->OnLabelsEnd(); - } - e->OnHistogram(TInstant::Zero(), s); - e->OnMetricEnd(); - } - e->OnStreamEnd(); - }); - - UNIT_ASSERT_STRINGS_EQUAL(result, - " HIST readTimeMillis{} [{1: 0, 2: 0, 3: 1, 4: 0, 5: 7, inf: 1}]\n" - "HIST_RATE writeTimeMillis{} [{1: 0, 2: 0, 3: 1, 4: 0, 5: 7, inf: 1}]\n"); - } + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }; + + auto result1 = EncodeToString(false, doEncode); + UNIT_ASSERT_STRINGS_EQUAL(result1, + " COUNTER cpuUsage{}\n" + " COUNTER diskUsage{disk='sda1'} [1000]\n" + " COUNTER memoryUsage{host='solomon-man-00', dc='man'} [(1512216000, 1000)]\n" + " COUNTER bytesRx{host='solomon-sas-01', dc='sas'} [(1512216000, 2), (1512216005, 4), (1512216010, 8)]\n"); + + auto result2 = EncodeToString(true, doEncode); + UNIT_ASSERT_STRINGS_EQUAL(result2, + " COUNTER cpuUsage{}\n" + " COUNTER diskUsage{disk='sda1'} [1000]\n" + " COUNTER memoryUsage{host='solomon-man-00', dc='man'} [(2017-12-02T12:00:00Z, 1000)]\n" + " COUNTER bytesRx{host='solomon-sas-01', dc='sas'} [(2017-12-02T12:00:00Z, 2), (2017-12-02T12:00:05Z, 4), (2017-12-02T12:00:10Z, 8)]\n"); + } + + Y_UNIT_TEST(Histograms) { + auto h = ExplicitHistogram({1, 2, 3, 4, 5}); + h->Collect(3); + h->Collect(5, 7); + h->Collect(13); + auto s = h->Snapshot(); + + TString result = EncodeToString(true, [s](IMetricEncoder* e) { + e->OnStreamBegin(); + { + e->OnMetricBegin(EMetricType::HIST); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "readTimeMillis"); + e->OnLabelsEnd(); + } + e->OnHistogram(TInstant::Zero(), s); + e->OnMetricEnd(); + } + { + e->OnMetricBegin(EMetricType::HIST_RATE); + { + e->OnLabelsBegin(); + e->OnLabel("sensor", "writeTimeMillis"); + e->OnLabelsEnd(); + } + e->OnHistogram(TInstant::Zero(), s); + e->OnMetricEnd(); + } + e->OnStreamEnd(); + }); + + UNIT_ASSERT_STRINGS_EQUAL(result, + " HIST readTimeMillis{} [{1: 0, 2: 0, 3: 1, 4: 0, 5: 7, inf: 1}]\n" + "HIST_RATE writeTimeMillis{} [{1: 0, 2: 0, 3: 1, 4: 0, 5: 7, inf: 1}]\n"); + } Y_UNIT_TEST(Summary) { auto s = MakeIntrusive<TSummaryDoubleSnapshot>(10.1, -0.45, 0.478, 0.3, 30u); - TString result = EncodeToString(true, [s](IMetricEncoder* e) { + TString result = EncodeToString(true, [s](IMetricEncoder* e) { e->OnStreamBegin(); { - e->OnMetricBegin(EMetricType::DSUMMARY); + e->OnMetricBegin(EMetricType::DSUMMARY); { e->OnLabelsBegin(); e->OnLabel("sensor", "temperature"); e->OnLabelsEnd(); } e->OnSummaryDouble(TInstant::Zero(), s); - e->OnMetricEnd(); + e->OnMetricEnd(); } e->OnStreamEnd(); }); UNIT_ASSERT_STRINGS_EQUAL(result, " DSUMMARY temperature{} [{sum: 10.1, min: -0.45, max: 0.478, last: 0.3, count: 30}]\n"); } -} +} diff --git a/library/cpp/monlib/encode/text/ut/ya.make b/library/cpp/monlib/encode/text/ut/ya.make index 3d507800e0..df23a252d1 100644 --- a/library/cpp/monlib/encode/text/ut/ya.make +++ b/library/cpp/monlib/encode/text/ut/ya.make @@ -1,12 +1,12 @@ -UNITTEST_FOR(library/cpp/monlib/encode/text) - +UNITTEST_FOR(library/cpp/monlib/encode/text) + OWNER( g:solomon jamel ) - -SRCS( - text_encoder_ut.cpp -) - -END() + +SRCS( + text_encoder_ut.cpp +) + +END() diff --git a/library/cpp/monlib/encode/text/ya.make b/library/cpp/monlib/encode/text/ya.make index 85ae8043ec..d296c78c1b 100644 --- a/library/cpp/monlib/encode/text/ya.make +++ b/library/cpp/monlib/encode/text/ya.make @@ -1,16 +1,16 @@ -LIBRARY() - +LIBRARY() + OWNER( g:solomon jamel ) - -SRCS( - text_encoder.cpp -) - -PEERDIR( - library/cpp/monlib/encode -) - -END() + +SRCS( + text_encoder.cpp +) + +PEERDIR( + library/cpp/monlib/encode +) + +END() diff --git a/library/cpp/monlib/encode/unistat/unistat.h b/library/cpp/monlib/encode/unistat/unistat.h index c550dc3b6a..1c43b7fa1b 100644 --- a/library/cpp/monlib/encode/unistat/unistat.h +++ b/library/cpp/monlib/encode/unistat/unistat.h @@ -6,8 +6,8 @@ namespace NMonitoring { /// Decodes unistat-style metrics /// https://wiki.yandex-team.ru/golovan/stat-handle - void DecodeUnistat(TStringBuf data, class IMetricConsumer* c, TInstant ts = TInstant::Zero()); + void DecodeUnistat(TStringBuf data, class IMetricConsumer* c, TInstant ts = TInstant::Zero()); /// Assumes consumer's stream is open by the caller - void DecodeUnistatToStream(TStringBuf data, class IMetricConsumer* c, TInstant = TInstant::Zero()); + void DecodeUnistatToStream(TStringBuf data, class IMetricConsumer* c, TInstant = TInstant::Zero()); } diff --git a/library/cpp/monlib/encode/unistat/unistat_decoder.cpp b/library/cpp/monlib/encode/unistat/unistat_decoder.cpp index e97ca884da..b2344b0905 100644 --- a/library/cpp/monlib/encode/unistat/unistat_decoder.cpp +++ b/library/cpp/monlib/encode/unistat/unistat_decoder.cpp @@ -1,10 +1,10 @@ #include "unistat.h" -#include <library/cpp/monlib/metrics/histogram_collector.h> -#include <library/cpp/monlib/metrics/labels.h> -#include <library/cpp/monlib/metrics/metric_type.h> -#include <library/cpp/monlib/metrics/metric_value.h> -#include <library/cpp/monlib/metrics/metric_consumer.h> +#include <library/cpp/monlib/metrics/histogram_collector.h> +#include <library/cpp/monlib/metrics/labels.h> +#include <library/cpp/monlib/metrics/metric_type.h> +#include <library/cpp/monlib/metrics/metric_value.h> +#include <library/cpp/monlib/metrics/metric_consumer.h> #include <library/cpp/json/json_reader.h> @@ -86,7 +86,7 @@ namespace NMonitoring { class TDecoderUnistat { private: public: - explicit TDecoderUnistat(IMetricConsumer* consumer, IInputStream* is, TInstant ts) + explicit TDecoderUnistat(IMetricConsumer* consumer, IInputStream* is, TInstant ts) : Consumer_{consumer} , Timestamp_{ts} { ReadJsonTree(is, &Json_, /* throw */ true); @@ -120,19 +120,19 @@ namespace NMonitoring { private: void OnScalar(const TJsonValue& jsonValue) { if (MetricContext_.IsDeriv) { - MetricContext_.Type = EMetricType::RATE; - MetricContext_.Value = TMetricValue{ExtractUi64(jsonValue)}; + MetricContext_.Type = EMetricType::RATE; + MetricContext_.Value = TMetricValue{ExtractUi64(jsonValue)}; } else { - MetricContext_.Type = EMetricType::GAUGE; - MetricContext_.Value = TMetricValue{ExtractDouble(jsonValue)}; + MetricContext_.Type = EMetricType::GAUGE; + MetricContext_.Value = TMetricValue{ExtractDouble(jsonValue)}; } } void OnHistogram(const TJsonValue& jsonHist) { if (MetricContext_.IsDeriv) { - MetricContext_.Type = EMetricType::HIST_RATE; + MetricContext_.Type = EMetricType::HIST_RATE; } else { - MetricContext_.Type = EMetricType::HIST; + MetricContext_.Type = EMetricType::HIST; } auto histogramBuilder = THistogramBuilder(); @@ -147,7 +147,7 @@ namespace NMonitoring { } MetricContext_.Histogram = histogramBuilder.Finalize(); - MetricContext_.Value = TMetricValue{MetricContext_.Histogram.Get()}; + MetricContext_.Value = TMetricValue{MetricContext_.Histogram.Get()}; } bool IsDeriv(TStringBuf name) { @@ -190,7 +190,7 @@ namespace NMonitoring { private: void WriteValue() { - Consumer_->OnMetricBegin(MetricContext_.Type); + Consumer_->OnMetricBegin(MetricContext_.Type); Consumer_->OnLabelsBegin(); Consumer_->OnLabel("sensor", TString{MetricContext_.Name}); @@ -200,37 +200,37 @@ namespace NMonitoring { Consumer_->OnLabelsEnd(); - switch (MetricContext_.Type) { - case EMetricType::GAUGE: + switch (MetricContext_.Type) { + case EMetricType::GAUGE: Consumer_->OnDouble(Timestamp_, MetricContext_.Value.AsDouble()); break; - case EMetricType::RATE: + case EMetricType::RATE: Consumer_->OnUint64(Timestamp_, MetricContext_.Value.AsUint64()); break; - case EMetricType::HIST: - case EMetricType::HIST_RATE: + case EMetricType::HIST: + case EMetricType::HIST_RATE: Consumer_->OnHistogram(Timestamp_, MetricContext_.Value.AsHistogram()); break; case EMetricType::LOGHIST: - case EMetricType::DSUMMARY: - case EMetricType::IGAUGE: - case EMetricType::COUNTER: - case EMetricType::UNKNOWN: - ythrow yexception() << "Unexpected metric type: " << MetricContext_.Type; + case EMetricType::DSUMMARY: + case EMetricType::IGAUGE: + case EMetricType::COUNTER: + case EMetricType::UNKNOWN: + ythrow yexception() << "Unexpected metric type: " << MetricContext_.Type; } - Consumer_->OnMetricEnd(); + Consumer_->OnMetricEnd(); } private: - IMetricConsumer* Consumer_; + IMetricConsumer* Consumer_; NJson::TJsonValue Json_; TInstant Timestamp_; struct { TStringBuf Name; - EMetricType Type{EMetricType::UNKNOWN}; - TMetricValue Value; + EMetricType Type{EMetricType::UNKNOWN}; + TMetricValue Value; bool IsDeriv{false}; TLabels Labels; IHistogramSnapshotPtr Histogram; @@ -239,13 +239,13 @@ namespace NMonitoring { } - void DecodeUnistat(TStringBuf data, IMetricConsumer* c, TInstant ts) { + void DecodeUnistat(TStringBuf data, IMetricConsumer* c, TInstant ts) { c->OnStreamBegin(); DecodeUnistatToStream(data, c, ts); c->OnStreamEnd(); } - void DecodeUnistatToStream(TStringBuf data, IMetricConsumer* c, TInstant ts) { + void DecodeUnistatToStream(TStringBuf data, IMetricConsumer* c, TInstant ts) { TMemoryInput in{data.data(), data.size()}; TDecoderUnistat decoder(c, &in, ts); decoder.Decode(); diff --git a/library/cpp/monlib/encode/unistat/unistat_ut.cpp b/library/cpp/monlib/encode/unistat/unistat_ut.cpp index df71da3b47..dbbc238bf3 100644 --- a/library/cpp/monlib/encode/unistat/unistat_ut.cpp +++ b/library/cpp/monlib/encode/unistat/unistat_ut.cpp @@ -1,7 +1,7 @@ #include "unistat.h" -#include <library/cpp/monlib/encode/protobuf/protobuf.h> -#include <library/cpp/monlib/metrics/labels.h> +#include <library/cpp/monlib/encode/protobuf/protobuf.h> +#include <library/cpp/monlib/metrics/labels.h> #include <library/cpp/testing/unittest/registar.h> @@ -18,7 +18,7 @@ Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); auto sample = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); @@ -83,7 +83,7 @@ Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { DecodeUnistat(input, encoder.Get()); auto sample = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HIST_RATE); + UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HIST_RATE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); @@ -114,7 +114,7 @@ Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { DecodeUnistat(input, encoder.Get()); auto sample = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM); + UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::HISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); } @@ -159,7 +159,7 @@ Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 2); auto sample = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); @@ -170,7 +170,7 @@ Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { UNIT_ASSERT_VALUES_EQUAL(label.GetValue(), "something_axxx"); sample = samples.GetSamples(1); - UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE); + UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); @@ -190,7 +190,7 @@ Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); auto sample = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE); + UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::RATE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); @@ -210,7 +210,7 @@ Y_UNIT_TEST_SUITE(TUnistatDecoderTest) { UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 1); auto sample = samples.GetSamples(0); - UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); + UNIT_ASSERT_EQUAL(sample.GetMetricType(), NProto::GAUGE); UNIT_ASSERT_VALUES_EQUAL(sample.PointsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); diff --git a/library/cpp/monlib/encode/unistat/ut/ya.make b/library/cpp/monlib/encode/unistat/ut/ya.make index d9b2b51658..a652139f45 100644 --- a/library/cpp/monlib/encode/unistat/ut/ya.make +++ b/library/cpp/monlib/encode/unistat/ut/ya.make @@ -1,4 +1,4 @@ -UNITTEST_FOR(library/cpp/monlib/encode/unistat) +UNITTEST_FOR(library/cpp/monlib/encode/unistat) OWNER( msherbakov @@ -10,7 +10,7 @@ SRCS( ) PEERDIR( - library/cpp/monlib/encode/protobuf + library/cpp/monlib/encode/protobuf ) END() diff --git a/library/cpp/monlib/encode/unistat/ya.make b/library/cpp/monlib/encode/unistat/ya.make index ae3c1c40da..4ac2edadf4 100644 --- a/library/cpp/monlib/encode/unistat/ya.make +++ b/library/cpp/monlib/encode/unistat/ya.make @@ -8,7 +8,7 @@ OWNER( PEERDIR( contrib/libs/re2 library/cpp/json - library/cpp/monlib/metrics + library/cpp/monlib/metrics ) SRCS( diff --git a/library/cpp/monlib/encode/ut/ya.make b/library/cpp/monlib/encode/ut/ya.make index b83f62f2a2..1990386d76 100644 --- a/library/cpp/monlib/encode/ut/ya.make +++ b/library/cpp/monlib/encode/ut/ya.make @@ -1,12 +1,12 @@ -UNITTEST_FOR(library/cpp/monlib/encode) - +UNITTEST_FOR(library/cpp/monlib/encode) + OWNER( jamel g:solomon ) - -SRCS( - format_ut.cpp -) - -END() + +SRCS( + format_ut.cpp +) + +END() diff --git a/library/cpp/monlib/encode/ya.make b/library/cpp/monlib/encode/ya.make index a0dae3582f..d1bb09f07b 100644 --- a/library/cpp/monlib/encode/ya.make +++ b/library/cpp/monlib/encode/ya.make @@ -1,20 +1,20 @@ -LIBRARY() - +LIBRARY() + OWNER( g:solomon jamel ) - -SRCS( - encoder.cpp - encoder_state.cpp - format.cpp -) - -PEERDIR( - library/cpp/monlib/metrics -) - + +SRCS( + encoder.cpp + encoder_state.cpp + format.cpp +) + +PEERDIR( + library/cpp/monlib/metrics +) + GENERATE_ENUM_SERIALIZATION_WITH_HEADER(encoder_state_enum.h) -END() +END() diff --git a/library/cpp/monlib/messagebus/mon_messagebus.cpp b/library/cpp/monlib/messagebus/mon_messagebus.cpp index 414f3f6bb4..355b4386cd 100644 --- a/library/cpp/monlib/messagebus/mon_messagebus.cpp +++ b/library/cpp/monlib/messagebus/mon_messagebus.cpp @@ -6,6 +6,6 @@ using namespace NMonitoring; void TBusNgMonPage::Output(NMonitoring::IMonHttpRequest& request) { NBus::TBusWww::TOptionalParams params; - params.ParentLinks.push_back(NBus::TBusWww::TLink{"/", request.GetServiceTitle()}); + params.ParentLinks.push_back(NBus::TBusWww::TLink{"/", request.GetServiceTitle()}); BusWww->ServeHttp(request.Output(), request.GetParams(), params); } diff --git a/library/cpp/monlib/messagebus/mon_messagebus.h b/library/cpp/monlib/messagebus/mon_messagebus.h index 2cf46ecbbc..e1fa73c69f 100644 --- a/library/cpp/monlib/messagebus/mon_messagebus.h +++ b/library/cpp/monlib/messagebus/mon_messagebus.h @@ -3,44 +3,44 @@ #include <library/cpp/messagebus/ybus.h> #include <library/cpp/messagebus/www/www.h> -#include <library/cpp/monlib/service/pages/mon_page.h> +#include <library/cpp/monlib/service/pages/mon_page.h> namespace NMonitoring { - template <class TBusSmth> - class TBusSmthMonPage: public NMonitoring::IMonPage { - private: - TBusSmth* Smth; - - public: - explicit TBusSmthMonPage(const TString& name, const TString& title, TBusSmth* smth) - : IMonPage("msgbus/" + name, title) - , Smth(smth) - { - } + template <class TBusSmth> + class TBusSmthMonPage: public NMonitoring::IMonPage { + private: + TBusSmth* Smth; + + public: + explicit TBusSmthMonPage(const TString& name, const TString& title, TBusSmth* smth) + : IMonPage("msgbus/" + name, title) + , Smth(smth) + { + } void Output(NMonitoring::IMonHttpRequest& request) override { - Y_UNUSED(request); + Y_UNUSED(request); request.Output() << NMonitoring::HTTPOKHTML; request.Output() << "<h2>" << Title << "</h2>"; request.Output() << "<pre>"; request.Output() << Smth->GetStatus(); request.Output() << "</pre>"; - } - }; - - using TBusQueueMonPage = TBusSmthMonPage<NBus::TBusMessageQueue>; - using TBusModuleMonPage = TBusSmthMonPage<NBus::TBusModule>; - - class TBusNgMonPage: public NMonitoring::IMonPage { - public: - TIntrusivePtr<NBus::TBusWww> BusWww; - - public: - TBusNgMonPage() - : IMonPage("messagebus", "MessageBus") - , BusWww(new NBus::TBusWww) - { - } + } + }; + + using TBusQueueMonPage = TBusSmthMonPage<NBus::TBusMessageQueue>; + using TBusModuleMonPage = TBusSmthMonPage<NBus::TBusModule>; + + class TBusNgMonPage: public NMonitoring::IMonPage { + public: + TIntrusivePtr<NBus::TBusWww> BusWww; + + public: + TBusNgMonPage() + : IMonPage("messagebus", "MessageBus") + , BusWww(new NBus::TBusWww) + { + } void Output(NMonitoring::IMonHttpRequest& request) override; - }; - -} + }; + +} diff --git a/library/cpp/monlib/messagebus/mon_service_messagebus.cpp b/library/cpp/monlib/messagebus/mon_service_messagebus.cpp index 36ab81b012..4dd144ebe8 100644 --- a/library/cpp/monlib/messagebus/mon_service_messagebus.cpp +++ b/library/cpp/monlib/messagebus/mon_service_messagebus.cpp @@ -4,5 +4,5 @@ using namespace NMonitoring; TMonServiceMessageBus::TMonServiceMessageBus(ui16 port, const TString& title) : TMonService2(port, title) -{ -} +{ +} diff --git a/library/cpp/monlib/messagebus/mon_service_messagebus.h b/library/cpp/monlib/messagebus/mon_service_messagebus.h index 32c7b4cb70..fe791e8a9b 100644 --- a/library/cpp/monlib/messagebus/mon_service_messagebus.h +++ b/library/cpp/monlib/messagebus/mon_service_messagebus.h @@ -1,46 +1,46 @@ #pragma once -#include "mon_messagebus.h" - -#include <library/cpp/monlib/service/monservice.h> - +#include "mon_messagebus.h" + +#include <library/cpp/monlib/service/monservice.h> + #include <util/system/mutex.h> namespace NMonitoring { - class TMonServiceMessageBus: public TMonService2 { - private: - TMutex Mtx; - TIntrusivePtr<NMonitoring::TBusNgMonPage> BusNgMonPage; - - public: - TMonServiceMessageBus(ui16 port, const TString& title); - - private: - NBus::TBusWww* RegisterBusNgMonPage() { - TGuard<TMutex> g(Mtx); - if (!BusNgMonPage) { - BusNgMonPage = new NMonitoring::TBusNgMonPage(); - Register(BusNgMonPage.Get()); - } - return BusNgMonPage->BusWww.Get(); - } - - public: - void RegisterClientSession(NBus::TBusClientSessionPtr clientSession) { - RegisterBusNgMonPage()->RegisterClientSession(clientSession); + class TMonServiceMessageBus: public TMonService2 { + private: + TMutex Mtx; + TIntrusivePtr<NMonitoring::TBusNgMonPage> BusNgMonPage; + + public: + TMonServiceMessageBus(ui16 port, const TString& title); + + private: + NBus::TBusWww* RegisterBusNgMonPage() { + TGuard<TMutex> g(Mtx); + if (!BusNgMonPage) { + BusNgMonPage = new NMonitoring::TBusNgMonPage(); + Register(BusNgMonPage.Get()); + } + return BusNgMonPage->BusWww.Get(); } - void RegisterServerSession(NBus::TBusServerSessionPtr serverSession) { - RegisterBusNgMonPage()->RegisterServerSession(serverSession); - } + public: + void RegisterClientSession(NBus::TBusClientSessionPtr clientSession) { + RegisterBusNgMonPage()->RegisterClientSession(clientSession); + } - void RegisterQueue(NBus::TBusMessageQueuePtr queue) { - RegisterBusNgMonPage()->RegisterQueue(queue); - } + void RegisterServerSession(NBus::TBusServerSessionPtr serverSession) { + RegisterBusNgMonPage()->RegisterServerSession(serverSession); + } - void RegisterModule(NBus::TBusModule* module) { - RegisterBusNgMonPage()->RegisterModule(module); - } - }; + void RegisterQueue(NBus::TBusMessageQueuePtr queue) { + RegisterBusNgMonPage()->RegisterQueue(queue); + } + + void RegisterModule(NBus::TBusModule* module) { + RegisterBusNgMonPage()->RegisterModule(module); + } + }; -} +} diff --git a/library/cpp/monlib/messagebus/ya.make b/library/cpp/monlib/messagebus/ya.make index 79889e38a7..a0b5362296 100644 --- a/library/cpp/monlib/messagebus/ya.make +++ b/library/cpp/monlib/messagebus/ya.make @@ -10,7 +10,7 @@ SRCS( PEERDIR( library/cpp/messagebus library/cpp/messagebus/www - library/cpp/monlib/dynamic_counters + library/cpp/monlib/dynamic_counters ) END() diff --git a/library/cpp/monlib/metrics/atomics_array.h b/library/cpp/monlib/metrics/atomics_array.h index c9193f0a33..f19aebf291 100644 --- a/library/cpp/monlib/metrics/atomics_array.h +++ b/library/cpp/monlib/metrics/atomics_array.h @@ -1,52 +1,52 @@ -#pragma once - -#include <util/generic/ptr.h> -#include <util/generic/vector.h> - +#pragma once + +#include <util/generic/ptr.h> +#include <util/generic/vector.h> + #include <atomic> -namespace NMonitoring { - class TAtomicsArray { - public: - explicit TAtomicsArray(size_t size) +namespace NMonitoring { + class TAtomicsArray { + public: + explicit TAtomicsArray(size_t size) : Values_(new std::atomic<ui64>[size]) - , Size_(size) - { - for (size_t i = 0; i < Size_; i++) { + , Size_(size) + { + for (size_t i = 0; i < Size_; i++) { Values_[i].store(0, std::memory_order_relaxed); - } - } - - ui64 operator[](size_t index) const noexcept { - Y_VERIFY_DEBUG(index < Size_); + } + } + + ui64 operator[](size_t index) const noexcept { + Y_VERIFY_DEBUG(index < Size_); return Values_[index].load(std::memory_order_relaxed); - } - - size_t Size() const noexcept { - return Size_; - } - - void Add(size_t index, ui32 count) noexcept { - Y_VERIFY_DEBUG(index < Size_); + } + + size_t Size() const noexcept { + return Size_; + } + + void Add(size_t index, ui32 count) noexcept { + Y_VERIFY_DEBUG(index < Size_); Values_[index].fetch_add(count, std::memory_order_relaxed); - } - + } + void Reset() noexcept { for (size_t i = 0; i < Size_; i++) { Values_[i].store(0, std::memory_order_relaxed); } } - TVector<ui64> Copy() const { - TVector<ui64> copy(Reserve(Size_)); - for (size_t i = 0; i < Size_; i++) { + TVector<ui64> Copy() const { + TVector<ui64> copy(Reserve(Size_)); + for (size_t i = 0; i < Size_; i++) { copy.push_back(Values_[i].load(std::memory_order_relaxed)); - } - return copy; - } - - private: + } + return copy; + } + + private: TArrayHolder<std::atomic<ui64>> Values_; - size_t Size_; - }; -} + size_t Size_; + }; +} diff --git a/library/cpp/monlib/metrics/ewma.cpp b/library/cpp/monlib/metrics/ewma.cpp index 4ee78c0c3d..8a296c3225 100644 --- a/library/cpp/monlib/metrics/ewma.cpp +++ b/library/cpp/monlib/metrics/ewma.cpp @@ -1,5 +1,5 @@ #include "ewma.h" -#include "metric.h" +#include "metric.h" #include <atomic> #include <cmath> @@ -14,12 +14,12 @@ namespace { class TExpMovingAverage final: public IExpMovingAverage { public: - explicit TExpMovingAverage(IGauge* metric, double alpha, TDuration interval) - : Metric_{metric} + explicit TExpMovingAverage(IGauge* metric, double alpha, TDuration interval) + : Metric_{metric} , Alpha_{alpha} , Interval_{interval.Seconds()} { - Y_VERIFY(metric != nullptr, "Passing nullptr metric is not allowed"); + Y_VERIFY(metric != nullptr, "Passing nullptr metric is not allowed"); } ~TExpMovingAverage() override = default; @@ -30,11 +30,11 @@ namespace { const double instantRate = double(current) / Interval_; if (Y_UNLIKELY(!IsInitialized())) { - Metric_->Set(instantRate); + Metric_->Set(instantRate); Init_ = true; } else { - const double currentRate = Metric_->Get(); - Metric_->Set(Alpha_ * (instantRate - currentRate) + currentRate); + const double currentRate = Metric_->Get(); + Metric_->Set(Alpha_ * (instantRate - currentRate) + currentRate); } } @@ -44,7 +44,7 @@ namespace { } double Rate() const override { - return Metric_->Get(); + return Metric_->Get(); } void Reset() override { @@ -61,7 +61,7 @@ namespace { std::atomic<i64> Uncounted_{0}; std::atomic<bool> Init_{false}; - IGauge* Metric_{nullptr}; + IGauge* Metric_{nullptr}; double Alpha_; ui64 Interval_; }; @@ -132,19 +132,19 @@ namespace { return Ewma_->Rate(); } - IExpMovingAveragePtr OneMinuteEwma(IGauge* metric) { - return MakeHolder<TExpMovingAverage>(metric, ALPHA1, DEFAULT_INTERVAL); + IExpMovingAveragePtr OneMinuteEwma(IGauge* metric) { + return MakeHolder<TExpMovingAverage>(metric, ALPHA1, DEFAULT_INTERVAL); } - IExpMovingAveragePtr FiveMinuteEwma(IGauge* metric) { - return MakeHolder<TExpMovingAverage>(metric, ALPHA5, DEFAULT_INTERVAL); + IExpMovingAveragePtr FiveMinuteEwma(IGauge* metric) { + return MakeHolder<TExpMovingAverage>(metric, ALPHA5, DEFAULT_INTERVAL); } - IExpMovingAveragePtr FiveteenMinuteEwma(IGauge* metric) { - return MakeHolder<TExpMovingAverage>(metric, ALPHA15, DEFAULT_INTERVAL); + IExpMovingAveragePtr FiveteenMinuteEwma(IGauge* metric) { + return MakeHolder<TExpMovingAverage>(metric, ALPHA15, DEFAULT_INTERVAL); } - IExpMovingAveragePtr CreateEwma(IGauge* metric, double alpha, TDuration interval) { - return MakeHolder<TExpMovingAverage>(metric, alpha, interval); + IExpMovingAveragePtr CreateEwma(IGauge* metric, double alpha, TDuration interval) { + return MakeHolder<TExpMovingAverage>(metric, alpha, interval); } } // namespace NMonitoring diff --git a/library/cpp/monlib/metrics/ewma_ut.cpp b/library/cpp/monlib/metrics/ewma_ut.cpp index 56e292f9fd..01ef2478f7 100644 --- a/library/cpp/monlib/metrics/ewma_ut.cpp +++ b/library/cpp/monlib/metrics/ewma_ut.cpp @@ -1,5 +1,5 @@ #include "ewma.h" -#include "metric.h" +#include "metric.h" #include <library/cpp/testing/unittest/registar.h> @@ -15,9 +15,9 @@ void ElapseMinute(IExpMovingAverage& ewma) { Y_UNIT_TEST_SUITE(TEwmaTest) { Y_UNIT_TEST(OneMinute) { - TGauge gauge; + TGauge gauge; - auto ewma = OneMinuteEwma(&gauge); + auto ewma = OneMinuteEwma(&gauge); ewma->Update(3); ewma->Tick(); @@ -47,9 +47,9 @@ Y_UNIT_TEST_SUITE(TEwmaTest) { } Y_UNIT_TEST(FiveMinutes) { - TGauge gauge; + TGauge gauge; - auto ewma = FiveMinuteEwma(&gauge); + auto ewma = FiveMinuteEwma(&gauge); ewma->Update(3); ewma->Tick(); @@ -79,9 +79,9 @@ Y_UNIT_TEST_SUITE(TEwmaTest) { } Y_UNIT_TEST(FiveteenMinutes) { - TGauge gauge; + TGauge gauge; - auto ewma = FiveteenMinuteEwma(&gauge); + auto ewma = FiveteenMinuteEwma(&gauge); ewma->Update(3); ewma->Tick(); diff --git a/library/cpp/monlib/metrics/fake.cpp b/library/cpp/monlib/metrics/fake.cpp index 41522314ca..b6f5e37af8 100644 --- a/library/cpp/monlib/metrics/fake.cpp +++ b/library/cpp/monlib/metrics/fake.cpp @@ -1,9 +1,9 @@ #include "fake.h" namespace NMonitoring { - - IGauge* TFakeMetricRegistry::Gauge(ILabelsPtr labels) { - return Metric<TFakeGauge, EMetricType::GAUGE>(std::move(labels)); + + IGauge* TFakeMetricRegistry::Gauge(ILabelsPtr labels) { + return Metric<TFakeGauge, EMetricType::GAUGE>(std::move(labels)); } ILazyGauge* TFakeMetricRegistry::LazyGauge(ILabelsPtr labels, std::function<double()> supplier) { @@ -11,8 +11,8 @@ namespace NMonitoring { return Metric<TFakeLazyGauge, EMetricType::GAUGE>(std::move(labels)); } - IIntGauge* TFakeMetricRegistry::IntGauge(ILabelsPtr labels) { - return Metric<TFakeIntGauge, EMetricType::IGAUGE>(std::move(labels)); + IIntGauge* TFakeMetricRegistry::IntGauge(ILabelsPtr labels) { + return Metric<TFakeIntGauge, EMetricType::IGAUGE>(std::move(labels)); } ILazyIntGauge* TFakeMetricRegistry::LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) { @@ -20,8 +20,8 @@ namespace NMonitoring { return Metric<TFakeLazyIntGauge, EMetricType::IGAUGE>(std::move(labels)); } - ICounter* TFakeMetricRegistry::Counter(ILabelsPtr labels) { - return Metric<TFakeCounter, EMetricType::COUNTER>(std::move(labels)); + ICounter* TFakeMetricRegistry::Counter(ILabelsPtr labels) { + return Metric<TFakeCounter, EMetricType::COUNTER>(std::move(labels)); } ILazyCounter* TFakeMetricRegistry::LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) { @@ -29,8 +29,8 @@ namespace NMonitoring { return Metric<TFakeLazyCounter, EMetricType::COUNTER>(std::move(labels)); } - IRate* TFakeMetricRegistry::Rate(ILabelsPtr labels) { - return Metric<TFakeRate, EMetricType::RATE>(std::move(labels)); + IRate* TFakeMetricRegistry::Rate(ILabelsPtr labels) { + return Metric<TFakeRate, EMetricType::RATE>(std::move(labels)); } ILazyRate* TFakeMetricRegistry::LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) { @@ -38,46 +38,46 @@ namespace NMonitoring { return Metric<TFakeLazyRate, EMetricType::RATE>(std::move(labels)); } - IHistogram* TFakeMetricRegistry::HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) { + IHistogram* TFakeMetricRegistry::HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) { Y_UNUSED(collector); - return Metric<TFakeHistogram, EMetricType::HIST>(std::move(labels), false); + return Metric<TFakeHistogram, EMetricType::HIST>(std::move(labels), false); } - void TFakeMetricRegistry::RemoveMetric(const ILabels& labels) noexcept { + void TFakeMetricRegistry::RemoveMetric(const ILabels& labels) noexcept { TWriteGuard g{Lock_}; - Metrics_.erase(labels); + Metrics_.erase(labels); } - void TFakeMetricRegistry::Accept(TInstant time, IMetricConsumer* consumer) const { + void TFakeMetricRegistry::Accept(TInstant time, IMetricConsumer* consumer) const { Y_UNUSED(time); consumer->OnStreamBegin(); consumer->OnStreamEnd(); } - IHistogram* TFakeMetricRegistry::HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) { + IHistogram* TFakeMetricRegistry::HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) { Y_UNUSED(collector); - return Metric<TFakeHistogram, EMetricType::HIST_RATE>(std::move(labels), true); + return Metric<TFakeHistogram, EMetricType::HIST_RATE>(std::move(labels), true); } - void TFakeMetricRegistry::Append(TInstant time, IMetricConsumer* consumer) const { + void TFakeMetricRegistry::Append(TInstant time, IMetricConsumer* consumer) const { Y_UNUSED(time, consumer); } - const TLabels& TFakeMetricRegistry::CommonLabels() const noexcept { + const TLabels& TFakeMetricRegistry::CommonLabels() const noexcept { return CommonLabels_; } - template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> - TMetric* TFakeMetricRegistry::Metric(TLabelsType&& labels, Args&&... args) { + template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> + TMetric* TFakeMetricRegistry::Metric(TLabelsType&& labels, Args&&... args) { { TReadGuard g{Lock_}; - auto it = Metrics_.find(labels); - if (it != Metrics_.end()) { - Y_ENSURE(it->second->Type() == type, "cannot create metric " << labels - << " with type " << MetricTypeToStr(type) - << ", because registry already has same metric with type " << MetricTypeToStr(it->second->Type())); - return static_cast<TMetric*>(it->second.Get()); + auto it = Metrics_.find(labels); + if (it != Metrics_.end()) { + Y_ENSURE(it->second->Type() == type, "cannot create metric " << labels + << " with type " << MetricTypeToStr(type) + << ", because registry already has same metric with type " << MetricTypeToStr(it->second->Type())); + return static_cast<TMetric*>(it->second.Get()); } } @@ -86,15 +86,15 @@ namespace NMonitoring { IMetricPtr metric = MakeHolder<TMetric>(std::forward<Args>(args)...); - // decltype(Metrics_)::iterator breaks build on windows - THashMap<ILabelsPtr, IMetricPtr>::iterator it; + // decltype(Metrics_)::iterator breaks build on windows + THashMap<ILabelsPtr, IMetricPtr>::iterator it; if constexpr (!std::is_convertible_v<TLabelsType, ILabelsPtr>) { - it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metric)).first; + it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metric)).first; } else { - it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metric)).first; + it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metric)).first; } - return static_cast<TMetric*>(it->second.Get()); + return static_cast<TMetric*>(it->second.Get()); } } } // namespace NMonitoring diff --git a/library/cpp/monlib/metrics/fake.h b/library/cpp/monlib/metrics/fake.h index c2e40b267b..61ba4f2bd4 100644 --- a/library/cpp/monlib/metrics/fake.h +++ b/library/cpp/monlib/metrics/fake.h @@ -1,21 +1,21 @@ #pragma once -#include "metric.h" -#include "metric_registry.h" +#include "metric.h" +#include "metric_registry.h" namespace NMonitoring { - class TFakeMetricRegistry: public IMetricRegistry { + class TFakeMetricRegistry: public IMetricRegistry { public: - TFakeMetricRegistry() noexcept - : CommonLabels_{0} - { - } - - explicit TFakeMetricRegistry(TLabels commonLabels) noexcept - : CommonLabels_{std::move(commonLabels)} - { - } - + TFakeMetricRegistry() noexcept + : CommonLabels_{0} + { + } + + explicit TFakeMetricRegistry(TLabels commonLabels) noexcept + : CommonLabels_{std::move(commonLabels)} + { + } + IGauge* Gauge(ILabelsPtr labels) override; ILazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) override; IIntGauge* IntGauge(ILabelsPtr labels) override; @@ -32,25 +32,25 @@ namespace NMonitoring { IHistogram* HistogramRate( ILabelsPtr labels, IHistogramCollectorPtr collector) override; - void Accept(TInstant time, IMetricConsumer* consumer) const override; - void Append(TInstant time, IMetricConsumer* consumer) const override; + void Accept(TInstant time, IMetricConsumer* consumer) const override; + void Append(TInstant time, IMetricConsumer* consumer) const override; const TLabels& CommonLabels() const noexcept override; - void RemoveMetric(const ILabels& labels) noexcept override; + void RemoveMetric(const ILabels& labels) noexcept override; private: TRWMutex Lock_; - THashMap<ILabelsPtr, IMetricPtr> Metrics_; + THashMap<ILabelsPtr, IMetricPtr> Metrics_; - template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> - TMetric* Metric(TLabelsType&& labels, Args&&... args); + template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> + TMetric* Metric(TLabelsType&& labels, Args&&... args); const TLabels CommonLabels_; }; template <typename TBase> struct TFakeAcceptor: TBase { - void Accept(TInstant time, IMetricConsumer* consumer) const override { + void Accept(TInstant time, IMetricConsumer* consumer) const override { Y_UNUSED(time, consumer); } }; @@ -85,9 +85,9 @@ namespace NMonitoring { ui64 Get() const noexcept override { return 0; } - - void Reset() noexcept override { - } + + void Reset() noexcept override { + } }; struct TFakeLazyRate final: public TFakeAcceptor<ILazyRate> { @@ -123,11 +123,11 @@ namespace NMonitoring { { } - void Record(double value) override { + void Record(double value) override { Y_UNUSED(value); } - void Record(double value, ui32 count) override { + void Record(double value, ui32 count) override { Y_UNUSED(value, count); } @@ -135,7 +135,7 @@ namespace NMonitoring { return nullptr; } - void Accept(TInstant time, IMetricConsumer* consumer) const override { + void Accept(TInstant time, IMetricConsumer* consumer) const override { Y_UNUSED(time, consumer); } @@ -148,7 +148,7 @@ namespace NMonitoring { Y_UNUSED(n); return 0; } - + ui64 Get() const noexcept override { return 0; } diff --git a/library/cpp/monlib/metrics/fake_ut.cpp b/library/cpp/monlib/metrics/fake_ut.cpp index af164f4628..c3368ca302 100644 --- a/library/cpp/monlib/metrics/fake_ut.cpp +++ b/library/cpp/monlib/metrics/fake_ut.cpp @@ -1,34 +1,34 @@ -#include "fake.h" - -#include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/ptr.h> - -using namespace NMonitoring; - -Y_UNIT_TEST_SUITE(TFakeTest) { - - Y_UNIT_TEST(CreateOnStack) { - TFakeMetricRegistry registry; - } - - Y_UNIT_TEST(CreateOnHeap) { - auto registry = MakeAtomicShared<TFakeMetricRegistry>(); - UNIT_ASSERT(registry); - } - - Y_UNIT_TEST(Gauge) { - TFakeMetricRegistry registry(TLabels{{"common", "label"}}); - - IGauge* g = registry.Gauge(MakeLabels({{"my", "gauge"}})); - UNIT_ASSERT(g); - - UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 0.0, 1E-6); - g->Set(12.34); - UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 0.0, 1E-6); // no changes - - double val = g->Add(1.2); - UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 0.0, 1E-6); - UNIT_ASSERT_DOUBLES_EQUAL(val, 0.0, 1E-6); - } -} +#include "fake.h" + +#include <library/cpp/testing/unittest/registar.h> + +#include <util/generic/ptr.h> + +using namespace NMonitoring; + +Y_UNIT_TEST_SUITE(TFakeTest) { + + Y_UNIT_TEST(CreateOnStack) { + TFakeMetricRegistry registry; + } + + Y_UNIT_TEST(CreateOnHeap) { + auto registry = MakeAtomicShared<TFakeMetricRegistry>(); + UNIT_ASSERT(registry); + } + + Y_UNIT_TEST(Gauge) { + TFakeMetricRegistry registry(TLabels{{"common", "label"}}); + + IGauge* g = registry.Gauge(MakeLabels({{"my", "gauge"}})); + UNIT_ASSERT(g); + + UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 0.0, 1E-6); + g->Set(12.34); + UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 0.0, 1E-6); // no changes + + double val = g->Add(1.2); + UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 0.0, 1E-6); + UNIT_ASSERT_DOUBLES_EQUAL(val, 0.0, 1E-6); + } +} diff --git a/library/cpp/monlib/metrics/fwd.h b/library/cpp/monlib/metrics/fwd.h index 91b0ad9fcb..b4327ee5d5 100644 --- a/library/cpp/monlib/metrics/fwd.h +++ b/library/cpp/monlib/metrics/fwd.h @@ -1,40 +1,40 @@ -#pragma once - -namespace NMonitoring { - - struct ILabel; - struct ILabels; - - class ICounter; - class IGauge; - class IHistogram; - class IIntGauge; - class ILazyCounter; - class ILazyGauge; - class ILazyIntGauge; - class ILazyRate; - class IMetric; - class IRate; - class TCounter; - class TGauge; - class THistogram; - class TIntGauge; - class TLazyCounter; - class TLazyGauge; - class TLazyIntGauge; - class TLazyRate; - class TRate; - - class IMetricSupplier; - class IMetricFactory; - class IMetricConsumer; - - class IMetricRegistry; - class TMetricRegistry; - - class IHistogramCollector; - class IHistogramSnapshot; - - class IExpMovingAverage; - -} // namespace NMonitoring +#pragma once + +namespace NMonitoring { + + struct ILabel; + struct ILabels; + + class ICounter; + class IGauge; + class IHistogram; + class IIntGauge; + class ILazyCounter; + class ILazyGauge; + class ILazyIntGauge; + class ILazyRate; + class IMetric; + class IRate; + class TCounter; + class TGauge; + class THistogram; + class TIntGauge; + class TLazyCounter; + class TLazyGauge; + class TLazyIntGauge; + class TLazyRate; + class TRate; + + class IMetricSupplier; + class IMetricFactory; + class IMetricConsumer; + + class IMetricRegistry; + class TMetricRegistry; + + class IHistogramCollector; + class IHistogramSnapshot; + + class IExpMovingAverage; + +} // namespace NMonitoring diff --git a/library/cpp/monlib/metrics/histogram_collector.h b/library/cpp/monlib/metrics/histogram_collector.h index b1d628ce9e..9f6bbbdfb7 100644 --- a/library/cpp/monlib/metrics/histogram_collector.h +++ b/library/cpp/monlib/metrics/histogram_collector.h @@ -1,119 +1,119 @@ -#pragma once - -#include "histogram_snapshot.h" - -namespace NMonitoring { - - /////////////////////////////////////////////////////////////////////////// - // IHistogramCollector - /////////////////////////////////////////////////////////////////////////// - class IHistogramCollector { - public: - virtual ~IHistogramCollector() = default; - - /** - * Store {@code count} times given {@code value} in this collector. - */ +#pragma once + +#include "histogram_snapshot.h" + +namespace NMonitoring { + + /////////////////////////////////////////////////////////////////////////// + // IHistogramCollector + /////////////////////////////////////////////////////////////////////////// + class IHistogramCollector { + public: + virtual ~IHistogramCollector() = default; + + /** + * Store {@code count} times given {@code value} in this collector. + */ virtual void Collect(double value, ui32 count) = 0; - - /** - * Store given {@code value} in this collector. - */ - void Collect(double value) { - Collect(value, 1); - } - - /** - * Add counts from snapshot into this collector - */ - void Collect(const IHistogramSnapshot& snapshot) { - for (ui32 i = 0; i < snapshot.Count(); i++) { - Collect(snapshot.UpperBound(i), snapshot.Value(i)); - } - } - - /** + + /** + * Store given {@code value} in this collector. + */ + void Collect(double value) { + Collect(value, 1); + } + + /** + * Add counts from snapshot into this collector + */ + void Collect(const IHistogramSnapshot& snapshot) { + for (ui32 i = 0; i < snapshot.Count(); i++) { + Collect(snapshot.UpperBound(i), snapshot.Value(i)); + } + } + + /** * Reset collector values */ virtual void Reset() = 0; /** - * @return snapshot of the state of this collector. - */ - virtual IHistogramSnapshotPtr Snapshot() const = 0; - }; - - using IHistogramCollectorPtr = THolder<IHistogramCollector>; - - /////////////////////////////////////////////////////////////////////////// - // free functions - /////////////////////////////////////////////////////////////////////////// - - /** - * <p>Creates histogram collector for a set of buckets with arbitrary - * bounds.</p> - * - * <p>Defines {@code bounds.size() + 1} buckets with these boundaries for - * bucket i:</p> - * <ul> - * <li>Upper bound (0 <= i < N-1): {@code bounds[i]}</li> - * <li>Lower bound (1 <= i < N): {@code bounds[i - 1]}</li> - * </ul> - * - * <p>For example, if the list of boundaries is:</p> - * <pre>0, 1, 2, 5, 10, 20</pre> - * - * <p>then there are five finite buckets with the following ranges:</p> - * <pre>(-INF, 0], (0, 1], (1, 2], (2, 5], (5, 10], (10, 20], (20, +INF)</pre> - * - * @param bounds array of upper bounds for buckets. Values must be sorted. - */ + * @return snapshot of the state of this collector. + */ + virtual IHistogramSnapshotPtr Snapshot() const = 0; + }; + + using IHistogramCollectorPtr = THolder<IHistogramCollector>; + + /////////////////////////////////////////////////////////////////////////// + // free functions + /////////////////////////////////////////////////////////////////////////// + + /** + * <p>Creates histogram collector for a set of buckets with arbitrary + * bounds.</p> + * + * <p>Defines {@code bounds.size() + 1} buckets with these boundaries for + * bucket i:</p> + * <ul> + * <li>Upper bound (0 <= i < N-1): {@code bounds[i]}</li> + * <li>Lower bound (1 <= i < N): {@code bounds[i - 1]}</li> + * </ul> + * + * <p>For example, if the list of boundaries is:</p> + * <pre>0, 1, 2, 5, 10, 20</pre> + * + * <p>then there are five finite buckets with the following ranges:</p> + * <pre>(-INF, 0], (0, 1], (1, 2], (2, 5], (5, 10], (10, 20], (20, +INF)</pre> + * + * @param bounds array of upper bounds for buckets. Values must be sorted. + */ IHistogramCollectorPtr ExplicitHistogram(TBucketBounds bounds); - - /** - * <p>Creates histogram collector for a sequence of buckets that have a - * width proportional to the value of the lower bound.</p> - * - * <p>Defines {@code bucketsCount} buckets with these boundaries for bucket i:</p> - * <ul> - * <li>Upper bound (0 <= i < N-1): {@code scale * (base ^ i)}</li> - * <li>Lower bound (1 <= i < N): {@code scale * (base ^ (i - 1))}</li> - * </ul> - * - * <p>For example, if {@code bucketsCount=6}, {@code base=2}, and {@code scale=3}, - * then the bucket ranges are as follows:</p> - * - * <pre>(-INF, 3], (3, 6], (6, 12], (12, 24], (24, 48], (48, +INF)</pre> - * - * @param bucketsCount the total number of buckets. The value must be >= 2. - * @param base the exponential growth factor for the buckets width. - * The value must be >= 1.0. - * @param scale the linear scale for the buckets. The value must be >= 1.0. - */ - IHistogramCollectorPtr ExponentialHistogram( - ui32 bucketsCount, double base, double scale = 1.0); - - /** - * <p>Creates histogram collector for a sequence of buckets that all have - * the same width (except overflow and underflow).</p> - * - * <p>Defines {@code bucketsCount} buckets with these boundaries for bucket i:</p> - * <ul> - * <li>Upper bound (0 <= i < N-1): {@code startValue + bucketWidth * i}</li> - * <li>Lower bound (1 <= i < N): {@code startValue + bucketWidth * (i - 1)}</li> - * </ul> - * - * <p>For example, if {@code bucketsCount=6}, {@code startValue=5}, and - * {@code bucketWidth=15}, then the bucket ranges are as follows:</p> - * - * <pre>(-INF, 5], (5, 20], (20, 35], (35, 50], (50, 65], (65, +INF)</pre> - * - * @param bucketsCount the total number of buckets. The value must be >= 2. - * @param startValue the upper boundary of the first bucket. - * @param bucketWidth the difference between the upper and lower bounds for - * each bucket. The value must be >= 1. - */ - IHistogramCollectorPtr LinearHistogram( + + /** + * <p>Creates histogram collector for a sequence of buckets that have a + * width proportional to the value of the lower bound.</p> + * + * <p>Defines {@code bucketsCount} buckets with these boundaries for bucket i:</p> + * <ul> + * <li>Upper bound (0 <= i < N-1): {@code scale * (base ^ i)}</li> + * <li>Lower bound (1 <= i < N): {@code scale * (base ^ (i - 1))}</li> + * </ul> + * + * <p>For example, if {@code bucketsCount=6}, {@code base=2}, and {@code scale=3}, + * then the bucket ranges are as follows:</p> + * + * <pre>(-INF, 3], (3, 6], (6, 12], (12, 24], (24, 48], (48, +INF)</pre> + * + * @param bucketsCount the total number of buckets. The value must be >= 2. + * @param base the exponential growth factor for the buckets width. + * The value must be >= 1.0. + * @param scale the linear scale for the buckets. The value must be >= 1.0. + */ + IHistogramCollectorPtr ExponentialHistogram( + ui32 bucketsCount, double base, double scale = 1.0); + + /** + * <p>Creates histogram collector for a sequence of buckets that all have + * the same width (except overflow and underflow).</p> + * + * <p>Defines {@code bucketsCount} buckets with these boundaries for bucket i:</p> + * <ul> + * <li>Upper bound (0 <= i < N-1): {@code startValue + bucketWidth * i}</li> + * <li>Lower bound (1 <= i < N): {@code startValue + bucketWidth * (i - 1)}</li> + * </ul> + * + * <p>For example, if {@code bucketsCount=6}, {@code startValue=5}, and + * {@code bucketWidth=15}, then the bucket ranges are as follows:</p> + * + * <pre>(-INF, 5], (5, 20], (20, 35], (35, 50], (50, 65], (65, +INF)</pre> + * + * @param bucketsCount the total number of buckets. The value must be >= 2. + * @param startValue the upper boundary of the first bucket. + * @param bucketWidth the difference between the upper and lower bounds for + * each bucket. The value must be >= 1. + */ + IHistogramCollectorPtr LinearHistogram( ui32 bucketsCount, TBucketBound startValue, TBucketBound bucketWidth); - + } // namespace NMonitoring diff --git a/library/cpp/monlib/metrics/histogram_collector_explicit.cpp b/library/cpp/monlib/metrics/histogram_collector_explicit.cpp index 90c41a235a..377fc233ef 100644 --- a/library/cpp/monlib/metrics/histogram_collector_explicit.cpp +++ b/library/cpp/monlib/metrics/histogram_collector_explicit.cpp @@ -1,55 +1,55 @@ -#include "histogram_collector.h" -#include "atomics_array.h" - -#include <util/generic/algorithm.h> -#include <util/generic/vector.h> -#include <util/generic/yexception.h> -#include <util/generic/ylimits.h> - -namespace NMonitoring { - - /////////////////////////////////////////////////////////////////////////// - // TExplicitHistogramCollector - /////////////////////////////////////////////////////////////////////////// - class TExplicitHistogramCollector: public IHistogramCollector { - public: +#include "histogram_collector.h" +#include "atomics_array.h" + +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> +#include <util/generic/yexception.h> +#include <util/generic/ylimits.h> + +namespace NMonitoring { + + /////////////////////////////////////////////////////////////////////////// + // TExplicitHistogramCollector + /////////////////////////////////////////////////////////////////////////// + class TExplicitHistogramCollector: public IHistogramCollector { + public: TExplicitHistogramCollector(TBucketBounds bounds) : Values_(bounds.size() + 1) , Bounds_(std::move(bounds)) - { - // add one bucket as +INF - Bounds_.push_back(Max<TBucketBound>()); - } - + { + // add one bucket as +INF + Bounds_.push_back(Max<TBucketBound>()); + } + void Collect(double value, ui32 count) override { auto it = LowerBound(Bounds_.begin(), Bounds_.end(), value); - auto index = std::distance(Bounds_.begin(), it); - Values_.Add(index, count); - } - + auto index = std::distance(Bounds_.begin(), it); + Values_.Add(index, count); + } + void Reset() override { Values_.Reset(); } - IHistogramSnapshotPtr Snapshot() const override { + IHistogramSnapshotPtr Snapshot() const override { auto values = Values_.Copy(); return ExplicitHistogramSnapshot(Bounds_, values); - } - - private: + } + + private: TAtomicsArray Values_; - TBucketBounds Bounds_; - }; - - IHistogramCollectorPtr ExplicitHistogram(TBucketBounds bounds) { - Y_ENSURE(bounds.size() >= 1, - "explicit histogram must contain at least one bucket"); + TBucketBounds Bounds_; + }; + + IHistogramCollectorPtr ExplicitHistogram(TBucketBounds bounds) { + Y_ENSURE(bounds.size() >= 1, + "explicit histogram must contain at least one bucket"); Y_ENSURE(bounds.size() <= HISTOGRAM_MAX_BUCKETS_COUNT, "buckets count must be <=" << HISTOGRAM_MAX_BUCKETS_COUNT - << ", but got: " << bounds.size()); - Y_ENSURE(IsSorted(bounds.begin(), bounds.end()), - "bounds for explicit histogram must be sorted"); - + << ", but got: " << bounds.size()); + Y_ENSURE(IsSorted(bounds.begin(), bounds.end()), + "bounds for explicit histogram must be sorted"); + return MakeHolder<TExplicitHistogramCollector>(bounds); - } -} + } +} diff --git a/library/cpp/monlib/metrics/histogram_collector_exponential.cpp b/library/cpp/monlib/metrics/histogram_collector_exponential.cpp index a6b929e8f3..2f8a50a5f9 100644 --- a/library/cpp/monlib/metrics/histogram_collector_exponential.cpp +++ b/library/cpp/monlib/metrics/histogram_collector_exponential.cpp @@ -1,68 +1,68 @@ -#include "histogram_collector.h" -#include "atomics_array.h" - -#include <util/generic/algorithm.h> -#include <util/generic/vector.h> -#include <util/generic/yexception.h> -#include <util/generic/ylimits.h> - -namespace NMonitoring { - /////////////////////////////////////////////////////////////////////////// - // TExponentialHistogramCollector - /////////////////////////////////////////////////////////////////////////// - class TExponentialHistogramCollector: public IHistogramCollector { - public: - TExponentialHistogramCollector(ui32 bucketsCount, double base, double scale) - : Values_(bucketsCount) - , Base_(base) - , Scale_(scale) +#include "histogram_collector.h" +#include "atomics_array.h" + +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> +#include <util/generic/yexception.h> +#include <util/generic/ylimits.h> + +namespace NMonitoring { + /////////////////////////////////////////////////////////////////////////// + // TExponentialHistogramCollector + /////////////////////////////////////////////////////////////////////////// + class TExponentialHistogramCollector: public IHistogramCollector { + public: + TExponentialHistogramCollector(ui32 bucketsCount, double base, double scale) + : Values_(bucketsCount) + , Base_(base) + , Scale_(scale) , MinValue_(scale) , MaxValue_(scale * std::pow(base, bucketsCount - 2)) - , LogOfBase_(std::log(base)) - { - } - + , LogOfBase_(std::log(base)) + { + } + void Collect(double value, ui32 count) override { - ui32 index = Max<ui32>(); - if (value <= MinValue_) { - index = 0; - } else if (value > MaxValue_) { - index = Values_.Size() - 1; - } else { - double logBase = std::log(value / Scale_) / LogOfBase_; - index = static_cast<ui32>(std::ceil(logBase)); - } - Values_.Add(index, count); - } - + ui32 index = Max<ui32>(); + if (value <= MinValue_) { + index = 0; + } else if (value > MaxValue_) { + index = Values_.Size() - 1; + } else { + double logBase = std::log(value / Scale_) / LogOfBase_; + index = static_cast<ui32>(std::ceil(logBase)); + } + Values_.Add(index, count); + } + void Reset() override { Values_.Reset(); } - IHistogramSnapshotPtr Snapshot() const override { - return new TExponentialHistogramSnapshot(Base_, Scale_, Values_.Copy()); - } - - private: - TAtomicsArray Values_; - double Base_; - double Scale_; + IHistogramSnapshotPtr Snapshot() const override { + return new TExponentialHistogramSnapshot(Base_, Scale_, Values_.Copy()); + } + + private: + TAtomicsArray Values_; + double Base_; + double Scale_; TBucketBound MinValue_; TBucketBound MaxValue_; - double LogOfBase_; - }; - - IHistogramCollectorPtr ExponentialHistogram( - ui32 bucketsCount, double base, double scale) - { - Y_ENSURE(bucketsCount >= 2, - "exponential histogram must contain at least two buckets"); + double LogOfBase_; + }; + + IHistogramCollectorPtr ExponentialHistogram( + ui32 bucketsCount, double base, double scale) + { + Y_ENSURE(bucketsCount >= 2, + "exponential histogram must contain at least two buckets"); Y_ENSURE(bucketsCount <= HISTOGRAM_MAX_BUCKETS_COUNT, "buckets count must be <=" << HISTOGRAM_MAX_BUCKETS_COUNT - << ", but got: " << bucketsCount); - Y_ENSURE(base > 1.0, "base must be > 1.0, got: " << base); - Y_ENSURE(scale >= 1.0, "scale must be >= 1.0, got: " << scale); - - return MakeHolder<TExponentialHistogramCollector>(bucketsCount, base, scale); - } -} + << ", but got: " << bucketsCount); + Y_ENSURE(base > 1.0, "base must be > 1.0, got: " << base); + Y_ENSURE(scale >= 1.0, "scale must be >= 1.0, got: " << scale); + + return MakeHolder<TExponentialHistogramCollector>(bucketsCount, base, scale); + } +} diff --git a/library/cpp/monlib/metrics/histogram_collector_linear.cpp b/library/cpp/monlib/metrics/histogram_collector_linear.cpp index c0afa29241..f8ad86f3a4 100644 --- a/library/cpp/monlib/metrics/histogram_collector_linear.cpp +++ b/library/cpp/monlib/metrics/histogram_collector_linear.cpp @@ -1,67 +1,67 @@ -#include "histogram_collector.h" -#include "atomics_array.h" - -#include <util/generic/algorithm.h> -#include <util/generic/vector.h> -#include <util/generic/yexception.h> -#include <util/generic/ylimits.h> - -#include <cmath> - -namespace NMonitoring { - /////////////////////////////////////////////////////////////////////////// - // TLinearHistogramCollector - /////////////////////////////////////////////////////////////////////////// - class TLinearHistogramCollector: public IHistogramCollector { - public: - TLinearHistogramCollector( +#include "histogram_collector.h" +#include "atomics_array.h" + +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> +#include <util/generic/yexception.h> +#include <util/generic/ylimits.h> + +#include <cmath> + +namespace NMonitoring { + /////////////////////////////////////////////////////////////////////////// + // TLinearHistogramCollector + /////////////////////////////////////////////////////////////////////////// + class TLinearHistogramCollector: public IHistogramCollector { + public: + TLinearHistogramCollector( ui32 bucketsCount, TBucketBound startValue, TBucketBound bucketWidth) - : Values_(bucketsCount) - , StartValue_(startValue) - , BucketWidth_(bucketWidth) - , MaxValue_(startValue + bucketWidth * (bucketsCount - 2)) - { - } - + : Values_(bucketsCount) + , StartValue_(startValue) + , BucketWidth_(bucketWidth) + , MaxValue_(startValue + bucketWidth * (bucketsCount - 2)) + { + } + void Collect(double value, ui32 count) override { - ui32 index = Max<ui32>(); - if (value <= StartValue_) { - index = 0; - } else if (value > MaxValue_) { - index = Values_.Size() - 1; - } else { + ui32 index = Max<ui32>(); + if (value <= StartValue_) { + index = 0; + } else if (value > MaxValue_) { + index = Values_.Size() - 1; + } else { double buckets = (value - StartValue_) / BucketWidth_; - index = static_cast<ui32>(std::ceil(buckets)); - } - Values_.Add(index, count); - } - + index = static_cast<ui32>(std::ceil(buckets)); + } + Values_.Add(index, count); + } + void Reset() override { Values_.Reset(); } - IHistogramSnapshotPtr Snapshot() const override { - return new TLinearHistogramSnapshot( - StartValue_, BucketWidth_, Values_.Copy()); - } - - private: - TAtomicsArray Values_; + IHistogramSnapshotPtr Snapshot() const override { + return new TLinearHistogramSnapshot( + StartValue_, BucketWidth_, Values_.Copy()); + } + + private: + TAtomicsArray Values_; TBucketBound StartValue_; double BucketWidth_; TBucketBound MaxValue_; - }; - - IHistogramCollectorPtr LinearHistogram( + }; + + IHistogramCollectorPtr LinearHistogram( ui32 bucketsCount, TBucketBound startValue, TBucketBound bucketWidth) - { - Y_ENSURE(bucketsCount >= 2, - "linear histogram must contain at least two buckets"); + { + Y_ENSURE(bucketsCount >= 2, + "linear histogram must contain at least two buckets"); Y_ENSURE(bucketsCount <= HISTOGRAM_MAX_BUCKETS_COUNT, "buckets count must be <=" << HISTOGRAM_MAX_BUCKETS_COUNT - << ", but got: " << bucketsCount); - Y_ENSURE(bucketWidth >= 1, "bucketWidth must be >= 1, got: " << bucketWidth); - + << ", but got: " << bucketsCount); + Y_ENSURE(bucketWidth >= 1, "bucketWidth must be >= 1, got: " << bucketWidth); + return MakeHolder<TLinearHistogramCollector>(bucketsCount, startValue, bucketWidth); - } -} + } +} diff --git a/library/cpp/monlib/metrics/histogram_collector_ut.cpp b/library/cpp/monlib/metrics/histogram_collector_ut.cpp index bfbc1a5f2e..1cf66507fa 100644 --- a/library/cpp/monlib/metrics/histogram_collector_ut.cpp +++ b/library/cpp/monlib/metrics/histogram_collector_ut.cpp @@ -1,114 +1,114 @@ -#include "histogram_collector.h" - +#include "histogram_collector.h" + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - -Y_UNIT_TEST_SUITE(THistogramCollectorTest) { - void CheckSnapshot( - const IHistogramSnapshot& s, - const TBucketBounds& bounds, - const TBucketValues& values) { - UNIT_ASSERT_VALUES_EQUAL(bounds.size(), values.size()); - UNIT_ASSERT_VALUES_EQUAL(bounds.size(), s.Count()); - - double epsilon = std::numeric_limits<double>::epsilon(); - for (ui32 i = 0; i < s.Count(); i++) { - UNIT_ASSERT_DOUBLES_EQUAL(bounds[i], s.UpperBound(i), epsilon); - UNIT_ASSERT_VALUES_EQUAL(values[i], s.Value(i)); - } - } - - Y_UNIT_TEST(Explicit) { - auto histogram = ExplicitHistogram({0, 1, 2, 5, 10, 20}); - histogram->Collect(-2); - histogram->Collect(-1); - histogram->Collect(0); - histogram->Collect(1); - histogram->Collect(20); - histogram->Collect(21); - histogram->Collect(1000); - - TBucketBounds expectedBounds = {0, 1, 2, 5, 10, 20, Max<TBucketBound>()}; - TBucketValues expectedValues = {3, 1, 0, 0, 0, 1, 2}; - - CheckSnapshot(*histogram->Snapshot(), expectedBounds, expectedValues); - } - - Y_UNIT_TEST(ExplicitWithFloadBounds) { - auto histogram = ExplicitHistogram({0.1, 0.5, 1, 1.7, 10}); - histogram->Collect(0.3, 2); - histogram->Collect(0.01); - histogram->Collect(0.9); - histogram->Collect(0.6); - histogram->Collect(1.1); - histogram->Collect(0.7); - histogram->Collect(2.71); - - TBucketBounds expectedBounds = {0.1, 0.5, 1, 1.7, 10, Max<TBucketBound>()}; - TBucketValues expectedValues = {1, 2, 3, 1, 1, 0}; - - CheckSnapshot(*histogram->Snapshot(), expectedBounds, expectedValues); - } - - Y_UNIT_TEST(Exponential) { - auto histogram = ExponentialHistogram(6, 2.0, 3.0); - histogram->Collect(-1); - histogram->Collect(0); - histogram->Collect(1); - histogram->Collect(3); - histogram->Collect(4); - histogram->Collect(5); - histogram->Collect(22); - histogram->Collect(23); - histogram->Collect(24); - histogram->Collect(50); - histogram->Collect(100); - histogram->Collect(1000); - - TBucketBounds expectedBounds = {3, 6, 12, 24, 48, Max<TBucketBound>()}; - TBucketValues expectedValues = {4, 2, 0, 3, 0, 3}; - - CheckSnapshot(*histogram->Snapshot(), expectedBounds, expectedValues); - } - - Y_UNIT_TEST(Linear) { - auto histogram = LinearHistogram(6, 5, 15); - histogram->Collect(-1); - histogram->Collect(0); - histogram->Collect(1); - histogram->Collect(4); - histogram->Collect(5); - histogram->Collect(6); - histogram->Collect(64); - histogram->Collect(65); - histogram->Collect(66); - histogram->Collect(100); - histogram->Collect(1000); - - TBucketBounds expectedBounds = {5, 20, 35, 50, 65, Max<TBucketBound>()}; - TBucketValues expectedValues = {5, 1, 0, 0, 2, 3}; - - CheckSnapshot(*histogram->Snapshot(), expectedBounds, expectedValues); - } - - Y_UNIT_TEST(SnapshotOutput) { - auto histogram = ExplicitHistogram({0, 1, 2, 5, 10, 20}); - histogram->Collect(-2); - histogram->Collect(-1); - histogram->Collect(0); - histogram->Collect(1); - histogram->Collect(20); - histogram->Collect(21); - histogram->Collect(1000); - - auto snapshot = histogram->Snapshot(); - - TStringStream ss; - ss << *snapshot; - - UNIT_ASSERT_STRINGS_EQUAL( - "{0: 3, 1: 1, 2: 0, 5: 0, 10: 0, 20: 1, inf: 2}", - ss.Str()); - } -} + +using namespace NMonitoring; + +Y_UNIT_TEST_SUITE(THistogramCollectorTest) { + void CheckSnapshot( + const IHistogramSnapshot& s, + const TBucketBounds& bounds, + const TBucketValues& values) { + UNIT_ASSERT_VALUES_EQUAL(bounds.size(), values.size()); + UNIT_ASSERT_VALUES_EQUAL(bounds.size(), s.Count()); + + double epsilon = std::numeric_limits<double>::epsilon(); + for (ui32 i = 0; i < s.Count(); i++) { + UNIT_ASSERT_DOUBLES_EQUAL(bounds[i], s.UpperBound(i), epsilon); + UNIT_ASSERT_VALUES_EQUAL(values[i], s.Value(i)); + } + } + + Y_UNIT_TEST(Explicit) { + auto histogram = ExplicitHistogram({0, 1, 2, 5, 10, 20}); + histogram->Collect(-2); + histogram->Collect(-1); + histogram->Collect(0); + histogram->Collect(1); + histogram->Collect(20); + histogram->Collect(21); + histogram->Collect(1000); + + TBucketBounds expectedBounds = {0, 1, 2, 5, 10, 20, Max<TBucketBound>()}; + TBucketValues expectedValues = {3, 1, 0, 0, 0, 1, 2}; + + CheckSnapshot(*histogram->Snapshot(), expectedBounds, expectedValues); + } + + Y_UNIT_TEST(ExplicitWithFloadBounds) { + auto histogram = ExplicitHistogram({0.1, 0.5, 1, 1.7, 10}); + histogram->Collect(0.3, 2); + histogram->Collect(0.01); + histogram->Collect(0.9); + histogram->Collect(0.6); + histogram->Collect(1.1); + histogram->Collect(0.7); + histogram->Collect(2.71); + + TBucketBounds expectedBounds = {0.1, 0.5, 1, 1.7, 10, Max<TBucketBound>()}; + TBucketValues expectedValues = {1, 2, 3, 1, 1, 0}; + + CheckSnapshot(*histogram->Snapshot(), expectedBounds, expectedValues); + } + + Y_UNIT_TEST(Exponential) { + auto histogram = ExponentialHistogram(6, 2.0, 3.0); + histogram->Collect(-1); + histogram->Collect(0); + histogram->Collect(1); + histogram->Collect(3); + histogram->Collect(4); + histogram->Collect(5); + histogram->Collect(22); + histogram->Collect(23); + histogram->Collect(24); + histogram->Collect(50); + histogram->Collect(100); + histogram->Collect(1000); + + TBucketBounds expectedBounds = {3, 6, 12, 24, 48, Max<TBucketBound>()}; + TBucketValues expectedValues = {4, 2, 0, 3, 0, 3}; + + CheckSnapshot(*histogram->Snapshot(), expectedBounds, expectedValues); + } + + Y_UNIT_TEST(Linear) { + auto histogram = LinearHistogram(6, 5, 15); + histogram->Collect(-1); + histogram->Collect(0); + histogram->Collect(1); + histogram->Collect(4); + histogram->Collect(5); + histogram->Collect(6); + histogram->Collect(64); + histogram->Collect(65); + histogram->Collect(66); + histogram->Collect(100); + histogram->Collect(1000); + + TBucketBounds expectedBounds = {5, 20, 35, 50, 65, Max<TBucketBound>()}; + TBucketValues expectedValues = {5, 1, 0, 0, 2, 3}; + + CheckSnapshot(*histogram->Snapshot(), expectedBounds, expectedValues); + } + + Y_UNIT_TEST(SnapshotOutput) { + auto histogram = ExplicitHistogram({0, 1, 2, 5, 10, 20}); + histogram->Collect(-2); + histogram->Collect(-1); + histogram->Collect(0); + histogram->Collect(1); + histogram->Collect(20); + histogram->Collect(21); + histogram->Collect(1000); + + auto snapshot = histogram->Snapshot(); + + TStringStream ss; + ss << *snapshot; + + UNIT_ASSERT_STRINGS_EQUAL( + "{0: 3, 1: 1, 2: 0, 5: 0, 10: 0, 20: 1, inf: 2}", + ss.Str()); + } +} diff --git a/library/cpp/monlib/metrics/histogram_snapshot.cpp b/library/cpp/monlib/metrics/histogram_snapshot.cpp index df787bedaf..75b5811546 100644 --- a/library/cpp/monlib/metrics/histogram_snapshot.cpp +++ b/library/cpp/monlib/metrics/histogram_snapshot.cpp @@ -1,27 +1,27 @@ -#include "histogram_snapshot.h" - +#include "histogram_snapshot.h" + #include <util/stream/output.h> #include <iostream> -namespace NMonitoring { - +namespace NMonitoring { + IHistogramSnapshotPtr ExplicitHistogramSnapshot(TConstArrayRef<TBucketBound> bounds, TConstArrayRef<TBucketValue> values) { Y_ENSURE(bounds.size() == values.size(), "mismatched sizes: bounds(" << bounds.size() << ") != buckets(" << values.size() << ')'); - + auto snapshot = TExplicitHistogramSnapshot::New(bounds.size()); - + for (size_t i = 0; i != bounds.size(); ++i) { (*snapshot)[i].first = bounds[i]; (*snapshot)[i].second = values[i]; } - + return snapshot; - } - + } + } // namespace NMonitoring namespace { diff --git a/library/cpp/monlib/metrics/histogram_snapshot.h b/library/cpp/monlib/metrics/histogram_snapshot.h index 1f092a60d5..e8acf6ac2b 100644 --- a/library/cpp/monlib/metrics/histogram_snapshot.h +++ b/library/cpp/monlib/metrics/histogram_snapshot.h @@ -1,50 +1,50 @@ -#pragma once - +#pragma once + #include <util/generic/array_ref.h> -#include <util/generic/ptr.h> -#include <util/generic/vector.h> +#include <util/generic/ptr.h> +#include <util/generic/vector.h> #include <util/generic/yexception.h> - + #include <cmath> -#include <limits> - - -namespace NMonitoring { - - using TBucketBound = double; - using TBucketValue = ui64; - - using TBucketBounds = TVector<TBucketBound>; - using TBucketValues = TVector<TBucketValue>; - - constexpr ui32 HISTOGRAM_MAX_BUCKETS_COUNT = 51; - constexpr TBucketBound HISTOGRAM_INF_BOUND = std::numeric_limits<TBucketBound>::max(); - - /////////////////////////////////////////////////////////////////////////// - // IHistogramSnapshot - /////////////////////////////////////////////////////////////////////////// - class IHistogramSnapshot: public TAtomicRefCount<IHistogramSnapshot> { - public: - virtual ~IHistogramSnapshot() = default; - - /** - * @return buckets count. - */ - virtual ui32 Count() const = 0; - - /** - * @return upper bound for the bucket with particular index. - */ - virtual TBucketBound UpperBound(ui32 index) const = 0; - - /** - * @return value stored in the bucket with particular index. - */ - virtual TBucketValue Value(ui32 index) const = 0; - }; - - using IHistogramSnapshotPtr = TIntrusivePtr<IHistogramSnapshot>; - +#include <limits> + + +namespace NMonitoring { + + using TBucketBound = double; + using TBucketValue = ui64; + + using TBucketBounds = TVector<TBucketBound>; + using TBucketValues = TVector<TBucketValue>; + + constexpr ui32 HISTOGRAM_MAX_BUCKETS_COUNT = 51; + constexpr TBucketBound HISTOGRAM_INF_BOUND = std::numeric_limits<TBucketBound>::max(); + + /////////////////////////////////////////////////////////////////////////// + // IHistogramSnapshot + /////////////////////////////////////////////////////////////////////////// + class IHistogramSnapshot: public TAtomicRefCount<IHistogramSnapshot> { + public: + virtual ~IHistogramSnapshot() = default; + + /** + * @return buckets count. + */ + virtual ui32 Count() const = 0; + + /** + * @return upper bound for the bucket with particular index. + */ + virtual TBucketBound UpperBound(ui32 index) const = 0; + + /** + * @return value stored in the bucket with particular index. + */ + virtual TBucketValue Value(ui32 index) const = 0; + }; + + using IHistogramSnapshotPtr = TIntrusivePtr<IHistogramSnapshot>; + /////////////////////////////////////////////////////////////////////////////// // TLinearHistogramSnapshot /////////////////////////////////////////////////////////////////////////////// @@ -85,9 +85,9 @@ namespace NMonitoring { TBucketValues Values_; }; - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// // TExponentialHistogramSnapshot - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// class TExponentialHistogramSnapshot: public IHistogramSnapshot { public: TExponentialHistogramSnapshot( diff --git a/library/cpp/monlib/metrics/labels.cpp b/library/cpp/monlib/metrics/labels.cpp index 226bf5df26..1eaadb7cba 100644 --- a/library/cpp/monlib/metrics/labels.cpp +++ b/library/cpp/monlib/metrics/labels.cpp @@ -1,31 +1,31 @@ -#include "labels.h" - +#include "labels.h" + #include <util/stream/output.h> #include <util/string/split.h> - -static void OutputLabels(IOutputStream& out, const NMonitoring::ILabels& labels) { - size_t i = 0; + +static void OutputLabels(IOutputStream& out, const NMonitoring::ILabels& labels) { + size_t i = 0; out << '{'; - for (const auto& label: labels) { - if (i++ > 0) { + for (const auto& label: labels) { + if (i++ > 0) { out << TStringBuf(", "); } - out << label; - } + out << label; + } out << '}'; } template <> -void Out<NMonitoring::ILabelsPtr>(IOutputStream& out, const NMonitoring::ILabelsPtr& labels) { - OutputLabels(out, *labels); -} - -template <> -void Out<NMonitoring::ILabels>(IOutputStream& out, const NMonitoring::ILabels& labels) { - OutputLabels(out, labels); -} - -template <> +void Out<NMonitoring::ILabelsPtr>(IOutputStream& out, const NMonitoring::ILabelsPtr& labels) { + OutputLabels(out, *labels); +} + +template <> +void Out<NMonitoring::ILabels>(IOutputStream& out, const NMonitoring::ILabels& labels) { + OutputLabels(out, labels); +} + +template <> void Out<NMonitoring::ILabel>(IOutputStream& out, const NMonitoring::ILabel& labels) { out << labels.Name() << "=" << labels.Value(); } diff --git a/library/cpp/monlib/metrics/labels.h b/library/cpp/monlib/metrics/labels.h index 5afb7e332e..63dc997c28 100644 --- a/library/cpp/monlib/metrics/labels.h +++ b/library/cpp/monlib/metrics/labels.h @@ -1,19 +1,19 @@ -#pragma once - -#include <util/digest/multi.h> -#include <util/digest/sequence.h> -#include <util/generic/algorithm.h> -#include <util/generic/maybe.h> -#include <util/generic/string.h> -#include <util/generic/vector.h> +#pragma once + +#include <util/digest/multi.h> +#include <util/digest/sequence.h> +#include <util/generic/algorithm.h> +#include <util/generic/maybe.h> +#include <util/generic/string.h> +#include <util/generic/vector.h> #include <util/stream/output.h> #include <util/string/builder.h> #include <util/string/strip.h> - + #include <optional> #include <type_traits> -namespace NMonitoring { +namespace NMonitoring { struct ILabel { virtual ~ILabel() = default; @@ -21,38 +21,38 @@ namespace NMonitoring { virtual TStringBuf Value() const noexcept = 0; }; - /////////////////////////////////////////////////////////////////////////// - // TLabel - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + // TLabel + /////////////////////////////////////////////////////////////////////////// template <typename TStringBackend> class TLabelImpl: public ILabel { - public: + public: using TStringType = TStringBackend; TLabelImpl() = default; - + inline TLabelImpl(TStringBuf name, TStringBuf value) : Name_{name} , Value_{value} - { - } - + { + } + inline bool operator==(const TLabelImpl& rhs) const noexcept { - return Name_ == rhs.Name_ && Value_ == rhs.Value_; - } - + return Name_ == rhs.Name_ && Value_ == rhs.Value_; + } + inline bool operator!=(const TLabelImpl& rhs) const noexcept { - return !(*this == rhs); - } - + return !(*this == rhs); + } + inline TStringBuf Name() const noexcept { - return Name_; - } - + return Name_; + } + inline TStringBuf Value() const noexcept { - return Value_; - } - + return Value_; + } + inline const TStringBackend& NameStr() const { return Name_; } @@ -61,18 +61,18 @@ namespace NMonitoring { return Value_; } - inline size_t Hash() const noexcept { - return MultiHash(Name_, Value_); - } - + inline size_t Hash() const noexcept { + return MultiHash(Name_, Value_); + } + TStringBackend ToString() const { TStringBackend buf = Name_; buf += '='; buf += Value_; - + return buf; } - + static TLabelImpl FromString(TStringBuf str) { TStringBuf name, value; Y_ENSURE(str.TrySplit('=', name, value), @@ -107,11 +107,11 @@ namespace NMonitoring { return true; } - private: + private: TStringBackend Name_; TStringBackend Value_; - }; - + }; + using TLabel = TLabelImpl<TString>; struct ILabels { @@ -158,12 +158,12 @@ namespace NMonitoring { virtual ~ILabels() = default; - virtual bool Add(TStringBuf name, TStringBuf value) noexcept = 0; + virtual bool Add(TStringBuf name, TStringBuf value) noexcept = 0; virtual bool Add(const ILabel& label) noexcept { return Add(label.Name(), label.Value()); } - virtual bool Has(TStringBuf name) const noexcept = 0; + virtual bool Has(TStringBuf name) const noexcept = 0; virtual size_t Size() const noexcept = 0; virtual bool Empty() const noexcept = 0; @@ -171,7 +171,7 @@ namespace NMonitoring { virtual size_t Hash() const noexcept = 0; - virtual std::optional<const ILabel*> Get(TStringBuf name) const = 0; + virtual std::optional<const ILabel*> Get(TStringBuf name) const = 0; // NB: there's no guarantee that indices are preserved after any object modification virtual const ILabel* Get(size_t idx) const = 0; @@ -188,16 +188,16 @@ namespace NMonitoring { bool TryLoadLabelsFromString(TStringBuf sb, ILabels& labels); bool TryLoadLabelsFromString(IInputStream& is, ILabels& labels); - /////////////////////////////////////////////////////////////////////////// - // TLabels - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + // TLabels + /////////////////////////////////////////////////////////////////////////// template <typename TStringBackend> class TLabelsImpl: public ILabels { - public: + public: using value_type = TLabelImpl<TStringBackend>; - + TLabelsImpl() = default; - + explicit TLabelsImpl(::NDetail::TReserveTag rt) : Labels_(std::move(rt)) {} @@ -222,13 +222,13 @@ namespace NMonitoring { inline bool operator==(const TLabelsImpl& rhs) const { return Labels_ == rhs.Labels_; - } - + } + inline bool operator!=(const TLabelsImpl& rhs) const { return Labels_ != rhs.Labels_; - } - - bool Add(TStringBuf name, TStringBuf value) noexcept override { + } + + bool Add(TStringBuf name, TStringBuf value) noexcept override { if (Has(name)) { return false; } @@ -239,7 +239,7 @@ namespace NMonitoring { using ILabels::Add; - bool Has(TStringBuf name) const noexcept override { + bool Has(TStringBuf name) const noexcept override { auto it = FindIf(Labels_, [name](const TLabelImpl<TStringBackend>& label) { return name == TStringBuf{label.Name()}; }); @@ -264,7 +264,7 @@ namespace NMonitoring { return *it; } - std::optional<const ILabel*> Get(TStringBuf name) const override { + std::optional<const ILabel*> Get(TStringBuf name) const override { auto it = FindIf(Labels_, [name] (auto&& l) { return name == l.Name(); }); @@ -300,20 +300,20 @@ namespace NMonitoring { inline size_t Hash() const noexcept override { return TSimpleRangeHash()(Labels_); - } - - inline TLabel* Data() const noexcept { + } + + inline TLabel* Data() const noexcept { return const_cast<TLabel*>(Labels_.data()); - } - + } + inline size_t Size() const noexcept override { return Labels_.size(); - } - + } + inline bool Empty() const noexcept override { return Labels_.empty(); - } - + } + inline void Clear() noexcept override { Labels_.clear(); }; @@ -391,26 +391,26 @@ namespace NMonitoring { private: TVector<TLabelImpl<TStringBackend>> Labels_; - }; + }; using TLabels = TLabelsImpl<TString>; using ILabelsPtr = THolder<ILabels>; - - template <typename T> - ILabelsPtr MakeLabels() { - return MakeHolder<TLabelsImpl<T>>(); - } - - template <typename T> - ILabelsPtr MakeLabels(std::initializer_list<TLabelImpl<T>> labels) { - return MakeHolder<TLabelsImpl<T>>(labels); - } - - inline ILabelsPtr MakeLabels(TLabels&& labels) { - return MakeHolder<TLabels>(std::move(labels)); - } -} - + + template <typename T> + ILabelsPtr MakeLabels() { + return MakeHolder<TLabelsImpl<T>>(); + } + + template <typename T> + ILabelsPtr MakeLabels(std::initializer_list<TLabelImpl<T>> labels) { + return MakeHolder<TLabelsImpl<T>>(labels); + } + + inline ILabelsPtr MakeLabels(TLabels&& labels) { + return MakeHolder<TLabels>(std::move(labels)); + } +} + template<> struct THash<NMonitoring::ILabelsPtr> { size_t operator()(const NMonitoring::ILabelsPtr& labels) const noexcept { @@ -432,14 +432,14 @@ struct THash<NMonitoring::TLabelsImpl<TStringBackend>> { template <typename TStringBackend> struct THash<NMonitoring::TLabelImpl<TStringBackend>> { inline size_t operator()(const NMonitoring::TLabelImpl<TStringBackend>& label) const noexcept { - return label.Hash(); - } -}; - + return label.Hash(); + } +}; + inline bool operator==(const NMonitoring::ILabels& lhs, const NMonitoring::ILabels& rhs) { if (lhs.Size() != rhs.Size()) { return false; - } + } for (auto&& l : lhs) { auto rl = rhs.Get(l.Name()); @@ -468,7 +468,7 @@ struct TEqualTo<NMonitoring::ILabelsPtr> { bool operator()(const NMonitoring::ILabels& lhs, const NMonitoring::ILabelsPtr& rhs) { return lhs == *rhs; } -}; +}; #define Y_MONLIB_DEFINE_LABELS_OUT(T) \ template <> \ diff --git a/library/cpp/monlib/metrics/labels_ut.cpp b/library/cpp/monlib/metrics/labels_ut.cpp index 8c96c23bfb..f0e4f532ab 100644 --- a/library/cpp/monlib/metrics/labels_ut.cpp +++ b/library/cpp/monlib/metrics/labels_ut.cpp @@ -1,194 +1,194 @@ -#include "labels.h" - +#include "labels.h" + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - + +using namespace NMonitoring; + Y_UNIT_TEST_SUITE(TLabelsTest) { - TLabel pSolomon("project", "solomon"); - TLabel pKikimr("project", "kikimr"); - + TLabel pSolomon("project", "solomon"); + TLabel pKikimr("project", "kikimr"); + Y_UNIT_TEST(Equals) { - UNIT_ASSERT(pSolomon == TLabel("project", "solomon")); - - UNIT_ASSERT_STRINGS_EQUAL(pSolomon.Name(), "project"); - UNIT_ASSERT_STRINGS_EQUAL(pSolomon.Value(), "solomon"); - - UNIT_ASSERT(pSolomon != pKikimr); - } - + UNIT_ASSERT(pSolomon == TLabel("project", "solomon")); + + UNIT_ASSERT_STRINGS_EQUAL(pSolomon.Name(), "project"); + UNIT_ASSERT_STRINGS_EQUAL(pSolomon.Value(), "solomon"); + + UNIT_ASSERT(pSolomon != pKikimr); + } + Y_UNIT_TEST(ToString) { - UNIT_ASSERT_STRINGS_EQUAL(pSolomon.ToString(), "project=solomon"); - UNIT_ASSERT_STRINGS_EQUAL(pKikimr.ToString(), "project=kikimr"); - } - + UNIT_ASSERT_STRINGS_EQUAL(pSolomon.ToString(), "project=solomon"); + UNIT_ASSERT_STRINGS_EQUAL(pKikimr.ToString(), "project=kikimr"); + } + Y_UNIT_TEST(FromString) { - auto pYql = TLabel::FromString("project=yql"); - UNIT_ASSERT_EQUAL(pYql, TLabel("project", "yql")); - - UNIT_ASSERT_EQUAL(TLabel::FromString("k=v"), TLabel("k", "v")); - UNIT_ASSERT_EQUAL(TLabel::FromString("k=v "), TLabel("k", "v")); - UNIT_ASSERT_EQUAL(TLabel::FromString("k= v"), TLabel("k", "v")); - UNIT_ASSERT_EQUAL(TLabel::FromString("k =v"), TLabel("k", "v")); - UNIT_ASSERT_EQUAL(TLabel::FromString(" k=v"), TLabel("k", "v")); - UNIT_ASSERT_EQUAL(TLabel::FromString(" k = v "), TLabel("k", "v")); - - UNIT_ASSERT_EXCEPTION_CONTAINS( - TLabel::FromString(""), - yexception, - "invalid label string format"); - - UNIT_ASSERT_EXCEPTION_CONTAINS( - TLabel::FromString("k v"), - yexception, - "invalid label string format"); - - UNIT_ASSERT_EXCEPTION_CONTAINS( - TLabel::FromString(" =v"), - yexception, - "label name cannot be empty"); - - UNIT_ASSERT_EXCEPTION_CONTAINS( - TLabel::FromString("k= "), - yexception, - "label value cannot be empty"); - } - + auto pYql = TLabel::FromString("project=yql"); + UNIT_ASSERT_EQUAL(pYql, TLabel("project", "yql")); + + UNIT_ASSERT_EQUAL(TLabel::FromString("k=v"), TLabel("k", "v")); + UNIT_ASSERT_EQUAL(TLabel::FromString("k=v "), TLabel("k", "v")); + UNIT_ASSERT_EQUAL(TLabel::FromString("k= v"), TLabel("k", "v")); + UNIT_ASSERT_EQUAL(TLabel::FromString("k =v"), TLabel("k", "v")); + UNIT_ASSERT_EQUAL(TLabel::FromString(" k=v"), TLabel("k", "v")); + UNIT_ASSERT_EQUAL(TLabel::FromString(" k = v "), TLabel("k", "v")); + + UNIT_ASSERT_EXCEPTION_CONTAINS( + TLabel::FromString(""), + yexception, + "invalid label string format"); + + UNIT_ASSERT_EXCEPTION_CONTAINS( + TLabel::FromString("k v"), + yexception, + "invalid label string format"); + + UNIT_ASSERT_EXCEPTION_CONTAINS( + TLabel::FromString(" =v"), + yexception, + "label name cannot be empty"); + + UNIT_ASSERT_EXCEPTION_CONTAINS( + TLabel::FromString("k= "), + yexception, + "label value cannot be empty"); + } + Y_UNIT_TEST(TryFromString) { - TLabel pYql; - UNIT_ASSERT(TLabel::TryFromString("project=yql", pYql)); - UNIT_ASSERT_EQUAL(pYql, TLabel("project", "yql")); - - { - TLabel label; - UNIT_ASSERT(TLabel::TryFromString("k=v", label)); - UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); - } - { - TLabel label; - UNIT_ASSERT(TLabel::TryFromString("k=v ", label)); - UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); - } - { - TLabel label; - UNIT_ASSERT(TLabel::TryFromString("k= v", label)); - UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); - } - { - TLabel label; - UNIT_ASSERT(TLabel::TryFromString("k =v", label)); - UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); - } - { - TLabel label; - UNIT_ASSERT(TLabel::TryFromString(" k=v", label)); - UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); - } - { - TLabel label; - UNIT_ASSERT(TLabel::TryFromString(" k = v ", label)); - UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); - } - } - + TLabel pYql; + UNIT_ASSERT(TLabel::TryFromString("project=yql", pYql)); + UNIT_ASSERT_EQUAL(pYql, TLabel("project", "yql")); + + { + TLabel label; + UNIT_ASSERT(TLabel::TryFromString("k=v", label)); + UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); + } + { + TLabel label; + UNIT_ASSERT(TLabel::TryFromString("k=v ", label)); + UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); + } + { + TLabel label; + UNIT_ASSERT(TLabel::TryFromString("k= v", label)); + UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); + } + { + TLabel label; + UNIT_ASSERT(TLabel::TryFromString("k =v", label)); + UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); + } + { + TLabel label; + UNIT_ASSERT(TLabel::TryFromString(" k=v", label)); + UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); + } + { + TLabel label; + UNIT_ASSERT(TLabel::TryFromString(" k = v ", label)); + UNIT_ASSERT_EQUAL(label, TLabel("k", "v")); + } + } + Y_UNIT_TEST(Labels) { - TLabels labels; + TLabels labels; UNIT_ASSERT(labels.Add(TStringBuf("name1"), TStringBuf("value1"))); - UNIT_ASSERT(labels.Size() == 1); + UNIT_ASSERT(labels.Size() == 1); UNIT_ASSERT(labels.Has(TStringBuf("name1"))); - { - auto l = labels.Find("name1"); - UNIT_ASSERT(l.Defined()); - UNIT_ASSERT_STRINGS_EQUAL(l->Name(), "name1"); - UNIT_ASSERT_STRINGS_EQUAL(l->Value(), "value1"); - } - { - auto l = labels.Find("name2"); - UNIT_ASSERT(!l.Defined()); - } - - // duplicated name + { + auto l = labels.Find("name1"); + UNIT_ASSERT(l.Defined()); + UNIT_ASSERT_STRINGS_EQUAL(l->Name(), "name1"); + UNIT_ASSERT_STRINGS_EQUAL(l->Value(), "value1"); + } + { + auto l = labels.Find("name2"); + UNIT_ASSERT(!l.Defined()); + } + + // duplicated name UNIT_ASSERT(!labels.Add(TStringBuf("name1"), TStringBuf("value2"))); - UNIT_ASSERT(labels.Size() == 1); - + UNIT_ASSERT(labels.Size() == 1); + UNIT_ASSERT(labels.Add(TStringBuf("name2"), TStringBuf("value2"))); - UNIT_ASSERT(labels.Size() == 2); + UNIT_ASSERT(labels.Size() == 2); UNIT_ASSERT(labels.Has(TStringBuf("name2"))); - { - auto l = labels.Find("name2"); - UNIT_ASSERT(l.Defined()); - UNIT_ASSERT_STRINGS_EQUAL(l->Name(), "name2"); - UNIT_ASSERT_STRINGS_EQUAL(l->Value(), "value2"); - } - - UNIT_ASSERT_EQUAL(labels[0], TLabel("name1", "value1")); - UNIT_ASSERT_EQUAL(labels[1], TLabel("name2", "value2")); - + { + auto l = labels.Find("name2"); + UNIT_ASSERT(l.Defined()); + UNIT_ASSERT_STRINGS_EQUAL(l->Name(), "name2"); + UNIT_ASSERT_STRINGS_EQUAL(l->Value(), "value2"); + } + + UNIT_ASSERT_EQUAL(labels[0], TLabel("name1", "value1")); + UNIT_ASSERT_EQUAL(labels[1], TLabel("name2", "value2")); + TVector<TLabel> labelsCopy; for (auto&& label : labels) { labelsCopy.emplace_back(label.Name(), label.Value()); - } - + } + UNIT_ASSERT_EQUAL(labelsCopy, TVector<TLabel>({ - {"name1", "value1"}, - {"name2", "value2"}, - })); - } - + {"name1", "value1"}, + {"name2", "value2"}, + })); + } + Y_UNIT_TEST(Hash) { - TLabel label("name", "value"); - UNIT_ASSERT_EQUAL(ULL(2378153472115172159), label.Hash()); - - { - TLabels labels = {{"name", "value"}}; - UNIT_ASSERT_EQUAL(ULL(5420514431458887014), labels.Hash()); - } - { - TLabels labels = {{"name1", "value1"}, {"name2", "value2"}}; - UNIT_ASSERT_EQUAL(ULL(2226975250396609813), labels.Hash()); - } - } - - Y_UNIT_TEST(MakeEmptyLabels) { - { - auto labels = MakeLabels<TString>(); - UNIT_ASSERT(labels); - UNIT_ASSERT(labels->Empty()); - UNIT_ASSERT_VALUES_EQUAL(labels->Size(), 0); - } - { - auto labels = MakeLabels<TStringBuf>(); - UNIT_ASSERT(labels); - UNIT_ASSERT(labels->Empty()); - UNIT_ASSERT_VALUES_EQUAL(labels->Size(), 0); - } - } - - Y_UNIT_TEST(MakeLabelsFromInitializerList) { - auto labels = MakeLabels<TString>({{"my", "label"}}); - UNIT_ASSERT(labels); - UNIT_ASSERT(!labels->Empty()); - UNIT_ASSERT_VALUES_EQUAL(labels->Size(), 1); - - UNIT_ASSERT(labels->Has("my")); - - auto label = labels->Get("my"); - UNIT_ASSERT(label.has_value()); - UNIT_ASSERT_STRINGS_EQUAL((*label)->Name(), "my"); - UNIT_ASSERT_STRINGS_EQUAL((*label)->Value(), "label"); - } - - Y_UNIT_TEST(MakeLabelsFromOtherLabel) { - auto labels = MakeLabels({{"my", "label"}}); - UNIT_ASSERT(labels); - UNIT_ASSERT(!labels->Empty()); - UNIT_ASSERT_VALUES_EQUAL(labels->Size(), 1); - - UNIT_ASSERT(labels->Has("my")); - - auto label = labels->Get("my"); - UNIT_ASSERT(label.has_value()); - UNIT_ASSERT_STRINGS_EQUAL((*label)->Name(), "my"); - UNIT_ASSERT_STRINGS_EQUAL((*label)->Value(), "label"); - } -} + TLabel label("name", "value"); + UNIT_ASSERT_EQUAL(ULL(2378153472115172159), label.Hash()); + + { + TLabels labels = {{"name", "value"}}; + UNIT_ASSERT_EQUAL(ULL(5420514431458887014), labels.Hash()); + } + { + TLabels labels = {{"name1", "value1"}, {"name2", "value2"}}; + UNIT_ASSERT_EQUAL(ULL(2226975250396609813), labels.Hash()); + } + } + + Y_UNIT_TEST(MakeEmptyLabels) { + { + auto labels = MakeLabels<TString>(); + UNIT_ASSERT(labels); + UNIT_ASSERT(labels->Empty()); + UNIT_ASSERT_VALUES_EQUAL(labels->Size(), 0); + } + { + auto labels = MakeLabels<TStringBuf>(); + UNIT_ASSERT(labels); + UNIT_ASSERT(labels->Empty()); + UNIT_ASSERT_VALUES_EQUAL(labels->Size(), 0); + } + } + + Y_UNIT_TEST(MakeLabelsFromInitializerList) { + auto labels = MakeLabels<TString>({{"my", "label"}}); + UNIT_ASSERT(labels); + UNIT_ASSERT(!labels->Empty()); + UNIT_ASSERT_VALUES_EQUAL(labels->Size(), 1); + + UNIT_ASSERT(labels->Has("my")); + + auto label = labels->Get("my"); + UNIT_ASSERT(label.has_value()); + UNIT_ASSERT_STRINGS_EQUAL((*label)->Name(), "my"); + UNIT_ASSERT_STRINGS_EQUAL((*label)->Value(), "label"); + } + + Y_UNIT_TEST(MakeLabelsFromOtherLabel) { + auto labels = MakeLabels({{"my", "label"}}); + UNIT_ASSERT(labels); + UNIT_ASSERT(!labels->Empty()); + UNIT_ASSERT_VALUES_EQUAL(labels->Size(), 1); + + UNIT_ASSERT(labels->Has("my")); + + auto label = labels->Get("my"); + UNIT_ASSERT(label.has_value()); + UNIT_ASSERT_STRINGS_EQUAL((*label)->Name(), "my"); + UNIT_ASSERT_STRINGS_EQUAL((*label)->Value(), "label"); + } +} diff --git a/library/cpp/monlib/metrics/log_histogram_collector.h b/library/cpp/monlib/metrics/log_histogram_collector.h index 13b656af35..b81f84ebf3 100644 --- a/library/cpp/monlib/metrics/log_histogram_collector.h +++ b/library/cpp/monlib/metrics/log_histogram_collector.h @@ -25,9 +25,9 @@ namespace NMonitoring { Merge(logHist); } - bool Collect(double value) { + bool Collect(double value) { std::lock_guard guard(Mutex_); - return CollectDouble(value); + return CollectDouble(value); } TLogHistogramSnapshotPtr Snapshot() const { @@ -64,16 +64,16 @@ namespace NMonitoring { ++Buckets_[idx]; } - bool CollectDouble(double value) { - if (Y_UNLIKELY(std::isnan(value) || std::isinf(value))) { - return false; - } + bool CollectDouble(double value) { + if (Y_UNLIKELY(std::isnan(value) || std::isinf(value))) { + return false; + } if (value <= 0.0) { ++CountZero_; } else { CollectPositiveDouble(value); } - return true; + return true; } void Merge(TLogHistogramSnapshot* logHist) { diff --git a/library/cpp/monlib/metrics/metric.h b/library/cpp/monlib/metrics/metric.h index f4c7dc37f2..b8ce12d753 100644 --- a/library/cpp/monlib/metrics/metric.h +++ b/library/cpp/monlib/metrics/metric.h @@ -1,28 +1,28 @@ -#pragma once - -#include "metric_consumer.h" - -#include <util/datetime/base.h> -#include <util/generic/ptr.h> - -namespace NMonitoring { - /////////////////////////////////////////////////////////////////////////////// - // IMetric - /////////////////////////////////////////////////////////////////////////////// - class IMetric { - public: - virtual ~IMetric() = default; - - virtual EMetricType Type() const noexcept = 0; - virtual void Accept(TInstant time, IMetricConsumer* consumer) const = 0; - }; - - using IMetricPtr = THolder<IMetric>; - - class IGauge: public IMetric { +#pragma once + +#include "metric_consumer.h" + +#include <util/datetime/base.h> +#include <util/generic/ptr.h> + +namespace NMonitoring { + /////////////////////////////////////////////////////////////////////////////// + // IMetric + /////////////////////////////////////////////////////////////////////////////// + class IMetric { + public: + virtual ~IMetric() = default; + + virtual EMetricType Type() const noexcept = 0; + virtual void Accept(TInstant time, IMetricConsumer* consumer) const = 0; + }; + + using IMetricPtr = THolder<IMetric>; + + class IGauge: public IMetric { public: - EMetricType Type() const noexcept final { - return EMetricType::GAUGE; + EMetricType Type() const noexcept final { + return EMetricType::GAUGE; } virtual double Add(double n) noexcept = 0; @@ -41,10 +41,10 @@ namespace NMonitoring { virtual double Get() const noexcept = 0; }; - class IIntGauge: public IMetric { + class IIntGauge: public IMetric { public: - EMetricType Type() const noexcept final { - return EMetricType::IGAUGE; + EMetricType Type() const noexcept final { + return EMetricType::IGAUGE; } virtual i64 Add(i64 n) noexcept = 0; @@ -72,10 +72,10 @@ namespace NMonitoring { virtual i64 Get() const noexcept = 0; }; - class ICounter: public IMetric { + class ICounter: public IMetric { public: - EMetricType Type() const noexcept final { - return EMetricType::COUNTER; + EMetricType Type() const noexcept final { + return EMetricType::COUNTER; } virtual ui64 Inc() noexcept { @@ -96,10 +96,10 @@ namespace NMonitoring { virtual ui64 Get() const noexcept = 0; }; - class IRate: public IMetric { + class IRate: public IMetric { public: - EMetricType Type() const noexcept final { - return EMetricType::RATE; + EMetricType Type() const noexcept final { + return EMetricType::RATE; } virtual ui64 Inc() noexcept { @@ -108,7 +108,7 @@ namespace NMonitoring { virtual ui64 Add(ui64 n) noexcept = 0; virtual ui64 Get() const noexcept = 0; - virtual void Reset() noexcept = 0; + virtual void Reset() noexcept = 0; }; class ILazyRate: public IMetric { @@ -120,19 +120,19 @@ namespace NMonitoring { virtual ui64 Get() const noexcept = 0; }; - class IHistogram: public IMetric { + class IHistogram: public IMetric { public: explicit IHistogram(bool isRate) : IsRate_{isRate} { } - EMetricType Type() const noexcept final { - return IsRate_ ? EMetricType::HIST_RATE : EMetricType::HIST; + EMetricType Type() const noexcept final { + return IsRate_ ? EMetricType::HIST_RATE : EMetricType::HIST; } - virtual void Record(double value) = 0; - virtual void Record(double value, ui32 count) = 0; + virtual void Record(double value) = 0; + virtual void Record(double value, ui32 count) = 0; virtual IHistogramSnapshotPtr TakeSnapshot() const = 0; virtual void Reset() = 0; @@ -140,15 +140,15 @@ namespace NMonitoring { const bool IsRate_; }; - /////////////////////////////////////////////////////////////////////////////// - // TGauge - /////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// + // TGauge + /////////////////////////////////////////////////////////////////////////////// class TGauge final: public IGauge { - public: - explicit TGauge(double value = 0.0) { - Set(value); - } - + public: + explicit TGauge(double value = 0.0) { + Set(value); + } + double Add(double n) noexcept override { double newValue; double oldValue = Get(); @@ -162,21 +162,21 @@ namespace NMonitoring { void Set(double n) noexcept override { Value_.store(n, std::memory_order_relaxed); - } - + } + double Get() const noexcept override { return Value_.load(std::memory_order_relaxed); - } - - void Accept(TInstant time, IMetricConsumer* consumer) const override { - consumer->OnDouble(time, Get()); - } - - private: + } + + void Accept(TInstant time, IMetricConsumer* consumer) const override { + consumer->OnDouble(time, Get()); + } + + private: std::atomic<double> Value_; - }; - - /////////////////////////////////////////////////////////////////////////////// + }; + + /////////////////////////////////////////////////////////////////////////////// // TLazyGauge /////////////////////////////////////////////////////////////////////////////// class TLazyGauge final: public ILazyGauge { @@ -199,35 +199,35 @@ namespace NMonitoring { }; /////////////////////////////////////////////////////////////////////////////// - // TIntGauge - /////////////////////////////////////////////////////////////////////////////// + // TIntGauge + /////////////////////////////////////////////////////////////////////////////// class TIntGauge final: public IIntGauge { - public: - explicit TIntGauge(i64 value = 0) { - Set(value); - } - + public: + explicit TIntGauge(i64 value = 0) { + Set(value); + } + i64 Add(i64 n) noexcept override { return Value_.fetch_add(n, std::memory_order_relaxed) + n; } void Set(i64 value) noexcept override { Value_.store(value, std::memory_order_relaxed); - } - + } + i64 Get() const noexcept override { return Value_.load(std::memory_order_relaxed); - } - - void Accept(TInstant time, IMetricConsumer* consumer) const override { - consumer->OnInt64(time, Get()); - } - - private: + } + + void Accept(TInstant time, IMetricConsumer* consumer) const override { + consumer->OnInt64(time, Get()); + } + + private: std::atomic_int64_t Value_; - }; - - /////////////////////////////////////////////////////////////////////////////// + }; + + /////////////////////////////////////////////////////////////////////////////// // TLazyIntGauge /////////////////////////////////////////////////////////////////////////////// class TLazyIntGauge final: public ILazyIntGauge { @@ -250,35 +250,35 @@ namespace NMonitoring { }; /////////////////////////////////////////////////////////////////////////////// - // TCounter - /////////////////////////////////////////////////////////////////////////////// - class TCounter final: public ICounter { - public: - explicit TCounter(ui64 value = 0) { + // TCounter + /////////////////////////////////////////////////////////////////////////////// + class TCounter final: public ICounter { + public: + explicit TCounter(ui64 value = 0) { Value_.store(value, std::memory_order_relaxed); - } - + } + ui64 Add(ui64 n) noexcept override { return Value_.fetch_add(n, std::memory_order_relaxed) + n; - } - + } + ui64 Get() const noexcept override { return Value_.load(std::memory_order_relaxed); - } - + } + void Reset() noexcept override { Value_.store(0, std::memory_order_relaxed); - } - - void Accept(TInstant time, IMetricConsumer* consumer) const override { - consumer->OnUint64(time, Get()); - } - - private: + } + + void Accept(TInstant time, IMetricConsumer* consumer) const override { + consumer->OnUint64(time, Get()); + } + + private: std::atomic_uint64_t Value_; - }; - - /////////////////////////////////////////////////////////////////////////////// + }; + + /////////////////////////////////////////////////////////////////////////////// // TLazyCounter /////////////////////////////////////////////////////////////////////////////// class TLazyCounter final: public ILazyCounter { @@ -301,35 +301,35 @@ namespace NMonitoring { }; /////////////////////////////////////////////////////////////////////////////// - // TRate - /////////////////////////////////////////////////////////////////////////////// + // TRate + /////////////////////////////////////////////////////////////////////////////// class TRate final: public IRate { - public: - explicit TRate(ui64 value = 0) { + public: + explicit TRate(ui64 value = 0) { Value_.store(value, std::memory_order_relaxed); - } - + } + ui64 Add(ui64 n) noexcept override { return Value_.fetch_add(n, std::memory_order_relaxed) + n; - } - + } + ui64 Get() const noexcept override { return Value_.load(std::memory_order_relaxed); - } - - void Reset() noexcept override { - Value_.store(0, std::memory_order_relaxed); - } - - void Accept(TInstant time, IMetricConsumer* consumer) const override { - consumer->OnUint64(time, Get()); - } - - private: + } + + void Reset() noexcept override { + Value_.store(0, std::memory_order_relaxed); + } + + void Accept(TInstant time, IMetricConsumer* consumer) const override { + consumer->OnUint64(time, Get()); + } + + private: std::atomic_uint64_t Value_; - }; - - /////////////////////////////////////////////////////////////////////////////// + }; + + /////////////////////////////////////////////////////////////////////////////// // TLazyRate /////////////////////////////////////////////////////////////////////////////// class TLazyRate final: public ILazyRate { @@ -352,28 +352,28 @@ namespace NMonitoring { }; /////////////////////////////////////////////////////////////////////////////// - // THistogram - /////////////////////////////////////////////////////////////////////////////// + // THistogram + /////////////////////////////////////////////////////////////////////////////// class THistogram final: public IHistogram { - public: - THistogram(IHistogramCollectorPtr collector, bool isRate) + public: + THistogram(IHistogramCollectorPtr collector, bool isRate) : IHistogram(isRate) , Collector_(std::move(collector)) - { - } - - void Record(double value) override { - Collector_->Collect(value); - } - - void Record(double value, ui32 count) override { - Collector_->Collect(value, count); - } - - void Accept(TInstant time, IMetricConsumer* consumer) const override { + { + } + + void Record(double value) override { + Collector_->Collect(value); + } + + void Record(double value, ui32 count) override { + Collector_->Collect(value, count); + } + + void Accept(TInstant time, IMetricConsumer* consumer) const override { consumer->OnHistogram(time, TakeSnapshot()); - } - + } + IHistogramSnapshotPtr TakeSnapshot() const override { return Collector_->Snapshot(); } @@ -382,7 +382,7 @@ namespace NMonitoring { Collector_->Reset(); } - private: - IHistogramCollectorPtr Collector_; - }; -} + private: + IHistogramCollectorPtr Collector_; + }; +} diff --git a/library/cpp/monlib/metrics/metric_consumer.cpp b/library/cpp/monlib/metrics/metric_consumer.cpp index 4289efdad9..121ee368f0 100644 --- a/library/cpp/monlib/metrics/metric_consumer.cpp +++ b/library/cpp/monlib/metrics/metric_consumer.cpp @@ -8,7 +8,7 @@ namespace NMonitoring { Y_ENSURE(false, "Not implemented"); } - std::pair<ui32, ui32> IMetricConsumer::PrepareLabel(TStringBuf name, TStringBuf value) { + std::pair<ui32, ui32> IMetricConsumer::PrepareLabel(TStringBuf name, TStringBuf value) { Y_UNUSED(name, value); Y_ENSURE(false, "Not implemented"); } diff --git a/library/cpp/monlib/metrics/metric_consumer.h b/library/cpp/monlib/metrics/metric_consumer.h index 87deed785d..f7a727585a 100644 --- a/library/cpp/monlib/metrics/metric_consumer.h +++ b/library/cpp/monlib/metrics/metric_consumer.h @@ -1,40 +1,40 @@ -#pragma once - -#include "metric_type.h" -#include "histogram_collector.h" +#pragma once + +#include "metric_type.h" +#include "histogram_collector.h" #include "summary_collector.h" #include "log_histogram_snapshot.h" - -class TInstant; - -namespace NMonitoring { - class IMetricConsumer { - public: - virtual ~IMetricConsumer() = default; - - virtual void OnStreamBegin() = 0; - virtual void OnStreamEnd() = 0; - - virtual void OnCommonTime(TInstant time) = 0; - - virtual void OnMetricBegin(EMetricType type) = 0; - virtual void OnMetricEnd() = 0; - - virtual void OnLabelsBegin() = 0; - virtual void OnLabelsEnd() = 0; - virtual void OnLabel(TStringBuf name, TStringBuf value) = 0; + +class TInstant; + +namespace NMonitoring { + class IMetricConsumer { + public: + virtual ~IMetricConsumer() = default; + + virtual void OnStreamBegin() = 0; + virtual void OnStreamEnd() = 0; + + virtual void OnCommonTime(TInstant time) = 0; + + virtual void OnMetricBegin(EMetricType type) = 0; + virtual void OnMetricEnd() = 0; + + virtual void OnLabelsBegin() = 0; + virtual void OnLabelsEnd() = 0; + virtual void OnLabel(TStringBuf name, TStringBuf value) = 0; virtual void OnLabel(ui32 name, ui32 value); - virtual std::pair<ui32, ui32> PrepareLabel(TStringBuf name, TStringBuf value); - - virtual void OnDouble(TInstant time, double value) = 0; - virtual void OnInt64(TInstant time, i64 value) = 0; - virtual void OnUint64(TInstant time, ui64 value) = 0; - - virtual void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) = 0; + virtual std::pair<ui32, ui32> PrepareLabel(TStringBuf name, TStringBuf value); + + virtual void OnDouble(TInstant time, double value) = 0; + virtual void OnInt64(TInstant time, i64 value) = 0; + virtual void OnUint64(TInstant time, ui64 value) = 0; + + virtual void OnHistogram(TInstant time, IHistogramSnapshotPtr snapshot) = 0; virtual void OnLogHistogram(TInstant time, TLogHistogramSnapshotPtr snapshot) = 0; - virtual void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) = 0; - }; - - using IMetricConsumerPtr = THolder<IMetricConsumer>; - -} + virtual void OnSummaryDouble(TInstant time, ISummaryDoubleSnapshotPtr snapshot) = 0; + }; + + using IMetricConsumerPtr = THolder<IMetricConsumer>; + +} diff --git a/library/cpp/monlib/metrics/metric_registry.cpp b/library/cpp/monlib/metrics/metric_registry.cpp index 091a7b5282..b083163a7b 100644 --- a/library/cpp/monlib/metrics/metric_registry.cpp +++ b/library/cpp/monlib/metrics/metric_registry.cpp @@ -1,41 +1,41 @@ -#include "metric_registry.h" - +#include "metric_registry.h" + #include <memory> -namespace NMonitoring { - namespace { - void ConsumeLabels(IMetricConsumer* consumer, const ILabels& labels) { - for (auto&& label: labels) { - consumer->OnLabel(label.Name(), label.Value()); - } - } - - template <typename TLabelsConsumer> - void ConsumeMetric(TInstant time, IMetricConsumer* consumer, IMetric* metric, TLabelsConsumer&& labelsConsumer) { - consumer->OnMetricBegin(metric->Type()); - - // (1) add labels - consumer->OnLabelsBegin(); - labelsConsumer(); - consumer->OnLabelsEnd(); - - // (2) add time and value - metric->Accept(time, consumer); - consumer->OnMetricEnd(); - } - } - +namespace NMonitoring { + namespace { + void ConsumeLabels(IMetricConsumer* consumer, const ILabels& labels) { + for (auto&& label: labels) { + consumer->OnLabel(label.Name(), label.Value()); + } + } + + template <typename TLabelsConsumer> + void ConsumeMetric(TInstant time, IMetricConsumer* consumer, IMetric* metric, TLabelsConsumer&& labelsConsumer) { + consumer->OnMetricBegin(metric->Type()); + + // (1) add labels + consumer->OnLabelsBegin(); + labelsConsumer(); + consumer->OnLabelsEnd(); + + // (2) add time and value + metric->Accept(time, consumer); + consumer->OnMetricEnd(); + } + } + void WriteLabels(IMetricConsumer* consumer, const ILabels& labels) { consumer->OnLabelsBegin(); - ConsumeLabels(consumer, labels); + ConsumeLabels(consumer, labels); consumer->OnLabelsEnd(); } - TMetricRegistry::TMetricRegistry() = default; - TMetricRegistry::~TMetricRegistry() = default; + TMetricRegistry::TMetricRegistry() = default; + TMetricRegistry::~TMetricRegistry() = default; - TMetricRegistry::TMetricRegistry(const TLabels& commonLabels) - : TMetricRegistry{} + TMetricRegistry::TMetricRegistry(const TLabels& commonLabels) + : TMetricRegistry{} { CommonLabels_ = commonLabels; } @@ -44,14 +44,14 @@ namespace NMonitoring { return Singleton<TMetricRegistry>(); } - TGauge* TMetricRegistry::Gauge(TLabels labels) { - return Metric<TGauge, EMetricType::GAUGE>(std::move(labels)); - } - - TGauge* TMetricRegistry::Gauge(ILabelsPtr labels) { - return Metric<TGauge, EMetricType::GAUGE>(std::move(labels)); - } - + TGauge* TMetricRegistry::Gauge(TLabels labels) { + return Metric<TGauge, EMetricType::GAUGE>(std::move(labels)); + } + + TGauge* TMetricRegistry::Gauge(ILabelsPtr labels) { + return Metric<TGauge, EMetricType::GAUGE>(std::move(labels)); + } + TLazyGauge* TMetricRegistry::LazyGauge(TLabels labels, std::function<double()> supplier) { return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier)); } @@ -60,14 +60,14 @@ namespace NMonitoring { return Metric<TLazyGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier)); } - TIntGauge* TMetricRegistry::IntGauge(TLabels labels) { - return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels)); - } - - TIntGauge* TMetricRegistry::IntGauge(ILabelsPtr labels) { - return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels)); - } - + TIntGauge* TMetricRegistry::IntGauge(TLabels labels) { + return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels)); + } + + TIntGauge* TMetricRegistry::IntGauge(ILabelsPtr labels) { + return Metric<TIntGauge, EMetricType::IGAUGE>(std::move(labels)); + } + TLazyIntGauge* TMetricRegistry::LazyIntGauge(TLabels labels, std::function<i64()> supplier) { return Metric<TLazyIntGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier)); } @@ -76,12 +76,12 @@ namespace NMonitoring { return Metric<TLazyIntGauge, EMetricType::GAUGE>(std::move(labels), std::move(supplier)); } - TCounter* TMetricRegistry::Counter(TLabels labels) { - return Metric<TCounter, EMetricType::COUNTER>(std::move(labels)); + TCounter* TMetricRegistry::Counter(TLabels labels) { + return Metric<TCounter, EMetricType::COUNTER>(std::move(labels)); } - TCounter* TMetricRegistry::Counter(ILabelsPtr labels) { - return Metric<TCounter, EMetricType::COUNTER>(std::move(labels)); + TCounter* TMetricRegistry::Counter(ILabelsPtr labels) { + return Metric<TCounter, EMetricType::COUNTER>(std::move(labels)); } TLazyCounter* TMetricRegistry::LazyCounter(TLabels labels, std::function<ui64()> supplier) { @@ -92,12 +92,12 @@ namespace NMonitoring { return Metric<TLazyCounter, EMetricType::COUNTER>(std::move(labels), std::move(supplier)); } - TRate* TMetricRegistry::Rate(TLabels labels) { - return Metric<TRate, EMetricType::RATE>(std::move(labels)); + TRate* TMetricRegistry::Rate(TLabels labels) { + return Metric<TRate, EMetricType::RATE>(std::move(labels)); } - TRate* TMetricRegistry::Rate(ILabelsPtr labels) { - return Metric<TRate, EMetricType::RATE>(std::move(labels)); + TRate* TMetricRegistry::Rate(ILabelsPtr labels) { + return Metric<TRate, EMetricType::RATE>(std::move(labels)); } TLazyRate* TMetricRegistry::LazyRate(TLabels labels, std::function<ui64()> supplier) { @@ -108,20 +108,20 @@ namespace NMonitoring { return Metric<TLazyRate, EMetricType::RATE>(std::move(labels), std::move(supplier)); } - THistogram* TMetricRegistry::HistogramCounter(TLabels labels, IHistogramCollectorPtr collector) { - return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false); - } - - THistogram* TMetricRegistry::HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) { - return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false); + THistogram* TMetricRegistry::HistogramCounter(TLabels labels, IHistogramCollectorPtr collector) { + return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false); } - THistogram* TMetricRegistry::HistogramRate(TLabels labels, IHistogramCollectorPtr collector) { - return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true); - } - - THistogram* TMetricRegistry::HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) { - return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true); + THistogram* TMetricRegistry::HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) { + return Metric<THistogram, EMetricType::HIST>(std::move(labels), std::move(collector), false); + } + + THistogram* TMetricRegistry::HistogramRate(TLabels labels, IHistogramCollectorPtr collector) { + return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true); + } + + THistogram* TMetricRegistry::HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) { + return Metric<THistogram, EMetricType::HIST_RATE>(std::move(labels), std::move(collector), true); } void TMetricRegistry::Reset() { @@ -157,74 +157,74 @@ namespace NMonitoring { Metrics_.clear(); } - template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> - TMetric* TMetricRegistry::Metric(TLabelsType&& labels, Args&&... args) { - { + template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> + TMetric* TMetricRegistry::Metric(TLabelsType&& labels, Args&&... args) { + { TReadGuard g{Lock_}; - auto it = Metrics_.find(labels); - if (it != Metrics_.end()) { - Y_ENSURE(it->second->Type() == type, "cannot create metric " << labels - << " with type " << MetricTypeToStr(type) - << ", because registry already has same metric with type " << MetricTypeToStr(it->second->Type())); - return static_cast<TMetric*>(it->second.Get()); - } - } - - { - IMetricPtr metric = MakeHolder<TMetric>(std::forward<Args>(args)...); - + auto it = Metrics_.find(labels); + if (it != Metrics_.end()) { + Y_ENSURE(it->second->Type() == type, "cannot create metric " << labels + << " with type " << MetricTypeToStr(type) + << ", because registry already has same metric with type " << MetricTypeToStr(it->second->Type())); + return static_cast<TMetric*>(it->second.Get()); + } + } + + { + IMetricPtr metric = MakeHolder<TMetric>(std::forward<Args>(args)...); + TWriteGuard g{Lock_}; - // decltype(Metrics_)::iterator breaks build on windows - THashMap<ILabelsPtr, IMetricPtr>::iterator it; + // decltype(Metrics_)::iterator breaks build on windows + THashMap<ILabelsPtr, IMetricPtr>::iterator it; if constexpr (!std::is_convertible_v<TLabelsType, ILabelsPtr>) { - it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metric)).first; + it = Metrics_.emplace(new TLabels{std::forward<TLabelsType>(labels)}, std::move(metric)).first; } else { - it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metric)).first; + it = Metrics_.emplace(std::forward<TLabelsType>(labels), std::move(metric)).first; } - return static_cast<TMetric*>(it->second.Get()); - } - } + return static_cast<TMetric*>(it->second.Get()); + } + } - void TMetricRegistry::RemoveMetric(const ILabels& labels) noexcept { + void TMetricRegistry::RemoveMetric(const ILabels& labels) noexcept { TWriteGuard g{Lock_}; - Metrics_.erase(labels); + Metrics_.erase(labels); } - void TMetricRegistry::Accept(TInstant time, IMetricConsumer* consumer) const { + void TMetricRegistry::Accept(TInstant time, IMetricConsumer* consumer) const { consumer->OnStreamBegin(); if (!CommonLabels_.Empty()) { - consumer->OnLabelsBegin(); - ConsumeLabels(consumer, CommonLabels_); - consumer->OnLabelsEnd(); + consumer->OnLabelsBegin(); + ConsumeLabels(consumer, CommonLabels_); + consumer->OnLabelsEnd(); + } + + { + TReadGuard g{Lock_}; + for (const auto& it: Metrics_) { + ILabels* labels = it.first.Get(); + IMetric* metric = it.second.Get(); + ConsumeMetric(time, consumer, metric, [&]() { + ConsumeLabels(consumer, *labels); + }); + } } - { - TReadGuard g{Lock_}; - for (const auto& it: Metrics_) { - ILabels* labels = it.first.Get(); - IMetric* metric = it.second.Get(); - ConsumeMetric(time, consumer, metric, [&]() { - ConsumeLabels(consumer, *labels); - }); - } - } - consumer->OnStreamEnd(); } - void TMetricRegistry::Append(TInstant time, IMetricConsumer* consumer) const { + void TMetricRegistry::Append(TInstant time, IMetricConsumer* consumer) const { TReadGuard g{Lock_}; - for (const auto& it: Metrics_) { - ILabels* labels = it.first.Get(); - IMetric* metric = it.second.Get(); - ConsumeMetric(time, consumer, metric, [&]() { - ConsumeLabels(consumer, CommonLabels_); - ConsumeLabels(consumer, *labels); - }); - } - } -} + for (const auto& it: Metrics_) { + ILabels* labels = it.first.Get(); + IMetric* metric = it.second.Get(); + ConsumeMetric(time, consumer, metric, [&]() { + ConsumeLabels(consumer, CommonLabels_); + ConsumeLabels(consumer, *labels); + }); + } + } +} diff --git a/library/cpp/monlib/metrics/metric_registry.h b/library/cpp/monlib/metrics/metric_registry.h index e308065da9..670cf8651e 100644 --- a/library/cpp/monlib/metrics/metric_registry.h +++ b/library/cpp/monlib/metrics/metric_registry.h @@ -1,17 +1,17 @@ -#pragma once - -#include "labels.h" -#include "metric.h" - +#pragma once + +#include "labels.h" +#include "metric.h" + #include <util/system/rwlock.h> - + #include <library/cpp/threading/light_rw_lock/lightrwlock.h> -namespace NMonitoring { - class IMetricFactory { +namespace NMonitoring { + class IMetricFactory { public: - virtual ~IMetricFactory() = default; + virtual ~IMetricFactory() = default; virtual IGauge* Gauge(ILabelsPtr labels) = 0; virtual ILazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) = 0; @@ -36,27 +36,27 @@ namespace NMonitoring { public: virtual ~IMetricSupplier() = default; - virtual void Accept(TInstant time, IMetricConsumer* consumer) const = 0; - virtual void Append(TInstant time, IMetricConsumer* consumer) const = 0; + virtual void Accept(TInstant time, IMetricConsumer* consumer) const = 0; + virtual void Append(TInstant time, IMetricConsumer* consumer) const = 0; }; class IMetricRegistry: public IMetricSupplier, public IMetricFactory { public: virtual const TLabels& CommonLabels() const noexcept = 0; - virtual void RemoveMetric(const ILabels& labels) noexcept = 0; + virtual void RemoveMetric(const ILabels& labels) noexcept = 0; }; - /////////////////////////////////////////////////////////////////////////////// - // TMetricRegistry - /////////////////////////////////////////////////////////////////////////////// - class TMetricRegistry: public IMetricRegistry { - public: - TMetricRegistry(); - ~TMetricRegistry(); - - explicit TMetricRegistry(const TLabels& commonLabels); - + /////////////////////////////////////////////////////////////////////////////// + // TMetricRegistry + /////////////////////////////////////////////////////////////////////////////// + class TMetricRegistry: public IMetricRegistry { + public: + TMetricRegistry(); + ~TMetricRegistry(); + + explicit TMetricRegistry(const TLabels& commonLabels); + /** * Get a global metrics registry instance. */ @@ -66,19 +66,19 @@ namespace NMonitoring { TLazyGauge* LazyGauge(TLabels labels, std::function<double()> supplier); TIntGauge* IntGauge(TLabels labels); TLazyIntGauge* LazyIntGauge(TLabels labels, std::function<i64()> supplier); - TCounter* Counter(TLabels labels); + TCounter* Counter(TLabels labels); TLazyCounter* LazyCounter(TLabels labels, std::function<ui64()> supplier); TRate* Rate(TLabels labels); TLazyRate* LazyRate(TLabels labels, std::function<ui64()> supplier); - - THistogram* HistogramCounter( + + THistogram* HistogramCounter( TLabels labels, - IHistogramCollectorPtr collector); - - THistogram* HistogramRate( + IHistogramCollectorPtr collector); + + THistogram* HistogramRate( TLabels labels, - IHistogramCollectorPtr collector); - + IHistogramCollectorPtr collector); + /** * Set all registered metrics to zero */ @@ -88,21 +88,21 @@ namespace NMonitoring { */ void Clear(); - void Accept(TInstant time, IMetricConsumer* consumer) const override; - void Append(TInstant time, IMetricConsumer* consumer) const override; - + void Accept(TInstant time, IMetricConsumer* consumer) const override; + void Append(TInstant time, IMetricConsumer* consumer) const override; + const TLabels& CommonLabels() const noexcept override { - return CommonLabels_; - } - - void RemoveMetric(const ILabels& labels) noexcept override; + return CommonLabels_; + } - private: + void RemoveMetric(const ILabels& labels) noexcept override; + + private: TGauge* Gauge(ILabelsPtr labels) override; TLazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) override; TIntGauge* IntGauge(ILabelsPtr labels) override; TLazyIntGauge* LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) override; - TCounter* Counter(ILabelsPtr labels) override; + TCounter* Counter(ILabelsPtr labels) override; TLazyCounter* LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) override; TRate* Rate(ILabelsPtr labels) override; TLazyRate* LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) override; @@ -117,13 +117,13 @@ namespace NMonitoring { private: TRWMutex Lock_; - THashMap<ILabelsPtr, IMetricPtr> Metrics_; + THashMap<ILabelsPtr, IMetricPtr> Metrics_; - template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> - TMetric* Metric(TLabelsType&& labels, Args&&... args); - - TLabels CommonLabels_; - }; + template <typename TMetric, EMetricType type, typename TLabelsType, typename... Args> + TMetric* Metric(TLabelsType&& labels, Args&&... args); + + TLabels CommonLabels_; + }; void WriteLabels(IMetricConsumer* consumer, const ILabels& labels); -} +} diff --git a/library/cpp/monlib/metrics/metric_registry_ut.cpp b/library/cpp/monlib/metrics/metric_registry_ut.cpp index e10d2efc02..86d9a52ec0 100644 --- a/library/cpp/monlib/metrics/metric_registry_ut.cpp +++ b/library/cpp/monlib/metrics/metric_registry_ut.cpp @@ -1,15 +1,15 @@ -#include "metric_registry.h" - -#include <library/cpp/monlib/encode/protobuf/protobuf.h> -#include <library/cpp/monlib/encode/json/json.h> +#include "metric_registry.h" + +#include <library/cpp/monlib/encode/protobuf/protobuf.h> +#include <library/cpp/monlib/encode/json/json.h> #include <library/cpp/resource/resource.h> - + #include <library/cpp/testing/unittest/registar.h> - -#include <util/stream/str.h> - -using namespace NMonitoring; - + +#include <util/stream/str.h> + +using namespace NMonitoring; + template<> void Out<NMonitoring::NProto::TSingleSample::ValueCase>(IOutputStream& os, NMonitoring::NProto::TSingleSample::ValueCase val) { switch (val) { @@ -37,14 +37,14 @@ void Out<NMonitoring::NProto::TSingleSample::ValueCase>(IOutputStream& os, NMoni } } -Y_UNIT_TEST_SUITE(TMetricRegistryTest) { +Y_UNIT_TEST_SUITE(TMetricRegistryTest) { Y_UNIT_TEST(Gauge) { - TMetricRegistry registry(TLabels{{"common", "label"}}); - TGauge* g = registry.Gauge({{"my", "gauge"}}); - - UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 0.0, 1E-6); - g->Set(12.34); - UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 12.34, 1E-6); + TMetricRegistry registry(TLabels{{"common", "label"}}); + TGauge* g = registry.Gauge({{"my", "gauge"}}); + + UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 0.0, 1E-6); + g->Set(12.34); + UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 12.34, 1E-6); double val; @@ -55,8 +55,8 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) { val = g->Add(-3.47); UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), 10.07, 1E-6); UNIT_ASSERT_DOUBLES_EQUAL(g->Get(), val, 1E-6); - } - + } + Y_UNIT_TEST(LazyGauge) { TMetricRegistry registry(TLabels{{"common", "label"}}); double val = 0.0; @@ -76,7 +76,7 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) { } Y_UNIT_TEST(IntGauge) { - TMetricRegistry registry(TLabels{{"common", "label"}}); + TMetricRegistry registry(TLabels{{"common", "label"}}); TIntGauge* g = registry.IntGauge({{"my", "gauge"}}); UNIT_ASSERT_VALUES_EQUAL(g->Get(), 0); @@ -123,16 +123,16 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) { } Y_UNIT_TEST(Counter) { - TMetricRegistry registry(TLabels{{"common", "label"}}); - TCounter* c = registry.Counter({{"my", "counter"}}); - + TMetricRegistry registry(TLabels{{"common", "label"}}); + TCounter* c = registry.Counter({{"my", "counter"}}); + UNIT_ASSERT_VALUES_EQUAL(c->Get(), 0); UNIT_ASSERT_VALUES_EQUAL(c->Inc(), 1); UNIT_ASSERT_VALUES_EQUAL(c->Get(), 1); UNIT_ASSERT_VALUES_EQUAL(c->Add(10), 11); UNIT_ASSERT_VALUES_EQUAL(c->Get(), 11); - } - + } + Y_UNIT_TEST(LazyCounter) { TMetricRegistry registry(TLabels{{"common", "label"}}); ui64 val = 0; @@ -156,9 +156,9 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) { } Y_UNIT_TEST(DoubleCounter) { - TMetricRegistry registry(TLabels{{"common", "label"}}); + TMetricRegistry registry(TLabels{{"common", "label"}}); - TCounter* c = registry.Counter({{"my", "counter"}}); + TCounter* c = registry.Counter({{"my", "counter"}}); UNIT_ASSERT_VALUES_EQUAL(c->Get(), 0); c->Add(10); @@ -167,19 +167,19 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) { } Y_UNIT_TEST(Sample) { - TMetricRegistry registry(TLabels{{"common", "label"}}); - - TGauge* g = registry.Gauge({{"my", "gauge"}}); - g->Set(12.34); - - TCounter* c = registry.Counter({{"my", "counter"}}); - c->Add(10); - - NProto::TSingleSamplesList samples; - auto encoder = EncoderProtobuf(&samples); - auto now = TInstant::Now(); - registry.Accept(now, encoder.Get()); - + TMetricRegistry registry(TLabels{{"common", "label"}}); + + TGauge* g = registry.Gauge({{"my", "gauge"}}); + g->Set(12.34); + + TCounter* c = registry.Counter({{"my", "counter"}}); + c->Add(10); + + NProto::TSingleSamplesList samples; + auto encoder = EncoderProtobuf(&samples); + auto now = TInstant::Now(); + registry.Accept(now, encoder.Get()); + UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 2); UNIT_ASSERT_VALUES_EQUAL(samples.CommonLabelsSize(), 1); { @@ -187,65 +187,65 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) { UNIT_ASSERT_STRINGS_EQUAL(label.GetName(), "common"); UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "label"); } - - for (const NProto::TSingleSample& sample : samples.GetSamples()) { + + for (const NProto::TSingleSample& sample : samples.GetSamples()) { UNIT_ASSERT_VALUES_EQUAL(sample.LabelsSize(), 1); UNIT_ASSERT_VALUES_EQUAL(sample.GetTime(), now.MilliSeconds()); - - if (sample.GetMetricType() == NProto::GAUGE) { + + if (sample.GetMetricType() == NProto::GAUGE) { UNIT_ASSERT_VALUES_EQUAL(sample.GetValueCase(), NProto::TSingleSample::kFloat64); - UNIT_ASSERT_DOUBLES_EQUAL(sample.GetFloat64(), 12.34, 1E-6); - + UNIT_ASSERT_DOUBLES_EQUAL(sample.GetFloat64(), 12.34, 1E-6); + const NProto::TLabel& label = sample.GetLabels(0); - UNIT_ASSERT_STRINGS_EQUAL(label.GetName(), "my"); - UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "gauge"); - } else if (sample.GetMetricType() == NProto::COUNTER) { + UNIT_ASSERT_STRINGS_EQUAL(label.GetName(), "my"); + UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "gauge"); + } else if (sample.GetMetricType() == NProto::COUNTER) { UNIT_ASSERT_VALUES_EQUAL(sample.GetValueCase(), NProto::TSingleSample::kUint64); UNIT_ASSERT_VALUES_EQUAL(sample.GetUint64(), 10); - + const NProto::TLabel& label = sample.GetLabels(0); - UNIT_ASSERT_STRINGS_EQUAL(label.GetName(), "my"); - UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "counter"); - } else { - UNIT_FAIL("unexpected sample type"); - } - } - } - - Y_UNIT_TEST(Histograms) { - TMetricRegistry registry(TLabels{{"common", "label"}}); - - THistogram* h1 = registry.HistogramCounter( - {{"sensor", "readTimeMillis"}}, - ExponentialHistogram(5, 2)); - - THistogram* h2 = registry.HistogramRate( - {{"sensor", "writeTimeMillis"}}, - ExplicitHistogram({1, 5, 15, 20, 25})); - - for (i64 i = 0; i < 100; i++) { - h1->Record(i); - h2->Record(i); - } - - TStringStream ss; - { - auto encoder = EncoderJson(&ss, 2); - registry.Accept(TInstant::Zero(), encoder.Get()); - } - ss << '\n'; - - UNIT_ASSERT_NO_DIFF(ss.Str(), NResource::Find("/histograms.json")); - } - + UNIT_ASSERT_STRINGS_EQUAL(label.GetName(), "my"); + UNIT_ASSERT_STRINGS_EQUAL(label.GetValue(), "counter"); + } else { + UNIT_FAIL("unexpected sample type"); + } + } + } + + Y_UNIT_TEST(Histograms) { + TMetricRegistry registry(TLabels{{"common", "label"}}); + + THistogram* h1 = registry.HistogramCounter( + {{"sensor", "readTimeMillis"}}, + ExponentialHistogram(5, 2)); + + THistogram* h2 = registry.HistogramRate( + {{"sensor", "writeTimeMillis"}}, + ExplicitHistogram({1, 5, 15, 20, 25})); + + for (i64 i = 0; i < 100; i++) { + h1->Record(i); + h2->Record(i); + } + + TStringStream ss; + { + auto encoder = EncoderJson(&ss, 2); + registry.Accept(TInstant::Zero(), encoder.Get()); + } + ss << '\n'; + + UNIT_ASSERT_NO_DIFF(ss.Str(), NResource::Find("/histograms.json")); + } + Y_UNIT_TEST(StreamingEncoderTest) { const TString expected { "{\"commonLabels\":{\"common\":\"label\"}," "\"sensors\":[{\"kind\":\"GAUGE\",\"labels\":{\"my\":\"gauge\"},\"value\":12.34}]}" }; - TMetricRegistry registry(TLabels{{"common", "label"}}); + TMetricRegistry registry(TLabels{{"common", "label"}}); TGauge* g = registry.Gauge({{"my", "gauge"}}); g->Set(12.34); @@ -257,48 +257,48 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) { UNIT_ASSERT_STRINGS_EQUAL(os.Str(), expected); } - Y_UNIT_TEST(CreatingSameMetricWithDifferentTypesShouldThrow) { - TMetricRegistry registry; - + Y_UNIT_TEST(CreatingSameMetricWithDifferentTypesShouldThrow) { + TMetricRegistry registry; + registry.Gauge({{"foo", "bar"}}); UNIT_ASSERT_EXCEPTION(registry.Counter({{"foo", "bar"}}), yexception); - + registry.HistogramCounter({{"bar", "baz"}}, nullptr); UNIT_ASSERT_EXCEPTION(registry.HistogramRate({{"bar", "baz"}}, nullptr), yexception); - } - - Y_UNIT_TEST(EncodeRegistryWithCommonLabels) { - TMetricRegistry registry(TLabels{{"common", "label"}}); - - TGauge* g = registry.Gauge({{"my", "gauge"}}); - g->Set(12.34); - - // Append() adds common labels to each metric, allowing to combine - // several metric registries in one resulting blob - { - TStringStream os; - auto encoder = EncoderJson(&os); - encoder->OnStreamBegin(); - registry.Append(TInstant::Zero(), encoder.Get()); - encoder->OnStreamEnd(); - - UNIT_ASSERT_STRINGS_EQUAL( - os.Str(), - "{\"sensors\":[{\"kind\":\"GAUGE\",\"labels\":{\"common\":\"label\",\"my\":\"gauge\"},\"value\":12.34}]}"); - } - - // Accept() adds common labels to the beginning of the blob - { - TStringStream os; - auto encoder = EncoderJson(&os); - registry.Accept(TInstant::Zero(), encoder.Get()); - - UNIT_ASSERT_STRINGS_EQUAL( - os.Str(), - "{\"commonLabels\":{\"common\":\"label\"}," - "\"sensors\":[{\"kind\":\"GAUGE\",\"labels\":{\"my\":\"gauge\"},\"value\":12.34}]}"); - } - } + } + + Y_UNIT_TEST(EncodeRegistryWithCommonLabels) { + TMetricRegistry registry(TLabels{{"common", "label"}}); + + TGauge* g = registry.Gauge({{"my", "gauge"}}); + g->Set(12.34); + + // Append() adds common labels to each metric, allowing to combine + // several metric registries in one resulting blob + { + TStringStream os; + auto encoder = EncoderJson(&os); + encoder->OnStreamBegin(); + registry.Append(TInstant::Zero(), encoder.Get()); + encoder->OnStreamEnd(); + + UNIT_ASSERT_STRINGS_EQUAL( + os.Str(), + "{\"sensors\":[{\"kind\":\"GAUGE\",\"labels\":{\"common\":\"label\",\"my\":\"gauge\"},\"value\":12.34}]}"); + } + + // Accept() adds common labels to the beginning of the blob + { + TStringStream os; + auto encoder = EncoderJson(&os); + registry.Accept(TInstant::Zero(), encoder.Get()); + + UNIT_ASSERT_STRINGS_EQUAL( + os.Str(), + "{\"commonLabels\":{\"common\":\"label\"}," + "\"sensors\":[{\"kind\":\"GAUGE\",\"labels\":{\"my\":\"gauge\"},\"value\":12.34}]}"); + } + } Y_UNIT_TEST(MetricsRegistryClear) { TMetricRegistry registry; @@ -316,4 +316,4 @@ Y_UNIT_TEST_SUITE(TMetricRegistryTest) { UNIT_ASSERT(samples.SamplesSize() == 0); } -} +} diff --git a/library/cpp/monlib/metrics/metric_sub_registry.h b/library/cpp/monlib/metrics/metric_sub_registry.h index 7039762336..e83eeeafb2 100644 --- a/library/cpp/monlib/metrics/metric_sub_registry.h +++ b/library/cpp/monlib/metrics/metric_sub_registry.h @@ -1,116 +1,116 @@ -#pragma once - -#include "metric_registry.h" - -namespace NMonitoring { - -/** - * This registry is wrapping given delegate registry to add common labels - * to all created metrics through this sub registry. - */ -class TMetricSubRegistry final: public IMetricRegistry { -public: - /** - * Do not keep ownership of the given delegate. - */ - TMetricSubRegistry(TLabels commonLabels, IMetricRegistry* delegate) noexcept - : CommonLabels_{std::move(commonLabels)} - , DelegatePtr_{delegate} - { - } - - /** - * Keeps ownership of the given delegate. - */ - TMetricSubRegistry(TLabels commonLabels, std::shared_ptr<IMetricRegistry> delegate) noexcept - : CommonLabels_{std::move(commonLabels)} - , Delegate_{std::move(delegate)} - , DelegatePtr_{Delegate_.get()} - { - } - - IGauge* Gauge(ILabelsPtr labels) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->Gauge(std::move(labels)); - } - - ILazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->LazyGauge(std::move(labels), std::move(supplier)); - } - - IIntGauge* IntGauge(ILabelsPtr labels) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->IntGauge(std::move(labels)); - } - - ILazyIntGauge* LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->LazyIntGauge(std::move(labels), std::move(supplier)); - } - - ICounter* Counter(ILabelsPtr labels) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->Counter(std::move(labels)); - } - - ILazyCounter* LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->LazyCounter(std::move(labels), std::move(supplier)); - } - - IRate* Rate(ILabelsPtr labels) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->Rate(std::move(labels)); - } - - ILazyRate* LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->LazyRate(std::move(labels), std::move(supplier)); - } - - IHistogram* HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->HistogramCounter(std::move(labels), std::move(collector)); - } - - IHistogram* HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) override { - AddCommonLabels(labels.Get()); - return DelegatePtr_->HistogramRate(std::move(labels), std::move(collector)); - } - - void Accept(TInstant time, IMetricConsumer* consumer) const override { - DelegatePtr_->Accept(time, consumer); - } - - void Append(TInstant time, IMetricConsumer* consumer) const override { - DelegatePtr_->Append(time, consumer); - } - - const TLabels& CommonLabels() const noexcept override { - return CommonLabels_; - } - - void RemoveMetric(const ILabels& labels) noexcept override { - TLabelsImpl<TStringBuf> toRemove; - for (auto& l: labels) { - toRemove.Add(l); - } - AddCommonLabels(&toRemove); - DelegatePtr_->RemoveMetric(toRemove); - } - -private: - void AddCommonLabels(ILabels* labels) const { - for (auto& label: CommonLabels_) { - labels->Add(label); - } - } - -private: - const TLabels CommonLabels_; - std::shared_ptr<IMetricRegistry> Delegate_; - IMetricRegistry* DelegatePtr_; -}; - -} // namespace NMonitoring +#pragma once + +#include "metric_registry.h" + +namespace NMonitoring { + +/** + * This registry is wrapping given delegate registry to add common labels + * to all created metrics through this sub registry. + */ +class TMetricSubRegistry final: public IMetricRegistry { +public: + /** + * Do not keep ownership of the given delegate. + */ + TMetricSubRegistry(TLabels commonLabels, IMetricRegistry* delegate) noexcept + : CommonLabels_{std::move(commonLabels)} + , DelegatePtr_{delegate} + { + } + + /** + * Keeps ownership of the given delegate. + */ + TMetricSubRegistry(TLabels commonLabels, std::shared_ptr<IMetricRegistry> delegate) noexcept + : CommonLabels_{std::move(commonLabels)} + , Delegate_{std::move(delegate)} + , DelegatePtr_{Delegate_.get()} + { + } + + IGauge* Gauge(ILabelsPtr labels) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->Gauge(std::move(labels)); + } + + ILazyGauge* LazyGauge(ILabelsPtr labels, std::function<double()> supplier) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->LazyGauge(std::move(labels), std::move(supplier)); + } + + IIntGauge* IntGauge(ILabelsPtr labels) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->IntGauge(std::move(labels)); + } + + ILazyIntGauge* LazyIntGauge(ILabelsPtr labels, std::function<i64()> supplier) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->LazyIntGauge(std::move(labels), std::move(supplier)); + } + + ICounter* Counter(ILabelsPtr labels) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->Counter(std::move(labels)); + } + + ILazyCounter* LazyCounter(ILabelsPtr labels, std::function<ui64()> supplier) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->LazyCounter(std::move(labels), std::move(supplier)); + } + + IRate* Rate(ILabelsPtr labels) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->Rate(std::move(labels)); + } + + ILazyRate* LazyRate(ILabelsPtr labels, std::function<ui64()> supplier) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->LazyRate(std::move(labels), std::move(supplier)); + } + + IHistogram* HistogramCounter(ILabelsPtr labels, IHistogramCollectorPtr collector) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->HistogramCounter(std::move(labels), std::move(collector)); + } + + IHistogram* HistogramRate(ILabelsPtr labels, IHistogramCollectorPtr collector) override { + AddCommonLabels(labels.Get()); + return DelegatePtr_->HistogramRate(std::move(labels), std::move(collector)); + } + + void Accept(TInstant time, IMetricConsumer* consumer) const override { + DelegatePtr_->Accept(time, consumer); + } + + void Append(TInstant time, IMetricConsumer* consumer) const override { + DelegatePtr_->Append(time, consumer); + } + + const TLabels& CommonLabels() const noexcept override { + return CommonLabels_; + } + + void RemoveMetric(const ILabels& labels) noexcept override { + TLabelsImpl<TStringBuf> toRemove; + for (auto& l: labels) { + toRemove.Add(l); + } + AddCommonLabels(&toRemove); + DelegatePtr_->RemoveMetric(toRemove); + } + +private: + void AddCommonLabels(ILabels* labels) const { + for (auto& label: CommonLabels_) { + labels->Add(label); + } + } + +private: + const TLabels CommonLabels_; + std::shared_ptr<IMetricRegistry> Delegate_; + IMetricRegistry* DelegatePtr_; +}; + +} // namespace NMonitoring diff --git a/library/cpp/monlib/metrics/metric_sub_registry_ut.cpp b/library/cpp/monlib/metrics/metric_sub_registry_ut.cpp index af6d4fa462..0c5d48b876 100644 --- a/library/cpp/monlib/metrics/metric_sub_registry_ut.cpp +++ b/library/cpp/monlib/metrics/metric_sub_registry_ut.cpp @@ -1,65 +1,65 @@ -#include "metric_sub_registry.h" - -#include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - -Y_UNIT_TEST_SUITE(TMetricSubRegistryTest) { - Y_UNIT_TEST(WrapRegistry) { - TMetricRegistry registry; - - { - TMetricSubRegistry subRegistry{{{"common", "label"}}, ®istry}; - IIntGauge* g = subRegistry.IntGauge(MakeLabels({{"my", "gauge"}})); - UNIT_ASSERT(g); - g->Set(42); - } - - TIntGauge* g = registry.IntGauge({{"my", "gauge"}, {"common", "label"}}); - UNIT_ASSERT(g); - UNIT_ASSERT_VALUES_EQUAL(g->Get(), 42); - } - - Y_UNIT_TEST(CommonLabelsDoNotOverrideGeneralLabel) { - TMetricRegistry registry; - - { - TMetricSubRegistry subRegistry{{{"common", "label"}, {"my", "notOverride"}}, ®istry}; - IIntGauge* g = subRegistry.IntGauge(MakeLabels({{"my", "gauge"}})); - UNIT_ASSERT(g); - g->Set(1234); - } - - TIntGauge* knownGauge = registry.IntGauge({{"my", "gauge"}, {"common", "label"}}); - UNIT_ASSERT(knownGauge); - UNIT_ASSERT_VALUES_EQUAL(knownGauge->Get(), 1234); - - TIntGauge* newGauge = registry.IntGauge({{"common", "label"}, {"my", "notOverride"}}); - UNIT_ASSERT(newGauge); - UNIT_ASSERT_VALUES_EQUAL(newGauge->Get(), 0); - } - - Y_UNIT_TEST(RemoveMetric) { - TMetricRegistry registry; - - { - TMetricSubRegistry subRegistry{{{"common", "label"}}, ®istry}; - IIntGauge* g = subRegistry.IntGauge(MakeLabels({{"my", "gauge"}})); - UNIT_ASSERT(g); - g->Set(1234); - } - - IIntGauge* g1 = registry.IntGauge({{"my", "gauge"}, {"common", "label"}}); - UNIT_ASSERT(g1); - UNIT_ASSERT_VALUES_EQUAL(g1->Get(), 1234); - - { - TMetricSubRegistry subRegistry{{{"common", "label"}}, ®istry}; - subRegistry.RemoveMetric(TLabels{{"my", "gauge"}}); - } - - IIntGauge* g2 = registry.IntGauge({{"my", "gauge"}, {"common", "label"}}); - UNIT_ASSERT(g2); - UNIT_ASSERT_VALUES_EQUAL(g2->Get(), 0); - } -} +#include "metric_sub_registry.h" + +#include <library/cpp/testing/unittest/registar.h> + +using namespace NMonitoring; + +Y_UNIT_TEST_SUITE(TMetricSubRegistryTest) { + Y_UNIT_TEST(WrapRegistry) { + TMetricRegistry registry; + + { + TMetricSubRegistry subRegistry{{{"common", "label"}}, ®istry}; + IIntGauge* g = subRegistry.IntGauge(MakeLabels({{"my", "gauge"}})); + UNIT_ASSERT(g); + g->Set(42); + } + + TIntGauge* g = registry.IntGauge({{"my", "gauge"}, {"common", "label"}}); + UNIT_ASSERT(g); + UNIT_ASSERT_VALUES_EQUAL(g->Get(), 42); + } + + Y_UNIT_TEST(CommonLabelsDoNotOverrideGeneralLabel) { + TMetricRegistry registry; + + { + TMetricSubRegistry subRegistry{{{"common", "label"}, {"my", "notOverride"}}, ®istry}; + IIntGauge* g = subRegistry.IntGauge(MakeLabels({{"my", "gauge"}})); + UNIT_ASSERT(g); + g->Set(1234); + } + + TIntGauge* knownGauge = registry.IntGauge({{"my", "gauge"}, {"common", "label"}}); + UNIT_ASSERT(knownGauge); + UNIT_ASSERT_VALUES_EQUAL(knownGauge->Get(), 1234); + + TIntGauge* newGauge = registry.IntGauge({{"common", "label"}, {"my", "notOverride"}}); + UNIT_ASSERT(newGauge); + UNIT_ASSERT_VALUES_EQUAL(newGauge->Get(), 0); + } + + Y_UNIT_TEST(RemoveMetric) { + TMetricRegistry registry; + + { + TMetricSubRegistry subRegistry{{{"common", "label"}}, ®istry}; + IIntGauge* g = subRegistry.IntGauge(MakeLabels({{"my", "gauge"}})); + UNIT_ASSERT(g); + g->Set(1234); + } + + IIntGauge* g1 = registry.IntGauge({{"my", "gauge"}, {"common", "label"}}); + UNIT_ASSERT(g1); + UNIT_ASSERT_VALUES_EQUAL(g1->Get(), 1234); + + { + TMetricSubRegistry subRegistry{{{"common", "label"}}, ®istry}; + subRegistry.RemoveMetric(TLabels{{"my", "gauge"}}); + } + + IIntGauge* g2 = registry.IntGauge({{"my", "gauge"}, {"common", "label"}}); + UNIT_ASSERT(g2); + UNIT_ASSERT_VALUES_EQUAL(g2->Get(), 0); + } +} diff --git a/library/cpp/monlib/metrics/metric_type.cpp b/library/cpp/monlib/metrics/metric_type.cpp index c903ae3dea..a8a546e843 100644 --- a/library/cpp/monlib/metrics/metric_type.cpp +++ b/library/cpp/monlib/metrics/metric_type.cpp @@ -1,57 +1,57 @@ -#include "metric_type.h" - -#include <util/generic/strbuf.h> -#include <util/generic/yexception.h> -#include <util/stream/output.h> - -namespace NMonitoring { - TStringBuf MetricTypeToStr(EMetricType type) { - switch (type) { - case EMetricType::GAUGE: +#include "metric_type.h" + +#include <util/generic/strbuf.h> +#include <util/generic/yexception.h> +#include <util/stream/output.h> + +namespace NMonitoring { + TStringBuf MetricTypeToStr(EMetricType type) { + switch (type) { + case EMetricType::GAUGE: return TStringBuf("GAUGE"); - case EMetricType::COUNTER: + case EMetricType::COUNTER: return TStringBuf("COUNTER"); - case EMetricType::RATE: + case EMetricType::RATE: return TStringBuf("RATE"); - case EMetricType::IGAUGE: + case EMetricType::IGAUGE: return TStringBuf("IGAUGE"); - case EMetricType::HIST: + case EMetricType::HIST: return TStringBuf("HIST"); - case EMetricType::HIST_RATE: + case EMetricType::HIST_RATE: return TStringBuf("HIST_RATE"); - case EMetricType::DSUMMARY: + case EMetricType::DSUMMARY: return TStringBuf("DSUMMARY"); case EMetricType::LOGHIST: return TStringBuf("LOGHIST"); - default: + default: return TStringBuf("UNKNOWN"); - } - } - - EMetricType MetricTypeFromStr(TStringBuf str) { + } + } + + EMetricType MetricTypeFromStr(TStringBuf str) { if (str == TStringBuf("GAUGE") || str == TStringBuf("DGAUGE")) { - return EMetricType::GAUGE; + return EMetricType::GAUGE; } else if (str == TStringBuf("COUNTER")) { - return EMetricType::COUNTER; + return EMetricType::COUNTER; } else if (str == TStringBuf("RATE")) { - return EMetricType::RATE; + return EMetricType::RATE; } else if (str == TStringBuf("IGAUGE")) { - return EMetricType::IGAUGE; + return EMetricType::IGAUGE; } else if (str == TStringBuf("HIST")) { - return EMetricType::HIST; + return EMetricType::HIST; } else if (str == TStringBuf("HIST_RATE")) { - return EMetricType::HIST_RATE; + return EMetricType::HIST_RATE; } else if (str == TStringBuf("DSUMMARY")) { - return EMetricType::DSUMMARY; + return EMetricType::DSUMMARY; } else if (str == TStringBuf("LOGHIST")) { return EMetricType::LOGHIST; - } else { - ythrow yexception() << "unknown metric type: " << str; - } - } -} - -template <> -void Out<NMonitoring::EMetricType>(IOutputStream& o, NMonitoring::EMetricType t) { - o << NMonitoring::MetricTypeToStr(t); -} + } else { + ythrow yexception() << "unknown metric type: " << str; + } + } +} + +template <> +void Out<NMonitoring::EMetricType>(IOutputStream& o, NMonitoring::EMetricType t) { + o << NMonitoring::MetricTypeToStr(t); +} diff --git a/library/cpp/monlib/metrics/metric_type.h b/library/cpp/monlib/metrics/metric_type.h index 00a8187af1..1984c42c1e 100644 --- a/library/cpp/monlib/metrics/metric_type.h +++ b/library/cpp/monlib/metrics/metric_type.h @@ -1,25 +1,25 @@ -#pragma once - -#include <util/generic/fwd.h> - -namespace NMonitoring { - - constexpr ui32 MaxMetricTypeNameLength = 9; - - enum class EMetricType { - UNKNOWN = 0, - GAUGE = 1, - COUNTER = 2, - RATE = 3, - IGAUGE = 4, - HIST = 5, - HIST_RATE = 6, +#pragma once + +#include <util/generic/fwd.h> + +namespace NMonitoring { + + constexpr ui32 MaxMetricTypeNameLength = 9; + + enum class EMetricType { + UNKNOWN = 0, + GAUGE = 1, + COUNTER = 2, + RATE = 3, + IGAUGE = 4, + HIST = 5, + HIST_RATE = 6, DSUMMARY = 7, // ISUMMARY = 8, reserved LOGHIST = 9, - }; - - TStringBuf MetricTypeToStr(EMetricType type); - EMetricType MetricTypeFromStr(TStringBuf str); - -} + }; + + TStringBuf MetricTypeToStr(EMetricType type); + EMetricType MetricTypeFromStr(TStringBuf str); + +} diff --git a/library/cpp/monlib/metrics/metric_value.cpp b/library/cpp/monlib/metrics/metric_value.cpp index 1ea2ed4142..b95d7011c6 100644 --- a/library/cpp/monlib/metrics/metric_value.cpp +++ b/library/cpp/monlib/metrics/metric_value.cpp @@ -1,27 +1,27 @@ -#include "metric_value.h" - - -namespace NMonitoring { - void TMetricTimeSeries::SortByTs() { +#include "metric_value.h" + + +namespace NMonitoring { + void TMetricTimeSeries::SortByTs() { SortPointsByTs(ValueType_, Points_); - } - - void TMetricTimeSeries::Clear() noexcept { - if (ValueType_ == EMetricValueType::HISTOGRAM) { - for (TPoint& p: Points_) { - SnapshotUnRef<EMetricValueType::HISTOGRAM>(p); - } - } else if (ValueType_ == EMetricValueType::SUMMARY) { + } + + void TMetricTimeSeries::Clear() noexcept { + if (ValueType_ == EMetricValueType::HISTOGRAM) { + for (TPoint& p: Points_) { + SnapshotUnRef<EMetricValueType::HISTOGRAM>(p); + } + } else if (ValueType_ == EMetricValueType::SUMMARY) { for (TPoint& p: Points_) { - SnapshotUnRef<EMetricValueType::SUMMARY>(p); + SnapshotUnRef<EMetricValueType::SUMMARY>(p); } } else if (ValueType_ == EMetricValueType::LOGHISTOGRAM) { for (TPoint& p: Points_) { SnapshotUnRef<EMetricValueType::LOGHISTOGRAM>(p); } - } + } - Points_.clear(); - ValueType_ = EMetricValueType::UNKNOWN; - } -} + Points_.clear(); + ValueType_ = EMetricValueType::UNKNOWN; + } +} diff --git a/library/cpp/monlib/metrics/metric_value.h b/library/cpp/monlib/metrics/metric_value.h index d7b2f6a680..607fcc8602 100644 --- a/library/cpp/monlib/metrics/metric_value.h +++ b/library/cpp/monlib/metrics/metric_value.h @@ -1,17 +1,17 @@ -#pragma once - -#include "histogram_collector.h" -#include "metric_value_type.h" +#pragma once + +#include "histogram_collector.h" +#include "metric_value_type.h" #include "summary_collector.h" #include "log_histogram_snapshot.h" - -#include <util/datetime/base.h> -#include <util/generic/algorithm.h> -#include <util/generic/vector.h> + +#include <util/datetime/base.h> +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> #include <util/generic/cast.h> #include <util/generic/ymath.h> - -namespace NMonitoring { + +namespace NMonitoring { namespace NPrivate { template <typename T> T FromFloatSafe(double d) { @@ -25,71 +25,71 @@ namespace NMonitoring { }; } // namespace NPrivate - template <typename T, typename Enable = void> - struct TValueType; - - template <> - struct TValueType<double> { - static constexpr auto Type = EMetricValueType::DOUBLE; - }; - - template <> - struct TValueType<i64> { - static constexpr auto Type = EMetricValueType::INT64; - }; - - template <> - struct TValueType<ui64> { - static constexpr auto Type = EMetricValueType::UINT64; - }; - + template <typename T, typename Enable = void> + struct TValueType; + + template <> + struct TValueType<double> { + static constexpr auto Type = EMetricValueType::DOUBLE; + }; + + template <> + struct TValueType<i64> { + static constexpr auto Type = EMetricValueType::INT64; + }; + + template <> + struct TValueType<ui64> { + static constexpr auto Type = EMetricValueType::UINT64; + }; + template <> struct TValueType<TLogHistogramSnapshot*> { static constexpr auto Type = EMetricValueType::LOGHISTOGRAM; }; - template <typename T> - struct TValueType<T*, typename std::enable_if_t<std::is_base_of<IHistogramSnapshot, T>::value>> { - static constexpr auto Type = EMetricValueType::HISTOGRAM; - }; - + template <typename T> + struct TValueType<T*, typename std::enable_if_t<std::is_base_of<IHistogramSnapshot, T>::value>> { + static constexpr auto Type = EMetricValueType::HISTOGRAM; + }; + template <typename T> struct TValueType<T*, typename std::enable_if_t<std::is_base_of<ISummaryDoubleSnapshot, T>::value>> { - static constexpr auto Type = EMetricValueType::SUMMARY; + static constexpr auto Type = EMetricValueType::SUMMARY; }; - - /////////////////////////////////////////////////////////////////////////// - // TMetricValue - /////////////////////////////////////////////////////////////////////////// - // TMetricValue represents a generic value. It does not contain type + + /////////////////////////////////////////////////////////////////////////// + // TMetricValue + /////////////////////////////////////////////////////////////////////////// + // TMetricValue represents a generic value. It does not contain type // information about a value. This is done to minimize object footprint. // To read an actual value from the object the type must be checked // first or provided to AsXxxx(type) member-functions. // This class does not hold an ownership of an IHistogramSnapshot or // SummarySnapshot, so this must be done somewhere outside. - class TMetricValue { - public: - TMetricValue() noexcept { - Value_.Uint64 = 0; - } - - explicit TMetricValue(double value) noexcept { - Value_.Double = value; - } - - explicit TMetricValue(i64 value) noexcept { - Value_.Int64 = value; - } - - explicit TMetricValue(ui64 value) noexcept { - Value_.Uint64 = value; - } - - explicit TMetricValue(IHistogramSnapshot* histogram) noexcept { - Value_.Histogram = histogram; - } - - explicit TMetricValue(ISummaryDoubleSnapshot* summary) noexcept { + class TMetricValue { + public: + TMetricValue() noexcept { + Value_.Uint64 = 0; + } + + explicit TMetricValue(double value) noexcept { + Value_.Double = value; + } + + explicit TMetricValue(i64 value) noexcept { + Value_.Int64 = value; + } + + explicit TMetricValue(ui64 value) noexcept { + Value_.Uint64 = value; + } + + explicit TMetricValue(IHistogramSnapshot* histogram) noexcept { + Value_.Histogram = histogram; + } + + explicit TMetricValue(ISummaryDoubleSnapshot* summary) noexcept { Value_.Summary = summary; } @@ -97,90 +97,90 @@ namespace NMonitoring { Value_.LogHistogram = logHist; } - double AsDouble() const noexcept { - return Value_.Double; - } - - // will cast value into double, current value type is determined by - // the given type argument - double AsDouble(EMetricValueType type) const { - switch (type) { - case EMetricValueType::DOUBLE: - return Value_.Double; - case EMetricValueType::INT64: - return static_cast<double>(Value_.Int64); - case EMetricValueType::UINT64: - return static_cast<double>(Value_.Uint64); - case EMetricValueType::HISTOGRAM: - ythrow yexception() << "histogram cannot be casted to Double"; - case EMetricValueType::SUMMARY: + double AsDouble() const noexcept { + return Value_.Double; + } + + // will cast value into double, current value type is determined by + // the given type argument + double AsDouble(EMetricValueType type) const { + switch (type) { + case EMetricValueType::DOUBLE: + return Value_.Double; + case EMetricValueType::INT64: + return static_cast<double>(Value_.Int64); + case EMetricValueType::UINT64: + return static_cast<double>(Value_.Uint64); + case EMetricValueType::HISTOGRAM: + ythrow yexception() << "histogram cannot be casted to Double"; + case EMetricValueType::SUMMARY: ythrow yexception() << "summary cannot be casted to Double"; case EMetricValueType::LOGHISTOGRAM: ythrow yexception() << "loghistogram cannot be casted to Double"; - case EMetricValueType::UNKNOWN: - ythrow yexception() << "unknown value type"; - } - Y_FAIL(); // for GCC - } - - ui64 AsUint64() const noexcept { - return Value_.Uint64; - } - - // will cast value into uint64, current value's type is determined by - // the given type argument - ui64 AsUint64(EMetricValueType type) const { - switch (type) { - case EMetricValueType::DOUBLE: + case EMetricValueType::UNKNOWN: + ythrow yexception() << "unknown value type"; + } + Y_FAIL(); // for GCC + } + + ui64 AsUint64() const noexcept { + return Value_.Uint64; + } + + // will cast value into uint64, current value's type is determined by + // the given type argument + ui64 AsUint64(EMetricValueType type) const { + switch (type) { + case EMetricValueType::DOUBLE: return NPrivate::FromFloatSafe<ui64>(Value_.Double); - case EMetricValueType::INT64: + case EMetricValueType::INT64: return SafeIntegerCast<ui64>(Value_.Int64); - case EMetricValueType::UINT64: - return Value_.Uint64; - case EMetricValueType::HISTOGRAM: - ythrow yexception() << "histogram cannot be casted to Uint64"; - case EMetricValueType::SUMMARY: + case EMetricValueType::UINT64: + return Value_.Uint64; + case EMetricValueType::HISTOGRAM: + ythrow yexception() << "histogram cannot be casted to Uint64"; + case EMetricValueType::SUMMARY: ythrow yexception() << "summary cannot be casted to Uint64"; case EMetricValueType::LOGHISTOGRAM: ythrow yexception() << "loghistogram cannot be casted to Uint64"; - case EMetricValueType::UNKNOWN: - ythrow yexception() << "unknown value type"; - } - Y_FAIL(); // for GCC - } - - i64 AsInt64() const noexcept { - return Value_.Int64; - } - - // will cast value into int64, current value's type is determined by - // the given type argument - i64 AsInt64(EMetricValueType type) const { - switch (type) { - case EMetricValueType::DOUBLE: + case EMetricValueType::UNKNOWN: + ythrow yexception() << "unknown value type"; + } + Y_FAIL(); // for GCC + } + + i64 AsInt64() const noexcept { + return Value_.Int64; + } + + // will cast value into int64, current value's type is determined by + // the given type argument + i64 AsInt64(EMetricValueType type) const { + switch (type) { + case EMetricValueType::DOUBLE: return NPrivate::FromFloatSafe<i64>(Value_.Double); - case EMetricValueType::INT64: - return Value_.Int64; - case EMetricValueType::UINT64: + case EMetricValueType::INT64: + return Value_.Int64; + case EMetricValueType::UINT64: return SafeIntegerCast<i64>(Value_.Uint64); - case EMetricValueType::HISTOGRAM: - ythrow yexception() << "histogram cannot be casted to Int64"; - case EMetricValueType::SUMMARY: + case EMetricValueType::HISTOGRAM: + ythrow yexception() << "histogram cannot be casted to Int64"; + case EMetricValueType::SUMMARY: ythrow yexception() << "summary cannot be casted to Int64"; case EMetricValueType::LOGHISTOGRAM: ythrow yexception() << "loghistogram cannot be casted to Int64"; - case EMetricValueType::UNKNOWN: - ythrow yexception() << "unknown value type"; - } - Y_FAIL(); // for GCC - } - - IHistogramSnapshot* AsHistogram() const noexcept { - return Value_.Histogram; - } - - IHistogramSnapshot* AsHistogram(EMetricValueType type) const { - if (type != EMetricValueType::HISTOGRAM) { + case EMetricValueType::UNKNOWN: + ythrow yexception() << "unknown value type"; + } + Y_FAIL(); // for GCC + } + + IHistogramSnapshot* AsHistogram() const noexcept { + return Value_.Histogram; + } + + IHistogramSnapshot* AsHistogram(EMetricValueType type) const { + if (type != EMetricValueType::HISTOGRAM) { ythrow yexception() << type << " cannot be casted to Histogram"; } @@ -191,8 +191,8 @@ namespace NMonitoring { return Value_.Summary; } - ISummaryDoubleSnapshot* AsSummaryDouble(EMetricValueType type) const { - if (type != EMetricValueType::SUMMARY) { + ISummaryDoubleSnapshot* AsSummaryDouble(EMetricValueType type) const { + if (type != EMetricValueType::SUMMARY) { ythrow yexception() << type << " cannot be casted to SummaryDouble"; } @@ -211,35 +211,35 @@ namespace NMonitoring { return Value_.LogHistogram; } - protected: - union { - double Double; - i64 Int64; - ui64 Uint64; - IHistogramSnapshot* Histogram; + protected: + union { + double Double; + i64 Int64; + ui64 Uint64; + IHistogramSnapshot* Histogram; ISummaryDoubleSnapshot* Summary; TLogHistogramSnapshot* LogHistogram; - } Value_; - }; - + } Value_; + }; + /////////////////////////////////////////////////////////////////////////// - // TMetricValueWithType + // TMetricValueWithType /////////////////////////////////////////////////////////////////////////// - // Same as TMetricValue, but this type holds an ownership of + // Same as TMetricValue, but this type holds an ownership of // snapshots and contains value type information. - class TMetricValueWithType: private TMetricValue, public TMoveOnly { + class TMetricValueWithType: private TMetricValue, public TMoveOnly { public: - using TBase = TMetricValue; + using TBase = TMetricValue; template <typename T> - explicit TMetricValueWithType(T value) + explicit TMetricValueWithType(T value) : TBase(value) , ValueType_{TValueType<T>::Type} { Ref(); } - TMetricValueWithType(TMetricValueWithType&& other) + TMetricValueWithType(TMetricValueWithType&& other) : TBase(std::move(other)) , ValueType_{other.ValueType_} { @@ -247,7 +247,7 @@ namespace NMonitoring { other.Clear(); } - TMetricValueWithType& operator=(TMetricValueWithType&& other) { + TMetricValueWithType& operator=(TMetricValueWithType&& other) { TBase::operator=(other); ValueType_ = other.ValueType_; @@ -257,16 +257,16 @@ namespace NMonitoring { return *this; } - ~TMetricValueWithType() { + ~TMetricValueWithType() { UnRef(); } void Clear() { UnRef(); - ValueType_ = EMetricValueType::UNKNOWN; + ValueType_ = EMetricValueType::UNKNOWN; } - EMetricValueType GetType() const noexcept { + EMetricValueType GetType() const noexcept { return ValueType_; } @@ -296,9 +296,9 @@ namespace NMonitoring { private: void Ref() { - if (ValueType_ == EMetricValueType::SUMMARY) { + if (ValueType_ == EMetricValueType::SUMMARY) { TBase::AsSummaryDouble()->Ref(); - } else if (ValueType_ == EMetricValueType::HISTOGRAM) { + } else if (ValueType_ == EMetricValueType::HISTOGRAM) { TBase::AsHistogram()->Ref(); } else if (ValueType_ == EMetricValueType::LOGHISTOGRAM) { TBase::AsLogHistogram()->Ref(); @@ -306,9 +306,9 @@ namespace NMonitoring { } void UnRef() { - if (ValueType_ == EMetricValueType::SUMMARY) { + if (ValueType_ == EMetricValueType::SUMMARY) { TBase::AsSummaryDouble()->UnRef(); - } else if (ValueType_ == EMetricValueType::HISTOGRAM) { + } else if (ValueType_ == EMetricValueType::HISTOGRAM) { TBase::AsHistogram()->UnRef(); } else if (ValueType_ == EMetricValueType::LOGHISTOGRAM) { TBase::AsLogHistogram()->UnRef(); @@ -316,114 +316,114 @@ namespace NMonitoring { } private: - EMetricValueType ValueType_ = EMetricValueType::UNKNOWN; + EMetricValueType ValueType_ = EMetricValueType::UNKNOWN; }; - static_assert(sizeof(TMetricValue) == sizeof(ui64), - "expected size of TMetricValue is one machine word"); - - /////////////////////////////////////////////////////////////////////////// - // TMetricTimeSeries - /////////////////////////////////////////////////////////////////////////// - class TMetricTimeSeries: private TMoveOnly { - public: - class TPoint { - public: - TPoint() - : Time_(TInstant::Zero()) - { - } - - template <typename T> - TPoint(TInstant time, T value) - : Time_(time) - , Value_(value) - { - } - - TInstant GetTime() const noexcept { - return Time_; - } - - TMetricValue GetValue() const noexcept { - return Value_; - } - - void ClearValue() { - Value_ = {}; - } - - private: - TInstant Time_; - TMetricValue Value_; - }; - - public: - TMetricTimeSeries() = default; - - TMetricTimeSeries(TMetricTimeSeries&& rhs) noexcept - : ValueType_(rhs.ValueType_) - , Points_(std::move(rhs.Points_)) - { - rhs.ValueType_ = EMetricValueType::UNKNOWN; - } - - TMetricTimeSeries& operator=(TMetricTimeSeries&& rhs) noexcept { - Clear(); - - ValueType_ = rhs.ValueType_; - rhs.ValueType_ = EMetricValueType::UNKNOWN; - - Points_ = std::move(rhs.Points_); - return *this; - } - - ~TMetricTimeSeries() { - Clear(); - } - - template <typename T> - void Add(TInstant time, T value) { + static_assert(sizeof(TMetricValue) == sizeof(ui64), + "expected size of TMetricValue is one machine word"); + + /////////////////////////////////////////////////////////////////////////// + // TMetricTimeSeries + /////////////////////////////////////////////////////////////////////////// + class TMetricTimeSeries: private TMoveOnly { + public: + class TPoint { + public: + TPoint() + : Time_(TInstant::Zero()) + { + } + + template <typename T> + TPoint(TInstant time, T value) + : Time_(time) + , Value_(value) + { + } + + TInstant GetTime() const noexcept { + return Time_; + } + + TMetricValue GetValue() const noexcept { + return Value_; + } + + void ClearValue() { + Value_ = {}; + } + + private: + TInstant Time_; + TMetricValue Value_; + }; + + public: + TMetricTimeSeries() = default; + + TMetricTimeSeries(TMetricTimeSeries&& rhs) noexcept + : ValueType_(rhs.ValueType_) + , Points_(std::move(rhs.Points_)) + { + rhs.ValueType_ = EMetricValueType::UNKNOWN; + } + + TMetricTimeSeries& operator=(TMetricTimeSeries&& rhs) noexcept { + Clear(); + + ValueType_ = rhs.ValueType_; + rhs.ValueType_ = EMetricValueType::UNKNOWN; + + Points_ = std::move(rhs.Points_); + return *this; + } + + ~TMetricTimeSeries() { + Clear(); + } + + template <typename T> + void Add(TInstant time, T value) { Add(TPoint(time, value), TValueType<T>::Type); } void Add(TPoint point, EMetricValueType valueType) { - if (Empty()) { + if (Empty()) { ValueType_ = valueType; - } else { + } else { CheckTypes(ValueType_, valueType); - } + } Points_.push_back(point); - - if (ValueType_ == EMetricValueType::SUMMARY) { + + if (ValueType_ == EMetricValueType::SUMMARY) { TPoint& p = Points_.back(); p.GetValue().AsSummaryDouble()->Ref(); - } else if (ValueType_ == EMetricValueType::HISTOGRAM) { + } else if (ValueType_ == EMetricValueType::HISTOGRAM) { TPoint& p = Points_.back(); p.GetValue().AsHistogram()->Ref(); } else if (ValueType_ == EMetricValueType::LOGHISTOGRAM) { TPoint& p = Points_.back(); p.GetValue().AsLogHistogram()->Ref(); - } - } - - void CopyFrom(const TMetricTimeSeries& other) { + } + } + + void CopyFrom(const TMetricTimeSeries& other) { if (Empty()) { ValueType_ = other.ValueType_; } else { CheckTypes(GetValueType(), other.GetValueType()); } - - size_t prevSize = Points_.size(); - Copy(std::begin(other.Points_), std::end(other.Points_), - std::back_inserter(Points_)); - - if (ValueType_ == EMetricValueType::HISTOGRAM) { - for (size_t i = prevSize; i < Points_.size(); i++) { - TPoint& point = Points_[i]; - point.GetValue().AsHistogram()->Ref(); - } - } else if (ValueType_ == EMetricValueType::SUMMARY) { + + size_t prevSize = Points_.size(); + Copy(std::begin(other.Points_), std::end(other.Points_), + std::back_inserter(Points_)); + + if (ValueType_ == EMetricValueType::HISTOGRAM) { + for (size_t i = prevSize; i < Points_.size(); i++) { + TPoint& point = Points_[i]; + point.GetValue().AsHistogram()->Ref(); + } + } else if (ValueType_ == EMetricValueType::SUMMARY) { for (size_t i = prevSize; i < Points_.size(); ++i) { TPoint& point = Points_[i]; point.GetValue().AsSummaryDouble()->Ref(); @@ -436,56 +436,56 @@ namespace NMonitoring { } } - template <typename TConsumer> - void ForEach(TConsumer c) const { - for (const auto& point : Points_) { - c(point.GetTime(), ValueType_, point.GetValue()); - } - } - - bool Empty() const noexcept { - return Points_.empty(); - } - - size_t Size() const noexcept { - return Points_.size(); - } - + template <typename TConsumer> + void ForEach(TConsumer c) const { + for (const auto& point : Points_) { + c(point.GetTime(), ValueType_, point.GetValue()); + } + } + + bool Empty() const noexcept { + return Points_.empty(); + } + + size_t Size() const noexcept { + return Points_.size(); + } + size_t Capacity() const noexcept { return Points_.capacity(); } - const TPoint& operator[](size_t index) const noexcept { - return Points_[index]; - } - - void SortByTs(); - - void Clear() noexcept; - - EMetricValueType GetValueType() const noexcept { - return ValueType_; - } - - private: - static void CheckTypes(EMetricValueType t1, EMetricValueType t2) { - Y_ENSURE(t1 == t2, + const TPoint& operator[](size_t index) const noexcept { + return Points_[index]; + } + + void SortByTs(); + + void Clear() noexcept; + + EMetricValueType GetValueType() const noexcept { + return ValueType_; + } + + private: + static void CheckTypes(EMetricValueType t1, EMetricValueType t2) { + Y_ENSURE(t1 == t2, "Series type mismatch: expected " << t1 << ", but got " << t2); - } - - private: - EMetricValueType ValueType_ = EMetricValueType::UNKNOWN; - TVector<TPoint> Points_; - }; - - template <EMetricValueType valueType, typename TPoint> + } + + private: + EMetricValueType ValueType_ = EMetricValueType::UNKNOWN; + TVector<TPoint> Points_; + }; + + template <EMetricValueType valueType, typename TPoint> static inline void SnapshotUnRef(TPoint& point) { - if constexpr (valueType == EMetricValueType::HISTOGRAM) { + if constexpr (valueType == EMetricValueType::HISTOGRAM) { if (auto* hist = point.GetValue().AsHistogram()) { hist->UnRef(); } - } else if constexpr (valueType == EMetricValueType::SUMMARY) { + } else if constexpr (valueType == EMetricValueType::SUMMARY) { if (auto* summary = point.GetValue().AsSummaryDouble()) { summary->UnRef(); } @@ -496,14 +496,14 @@ namespace NMonitoring { } } - template <EMetricValueType valueType, typename TPoint> + template <EMetricValueType valueType, typename TPoint> static void EraseDuplicates(TVector<TPoint>& points) { // we have to manually clean reference to a snapshot from point // while removing duplicates auto result = points.rbegin(); for (auto it = result + 1; it != points.rend(); ++it) { if (result->GetTime() != it->GetTime() && ++result != it) { - SnapshotUnRef<valueType>(*result); + SnapshotUnRef<valueType>(*result); *result = *it; // (2) copy it->ClearValue(); // (3) clean pointer in the source } @@ -511,13 +511,13 @@ namespace NMonitoring { // erase tail points for (auto it = result + 1; it != points.rend(); ++it) { - SnapshotUnRef<valueType>(*it); + SnapshotUnRef<valueType>(*it); } points.erase(points.begin(), (result + 1).base()); } template <typename TPoint> - void SortPointsByTs(EMetricValueType valueType, TVector<TPoint>& points) { + void SortPointsByTs(EMetricValueType valueType, TVector<TPoint>& points) { if (points.size() < 2) { return; } @@ -530,13 +530,13 @@ namespace NMonitoring { points.erase(points.begin(), it.base()); } else { StableSortBy(points, NPrivate::POINT_KEY_FN); - if (valueType == EMetricValueType::HISTOGRAM) { - EraseDuplicates<EMetricValueType::HISTOGRAM>(points); + if (valueType == EMetricValueType::HISTOGRAM) { + EraseDuplicates<EMetricValueType::HISTOGRAM>(points); } else if (valueType == EMetricValueType::LOGHISTOGRAM) { EraseDuplicates<EMetricValueType::LOGHISTOGRAM>(points); } else { - EraseDuplicates<EMetricValueType::SUMMARY>(points); + EraseDuplicates<EMetricValueType::SUMMARY>(points); } } } -} +} diff --git a/library/cpp/monlib/metrics/metric_value_type.h b/library/cpp/monlib/metrics/metric_value_type.h index b17d1ca04a..ab30a958c2 100644 --- a/library/cpp/monlib/metrics/metric_value_type.h +++ b/library/cpp/monlib/metrics/metric_value_type.h @@ -3,7 +3,7 @@ namespace NMonitoring { -enum class EMetricValueType { +enum class EMetricValueType { UNKNOWN, DOUBLE, INT64, diff --git a/library/cpp/monlib/metrics/metric_value_ut.cpp b/library/cpp/monlib/metrics/metric_value_ut.cpp index 6db9c583ad..49b47c4057 100644 --- a/library/cpp/monlib/metrics/metric_value_ut.cpp +++ b/library/cpp/monlib/metrics/metric_value_ut.cpp @@ -1,33 +1,33 @@ -#include "metric_value.h" - +#include "metric_value.h" + #include <library/cpp/testing/unittest/registar.h> - -using namespace NMonitoring; - -Y_UNIT_TEST_SUITE(TMetricValueTest) { - - class TTestHistogram: public IHistogramSnapshot { + +using namespace NMonitoring; + +Y_UNIT_TEST_SUITE(TMetricValueTest) { + + class TTestHistogram: public IHistogramSnapshot { public: TTestHistogram(ui32 count = 1) : Count_{count} {} private: - ui32 Count() const override { + ui32 Count() const override { return Count_; - } - - TBucketBound UpperBound(ui32 /*index*/) const override { - return 1234.56; - } - - TBucketValue Value(ui32 /*index*/) const override { - return 42; - } + } + + TBucketBound UpperBound(ui32 /*index*/) const override { + return 1234.56; + } + + TBucketValue Value(ui32 /*index*/) const override { + return 42; + } ui32 Count_{0}; - }; - + }; + IHistogramSnapshotPtr MakeHistogramSnapshot() { return MakeIntrusive<TTestHistogram>(); } @@ -44,46 +44,46 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { return MakeIntrusive<TLogHistogramSnapshot>(1.5, 0u, 0, buckets); } - Y_UNIT_TEST(Sorted) { - auto ts1 = TInstant::Now(); - auto ts2 = ts1 + TDuration::Seconds(1); - - TMetricTimeSeries timeSeries; - timeSeries.Add(ts1, 3.14159); - timeSeries.Add(ts1, 6.28318); - timeSeries.Add(ts2, 2.71828); - - UNIT_ASSERT_EQUAL(timeSeries.Size(), 3); - - timeSeries.SortByTs(); - UNIT_ASSERT_EQUAL(timeSeries.Size(), 2); - - UNIT_ASSERT_EQUAL(ts1, timeSeries[0].GetTime()); + Y_UNIT_TEST(Sorted) { + auto ts1 = TInstant::Now(); + auto ts2 = ts1 + TDuration::Seconds(1); + + TMetricTimeSeries timeSeries; + timeSeries.Add(ts1, 3.14159); + timeSeries.Add(ts1, 6.28318); + timeSeries.Add(ts2, 2.71828); + + UNIT_ASSERT_EQUAL(timeSeries.Size(), 3); + + timeSeries.SortByTs(); + UNIT_ASSERT_EQUAL(timeSeries.Size(), 2); + + UNIT_ASSERT_EQUAL(ts1, timeSeries[0].GetTime()); UNIT_ASSERT_DOUBLES_EQUAL(6.28318, timeSeries[0].GetValue().AsDouble(), Min<double>()); - - UNIT_ASSERT_EQUAL(ts2, timeSeries[1].GetTime()); - UNIT_ASSERT_DOUBLES_EQUAL(2.71828, timeSeries[1].GetValue().AsDouble(), Min<double>()); - } - - Y_UNIT_TEST(Histograms) { - auto ts = TInstant::Now(); - auto histogram = MakeIntrusive<TTestHistogram>(); - - UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); - { - TMetricTimeSeries timeSeries; - timeSeries.Add(ts, histogram.Get()); - UNIT_ASSERT_VALUES_EQUAL(2, histogram->RefCount()); - } - UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); - } - + + UNIT_ASSERT_EQUAL(ts2, timeSeries[1].GetTime()); + UNIT_ASSERT_DOUBLES_EQUAL(2.71828, timeSeries[1].GetValue().AsDouble(), Min<double>()); + } + + Y_UNIT_TEST(Histograms) { + auto ts = TInstant::Now(); + auto histogram = MakeIntrusive<TTestHistogram>(); + + UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); + { + TMetricTimeSeries timeSeries; + timeSeries.Add(ts, histogram.Get()); + UNIT_ASSERT_VALUES_EQUAL(2, histogram->RefCount()); + } + UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); + } + Y_UNIT_TEST(Summary) { auto ts = TInstant::Now(); auto summary = MakeSummarySnapshot(); UNIT_ASSERT_VALUES_EQUAL(1, summary->RefCount()); { - TMetricTimeSeries timeSeries; + TMetricTimeSeries timeSeries; timeSeries.Add(ts, summary.Get()); UNIT_ASSERT_VALUES_EQUAL(2, summary->RefCount()); } @@ -102,73 +102,73 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { UNIT_ASSERT_VALUES_EQUAL(1, logHist->RefCount()); } - Y_UNIT_TEST(TimeSeriesMovable) { - auto ts = TInstant::Now(); - auto histogram = MakeIntrusive<TTestHistogram>(); - - UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); - { - TMetricTimeSeries timeSeriesA; - timeSeriesA.Add(ts, histogram.Get()); - UNIT_ASSERT_VALUES_EQUAL(2, histogram->RefCount()); - - TMetricTimeSeries timeSeriesB = std::move(timeSeriesA); - UNIT_ASSERT_VALUES_EQUAL(2, histogram->RefCount()); - - UNIT_ASSERT_VALUES_EQUAL(1, timeSeriesB.Size()); - UNIT_ASSERT_EQUAL(EMetricValueType::HISTOGRAM, timeSeriesB.GetValueType()); - - UNIT_ASSERT_VALUES_EQUAL(0, timeSeriesA.Size()); - UNIT_ASSERT_EQUAL(EMetricValueType::UNKNOWN, timeSeriesA.GetValueType()); - } - UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); - } - - Y_UNIT_TEST(HistogramsUnique) { - auto ts1 = TInstant::Now(); - auto ts2 = ts1 + TDuration::Seconds(1); - auto ts3 = ts2 + TDuration::Seconds(1); - - auto h1 = MakeIntrusive<TTestHistogram>(); - auto h2 = MakeIntrusive<TTestHistogram>(); - auto h3 = MakeIntrusive<TTestHistogram>(); - - UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); - UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); - UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); - - { - TMetricTimeSeries timeSeries; - timeSeries.Add(ts1, h1.Get()); // drop at the head - timeSeries.Add(ts1, h1.Get()); - timeSeries.Add(ts1, h1.Get()); - - timeSeries.Add(ts2, h2.Get()); // drop in the middle - timeSeries.Add(ts2, h2.Get()); - timeSeries.Add(ts2, h2.Get()); - - timeSeries.Add(ts3, h3.Get()); // drop at the end - timeSeries.Add(ts3, h3.Get()); - timeSeries.Add(ts3, h3.Get()); - - UNIT_ASSERT_EQUAL(timeSeries.Size(), 9); - - UNIT_ASSERT_VALUES_EQUAL(4, h1->RefCount()); - UNIT_ASSERT_VALUES_EQUAL(4, h2->RefCount()); - UNIT_ASSERT_VALUES_EQUAL(4, h3->RefCount()); - - timeSeries.SortByTs(); - UNIT_ASSERT_EQUAL(timeSeries.Size(), 3); - - UNIT_ASSERT_VALUES_EQUAL(2, h1->RefCount()); - UNIT_ASSERT_VALUES_EQUAL(2, h2->RefCount()); - UNIT_ASSERT_VALUES_EQUAL(2, h3->RefCount()); - } - - UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); - UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); - UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); - } + Y_UNIT_TEST(TimeSeriesMovable) { + auto ts = TInstant::Now(); + auto histogram = MakeIntrusive<TTestHistogram>(); + + UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); + { + TMetricTimeSeries timeSeriesA; + timeSeriesA.Add(ts, histogram.Get()); + UNIT_ASSERT_VALUES_EQUAL(2, histogram->RefCount()); + + TMetricTimeSeries timeSeriesB = std::move(timeSeriesA); + UNIT_ASSERT_VALUES_EQUAL(2, histogram->RefCount()); + + UNIT_ASSERT_VALUES_EQUAL(1, timeSeriesB.Size()); + UNIT_ASSERT_EQUAL(EMetricValueType::HISTOGRAM, timeSeriesB.GetValueType()); + + UNIT_ASSERT_VALUES_EQUAL(0, timeSeriesA.Size()); + UNIT_ASSERT_EQUAL(EMetricValueType::UNKNOWN, timeSeriesA.GetValueType()); + } + UNIT_ASSERT_VALUES_EQUAL(1, histogram->RefCount()); + } + + Y_UNIT_TEST(HistogramsUnique) { + auto ts1 = TInstant::Now(); + auto ts2 = ts1 + TDuration::Seconds(1); + auto ts3 = ts2 + TDuration::Seconds(1); + + auto h1 = MakeIntrusive<TTestHistogram>(); + auto h2 = MakeIntrusive<TTestHistogram>(); + auto h3 = MakeIntrusive<TTestHistogram>(); + + UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); + UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); + UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); + + { + TMetricTimeSeries timeSeries; + timeSeries.Add(ts1, h1.Get()); // drop at the head + timeSeries.Add(ts1, h1.Get()); + timeSeries.Add(ts1, h1.Get()); + + timeSeries.Add(ts2, h2.Get()); // drop in the middle + timeSeries.Add(ts2, h2.Get()); + timeSeries.Add(ts2, h2.Get()); + + timeSeries.Add(ts3, h3.Get()); // drop at the end + timeSeries.Add(ts3, h3.Get()); + timeSeries.Add(ts3, h3.Get()); + + UNIT_ASSERT_EQUAL(timeSeries.Size(), 9); + + UNIT_ASSERT_VALUES_EQUAL(4, h1->RefCount()); + UNIT_ASSERT_VALUES_EQUAL(4, h2->RefCount()); + UNIT_ASSERT_VALUES_EQUAL(4, h3->RefCount()); + + timeSeries.SortByTs(); + UNIT_ASSERT_EQUAL(timeSeries.Size(), 3); + + UNIT_ASSERT_VALUES_EQUAL(2, h1->RefCount()); + UNIT_ASSERT_VALUES_EQUAL(2, h2->RefCount()); + UNIT_ASSERT_VALUES_EQUAL(2, h3->RefCount()); + } + + UNIT_ASSERT_VALUES_EQUAL(1, h1->RefCount()); + UNIT_ASSERT_VALUES_EQUAL(1, h2->RefCount()); + UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); + } Y_UNIT_TEST(LogHistogramsUnique) { auto ts1 = TInstant::Now(); @@ -230,7 +230,7 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { UNIT_ASSERT_VALUES_EQUAL(1, h3->RefCount()); { - TMetricTimeSeries timeSeries; + TMetricTimeSeries timeSeries; timeSeries.Add(ts1, h1.Get()); // drop at the head timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts1, h1.Get()); @@ -278,7 +278,7 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { auto h7 = MakeIntrusive<TTestHistogram>(7u); { - TMetricTimeSeries timeSeries; + TMetricTimeSeries timeSeries; timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts1, h2.Get()); @@ -356,7 +356,7 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { auto h7 = MakeSummarySnapshot(7u); { - TMetricTimeSeries timeSeries; + TMetricTimeSeries timeSeries; timeSeries.Add(ts1, h1.Get()); timeSeries.Add(ts1, h2.Get()); @@ -379,27 +379,27 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { } } - Y_UNIT_TEST(TMetricValueWithType) { + Y_UNIT_TEST(TMetricValueWithType) { // correct usage { double value = 1.23; - TMetricValueWithType v{value}; + TMetricValueWithType v{value}; - UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::DOUBLE); + UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::DOUBLE); UNIT_ASSERT_VALUES_EQUAL(v.AsDouble(), value); } { ui64 value = 12; - TMetricValueWithType v{value}; + TMetricValueWithType v{value}; - UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::UINT64); + UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::UINT64); UNIT_ASSERT_VALUES_EQUAL(v.AsUint64(), value); } { i64 value = i64(-12); - TMetricValueWithType v{value}; + TMetricValueWithType v{value}; - UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::INT64); + UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::INT64); UNIT_ASSERT_VALUES_EQUAL(v.AsInt64(), value); } { @@ -408,11 +408,11 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { { auto value = h.Get(); - TMetricValueWithType v{value}; + TMetricValueWithType v{value}; UNIT_ASSERT_VALUES_EQUAL(h.RefCount(), 2); - UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::HISTOGRAM); + UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::HISTOGRAM); UNIT_ASSERT_VALUES_EQUAL(v.AsHistogram(), value); } @@ -425,11 +425,11 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); { - TMetricValueWithType v{value}; + TMetricValueWithType v{value}; UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); - UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::SUMMARY); + UNIT_ASSERT_VALUES_EQUAL(v.GetType(), EMetricValueType::SUMMARY); UNIT_ASSERT_VALUES_EQUAL(v.AsSummaryDouble(), value); } @@ -442,7 +442,7 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); { - TMetricValueWithType v{value}; + TMetricValueWithType v{value}; UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); @@ -457,19 +457,19 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { auto value = s.Get(); { - TMetricValueWithType v1{ui64{1}}; + TMetricValueWithType v1{ui64{1}}; UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 1); { - TMetricValueWithType v2{value}; + TMetricValueWithType v2{value}; UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); v1 = std::move(v2); UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); UNIT_ASSERT_VALUES_EQUAL(v1.AsSummaryDouble(), value); - UNIT_ASSERT_VALUES_EQUAL(v1.GetType(), EMetricValueType::SUMMARY); - UNIT_ASSERT_VALUES_EQUAL(v2.GetType(), EMetricValueType::UNKNOWN); + UNIT_ASSERT_VALUES_EQUAL(v1.GetType(), EMetricValueType::SUMMARY); + UNIT_ASSERT_VALUES_EQUAL(v2.GetType(), EMetricValueType::UNKNOWN); } UNIT_ASSERT_VALUES_EQUAL(s.RefCount(), 2); @@ -480,14 +480,14 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { // incorrect usage { - TMetricValueWithType v{1.23}; + TMetricValueWithType v{1.23}; UNIT_ASSERT_EXCEPTION(v.AsHistogram(), yexception); UNIT_ASSERT_EXCEPTION(v.AsSummaryDouble(), yexception); } { auto h = MakeHistogramSnapshot(); - TMetricValueWithType v{h.Get()}; + TMetricValueWithType v{h.Get()}; UNIT_ASSERT_EXCEPTION(v.AsUint64(), yexception); UNIT_ASSERT_EXCEPTION(v.AsInt64(), yexception); @@ -496,7 +496,7 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { } { auto s = MakeSummarySnapshot(); - TMetricValueWithType v{s.Get()}; + TMetricValueWithType v{s.Get()}; UNIT_ASSERT_EXCEPTION(v.AsUint64(), yexception); UNIT_ASSERT_EXCEPTION(v.AsInt64(), yexception); @@ -504,4 +504,4 @@ Y_UNIT_TEST_SUITE(TMetricValueTest) { UNIT_ASSERT_EXCEPTION(v.AsHistogram(), yexception); } } -} +} diff --git a/library/cpp/monlib/metrics/timer.h b/library/cpp/monlib/metrics/timer.h index 35d7824fac..5c4e26e37b 100644 --- a/library/cpp/monlib/metrics/timer.h +++ b/library/cpp/monlib/metrics/timer.h @@ -1,6 +1,6 @@ #pragma once -#include "metric.h" +#include "metric.h" #include <util/generic/typetraits.h> @@ -12,59 +12,59 @@ namespace NMonitoring { /** * A timing scope to record elapsed time since creation. */ - template <typename TMetric, + template <typename TMetric, typename Resolution = std::chrono::milliseconds, typename Clock = std::chrono::high_resolution_clock> - class TMetricTimerScope { + class TMetricTimerScope { public: - explicit TMetricTimerScope(TMetric* metric) - : Metric_(metric) + explicit TMetricTimerScope(TMetric* metric) + : Metric_(metric) , StartTime_(Clock::now()) { - Y_ENSURE(Metric_); + Y_ENSURE(Metric_); } - TMetricTimerScope(TMetricTimerScope&) = delete; - TMetricTimerScope& operator=(const TMetricTimerScope&) = delete; + TMetricTimerScope(TMetricTimerScope&) = delete; + TMetricTimerScope& operator=(const TMetricTimerScope&) = delete; - TMetricTimerScope(TMetricTimerScope&& other) { + TMetricTimerScope(TMetricTimerScope&& other) { *this = std::move(other); } - TMetricTimerScope& operator=(TMetricTimerScope&& other) { - Metric_ = other.Metric_; - other.Metric_ = nullptr; + TMetricTimerScope& operator=(TMetricTimerScope&& other) { + Metric_ = other.Metric_; + other.Metric_ = nullptr; StartTime_ = std::move(other.StartTime_); return *this; } void Record() { - Y_VERIFY_DEBUG(Metric_); - if (Metric_ == nullptr) { + Y_VERIFY_DEBUG(Metric_); + if (Metric_ == nullptr) { return; } auto duration = std::chrono::duration_cast<Resolution>(Clock::now() - StartTime_).count(); - if constexpr (std::is_same<TMetric, TGauge>::value) { - Metric_->Set(duration); - } else if constexpr (std::is_same<TMetric, TIntGauge>::value) { - Metric_->Set(duration); - } else if constexpr (std::is_same<TMetric, TCounter>::value) { - Metric_->Add(duration); - } else if constexpr (std::is_same<TMetric, TRate>::value) { - Metric_->Add(duration); - } else if constexpr (std::is_same<TMetric, THistogram>::value) { - Metric_->Record(duration); + if constexpr (std::is_same<TMetric, TGauge>::value) { + Metric_->Set(duration); + } else if constexpr (std::is_same<TMetric, TIntGauge>::value) { + Metric_->Set(duration); + } else if constexpr (std::is_same<TMetric, TCounter>::value) { + Metric_->Add(duration); + } else if constexpr (std::is_same<TMetric, TRate>::value) { + Metric_->Add(duration); + } else if constexpr (std::is_same<TMetric, THistogram>::value) { + Metric_->Record(duration); } else { static_assert(TDependentFalse<TMetric>, "Not supported metric type"); } - Metric_ = nullptr; + Metric_ = nullptr; } - ~TMetricTimerScope() { - if (Metric_ == nullptr) { + ~TMetricTimerScope() { + if (Metric_ == nullptr) { return; } @@ -72,7 +72,7 @@ namespace NMonitoring { } private: - TMetric* Metric_{nullptr}; + TMetric* Metric_{nullptr}; typename Clock::time_point StartTime_; }; @@ -80,18 +80,18 @@ namespace NMonitoring { * @brief A class that is supposed to use to measure execution time of an asynchronuous operation. * * In order to be able to capture an object into a lambda which is then passed to TFuture::Subscribe/Apply, - * the object must be copy constructible (limitation of the std::function class). So, we cannot use the TMetricTimerScope + * the object must be copy constructible (limitation of the std::function class). So, we cannot use the TMetricTimerScope * with the abovementioned functions without storing it in a shared pointer or somewhere else. This class works around this * issue with wrapping the timer with a auto_ptr-like hack Also, Record is const so that one doesn't need to make every lambda mutable * just to record time measurement. */ - template <typename TMetric, + template <typename TMetric, typename Resolution = std::chrono::milliseconds, typename Clock = std::chrono::high_resolution_clock> class TFutureFriendlyTimer { public: - explicit TFutureFriendlyTimer(TMetric* metric) - : Impl_{metric} + explicit TFutureFriendlyTimer(TMetric* metric) + : Impl_{metric} { } @@ -112,16 +112,16 @@ namespace NMonitoring { } private: - mutable TMetricTimerScope<TMetric, Resolution, Clock> Impl_; + mutable TMetricTimerScope<TMetric, Resolution, Clock> Impl_; }; - template <typename TMetric> - TMetricTimerScope<TMetric> ScopeTimer(TMetric* metric) { - return TMetricTimerScope<TMetric>{metric}; + template <typename TMetric> + TMetricTimerScope<TMetric> ScopeTimer(TMetric* metric) { + return TMetricTimerScope<TMetric>{metric}; } - template <typename TMetric> - TFutureFriendlyTimer<TMetric> FutureTimer(TMetric* metric) { - return TFutureFriendlyTimer<TMetric>{metric}; + template <typename TMetric> + TFutureFriendlyTimer<TMetric> FutureTimer(TMetric* metric) { + return TFutureFriendlyTimer<TMetric>{metric}; } } diff --git a/library/cpp/monlib/metrics/timer_ut.cpp b/library/cpp/monlib/metrics/timer_ut.cpp index f72c965fee..c244a8c9e1 100644 --- a/library/cpp/monlib/metrics/timer_ut.cpp +++ b/library/cpp/monlib/metrics/timer_ut.cpp @@ -29,13 +29,13 @@ Y_UNIT_TEST_SUITE(TTimerTest) { TGauge gauge(0); { - TMetricTimerScope<TGauge, milliseconds, TTestClock> t{&gauge}; + TMetricTimerScope<TGauge, milliseconds, TTestClock> t{&gauge}; TTestClock::TimePoint += milliseconds(10); } UNIT_ASSERT_EQUAL(10, gauge.Get()); { - TMetricTimerScope<TGauge, milliseconds, TTestClock> t{&gauge}; + TMetricTimerScope<TGauge, milliseconds, TTestClock> t{&gauge}; TTestClock::TimePoint += milliseconds(20); } UNIT_ASSERT_EQUAL(20, gauge.Get()); @@ -46,13 +46,13 @@ Y_UNIT_TEST_SUITE(TTimerTest) { TIntGauge gauge(0); { - TMetricTimerScope<TIntGauge, milliseconds, TTestClock> t{&gauge}; + TMetricTimerScope<TIntGauge, milliseconds, TTestClock> t{&gauge}; TTestClock::TimePoint += milliseconds(10); } UNIT_ASSERT_EQUAL(10, gauge.Get()); { - TMetricTimerScope<TIntGauge, milliseconds, TTestClock> t{&gauge}; + TMetricTimerScope<TIntGauge, milliseconds, TTestClock> t{&gauge}; TTestClock::TimePoint += milliseconds(20); } UNIT_ASSERT_EQUAL(20, gauge.Get()); @@ -61,15 +61,15 @@ Y_UNIT_TEST_SUITE(TTimerTest) { Y_UNIT_TEST(CounterNew) { TTestClock::TimePoint = TTestClock::time_point::min(); - TCounter counter(0); + TCounter counter(0); { - TMetricTimerScope<TCounter, milliseconds, TTestClock> t{&counter}; + TMetricTimerScope<TCounter, milliseconds, TTestClock> t{&counter}; TTestClock::TimePoint += milliseconds(10); } UNIT_ASSERT_EQUAL(10, counter.Get()); { - TMetricTimerScope<TCounter, milliseconds, TTestClock> t{&counter}; + TMetricTimerScope<TCounter, milliseconds, TTestClock> t{&counter}; TTestClock::TimePoint += milliseconds(20); } UNIT_ASSERT_EQUAL(30, counter.Get()); @@ -80,13 +80,13 @@ Y_UNIT_TEST_SUITE(TTimerTest) { TRate rate(0); { - TMetricTimerScope<TRate, milliseconds, TTestClock> t{&rate}; + TMetricTimerScope<TRate, milliseconds, TTestClock> t{&rate}; TTestClock::TimePoint += milliseconds(10); } UNIT_ASSERT_EQUAL(10, rate.Get()); { - TMetricTimerScope<TRate, milliseconds, TTestClock> t{&rate}; + TMetricTimerScope<TRate, milliseconds, TTestClock> t{&rate}; TTestClock::TimePoint += milliseconds(20); } UNIT_ASSERT_EQUAL(30, rate.Get()); @@ -104,13 +104,13 @@ Y_UNIT_TEST_SUITE(TTimerTest) { THistogram histogram(ExplicitHistogram({10, 20, 30}), true); { - TMetricTimerScope<THistogram, milliseconds, TTestClock> t{&histogram}; + TMetricTimerScope<THistogram, milliseconds, TTestClock> t{&histogram}; TTestClock::TimePoint += milliseconds(5); } assertHistogram({1, 0, 0, 0}, histogram.TakeSnapshot()); { - TMetricTimerScope<THistogram, milliseconds, TTestClock> t{&histogram}; + TMetricTimerScope<THistogram, milliseconds, TTestClock> t{&histogram}; TTestClock::TimePoint += milliseconds(15); } assertHistogram({1, 1, 0, 0}, histogram.TakeSnapshot()); @@ -119,9 +119,9 @@ Y_UNIT_TEST_SUITE(TTimerTest) { Y_UNIT_TEST(Moving) { TTestClock::TimePoint = TTestClock::time_point::min(); - TCounter counter(0); + TCounter counter(0); { - TMetricTimerScope<TCounter, milliseconds, TTestClock> t{&counter}; + TMetricTimerScope<TCounter, milliseconds, TTestClock> t{&counter}; [tt = std::move(t)] { TTestClock::TimePoint += milliseconds(5); Y_UNUSED(tt); @@ -137,9 +137,9 @@ Y_UNIT_TEST_SUITE(TTimerTest) { TTestClock::TimePoint = TTestClock::time_point::min(); auto pool = CreateThreadPool(1); - TCounter counter(0); + TCounter counter(0); { - TFutureFriendlyTimer<TCounter, milliseconds, TTestClock> t{&counter}; + TFutureFriendlyTimer<TCounter, milliseconds, TTestClock> t{&counter}; auto f = Async([=] { return; diff --git a/library/cpp/monlib/metrics/ut/histograms.json b/library/cpp/monlib/metrics/ut/histograms.json index 074273cfc4..a6e8b78fea 100644 --- a/library/cpp/monlib/metrics/ut/histograms.json +++ b/library/cpp/monlib/metrics/ut/histograms.json @@ -1,61 +1,61 @@ -{ - "commonLabels": - { - "common":"label" - }, - "sensors": - [ - { - "kind":"HIST", - "labels": - { - "sensor":"readTimeMillis" - }, - "hist": - { - "bounds": - [ - 1, - 2, - 4, - 8 - ], - "buckets": - [ - 2, - 1, - 2, - 4 - ], - "inf":91 - } - }, - { - "kind":"HIST_RATE", - "labels": - { - "sensor":"writeTimeMillis" - }, - "hist": - { - "bounds": - [ - 1, - 5, - 15, - 20, - 25 - ], - "buckets": - [ - 2, - 4, - 10, - 5, - 5 - ], - "inf":74 - } - } - ] -} +{ + "commonLabels": + { + "common":"label" + }, + "sensors": + [ + { + "kind":"HIST", + "labels": + { + "sensor":"readTimeMillis" + }, + "hist": + { + "bounds": + [ + 1, + 2, + 4, + 8 + ], + "buckets": + [ + 2, + 1, + 2, + 4 + ], + "inf":91 + } + }, + { + "kind":"HIST_RATE", + "labels": + { + "sensor":"writeTimeMillis" + }, + "hist": + { + "bounds": + [ + 1, + 5, + 15, + 20, + 25 + ], + "buckets": + [ + 2, + 4, + 10, + 5, + 5 + ], + "inf":74 + } + } + ] +} diff --git a/library/cpp/monlib/metrics/ut/ya.make b/library/cpp/monlib/metrics/ut/ya.make index 2f57822c05..aec9974fbd 100644 --- a/library/cpp/monlib/metrics/ut/ya.make +++ b/library/cpp/monlib/metrics/ut/ya.make @@ -1,32 +1,32 @@ -UNITTEST_FOR(library/cpp/monlib/metrics) - +UNITTEST_FOR(library/cpp/monlib/metrics) + OWNER( jamel g:solomon ) - -SRCS( - ewma_ut.cpp - fake_ut.cpp - histogram_collector_ut.cpp - labels_ut.cpp + +SRCS( + ewma_ut.cpp + fake_ut.cpp + histogram_collector_ut.cpp + labels_ut.cpp log_histogram_collector_ut.cpp - metric_registry_ut.cpp - metric_sub_registry_ut.cpp - metric_value_ut.cpp - summary_collector_ut.cpp + metric_registry_ut.cpp + metric_sub_registry_ut.cpp + metric_value_ut.cpp + summary_collector_ut.cpp timer_ut.cpp -) - -RESOURCE( - histograms.json /histograms.json -) - -PEERDIR( +) + +RESOURCE( + histograms.json /histograms.json +) + +PEERDIR( library/cpp/resource - library/cpp/monlib/encode/protobuf - library/cpp/monlib/encode/json + library/cpp/monlib/encode/protobuf + library/cpp/monlib/encode/json library/cpp/threading/future -) - -END() +) + +END() diff --git a/library/cpp/monlib/metrics/ya.make b/library/cpp/monlib/metrics/ya.make index a4bacb0180..0e1fa143f9 100644 --- a/library/cpp/monlib/metrics/ya.make +++ b/library/cpp/monlib/metrics/ya.make @@ -1,26 +1,26 @@ -LIBRARY() - +LIBRARY() + OWNER( g:solomon jamel ) - -GENERATE_ENUM_SERIALIZATION_WITH_HEADER(metric_value_type.h) -SRCS( - ewma.cpp - fake.cpp - histogram_collector_explicit.cpp - histogram_collector_exponential.cpp - histogram_collector_linear.cpp - histogram_snapshot.cpp +GENERATE_ENUM_SERIALIZATION_WITH_HEADER(metric_value_type.h) + +SRCS( + ewma.cpp + fake.cpp + histogram_collector_explicit.cpp + histogram_collector_exponential.cpp + histogram_collector_linear.cpp + histogram_snapshot.cpp log_histogram_snapshot.cpp - labels.cpp - metric_registry.cpp + labels.cpp + metric_registry.cpp metric_consumer.cpp - metric_type.cpp - metric_value.cpp - summary_snapshot.cpp -) - -END() + metric_type.cpp + metric_value.cpp + summary_snapshot.cpp +) + +END() diff --git a/library/cpp/monlib/service/auth/tvm/auth.cpp b/library/cpp/monlib/service/auth/tvm/auth.cpp index 22f126eaad..e071c11ebc 100644 --- a/library/cpp/monlib/service/auth/tvm/auth.cpp +++ b/library/cpp/monlib/service/auth/tvm/auth.cpp @@ -33,7 +33,7 @@ namespace { return AllowedClients_.contains(clientId); } - TCheckedServiceTicket CheckServiceTicket(TStringBuf ticket) override { + TCheckedServiceTicket CheckServiceTicket(TStringBuf ticket) override { return Tvm_->CheckServiceTicket(ticket); } diff --git a/library/cpp/monlib/service/auth/tvm/auth.h b/library/cpp/monlib/service/auth/tvm/auth.h index e9b71ef2d8..432beff9d6 100644 --- a/library/cpp/monlib/service/auth/tvm/auth.h +++ b/library/cpp/monlib/service/auth/tvm/auth.h @@ -8,7 +8,7 @@ namespace NMonitoring { struct ITvmManager { virtual ~ITvmManager() = default; virtual bool IsAllowedClient(NTvmAuth::TTvmId clientId) = 0; - virtual NTvmAuth::TCheckedServiceTicket CheckServiceTicket(TStringBuf ticket) = 0; + virtual NTvmAuth::TCheckedServiceTicket CheckServiceTicket(TStringBuf ticket) = 0; }; THolder<ITvmManager> CreateDefaultTvmManager( diff --git a/library/cpp/monlib/service/format.h b/library/cpp/monlib/service/format.h index 16b6c12c48..0044b586b1 100644 --- a/library/cpp/monlib/service/format.h +++ b/library/cpp/monlib/service/format.h @@ -1,6 +1,6 @@ #pragma once -#include <library/cpp/monlib/encode/format.h> +#include <library/cpp/monlib/encode/format.h> #include <util/string/ascii.h> #include <util/generic/yexception.h> diff --git a/library/cpp/monlib/service/mon_service_http_request.cpp b/library/cpp/monlib/service/mon_service_http_request.cpp index a0164afaec..5d805631d9 100644 --- a/library/cpp/monlib/service/mon_service_http_request.cpp +++ b/library/cpp/monlib/service/mon_service_http_request.cpp @@ -1,4 +1,4 @@ -#include "mon_service_http_request.h" +#include "mon_service_http_request.h" #include "monservice.h" using namespace NMonitoring; diff --git a/library/cpp/monlib/service/mon_service_http_request.h b/library/cpp/monlib/service/mon_service_http_request.h index 80fce27675..b4f2f8f0c5 100644 --- a/library/cpp/monlib/service/mon_service_http_request.h +++ b/library/cpp/monlib/service/mon_service_http_request.h @@ -1,12 +1,12 @@ #pragma once -#include "service.h" - +#include "service.h" + #include <util/stream/output.h> namespace NMonitoring { - class TMonService2; - class IMonPage; + class TMonService2; + class IMonPage; // XXX: IHttpRequest is already taken struct IMonHttpRequest { @@ -34,26 +34,26 @@ namespace NMonitoring { }; struct TMonService2HttpRequest: IMonHttpRequest { - IOutputStream* const Out; - const IHttpRequest* const HttpRequest; - TMonService2* const MonService; - IMonPage* const MonPage; - const TString PathInfo; - TMonService2HttpRequest* const Parent; - - TMonService2HttpRequest( + IOutputStream* const Out; + const IHttpRequest* const HttpRequest; + TMonService2* const MonService; + IMonPage* const MonPage; + const TString PathInfo; + TMonService2HttpRequest* const Parent; + + TMonService2HttpRequest( IOutputStream* out, const IHttpRequest* httpRequest, TMonService2* monService, IMonPage* monPage, const TString& pathInfo, TMonService2HttpRequest* parent) - : Out(out) - , HttpRequest(httpRequest) - , MonService(monService) - , MonPage(monPage) - , PathInfo(pathInfo) - , Parent(parent) - { - } + : Out(out) + , HttpRequest(httpRequest) + , MonService(monService) + , MonPage(monPage) + , PathInfo(pathInfo) + , Parent(parent) + { + } ~TMonService2HttpRequest() override; @@ -85,6 +85,6 @@ namespace NMonitoring { } TString GetServiceTitle() const override; - }; + }; -} +} diff --git a/library/cpp/monlib/service/monservice.cpp b/library/cpp/monlib/service/monservice.cpp index 5c8fd6aaea..d1b9cda1d2 100644 --- a/library/cpp/monlib/service/monservice.cpp +++ b/library/cpp/monlib/service/monservice.cpp @@ -1,21 +1,21 @@ #include "monservice.h" - + #include <library/cpp/malloc/api/malloc.h> #include <library/cpp/string_utils/base64/base64.h> #include <library/cpp/svnversion/svnversion.h> - + #include <util/generic/map.h> #include <util/generic/ptr.h> #include <util/system/hostname.h> - + #include <google/protobuf/text_format.h> using namespace NMonitoring; TMonService2::TMonService2(ui16 port, const TString& host, ui32 threads, const TString& title, THolder<IAuthProvider> auth) : TMonService2(HttpServerOptions(port, host, threads), title, std::move(auth)) -{ -} +{ +} TMonService2::TMonService2(const THttpServerOptions& options, const TString& title, THolder<IAuthProvider> auth) : NMonitoring::TMtHttpServer(options, std::bind(&TMonService2::ServeRequest, this, std::placeholders::_1, std::placeholders::_2)) @@ -46,14 +46,14 @@ TMonService2::TMonService2(ui16 port, ui32 threads, const TString& title, THolde TMonService2::TMonService2(ui16 port, const TString& title, THolder<IAuthProvider> auth) : TMonService2(port, TString(), 0, title, std::move(auth)) -{ -} +{ +} -void TMonService2::OutputIndex(IOutputStream& out) { +void TMonService2::OutputIndex(IOutputStream& out) { IndexMonPage->OutputIndex(out, true); } -void TMonService2::OutputIndexPage(IOutputStream& out) { +void TMonService2::OutputIndexPage(IOutputStream& out) { out << HTTPOKHTML; out << "<html>\n"; IndexMonPage->OutputHead(out); @@ -61,7 +61,7 @@ void TMonService2::OutputIndexPage(IOutputStream& out) { out << "</html>\n"; } -void TMonService2::OutputIndexBody(IOutputStream& out) { +void TMonService2::OutputIndexBody(IOutputStream& out) { out << "<body>\n"; // part of common navbar @@ -77,7 +77,7 @@ void TMonService2::OutputIndexBody(IOutputStream& out) { << "</body>\n"; } -void TMonService2::ServeRequest(IOutputStream& out, const NMonitoring::IHttpRequest& request) { +void TMonService2::ServeRequest(IOutputStream& out, const NMonitoring::IHttpRequest& request) { TString path = request.GetPath(); Y_VERIFY(path.StartsWith('/')); @@ -99,12 +99,12 @@ void TMonService2::ServeRequest(IOutputStream& out, const NMonitoring::IHttpRequ OutputIndexPage(out); } else { TMonService2HttpRequest monService2HttpRequest( - &out, &request, this, IndexMonPage.Get(), path, nullptr); + &out, &request, this, IndexMonPage.Get(), path, nullptr); IndexMonPage->Output(monService2HttpRequest); } } -void TMonService2::Register(IMonPage* page) { +void TMonService2::Register(IMonPage* page) { IndexMonPage->Register(page); } diff --git a/library/cpp/monlib/service/monservice.h b/library/cpp/monlib/service/monservice.h index 492bd9bec7..8f5e52fcdb 100644 --- a/library/cpp/monlib/service/monservice.h +++ b/library/cpp/monlib/service/monservice.h @@ -1,73 +1,73 @@ #pragma once -#include "service.h" +#include "service.h" #include "auth.h" -#include "mon_service_http_request.h" - -#include <library/cpp/monlib/service/pages/index_mon_page.h> -#include <library/cpp/monlib/service/pages/mon_page.h> - +#include "mon_service_http_request.h" + +#include <library/cpp/monlib/service/pages/index_mon_page.h> +#include <library/cpp/monlib/service/pages/mon_page.h> + #include <util/system/progname.h> - + #include <functional> namespace NMonitoring { - class TMonService2: public TMtHttpServer { - protected: - const TString Title; - char StartTime[26]; - TIntrusivePtr<TIndexMonPage> IndexMonPage; + class TMonService2: public TMtHttpServer { + protected: + const TString Title; + char StartTime[26]; + TIntrusivePtr<TIndexMonPage> IndexMonPage; THolder<IAuthProvider> AuthProvider_; - public: + public: static THttpServerOptions HttpServerOptions(ui16 port, const TString& host, ui32 threads) { - THttpServerOptions opts(port); + THttpServerOptions opts(port); if (!host.empty()) { opts.SetHost(host); } - opts.SetClientTimeout(TDuration::Minutes(1)); - opts.EnableCompression(true); - opts.SetThreads(threads); + opts.SetClientTimeout(TDuration::Minutes(1)); + opts.EnableCompression(true); + opts.SetThreads(threads); opts.SetMaxConnections(std::max<ui32>(100, threads)); opts.EnableRejectExcessConnections(true); - return opts; - } + return opts; + } static THttpServerOptions HttpServerOptions(ui16 port, ui32 threads) { return HttpServerOptions(port, TString(), threads); } - public: + public: explicit TMonService2(ui16 port, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr); explicit TMonService2(ui16 port, ui32 threads, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr); explicit TMonService2(ui16 port, const TString& host, ui32 threads, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr); explicit TMonService2(const THttpServerOptions& options, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr); explicit TMonService2(const THttpServerOptions& options, TSimpleSharedPtr<IThreadPool> pool, const TString& title = GetProgramName(), THolder<IAuthProvider> auth = nullptr); - ~TMonService2() override { - } + ~TMonService2() override { + } - const char* GetStartTime() const { - return StartTime; - } + const char* GetStartTime() const { + return StartTime; + } - const TString& GetTitle() const { - return Title; - } + const TString& GetTitle() const { + return Title; + } - virtual void ServeRequest(IOutputStream& out, const NMonitoring::IHttpRequest& request); - virtual void OutputIndex(IOutputStream& out); - virtual void OutputIndexPage(IOutputStream& out); - virtual void OutputIndexBody(IOutputStream& out); + virtual void ServeRequest(IOutputStream& out, const NMonitoring::IHttpRequest& request); + virtual void OutputIndex(IOutputStream& out); + virtual void OutputIndexPage(IOutputStream& out); + virtual void OutputIndexBody(IOutputStream& out); - void Register(IMonPage* page); + void Register(IMonPage* page); void Register(TMonPagePtr page); - TIndexMonPage* RegisterIndexPage(const TString& path, const TString& title); + TIndexMonPage* RegisterIndexPage(const TString& path, const TString& title); - IMonPage* FindPage(const TString& relativePath); - TIndexMonPage* FindIndexPage(const TString& relativePath); - void SortPages(); - }; + IMonPage* FindPage(const TString& relativePath); + TIndexMonPage* FindIndexPage(const TString& relativePath); + void SortPages(); + }; -} +} diff --git a/library/cpp/monlib/service/pages/diag_mon_page.h b/library/cpp/monlib/service/pages/diag_mon_page.h index 2d90d5850d..761194d4ec 100644 --- a/library/cpp/monlib/service/pages/diag_mon_page.h +++ b/library/cpp/monlib/service/pages/diag_mon_page.h @@ -3,14 +3,14 @@ #include "pre_mon_page.h" namespace NMonitoring { - // internal diagnostics page - struct TDiagMonPage: public TPreMonPage { - TDiagMonPage() - : TPreMonPage("diag", "Diagnostics Page") - { - } + // internal diagnostics page + struct TDiagMonPage: public TPreMonPage { + TDiagMonPage() + : TPreMonPage("diag", "Diagnostics Page") + { + } void OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) override; - }; + }; -} +} diff --git a/library/cpp/monlib/service/pages/html_mon_page.cpp b/library/cpp/monlib/service/pages/html_mon_page.cpp index 8c178e135f..eb4eb3b66c 100644 --- a/library/cpp/monlib/service/pages/html_mon_page.cpp +++ b/library/cpp/monlib/service/pages/html_mon_page.cpp @@ -1,6 +1,6 @@ #include "html_mon_page.h" -#include <library/cpp/monlib/service/pages/templates.h> +#include <library/cpp/monlib/service/pages/templates.h> using namespace NMonitoring; @@ -20,8 +20,8 @@ void THtmlMonPage::Output(NMonitoring::IMonHttpRequest& request) { out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n"; if (OutputTableSorterJsCss) { - out << "<link rel='stylesheet' href='/jquery.tablesorter.css'>\n"; - out << "<script language='javascript' type='text/javascript' src='/jquery.tablesorter.js'></script>\n"; + out << "<link rel='stylesheet' href='/jquery.tablesorter.css'>\n"; + out << "<script language='javascript' type='text/javascript' src='/jquery.tablesorter.js'></script>\n"; } out << "<style type=\"text/css\">\n"; @@ -34,7 +34,7 @@ void THtmlMonPage::Output(NMonitoring::IMonHttpRequest& request) { out << "</style>\n"; } BODY() { - OutputNavBar(out); + OutputNavBar(out); DIV_CLASS("container") { if (!!Title) { diff --git a/library/cpp/monlib/service/pages/html_mon_page.h b/library/cpp/monlib/service/pages/html_mon_page.h index 305af355cb..e87c53b62b 100644 --- a/library/cpp/monlib/service/pages/html_mon_page.h +++ b/library/cpp/monlib/service/pages/html_mon_page.h @@ -3,14 +3,14 @@ #include "mon_page.h" namespace NMonitoring { - struct THtmlMonPage: public IMonPage { - THtmlMonPage(const TString& path, - const TString& title = TString(), - bool outputTableSorterJsCss = false) + struct THtmlMonPage: public IMonPage { + THtmlMonPage(const TString& path, + const TString& title = TString(), + bool outputTableSorterJsCss = false) : IMonPage(path, title) - , OutputTableSorterJsCss(outputTableSorterJsCss) - { - } + , OutputTableSorterJsCss(outputTableSorterJsCss) + { + } void Output(NMonitoring::IMonHttpRequest& request) override; @@ -19,7 +19,7 @@ namespace NMonitoring { virtual void OutputContent(NMonitoring::IMonHttpRequest& request) = 0; - bool OutputTableSorterJsCss; - }; + bool OutputTableSorterJsCss; + }; -} +} diff --git a/library/cpp/monlib/service/pages/index_mon_page.cpp b/library/cpp/monlib/service/pages/index_mon_page.cpp index 65f6c1ea59..83ff8b529a 100644 --- a/library/cpp/monlib/service/pages/index_mon_page.cpp +++ b/library/cpp/monlib/service/pages/index_mon_page.cpp @@ -1,7 +1,7 @@ -#include "index_mon_page.h" - +#include "index_mon_page.h" + #include <util/generic/cast.h> -#include <util/string/ascii.h> +#include <util/string/ascii.h> using namespace NMonitoring; @@ -51,7 +51,7 @@ void TIndexMonPage::Output(IMonHttpRequest& request) { } } -void TIndexMonPage::OutputIndex(IOutputStream& out, bool pathEndsWithSlash) { +void TIndexMonPage::OutputIndex(IOutputStream& out, bool pathEndsWithSlash) { TGuard<TMutex> g(Mtx); for (auto& Page : Pages) { IMonPage* page = Page.Get(); @@ -65,7 +65,7 @@ void TIndexMonPage::OutputIndex(IOutputStream& out, bool pathEndsWithSlash) { } } -void TIndexMonPage::Register(TMonPagePtr page) { +void TIndexMonPage::Register(TMonPagePtr page) { TGuard<TMutex> g(Mtx); auto insres = PagesByPath.insert(std::make_pair("/" + page->GetPath(), page)); if (insres.second) { @@ -80,10 +80,10 @@ void TIndexMonPage::Register(TMonPagePtr page) { // this already present, replace it insres.first->second = page; } - page->Parent = this; + page->Parent = this; } -TIndexMonPage* TIndexMonPage::RegisterIndexPage(const TString& path, const TString& title) { +TIndexMonPage* TIndexMonPage::RegisterIndexPage(const TString& path, const TString& title) { TGuard<TMutex> g(Mtx); TIndexMonPage* page = VerifyDynamicCast<TIndexMonPage*>(FindPage(path)); if (page) { @@ -116,7 +116,7 @@ void TIndexMonPage::OutputCommonJsCss(IOutputStream& out) { out << "<script language='javascript' type='text/javascript' src='https://yastatic.net/bootstrap/3.3.1/js/bootstrap.min.js'></script>\n"; } -void TIndexMonPage::OutputHead(IOutputStream& out) { +void TIndexMonPage::OutputHead(IOutputStream& out) { out << "<head>\n"; OutputCommonJsCss(out); out << "<title>" << Title << "</title>\n"; @@ -128,19 +128,19 @@ void TIndexMonPage::OutputBody(IMonHttpRequest& req) { out << "<body>\n"; // part of common navbar - OutputNavBar(out); + OutputNavBar(out); out << "<div class='container'>\n" - << "<h2>" << Title << "</h2>\n"; + << "<h2>" << Title << "</h2>\n"; OutputIndex(out, req.GetPathInfo().EndsWith('/')); out << "<div>\n" << "</body>\n"; } -void TIndexMonPage::SortPages() { +void TIndexMonPage::SortPages() { TGuard<TMutex> g(Mtx); std::sort(Pages.begin(), Pages.end(), [](const TMonPagePtr& a, const TMonPagePtr& b) { - return AsciiCompareIgnoreCase(a->GetTitle(), b->GetTitle()) < 0; + return AsciiCompareIgnoreCase(a->GetTitle(), b->GetTitle()) < 0; }); } diff --git a/library/cpp/monlib/service/pages/index_mon_page.h b/library/cpp/monlib/service/pages/index_mon_page.h index 6831fd15ca..bf514a3105 100644 --- a/library/cpp/monlib/service/pages/index_mon_page.h +++ b/library/cpp/monlib/service/pages/index_mon_page.h @@ -3,36 +3,36 @@ #include "mon_page.h" namespace NMonitoring { - struct TIndexMonPage: public IMonPage { - TMutex Mtx; - typedef TVector<TMonPagePtr> TPages; - TPages Pages; - typedef THashMap<TString, TMonPagePtr> TPagesByPath; - TPagesByPath PagesByPath; + struct TIndexMonPage: public IMonPage { + TMutex Mtx; + typedef TVector<TMonPagePtr> TPages; + TPages Pages; + typedef THashMap<TString, TMonPagePtr> TPagesByPath; + TPagesByPath PagesByPath; - TIndexMonPage(const TString& path, const TString& title) - : IMonPage(path, title) - { - } + TIndexMonPage(const TString& path, const TString& title) + : IMonPage(path, title) + { + } - ~TIndexMonPage() override { - } + ~TIndexMonPage() override { + } void Output(IMonHttpRequest& request) override; void OutputIndexPage(IMonHttpRequest& request); - virtual void OutputIndex(IOutputStream& out, bool pathEndsWithSlash); - virtual void OutputCommonJsCss(IOutputStream& out); - void OutputHead(IOutputStream& out); + virtual void OutputIndex(IOutputStream& out, bool pathEndsWithSlash); + virtual void OutputCommonJsCss(IOutputStream& out); + void OutputHead(IOutputStream& out); void OutputBody(IMonHttpRequest& out); - void Register(TMonPagePtr page); - TIndexMonPage* RegisterIndexPage(const TString& path, const TString& title); + void Register(TMonPagePtr page); + TIndexMonPage* RegisterIndexPage(const TString& path, const TString& title); - IMonPage* FindPage(const TString& relativePath); - TIndexMonPage* FindIndexPage(const TString& relativePath); + IMonPage* FindPage(const TString& relativePath); + TIndexMonPage* FindIndexPage(const TString& relativePath); - void SortPages(); + void SortPages(); void ClearPages(); - }; + }; -} +} diff --git a/library/cpp/monlib/service/pages/mon_page.cpp b/library/cpp/monlib/service/pages/mon_page.cpp index 1bffd42027..72033b1699 100644 --- a/library/cpp/monlib/service/pages/mon_page.cpp +++ b/library/cpp/monlib/service/pages/mon_page.cpp @@ -9,28 +9,28 @@ IMonPage::IMonPage(const TString& path, const TString& title) Y_VERIFY(!Path.StartsWith('/')); Y_VERIFY(!Path.EndsWith('/')); } - -void IMonPage::OutputNavBar(IOutputStream& out) { - TVector<const IMonPage*> parents; - for (const IMonPage* p = this; p; p = p->Parent) { - parents.push_back(p); - } - std::reverse(parents.begin(), parents.end()); - - out << "<ol class='breadcrumb'>\n"; - - TString absolutePath; - for (size_t i = 0; i < parents.size(); ++i) { - const TString& title = parents[i]->GetTitle(); - if (i == parents.size() - 1) { - out << "<li>" << title << "</li>\n"; - } else { - if (!absolutePath.EndsWith('/')) { - absolutePath += '/'; - } - absolutePath += parents[i]->GetPath(); - out << "<li class='active'><a href='" << absolutePath << "'>" << title << "</a></li>\n"; - } - } - out << "</ol>\n"; -} + +void IMonPage::OutputNavBar(IOutputStream& out) { + TVector<const IMonPage*> parents; + for (const IMonPage* p = this; p; p = p->Parent) { + parents.push_back(p); + } + std::reverse(parents.begin(), parents.end()); + + out << "<ol class='breadcrumb'>\n"; + + TString absolutePath; + for (size_t i = 0; i < parents.size(); ++i) { + const TString& title = parents[i]->GetTitle(); + if (i == parents.size() - 1) { + out << "<li>" << title << "</li>\n"; + } else { + if (!absolutePath.EndsWith('/')) { + absolutePath += '/'; + } + absolutePath += parents[i]->GetPath(); + out << "<li class='active'><a href='" << absolutePath << "'>" << title << "</a></li>\n"; + } + } + out << "</ol>\n"; +} diff --git a/library/cpp/monlib/service/pages/mon_page.h b/library/cpp/monlib/service/pages/mon_page.h index da151e5255..e396612bb0 100644 --- a/library/cpp/monlib/service/pages/mon_page.h +++ b/library/cpp/monlib/service/pages/mon_page.h @@ -1,66 +1,66 @@ #pragma once -#include <library/cpp/monlib/service/service.h> -#include <library/cpp/monlib/service/mon_service_http_request.h> - +#include <library/cpp/monlib/service/service.h> +#include <library/cpp/monlib/service/mon_service_http_request.h> + #include <util/generic/string.h> #include <util/generic/ptr.h> namespace NMonitoring { - static const char HTTPOKTEXT[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/plain\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKBIN[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/octet-stream\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKHTML[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKJSON[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/json\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKSPACK[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/x-solomon-spack\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKTEXT[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/plain\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKBIN[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/octet-stream\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKHTML[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKJSON[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/json\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKSPACK[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/x-solomon-spack\r\nConnection: Close\r\n\r\n"; static const char HTTPOKPROMETHEUS[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/plain\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKJAVASCRIPT[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/javascript\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKCSS[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/css\r\nConnection: Close\r\n\r\n"; - static const char HTTPNOCONTENT[] = "HTTP/1.1 204 No content\r\nConnection: Close\r\n\r\n"; - static const char HTTPNOTFOUND[] = "HTTP/1.1 404 Invalid URI\r\nConnection: Close\r\n\r\nInvalid URL\r\n"; + static const char HTTPOKJAVASCRIPT[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/javascript\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKCSS[] = "HTTP/1.1 200 Ok\r\nContent-Type: text/css\r\nConnection: Close\r\n\r\n"; + static const char HTTPNOCONTENT[] = "HTTP/1.1 204 No content\r\nConnection: Close\r\n\r\n"; + static const char HTTPNOTFOUND[] = "HTTP/1.1 404 Invalid URI\r\nConnection: Close\r\n\r\nInvalid URL\r\n"; static const char HTTPUNAUTHORIZED[] = "HTTP/1.1 401 Unauthorized\r\nConnection: Close\r\n\r\nUnauthorized\r\n"; static const char HTTPFORBIDDEN[] = "HTTP/1.1 403 Forbidden\r\nConnection: Close\r\n\r\nForbidden\r\n"; - // Fonts - static const char HTTPOKFONTEOT[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/vnd.ms-fontobject\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKFONTTTF[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/x-font-ttf\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKFONTWOFF[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/font-woff\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKFONTWOFF2[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/font-woff2\r\nConnection: Close\r\n\r\n"; + // Fonts + static const char HTTPOKFONTEOT[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/vnd.ms-fontobject\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKFONTTTF[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/x-font-ttf\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKFONTWOFF[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/font-woff\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKFONTWOFF2[] = "HTTP/1.1 200 Ok\r\nContent-Type: application/font-woff2\r\nConnection: Close\r\n\r\n"; + + // Images + static const char HTTPOKPNG[] = "HTTP/1.1 200 Ok\r\nContent-Type: image/png\r\nConnection: Close\r\n\r\n"; + static const char HTTPOKSVG[] = "HTTP/1.1 200 Ok\r\nContent-Type: image/svg+xml\r\nConnection: Close\r\n\r\n"; - // Images - static const char HTTPOKPNG[] = "HTTP/1.1 200 Ok\r\nContent-Type: image/png\r\nConnection: Close\r\n\r\n"; - static const char HTTPOKSVG[] = "HTTP/1.1 200 Ok\r\nContent-Type: image/svg+xml\r\nConnection: Close\r\n\r\n"; + class IMonPage; - class IMonPage; + using TMonPagePtr = TIntrusivePtr<IMonPage>; - using TMonPagePtr = TIntrusivePtr<IMonPage>; + class IMonPage: public TAtomicRefCount<IMonPage> { + public: + const TString Path; + const TString Title; + const IMonPage* Parent = nullptr; - class IMonPage: public TAtomicRefCount<IMonPage> { - public: - const TString Path; - const TString Title; - const IMonPage* Parent = nullptr; + public: + IMonPage(const TString& path, const TString& title = TString()); - public: - IMonPage(const TString& path, const TString& title = TString()); + virtual ~IMonPage() { + } - virtual ~IMonPage() { - } + void OutputNavBar(IOutputStream& out); - void OutputNavBar(IOutputStream& out); - - virtual const TString& GetPath() const { - return Path; - } + virtual const TString& GetPath() const { + return Path; + } - virtual const TString& GetTitle() const { - return Title; - } + virtual const TString& GetTitle() const { + return Title; + } - bool IsInIndex() const { + bool IsInIndex() const { return !Title.empty(); - } + } virtual void Output(IMonHttpRequest& request) = 0; - }; + }; } diff --git a/library/cpp/monlib/service/pages/pre_mon_page.h b/library/cpp/monlib/service/pages/pre_mon_page.h index 7f4199287d..c9a923d39a 100644 --- a/library/cpp/monlib/service/pages/pre_mon_page.h +++ b/library/cpp/monlib/service/pages/pre_mon_page.h @@ -3,25 +3,25 @@ #include "html_mon_page.h" namespace NMonitoring { - struct TPreMonPage: public THtmlMonPage { - TPreMonPage(const TString& path, - const TString& title = TString(), - bool preTag = true, - bool outputTableSorterJsCss = false) - : THtmlMonPage(path, title, outputTableSorterJsCss) - , PreTag(preTag) - { - } + struct TPreMonPage: public THtmlMonPage { + TPreMonPage(const TString& path, + const TString& title = TString(), + bool preTag = true, + bool outputTableSorterJsCss = false) + : THtmlMonPage(path, title, outputTableSorterJsCss) + , PreTag(preTag) + { + } void OutputContent(NMonitoring::IMonHttpRequest& request) override; - // hook to customize output + // hook to customize output virtual void BeforePre(NMonitoring::IMonHttpRequest& request); - // put your text here + // put your text here virtual void OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) = 0; - const bool PreTag; - }; + const bool PreTag; + }; -} +} diff --git a/library/cpp/monlib/service/pages/registry_mon_page.cpp b/library/cpp/monlib/service/pages/registry_mon_page.cpp index e05c80d07f..c59e50f622 100644 --- a/library/cpp/monlib/service/pages/registry_mon_page.cpp +++ b/library/cpp/monlib/service/pages/registry_mon_page.cpp @@ -1,18 +1,18 @@ #include "registry_mon_page.h" -#include <library/cpp/monlib/encode/text/text.h> -#include <library/cpp/monlib/encode/json/json.h> +#include <library/cpp/monlib/encode/text/text.h> +#include <library/cpp/monlib/encode/json/json.h> #include <library/cpp/monlib/encode/prometheus/prometheus.h> -#include <library/cpp/monlib/encode/spack/spack_v1.h> +#include <library/cpp/monlib/encode/spack/spack_v1.h> #include <library/cpp/monlib/service/format.h> namespace NMonitoring { - void TMetricRegistryPage::Output(NMonitoring::IMonHttpRequest& request) { + void TMetricRegistryPage::Output(NMonitoring::IMonHttpRequest& request) { const auto formatStr = TStringBuf{request.GetPathInfo()}.RNextTok('/'); auto& out = request.Output(); if (!formatStr.empty()) { - IMetricEncoderPtr encoder; + IMetricEncoderPtr encoder; TString resp; if (formatStr == TStringBuf("json")) { @@ -26,7 +26,7 @@ namespace NMonitoring { resp = HTTPOKPROMETHEUS; encoder = NMonitoring::EncoderPrometheus(&out); } else { - ythrow yexception() << "unsupported metric encoding format: " << formatStr; + ythrow yexception() << "unsupported metric encoding format: " << formatStr; } out.Write(resp); @@ -38,8 +38,8 @@ namespace NMonitoring { } } - void TMetricRegistryPage::OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) { - IMetricEncoderPtr encoder = NMonitoring::EncoderText(&out); + void TMetricRegistryPage::OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) { + IMetricEncoderPtr encoder = NMonitoring::EncoderText(&out); RegistryRawPtr_->Accept(TInstant::Zero(), encoder.Get()); } diff --git a/library/cpp/monlib/service/pages/registry_mon_page.h b/library/cpp/monlib/service/pages/registry_mon_page.h index c370dfc97b..2d26d3319c 100644 --- a/library/cpp/monlib/service/pages/registry_mon_page.h +++ b/library/cpp/monlib/service/pages/registry_mon_page.h @@ -2,11 +2,11 @@ #include "pre_mon_page.h" -#include <library/cpp/monlib/metrics/metric_registry.h> +#include <library/cpp/monlib/metrics/metric_registry.h> namespace NMonitoring { // For now this class can only enumerate all metrics without any grouping or serve JSON/Spack/Prometheus - class TMetricRegistryPage: public TPreMonPage { + class TMetricRegistryPage: public TPreMonPage { public: TMetricRegistryPage(const TString& path, const TString& title, TAtomicSharedPtr<IMetricSupplier> registry) : TPreMonPage(path, title) diff --git a/library/cpp/monlib/service/pages/resource_mon_page.cpp b/library/cpp/monlib/service/pages/resource_mon_page.cpp index b8f7c73b25..ec4ac6a1a7 100644 --- a/library/cpp/monlib/service/pages/resource_mon_page.cpp +++ b/library/cpp/monlib/service/pages/resource_mon_page.cpp @@ -4,7 +4,7 @@ using namespace NMonitoring; void TResourceMonPage::Output(NMonitoring::IMonHttpRequest& request) { IOutputStream& out = request.Output(); - switch (ResourceType) { + switch (ResourceType) { case TEXT: out << HTTPOKTEXT; break; diff --git a/library/cpp/monlib/service/pages/resource_mon_page.h b/library/cpp/monlib/service/pages/resource_mon_page.h index 43b1dfc9c4..f6ab67200e 100644 --- a/library/cpp/monlib/service/pages/resource_mon_page.h +++ b/library/cpp/monlib/service/pages/resource_mon_page.h @@ -5,39 +5,39 @@ #include <library/cpp/resource/resource.h> namespace NMonitoring { - struct TResourceMonPage: public IMonPage { - public: - enum EResourceType { - BINARY, - TEXT, - JSON, - CSS, - JAVASCRIPT, - - FONT_EOT, - FONT_TTF, - FONT_WOFF, - FONT_WOFF2, - - PNG, - SVG - }; - - TResourceMonPage(const TString& path, const TString& resourceName, - const EResourceType& resourceType = BINARY) - : IMonPage(path, "") - , ResourceName(resourceName) - , ResourceType(resourceType) - { - } + struct TResourceMonPage: public IMonPage { + public: + enum EResourceType { + BINARY, + TEXT, + JSON, + CSS, + JAVASCRIPT, + + FONT_EOT, + FONT_TTF, + FONT_WOFF, + FONT_WOFF2, + + PNG, + SVG + }; + + TResourceMonPage(const TString& path, const TString& resourceName, + const EResourceType& resourceType = BINARY) + : IMonPage(path, "") + , ResourceName(resourceName) + , ResourceType(resourceType) + { + } void Output(NMonitoring::IMonHttpRequest& request) override; void NotFound(NMonitoring::IMonHttpRequest& request) const; - private: - TString ResourceName; - EResourceType ResourceType; - }; + private: + TString ResourceName; + EResourceType ResourceType; + }; -} +} diff --git a/library/cpp/monlib/service/pages/tablesorter/css_mon_page.h b/library/cpp/monlib/service/pages/tablesorter/css_mon_page.h index abd1ed27b5..c2c8330089 100644 --- a/library/cpp/monlib/service/pages/tablesorter/css_mon_page.h +++ b/library/cpp/monlib/service/pages/tablesorter/css_mon_page.h @@ -1,13 +1,13 @@ #pragma once -#include <library/cpp/monlib/service/pages/resource_mon_page.h> +#include <library/cpp/monlib/service/pages/resource_mon_page.h> namespace NMonitoring { - struct TTablesorterCssMonPage: public TResourceMonPage { - TTablesorterCssMonPage() - : TResourceMonPage("jquery.tablesorter.css", "jquery.tablesorter.css", CSS) - { - } - }; + struct TTablesorterCssMonPage: public TResourceMonPage { + TTablesorterCssMonPage() + : TResourceMonPage("jquery.tablesorter.css", "jquery.tablesorter.css", CSS) + { + } + }; -} +} diff --git a/library/cpp/monlib/service/pages/tablesorter/js_mon_page.h b/library/cpp/monlib/service/pages/tablesorter/js_mon_page.h index 79a1a2f667..f8a1d8254e 100644 --- a/library/cpp/monlib/service/pages/tablesorter/js_mon_page.h +++ b/library/cpp/monlib/service/pages/tablesorter/js_mon_page.h @@ -1,13 +1,13 @@ #pragma once -#include <library/cpp/monlib/service/pages/resource_mon_page.h> +#include <library/cpp/monlib/service/pages/resource_mon_page.h> namespace NMonitoring { - struct TTablesorterJsMonPage: public TResourceMonPage { - TTablesorterJsMonPage() - : TResourceMonPage("jquery.tablesorter.js", "jquery.tablesorter.js", JAVASCRIPT) - { - } - }; + struct TTablesorterJsMonPage: public TResourceMonPage { + TTablesorterJsMonPage() + : TResourceMonPage("jquery.tablesorter.js", "jquery.tablesorter.js", JAVASCRIPT) + { + } + }; -} +} diff --git a/library/cpp/monlib/service/pages/tablesorter/ya.make b/library/cpp/monlib/service/pages/tablesorter/ya.make index a07e43750a..b5b6a64da8 100644 --- a/library/cpp/monlib/service/pages/tablesorter/ya.make +++ b/library/cpp/monlib/service/pages/tablesorter/ya.make @@ -8,7 +8,7 @@ RESOURCE( ) PEERDIR( - library/cpp/monlib/dynamic_counters + library/cpp/monlib/dynamic_counters ) END() diff --git a/library/cpp/monlib/service/pages/templates.cpp b/library/cpp/monlib/service/pages/templates.cpp index 17442c8c9b..ece12bea71 100644 --- a/library/cpp/monlib/service/pages/templates.cpp +++ b/library/cpp/monlib/service/pages/templates.cpp @@ -32,4 +32,4 @@ namespace NMonitoring { extern const char DTermTag[] = "dt"; extern const char DDescTag[] = "dd"; -} +} diff --git a/library/cpp/monlib/service/pages/templates.h b/library/cpp/monlib/service/pages/templates.h index 356cd13483..b4656f059f 100644 --- a/library/cpp/monlib/service/pages/templates.h +++ b/library/cpp/monlib/service/pages/templates.h @@ -7,76 +7,76 @@ #define WITH_SCOPED_I(var, value, label) \ if (auto var = (value)) { \ - Y_UNUSED(var); \ - goto label; \ - } else \ - label \ - : - -#define TAG(name) WITH_SCOPED(tmp, NMonitoring::name(__stream)) -#define TAG_CLASS(name, cls) WITH_SCOPED(tmp, NMonitoring::name(__stream, cls)) -#define TAG_CLASS_STYLE(name, cls, style) WITH_SCOPED(tmp, NMonitoring::name(__stream, {{"class", cls}, {"style", style}})) -#define TAG_CLASS_ID(name, cls, id) WITH_SCOPED(tmp, NMonitoring::name(__stream, cls, "", id)) -#define TAG_CLASS_FOR(name, cls, for0) WITH_SCOPED(tmp, NMonitoring::name(__stream, cls, for0)) -#define TAG_ATTRS(name, ...) WITH_SCOPED(tmp, NMonitoring::name(__stream, ##__VA_ARGS__)) - -#define HTML(str) WITH_SCOPED(__stream, NMonitoring::TOutputStreamRef(str)) - -#define HEAD() TAG(THead) -#define BODY() TAG(TBody) -#define HTML_TAG() TAG(THtml) -#define DIV() TAG(TDiv) -#define DIV_CLASS(cls) TAG_CLASS(TDiv, cls) + Y_UNUSED(var); \ + goto label; \ + } else \ + label \ + : + +#define TAG(name) WITH_SCOPED(tmp, NMonitoring::name(__stream)) +#define TAG_CLASS(name, cls) WITH_SCOPED(tmp, NMonitoring::name(__stream, cls)) +#define TAG_CLASS_STYLE(name, cls, style) WITH_SCOPED(tmp, NMonitoring::name(__stream, {{"class", cls}, {"style", style}})) +#define TAG_CLASS_ID(name, cls, id) WITH_SCOPED(tmp, NMonitoring::name(__stream, cls, "", id)) +#define TAG_CLASS_FOR(name, cls, for0) WITH_SCOPED(tmp, NMonitoring::name(__stream, cls, for0)) +#define TAG_ATTRS(name, ...) WITH_SCOPED(tmp, NMonitoring::name(__stream, ##__VA_ARGS__)) + +#define HTML(str) WITH_SCOPED(__stream, NMonitoring::TOutputStreamRef(str)) + +#define HEAD() TAG(THead) +#define BODY() TAG(TBody) +#define HTML_TAG() TAG(THtml) +#define DIV() TAG(TDiv) +#define DIV_CLASS(cls) TAG_CLASS(TDiv, cls) #define DIV_CLASS_ID(cls, id) TAG_CLASS_ID(TDiv, cls, id) -#define PRE() TAG(TPre) -#define TABLE() TAG(TTable) -#define TABLE_CLASS(cls) TAG_CLASS(TTable, cls) -#define TABLE_SORTABLE() TABLE_CLASS("table-sortable") +#define PRE() TAG(TPre) +#define TABLE() TAG(TTable) +#define TABLE_CLASS(cls) TAG_CLASS(TTable, cls) +#define TABLE_SORTABLE() TABLE_CLASS("table-sortable") #define TABLE_SORTABLE_CLASS(cls) TABLE_CLASS(cls " table-sortable") -#define TABLEHEAD() TAG(TTableHead) -#define TABLEHEAD_CLASS(cls) TAG_CLASS(TTableHead, cls) -#define TABLEBODY() TAG(TTableBody) -#define TABLEBODY_CLASS(cls) TAG_CLASS(TTableBody, cls) -#define TABLER() TAG(TTableR) -#define TABLER_CLASS(cls) TAG_CLASS(TTableR, cls) -#define TABLED() TAG(TTableD) -#define TABLED_CLASS(cls) TAG_CLASS(TTableD, cls) -#define TABLED_ATTRS(...) TAG_ATTRS(TTableD, ##__VA_ARGS__) -#define TABLEH() TAG(TTableH) -#define TABLEH_CLASS(cls) TAG_CLASS(TTableH, cls) -#define FORM() TAG(TFormC) -#define FORM_CLASS(cls) TAG_CLASS(TFormC, cls) -#define LABEL() TAG(TLabelC) -#define LABEL_CLASS(cls) TAG_CLASS(TLabelC, cls) +#define TABLEHEAD() TAG(TTableHead) +#define TABLEHEAD_CLASS(cls) TAG_CLASS(TTableHead, cls) +#define TABLEBODY() TAG(TTableBody) +#define TABLEBODY_CLASS(cls) TAG_CLASS(TTableBody, cls) +#define TABLER() TAG(TTableR) +#define TABLER_CLASS(cls) TAG_CLASS(TTableR, cls) +#define TABLED() TAG(TTableD) +#define TABLED_CLASS(cls) TAG_CLASS(TTableD, cls) +#define TABLED_ATTRS(...) TAG_ATTRS(TTableD, ##__VA_ARGS__) +#define TABLEH() TAG(TTableH) +#define TABLEH_CLASS(cls) TAG_CLASS(TTableH, cls) +#define FORM() TAG(TFormC) +#define FORM_CLASS(cls) TAG_CLASS(TFormC, cls) +#define LABEL() TAG(TLabelC) +#define LABEL_CLASS(cls) TAG_CLASS(TLabelC, cls) #define LABEL_CLASS_FOR(cls, for0) TAG_CLASS_FOR(TLabelC, cls, for0) -#define SPAN_CLASS(cls) TAG_CLASS(TSpanC, cls) +#define SPAN_CLASS(cls) TAG_CLASS(TSpanC, cls) #define SPAN_CLASS_STYLE(cls, style) TAG_CLASS_STYLE(TSpanC, cls, style) -#define PARA() TAG(TPara) -#define PARA_CLASS(cls) TAG_CLASS(TPara, cls) - -#define H1() TAG(TH1) -#define H1_CLASS(cls) TAG_CLASS(TH1, cls) -#define H2() TAG(TH2) -#define H2_CLASS(cls) TAG_CLASS(TH2, cls) -#define H3() TAG(TH3) -#define H3_CLASS(cls) TAG_CLASS(TH3, cls) -#define H4() TAG(TH4) -#define H4_CLASS(cls) TAG_CLASS(TH4, cls) -#define H5() TAG(TH5) -#define H5_CLASS(cls) TAG_CLASS(TH5, cls) -#define H6() TAG(TH6) -#define H6_CLASS(cls) TAG_CLASS(TH6, cls) - -#define SMALL() TAG(TSMALL) -#define STRONG() TAG(TSTRONG) - -#define LI() TAG(TLIST) -#define LI_CLASS(cls) TAG_CLASS(TLIST, cls) -#define UL() TAG(TULIST) -#define UL_CLASS(cls) TAG_CLASS(TULIST, cls) -#define OL() TAG(TOLIST) -#define OL_CLASS(cls) TAG_CLASS(TOLIST, cls) +#define PARA() TAG(TPara) +#define PARA_CLASS(cls) TAG_CLASS(TPara, cls) + +#define H1() TAG(TH1) +#define H1_CLASS(cls) TAG_CLASS(TH1, cls) +#define H2() TAG(TH2) +#define H2_CLASS(cls) TAG_CLASS(TH2, cls) +#define H3() TAG(TH3) +#define H3_CLASS(cls) TAG_CLASS(TH3, cls) +#define H4() TAG(TH4) +#define H4_CLASS(cls) TAG_CLASS(TH4, cls) +#define H5() TAG(TH5) +#define H5_CLASS(cls) TAG_CLASS(TH5, cls) +#define H6() TAG(TH6) +#define H6_CLASS(cls) TAG_CLASS(TH6, cls) + +#define SMALL() TAG(TSMALL) +#define STRONG() TAG(TSTRONG) + +#define LI() TAG(TLIST) +#define LI_CLASS(cls) TAG_CLASS(TLIST, cls) +#define UL() TAG(TULIST) +#define UL_CLASS(cls) TAG_CLASS(TULIST, cls) +#define OL() TAG(TOLIST) +#define OL_CLASS(cls) TAG_CLASS(TOLIST, cls) #define DL() TAG(DLIST) #define DL_CLASS(cls) TAG_CLASS(DLIST, cls) @@ -85,8 +85,8 @@ #define DD() TAG(DDESC) #define DD_CLASS(cls) TAG_CLASS(DDESC, cls) -#define CAPTION() TAG(TCaption) -#define CAPTION_CLASS(cls) CAPTION_CLASS(TCaption, cls) +#define CAPTION() TAG(TCaption) +#define CAPTION_CLASS(cls) CAPTION_CLASS(TCaption, cls) #define HTML_OUTPUT_PARAM(str, param) str << #param << ": " << param << "<br/>" #define HTML_OUTPUT_TIME_PARAM(str, param) str << #param << ": " << ToStringLocalTimeUpToSeconds(param) << "<br/>" @@ -116,9 +116,9 @@ namespace NMonitoring { IOutputStream& Str; }; - template <const char* tag> + template <const char* tag> struct TTag { - TTag(IOutputStream& str, TStringBuf cls = "", TStringBuf for0 = "", TStringBuf id = "") + TTag(IOutputStream& str, TStringBuf cls = "", TStringBuf for0 = "", TStringBuf id = "") : Str(str) { Str << "<" << tag; @@ -137,7 +137,7 @@ namespace NMonitoring { Str << ">"; } - TTag(IOutputStream& str, std::initializer_list<std::pair<TStringBuf, TStringBuf>> attributes) + TTag(IOutputStream& str, std::initializer_list<std::pair<TStringBuf, TStringBuf>> attributes) : Str(str) { Str << "<" << tag; @@ -152,20 +152,20 @@ namespace NMonitoring { ~TTag() { try { Str << "</" << tag << ">"; - } catch (...) { - } + } catch (...) { + } } explicit inline operator bool() const noexcept { return true; // just to work with WITH_SCOPED } - IOutputStream& Str; + IOutputStream& Str; }; // a nice class for creating collapsable regions of html output struct TCollapsedButton { - TCollapsedButton(IOutputStream& str, const TString& targetId, const TString& buttonText) + TCollapsedButton(IOutputStream& str, const TString& targetId, const TString& buttonText) : Str(str) { Str << "<button type='button' class='btn' data-toggle='collapse' data-target='#" << targetId << "'>" @@ -176,22 +176,22 @@ namespace NMonitoring { ~TCollapsedButton() { try { Str << "</div>"; - } catch (...) { - } + } catch (...) { + } } explicit inline operator bool() const noexcept { return true; // just to work with WITH_SCOPED } - IOutputStream& Str; + IOutputStream& Str; }; struct TOutputStreamRef { TOutputStreamRef(IOutputStream& str) : Str(str) - { - } + { + } inline operator IOutputStream&() noexcept { return Str; @@ -265,4 +265,4 @@ namespace NMonitoring { typedef TTag<DListTag> DLIST; typedef TTag<DTermTag> DTERM; typedef TTag<DDescTag> DDESC; -} +} diff --git a/library/cpp/monlib/service/pages/version_mon_page.h b/library/cpp/monlib/service/pages/version_mon_page.h index 1ccfc6698e..f7649947e4 100644 --- a/library/cpp/monlib/service/pages/version_mon_page.h +++ b/library/cpp/monlib/service/pages/version_mon_page.h @@ -3,13 +3,13 @@ #include "pre_mon_page.h" namespace NMonitoring { - struct TVersionMonPage: public TPreMonPage { - TVersionMonPage(const TString& path = "ver", const TString& title = "Version") - : TPreMonPage(path, title) - { - } + struct TVersionMonPage: public TPreMonPage { + TVersionMonPage(const TString& path = "ver", const TString& title = "Version") + : TPreMonPage(path, title) + { + } void OutputText(IOutputStream& out, NMonitoring::IMonHttpRequest&) override; - }; + }; -} +} diff --git a/library/cpp/monlib/service/pages/ya.make b/library/cpp/monlib/service/pages/ya.make index b9b6ca5646..48d44a0838 100644 --- a/library/cpp/monlib/service/pages/ya.make +++ b/library/cpp/monlib/service/pages/ya.make @@ -1,31 +1,31 @@ -LIBRARY() - +LIBRARY() + OWNER(g:solomon) - + NO_WSHADOW() -SRCS( - diag_mon_page.cpp - html_mon_page.cpp - index_mon_page.cpp - mon_page.cpp - pre_mon_page.cpp - resource_mon_page.cpp - templates.cpp - version_mon_page.cpp +SRCS( + diag_mon_page.cpp + html_mon_page.cpp + index_mon_page.cpp + mon_page.cpp + pre_mon_page.cpp + resource_mon_page.cpp + templates.cpp + version_mon_page.cpp registry_mon_page.cpp -) - -PEERDIR( +) + +PEERDIR( library/cpp/build_info library/cpp/malloc/api library/cpp/svnversion library/cpp/resource - library/cpp/monlib/service - library/cpp/monlib/encode/json - library/cpp/monlib/encode/text - library/cpp/monlib/encode/spack + library/cpp/monlib/service + library/cpp/monlib/encode/json + library/cpp/monlib/encode/text + library/cpp/monlib/encode/spack library/cpp/monlib/encode/prometheus -) - -END() +) + +END() diff --git a/library/cpp/monlib/service/service.cpp b/library/cpp/monlib/service/service.cpp index 0db0e206d0..929efbf816 100644 --- a/library/cpp/monlib/service/service.cpp +++ b/library/cpp/monlib/service/service.cpp @@ -7,13 +7,13 @@ #include <library/cpp/uri/http_url.h> #include <util/generic/buffer.h> -#include <util/stream/str.h> +#include <util/stream/str.h> #include <util/stream/buffer.h> -#include <util/stream/zerocopy.h> -#include <util/string/vector.h> - +#include <util/stream/zerocopy.h> +#include <util/string/vector.h> + namespace NMonitoring { - class THttpClient: public IHttpRequest { + class THttpClient: public IHttpRequest { public: void ServeRequest(THttpInput& in, IOutputStream& out, const NAddr::IRemoteAddr* remoteAddr, const THandler& Handler) { try { @@ -36,7 +36,7 @@ namespace NMonitoring { } Headers = &in.Headers(); CgiParams.Scan(Url.Get(THttpURL::FieldQuery)); - } catch (...) { + } catch (...) { out << "HTTP/1.1 500 Internal server error\r\nConnection: Close\r\n\r\n"; YSYSLOG(TLOG_ERR, "THttpClient: internal error while serving monitoring request: %s", CurrentExceptionMessage().data()); } @@ -46,7 +46,7 @@ namespace NMonitoring { Handler(out, *this); out.Finish(); - } catch (...) { + } catch (...) { auto msg = CurrentExceptionMessage(); out << "HTTP/1.1 500 Internal server error\r\nConnection: Close\r\n\r\n" << msg; out.Finish(); @@ -102,7 +102,7 @@ namespace NMonitoring { /* TCoHttpServer */ - class TCoHttpServer::TConnection: public THttpClient { + class TCoHttpServer::TConnection: public THttpClient { public: TConnection(const TCoHttpServer::TAcceptFull& acc, const TCoHttpServer& parent) : Socket(acc.S->Release()) @@ -111,7 +111,7 @@ namespace NMonitoring { { } - void operator()(TCont* c) { + void operator()(TCont* c) { try { THolder<TConnection> me(this); TContIO io(Socket, c); @@ -122,11 +122,11 @@ namespace NMonitoring { ServeRequest(in, s, RemoteAddr, Parent.Handler); out << s.Str(); out.Finish(); - } catch (...) { + } catch (...) { YSYSLOG(TLOG_WARNING, "TCoHttpServer::TConnection: error: %s\n", CurrentExceptionMessage().data()); } } - + private: TSocketHolder Socket; const NAddr::IRemoteAddr* RemoteAddr; @@ -171,15 +171,15 @@ namespace NMonitoring { TSocket sock(addr); TSocketOutput sock_out(sock); TSocketInput sock_in(sock); - sock_out << "GET " << request.GetURI() << " HTTP/1.0\r\n\r\n"; + sock_out << "GET " << request.GetURI() << " HTTP/1.0\r\n\r\n"; THttpInput http_in(&sock_in); try { out << "HTTP/1.1 200 Ok\nConnection: Close\n\n"; TransferData(&http_in, &out); - } catch (...) { + } catch (...) { YSYSLOG(TLOG_DEBUG, "TCoHttpServer: while getting data from backend: %s", CurrentExceptionMessage().data()); } - } catch (const yexception& /*e*/) { + } catch (const yexception& /*e*/) { out << "HTTP/1.1 500 Internal server error\nConnection: Close\n\n"; YSYSLOG(TLOG_DEBUG, "TCoHttpServer: while getting data from backend: %s", CurrentExceptionMessage().data()); } @@ -187,7 +187,7 @@ namespace NMonitoring { /* TMtHttpServer */ - class TMtHttpServer::TConnection: public TClientRequest, public THttpClient { + class TMtHttpServer::TConnection: public TClientRequest, public THttpClient { public: TConnection(const TMtHttpServer& parent) : Parent(parent) @@ -198,7 +198,7 @@ namespace NMonitoring { ServeRequest(Input(), Output(), NAddr::GetPeerAddr(Socket()).Get(), Parent.Handler); return true; } - + private: const TMtHttpServer& Parent; }; @@ -215,32 +215,32 @@ namespace NMonitoring { { } - bool TMtHttpServer::Start() { - return THttpServer::Start(); - } - - void TMtHttpServer::StartOrThrow() { - if (!Start()) { - const auto& opts = THttpServer::Options(); - TNetworkAddress addr = opts.Host + bool TMtHttpServer::Start() { + return THttpServer::Start(); + } + + void TMtHttpServer::StartOrThrow() { + if (!Start()) { + const auto& opts = THttpServer::Options(); + TNetworkAddress addr = opts.Host ? TNetworkAddress(opts.Host, opts.Port) : TNetworkAddress(opts.Port); - ythrow TSystemError(GetErrorCode()) << addr; - } - } - - void TMtHttpServer::Stop() { - THttpServer::Stop(); - } - + ythrow TSystemError(GetErrorCode()) << addr; + } + } + + void TMtHttpServer::Stop() { + THttpServer::Stop(); + } + TClientRequest* TMtHttpServer::CreateClient() { return new TConnection(*this); } /* TService */ - TMonService::TMonService(TContExecutor& executor, TIpPort internalPort, TIpPort externalPort, - THandler coHandler, THandler mtHandler) + TMonService::TMonService(TContExecutor& executor, TIpPort internalPort, TIpPort externalPort, + THandler coHandler, THandler mtHandler) : CoServer(executor, "127.0.0.1", internalPort, std::move(coHandler)) , MtServer(THttpServerOptions(externalPort), std::bind(&TMonService::DispatchRequest, this, std::placeholders::_1, std::placeholders::_2)) , MtHandler(std::move(mtHandler)) @@ -261,8 +261,8 @@ namespace NMonitoring { if (strcmp(request.GetPath(), "/") == 0) { out << "HTTP/1.1 200 Ok\nConnection: Close\n\n"; MtHandler(out, request); - } else + } else CoServer.ProcessRequest(out, request); } -} +} diff --git a/library/cpp/monlib/service/service.h b/library/cpp/monlib/service/service.h index 1bff927199..2f66dddaf8 100644 --- a/library/cpp/monlib/service/service.h +++ b/library/cpp/monlib/service/service.h @@ -9,14 +9,14 @@ #include <util/network/ip.h> #include <library/cpp/cgiparam/cgiparam.h> -#include <functional> +#include <functional> struct TMonitor; namespace NMonitoring { struct IHttpRequest { - virtual ~IHttpRequest() { - } + virtual ~IHttpRequest() { + } virtual const char* GetURI() const = 0; virtual const char* GetPath() const = 0; virtual const TCgiParameters& GetParams() const = 0; @@ -28,9 +28,9 @@ namespace NMonitoring { }; // first param - output stream to write result to // second param - URL of request - typedef std::function<void(IOutputStream&, const IHttpRequest&)> THandler; + typedef std::function<void(IOutputStream&, const IHttpRequest&)> THandler; - class TCoHttpServer: private TContListener::ICallBack { + class TCoHttpServer: private TContListener::ICallBack { public: // initialize and schedule coroutines for execution TCoHttpServer(TContExecutor& executor, const TString& bindAddr, TIpPort port, THandler handler); @@ -42,14 +42,14 @@ namespace NMonitoring { // @note this call may be blocking; don't use inside coroutines // @throws may throw in case of connection error, etc void ProcessRequest(IOutputStream&, const IHttpRequest&); - + private: class TConnection; // ICallBack implementation void OnAcceptFull(const TAcceptFull& a) override; void OnError() override; - + private: TContExecutor& Executor; TContListener Listener; @@ -58,30 +58,30 @@ namespace NMonitoring { TIpPort Port; }; - class TMtHttpServer: public THttpServer, private THttpServer::ICallBack { + class TMtHttpServer: public THttpServer, private THttpServer::ICallBack { public: TMtHttpServer(const TOptions& options, THandler handler, IThreadFactory* pool = nullptr); TMtHttpServer(const TOptions& options, THandler handler, TSimpleSharedPtr<IThreadPool> pool); - - /** - * This will cause the server start to accept incoming connections. - * - * @return true if the port binding was successfull, - * false otherwise. - */ - bool Start(); - - /** - * Same as Start() member-function, but will throw TSystemError if - * there were some errors. - */ - void StartOrThrow(); - - /** - * Stops the server from accepting new connections. - */ - void Stop(); - + + /** + * This will cause the server start to accept incoming connections. + * + * @return true if the port binding was successfull, + * false otherwise. + */ + bool Start(); + + /** + * Same as Start() member-function, but will throw TSystemError if + * there were some errors. + */ + void StartOrThrow(); + + /** + * Stops the server from accepting new connections. + */ + void Stop(); + private: class TConnection; TClientRequest* CreateClient() override; @@ -95,18 +95,18 @@ namespace NMonitoring { // will be served in a coroutine context class TMonService { public: - TMonService(TContExecutor& executor, TIpPort internalPort, TIpPort externalPort, - THandler coHandler, THandler mtHandler); + TMonService(TContExecutor& executor, TIpPort internalPort, TIpPort externalPort, + THandler coHandler, THandler mtHandler); void Start(); void Stop(); - + protected: void DispatchRequest(IOutputStream& out, const IHttpRequest&); - + private: TCoHttpServer CoServer; TMtHttpServer MtServer; THandler MtHandler; }; -} +} diff --git a/library/cpp/monlib/service/ya.make b/library/cpp/monlib/service/ya.make index 7240be8071..ad088fc2c6 100644 --- a/library/cpp/monlib/service/ya.make +++ b/library/cpp/monlib/service/ya.make @@ -1,18 +1,18 @@ -LIBRARY() - +LIBRARY() + OWNER(g:solomon) - -SRCS( - monservice.cpp - mon_service_http_request.cpp - service.cpp + +SRCS( + monservice.cpp + mon_service_http_request.cpp + service.cpp format.cpp auth.cpp -) - -PEERDIR( +) + +PEERDIR( library/cpp/string_utils/base64 - contrib/libs/protobuf + contrib/libs/protobuf library/cpp/coroutine/engine library/cpp/coroutine/listener library/cpp/http/fetch @@ -23,6 +23,6 @@ PEERDIR( library/cpp/svnversion library/cpp/uri library/cpp/cgiparam -) - -END() +) + +END() diff --git a/library/cpp/monlib/ya.make b/library/cpp/monlib/ya.make index 12986ec20c..9bd236d6fd 100644 --- a/library/cpp/monlib/ya.make +++ b/library/cpp/monlib/ya.make @@ -3,43 +3,43 @@ OWNER( jamel ) -RECURSE( +RECURSE( consumers - counters - counters/ut - deprecated - dynamic_counters + counters + counters/ut + deprecated + dynamic_counters dynamic_counters/percentile dynamic_counters/percentile/ut - dynamic_counters/ut - encode - encode/buffered - encode/buffered/ut + dynamic_counters/ut + encode + encode/buffered + encode/buffered/ut encode/fake encode/fuzz - encode/json - encode/json/ut + encode/json + encode/json/ut encode/legacy_protobuf encode/legacy_protobuf/ut - encode/prometheus - encode/prometheus/ut + encode/prometheus + encode/prometheus/ut encode/protobuf - encode/spack - encode/spack/ut - encode/text - encode/text/ut + encode/spack + encode/spack/ut + encode/text + encode/text/ut encode/unistat encode/unistat/ut - encode/ut - example + encode/ut + example exception - libtimestats/ut - metrics - metrics/ut - messagebus - push_client - service + libtimestats/ut + metrics + metrics/ut + messagebus + push_client + service service/auth/tvm - service/pages - service/pages/tablesorter + service/pages + service/pages/tablesorter ) diff --git a/library/cpp/on_disk/chunks/chunks_ut.cpp b/library/cpp/on_disk/chunks/chunks_ut.cpp index 5b2c7d04d1..f727647f7f 100644 --- a/library/cpp/on_disk/chunks/chunks_ut.cpp +++ b/library/cpp/on_disk/chunks/chunks_ut.cpp @@ -55,7 +55,7 @@ public: TPlainHash<ui64, ui16> reader(temp); ui16 value = 0; UNIT_ASSERT(reader.Find(5, &value)); - UNIT_ASSERT_EQUAL(7, value); + UNIT_ASSERT_EQUAL(7, value); UNIT_ASSERT(!reader.Find(6, &value)); } } diff --git a/library/cpp/packers/ut/packers_ut.cpp b/library/cpp/packers/ut/packers_ut.cpp index 1203ba95c1..18ce2150d1 100644 --- a/library/cpp/packers/ut/packers_ut.cpp +++ b/library/cpp/packers/ut/packers_ut.cpp @@ -54,7 +54,7 @@ void TPackersTest::TestPacker(const TData& data) { TData dataTmp; TPacker().UnpackLeaf(buf.Get(), dataTmp); - UNIT_ASSERT(data == dataTmp); + UNIT_ASSERT(data == dataTmp); } template <class TData, class TPacker> diff --git a/library/cpp/scheme/tests/ut/scheme_json_ut.cpp b/library/cpp/scheme/tests/ut/scheme_json_ut.cpp index 23f6e1a346..daeb2654f9 100644 --- a/library/cpp/scheme/tests/ut/scheme_json_ut.cpp +++ b/library/cpp/scheme/tests/ut/scheme_json_ut.cpp @@ -60,7 +60,7 @@ Y_UNIT_TEST_SUITE(TSchemeJsonTest) { } { const char* json = "[a:b]"; - UNIT_ASSERT(NSc::TValue::FromJson(json).IsNull()); + UNIT_ASSERT(NSc::TValue::FromJson(json).IsNull()); } { UNIT_ASSERT_VALUES_EQUAL("{\n \"a\" : \"b\",\n \"c\" : \"d\"\n}", diff --git a/library/cpp/scheme/tests/ut/scheme_merge_ut.cpp b/library/cpp/scheme/tests/ut/scheme_merge_ut.cpp index 8658e6c6e8..2a06cf110d 100644 --- a/library/cpp/scheme/tests/ut/scheme_merge_ut.cpp +++ b/library/cpp/scheme/tests/ut/scheme_merge_ut.cpp @@ -30,7 +30,7 @@ Y_UNIT_TEST_SUITE(TSchemeMergeTest) { TStringBuf data = "{ a : [ { b : 1, d : { e : -1.e5 } }, { f : 0, g : [ h, i ] } ] }"; NSc::TValue v = NSc::TValue::FromJson(data); UNIT_ASSERT_VALUES_EQUAL(v.ToJson(true), v.Clone().ToJson(true)); - UNIT_ASSERT(v.Has("a")); + UNIT_ASSERT(v.Has("a")); UNIT_ASSERT(v["a"].Has(1)); UNIT_ASSERT(v["a"][0].Has("b")); UNIT_ASSERT(v["a"][0].Has("d")); @@ -62,8 +62,8 @@ Y_UNIT_TEST_SUITE(TSchemeMergeTest) { UNIT_ASSERT_C(NSc::TValue::Equal(v["a"], v2), Sprintf("\n%s\n!=\n%s\n", v["a"].ToJson().data(), v2.ToJson().data())); } - UNIT_ASSERT(v.Has("a")); - UNIT_ASSERT(v.Has("q")); + UNIT_ASSERT(v.Has("a")); + UNIT_ASSERT(v.Has("q")); UNIT_ASSERT(TStringBuf("r") == v["q"]); UNIT_ASSERT(v["a"].Has(1)); UNIT_ASSERT(!v["a"][0].Has("b")); diff --git a/library/cpp/scheme/tests/ut/scheme_path_ut.cpp b/library/cpp/scheme/tests/ut/scheme_path_ut.cpp index 45026fbdb2..0d4d79d483 100644 --- a/library/cpp/scheme/tests/ut/scheme_path_ut.cpp +++ b/library/cpp/scheme/tests/ut/scheme_path_ut.cpp @@ -18,9 +18,9 @@ Y_UNIT_TEST_SUITE(TSchemePathTest) { *v.TrySelectOrAdd(path) = 1; NSc::NUt::AssertSchemeJson(expected, v); UNIT_ASSERT(v.PathExists(path)); - UNIT_ASSERT(1 == v.TrySelectOrAdd(path)->GetNumber()); - UNIT_ASSERT(1 == v.TrySelect(path).GetNumber()); - UNIT_ASSERT(1 == v.TrySelectAndDelete(path).GetNumber()); + UNIT_ASSERT(1 == v.TrySelectOrAdd(path)->GetNumber()); + UNIT_ASSERT(1 == v.TrySelect(path).GetNumber()); + UNIT_ASSERT(1 == v.TrySelectAndDelete(path).GetNumber()); UNIT_ASSERT(NSc::TValue::Same(v.TrySelectAndDelete(path), NSc::Null())); NSc::NUt::AssertSchemeJson(delexpected, v); UNIT_ASSERT(!v.PathExists(path)); @@ -29,7 +29,7 @@ Y_UNIT_TEST_SUITE(TSchemePathTest) { Y_UNIT_TEST(TestSelect) { NSc::TValue v; - UNIT_ASSERT(!v.PathValid(" ")); + UNIT_ASSERT(!v.PathValid(" ")); UNIT_ASSERT(v.PathExists("")); UNIT_ASSERT(v.PathExists("//")); diff --git a/library/cpp/scheme/tests/ut/scheme_ut.cpp b/library/cpp/scheme/tests/ut/scheme_ut.cpp index e49ac959ff..1a5d07c31b 100644 --- a/library/cpp/scheme/tests/ut/scheme_ut.cpp +++ b/library/cpp/scheme/tests/ut/scheme_ut.cpp @@ -526,7 +526,7 @@ Y_UNIT_TEST_SUITE(TSchemeTest) { UNIT_ASSERT(2 > NSc::TValue(1)); UNIT_ASSERT(NSc::TValue(1) < 2); - UNIT_ASSERT(TString("test") == NSc::TValue("test")); + UNIT_ASSERT(TString("test") == NSc::TValue("test")); } Y_UNIT_TEST(TestDestructor) { diff --git a/library/cpp/sse/ut/test.cpp b/library/cpp/sse/ut/test.cpp index f72fd1cf91..33c999d284 100644 --- a/library/cpp/sse/ut/test.cpp +++ b/library/cpp/sse/ut/test.cpp @@ -1858,7 +1858,7 @@ void TSSEEmulTest::Test_mm_storeu_pd() { for (size_t shift = 0; shift != 3; ++shift) { _mm_storeu_pd(&res[shift], value); for (size_t j = 0; j != 2; ++j) { - UNIT_ASSERT_EQUAL_C(res[j + shift], valueBits[i + j], "res: " << HexEncode(&res[shift], 16) << " vs etalon: " << HexEncode(&valueBits[i], 16)); + UNIT_ASSERT_EQUAL_C(res[j + shift], valueBits[i + j], "res: " << HexEncode(&res[shift], 16) << " vs etalon: " << HexEncode(&valueBits[i], 16)); } } } diff --git a/library/cpp/string_utils/url/url.cpp b/library/cpp/string_utils/url/url.cpp index dc3d5aa00e..85f4ac5d69 100644 --- a/library/cpp/string_utils/url/url.cpp +++ b/library/cpp/string_utils/url/url.cpp @@ -206,35 +206,35 @@ void SeparateUrlFromQueryAndFragment(const TStringBuf url, TStringBuf& sanitized } } -bool TryGetSchemeHostAndPort(const TStringBuf url, TStringBuf& scheme, TStringBuf& host, ui16& port) { - const size_t schemeSize = GetSchemePrefixSize(url); - if (schemeSize != 0) { - scheme = url.Head(schemeSize); - } - - TStringBuf portStr; - TStringBuf hostAndPort = GetHostAndPort(url.Tail(schemeSize)); +bool TryGetSchemeHostAndPort(const TStringBuf url, TStringBuf& scheme, TStringBuf& host, ui16& port) { + const size_t schemeSize = GetSchemePrefixSize(url); + if (schemeSize != 0) { + scheme = url.Head(schemeSize); + } + + TStringBuf portStr; + TStringBuf hostAndPort = GetHostAndPort(url.Tail(schemeSize)); if (hostAndPort && hostAndPort.back() != ']' && hostAndPort.TryRSplit(':', host, portStr)) { - // URL has port - if (!TryFromString(portStr, port)) { - return false; - } - } else { - host = hostAndPort; + // URL has port + if (!TryFromString(portStr, port)) { + return false; + } + } else { + host = hostAndPort; if (scheme == TStringBuf("https://")) { - port = 443; + port = 443; } else if (scheme == TStringBuf("http://")) { - port = 80; - } - } - return true; -} - -void GetSchemeHostAndPort(const TStringBuf url, TStringBuf& scheme, TStringBuf& host, ui16& port) { - bool isOk = TryGetSchemeHostAndPort(url, scheme, host, port); - Y_ENSURE(isOk, "cannot parse port number from URL: " << url); -} - + port = 80; + } + } + return true; +} + +void GetSchemeHostAndPort(const TStringBuf url, TStringBuf& scheme, TStringBuf& host, ui16& port) { + bool isOk = TryGetSchemeHostAndPort(url, scheme, host, port); + Y_ENSURE(isOk, "cannot parse port number from URL: " << url); +} + TStringBuf GetOnlyHost(const TStringBuf url) noexcept { return GetHost(CutSchemePrefix(url)); } diff --git a/library/cpp/string_utils/url/url.h b/library/cpp/string_utils/url/url.h index 5e797e374a..84137ccc57 100644 --- a/library/cpp/string_utils/url/url.h +++ b/library/cpp/string_utils/url/url.h @@ -65,14 +65,14 @@ TString AddSchemePrefix(const TString& url); Y_PURE_FUNCTION TStringBuf GetHost(const TStringBuf url) noexcept; - + Y_PURE_FUNCTION TStringBuf GetHostAndPort(const TStringBuf url) noexcept; Y_PURE_FUNCTION TStringBuf GetSchemeHostAndPort(const TStringBuf url, bool trimHttp = true, bool trimDefaultPort = true) noexcept; -/** +/** * Splits URL to host and path * * @param[in] url any URL @@ -93,35 +93,35 @@ void SplitUrlToHostAndPath(const TStringBuf url, TString& host, TString& path); void SeparateUrlFromQueryAndFragment(const TStringBuf url, TStringBuf& sanitizedUrl, TStringBuf& query, TStringBuf& fragment); /** - * Extracts scheme, host and port from URL. - * - * Port will be parsed from URL with checks against ui16 overflow. If URL doesn't - * contain port it will be determined by one of the known schemes (currently - * https:// and http:// only). - * Given parameters will not be modified if URL has no appropriate components. - * - * @param[in] url any URL - * @param[out] scheme URL scheme - * @param[out] host host name - * @param[out] port parsed port number - * @return false if present port number cannot be parsed into ui16 - * true otherwise. - */ -bool TryGetSchemeHostAndPort(const TStringBuf url, TStringBuf& scheme, TStringBuf& host, ui16& port); - -/** - * Extracts scheme, host and port from URL. - * + * Extracts scheme, host and port from URL. + * + * Port will be parsed from URL with checks against ui16 overflow. If URL doesn't + * contain port it will be determined by one of the known schemes (currently + * https:// and http:// only). + * Given parameters will not be modified if URL has no appropriate components. + * + * @param[in] url any URL + * @param[out] scheme URL scheme + * @param[out] host host name + * @param[out] port parsed port number + * @return false if present port number cannot be parsed into ui16 + * true otherwise. + */ +bool TryGetSchemeHostAndPort(const TStringBuf url, TStringBuf& scheme, TStringBuf& host, ui16& port); + +/** + * Extracts scheme, host and port from URL. + * * This function perform the same actions as TryGetSchemeHostAndPort(), but in - * case of impossibility to parse port number throws yexception. - * - * @param[in] url any URL - * @param[out] scheme URL scheme - * @param[out] host host name - * @param[out] port parsed port number - * @throws yexception if present port number cannot be parsed into ui16. - */ -void GetSchemeHostAndPort(const TStringBuf url, TStringBuf& scheme, TStringBuf& host, ui16& port); + * case of impossibility to parse port number throws yexception. + * + * @param[in] url any URL + * @param[out] scheme URL scheme + * @param[out] host host name + * @param[out] port parsed port number + * @throws yexception if present port number cannot be parsed into ui16. + */ +void GetSchemeHostAndPort(const TStringBuf url, TStringBuf& scheme, TStringBuf& host, ui16& port); Y_PURE_FUNCTION TStringBuf GetPathAndQuery(const TStringBuf url, bool trimFragment = true) noexcept; diff --git a/library/cpp/string_utils/url/url_ut.cpp b/library/cpp/string_utils/url/url_ut.cpp index 3e64d3e2c5..1588013893 100644 --- a/library/cpp/string_utils/url/url_ut.cpp +++ b/library/cpp/string_utils/url/url_ut.cpp @@ -126,7 +126,7 @@ Y_UNIT_TEST_SUITE(TUtilUrlTest) { UNIT_ASSERT_VALUES_EQUAL("m", CutMPrefix("m")); UNIT_ASSERT_VALUES_EQUAL("ya.ru", CutMPrefix("m.ya.ru")); } - + Y_UNIT_TEST(TestSplitUrlToHostAndPath) { TStringBuf host, path; @@ -176,46 +176,46 @@ Y_UNIT_TEST_SUITE(TUtilUrlTest) { } Y_UNIT_TEST(TestGetSchemeHostAndPort) { - { // all components are present - TStringBuf scheme("unknown"), host("unknown"); - ui16 port = 0; - GetSchemeHostAndPort("https://ya.ru:8080/bebe", scheme, host, port); - UNIT_ASSERT_VALUES_EQUAL(scheme, "https://"); - UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); - UNIT_ASSERT_VALUES_EQUAL(port, 8080); - } - { // scheme is abset - TStringBuf scheme("unknown"), host("unknown"); - ui16 port = 0; - GetSchemeHostAndPort("ya.ru:8080/bebe", scheme, host, port); - UNIT_ASSERT_VALUES_EQUAL(scheme, "unknown"); - UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); - UNIT_ASSERT_VALUES_EQUAL(port, 8080); - } - { // scheme and port are absent - TStringBuf scheme("unknown"), host("unknown"); - ui16 port = 0; - GetSchemeHostAndPort("ya.ru/bebe", scheme, host, port); - UNIT_ASSERT_VALUES_EQUAL(scheme, "unknown"); - UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); - UNIT_ASSERT_VALUES_EQUAL(port, 0); - } - { // port is absent, but returned its default value for HTTP - TStringBuf scheme("unknown"), host("unknown"); - ui16 port = 0; - GetSchemeHostAndPort("http://ya.ru/bebe", scheme, host, port); - UNIT_ASSERT_VALUES_EQUAL(scheme, "http://"); - UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); - UNIT_ASSERT_VALUES_EQUAL(port, 80); - } - { // port is absent, but returned its default value for HTTPS - TStringBuf scheme("unknown"), host("unknown"); - ui16 port = 0; - GetSchemeHostAndPort("https://ya.ru/bebe", scheme, host, port); - UNIT_ASSERT_VALUES_EQUAL(scheme, "https://"); - UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); - UNIT_ASSERT_VALUES_EQUAL(port, 443); - } + { // all components are present + TStringBuf scheme("unknown"), host("unknown"); + ui16 port = 0; + GetSchemeHostAndPort("https://ya.ru:8080/bebe", scheme, host, port); + UNIT_ASSERT_VALUES_EQUAL(scheme, "https://"); + UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); + UNIT_ASSERT_VALUES_EQUAL(port, 8080); + } + { // scheme is abset + TStringBuf scheme("unknown"), host("unknown"); + ui16 port = 0; + GetSchemeHostAndPort("ya.ru:8080/bebe", scheme, host, port); + UNIT_ASSERT_VALUES_EQUAL(scheme, "unknown"); + UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); + UNIT_ASSERT_VALUES_EQUAL(port, 8080); + } + { // scheme and port are absent + TStringBuf scheme("unknown"), host("unknown"); + ui16 port = 0; + GetSchemeHostAndPort("ya.ru/bebe", scheme, host, port); + UNIT_ASSERT_VALUES_EQUAL(scheme, "unknown"); + UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); + UNIT_ASSERT_VALUES_EQUAL(port, 0); + } + { // port is absent, but returned its default value for HTTP + TStringBuf scheme("unknown"), host("unknown"); + ui16 port = 0; + GetSchemeHostAndPort("http://ya.ru/bebe", scheme, host, port); + UNIT_ASSERT_VALUES_EQUAL(scheme, "http://"); + UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); + UNIT_ASSERT_VALUES_EQUAL(port, 80); + } + { // port is absent, but returned its default value for HTTPS + TStringBuf scheme("unknown"), host("unknown"); + ui16 port = 0; + GetSchemeHostAndPort("https://ya.ru/bebe", scheme, host, port); + UNIT_ASSERT_VALUES_EQUAL(scheme, "https://"); + UNIT_ASSERT_VALUES_EQUAL(host, "ya.ru"); + UNIT_ASSERT_VALUES_EQUAL(port, 443); + } { // ipv6 TStringBuf scheme("unknown"), host("unknown"); ui16 port = 0; @@ -240,14 +240,14 @@ Y_UNIT_TEST_SUITE(TUtilUrlTest) { UNIT_ASSERT_VALUES_EQUAL(host, ""); UNIT_ASSERT_VALUES_EQUAL(port, 0); } - // port overflow - auto testCase = []() { - TStringBuf scheme("unknown"), host("unknown"); - ui16 port = 0; - GetSchemeHostAndPort("https://ya.ru:65536/bebe", scheme, host, port); - }; - UNIT_ASSERT_EXCEPTION(testCase(), yexception); - } + // port overflow + auto testCase = []() { + TStringBuf scheme("unknown"), host("unknown"); + ui16 port = 0; + GetSchemeHostAndPort("https://ya.ru:65536/bebe", scheme, host, port); + }; + UNIT_ASSERT_EXCEPTION(testCase(), yexception); + } Y_UNIT_TEST(TestCutUrlPrefixes) { UNIT_ASSERT_VALUES_EQUAL("ya.ru/bebe", CutUrlPrefixes("http://ya.ru/bebe")); diff --git a/library/cpp/testing/unittest/registar.h b/library/cpp/testing/unittest/registar.h index ec74ef88dc..44517a0092 100644 --- a/library/cpp/testing/unittest/registar.h +++ b/library/cpp/testing/unittest/registar.h @@ -375,26 +375,26 @@ public: \ #define UNIT_FAIL_NONFATAL(M) UNIT_FAIL_NONFATAL_IMPL("forced failure", M) //types -#define UNIT_ASSERT_TYPES_EQUAL(A, B) \ - do { \ - if (!std::is_same<A, B>::value) { \ +#define UNIT_ASSERT_TYPES_EQUAL(A, B) \ + do { \ + if (!std::is_same<A, B>::value) { \ UNIT_FAIL_IMPL("types equal assertion failed", (::TStringBuilder() << #A << " (" << TypeName<A>() << ") != " << #B << " (" << TypeName<B>() << ")").data()); \ - } \ - } while (false) + } \ + } while (false) //doubles // UNIT_ASSERT_DOUBLES_EQUAL_DEPRECATED* macros do not handle NaNs correctly (see IGNIETFERRO-1419) and are for backward compatibility // only. Consider switching to regular UNIT_ASSERT_DOUBLES_EQUAL* macros if you're still using the deprecated version. #define UNIT_ASSERT_DOUBLES_EQUAL_DEPRECATED_C(E, A, D, C) \ - do { \ - if (std::abs((E) - (A)) > (D)) { \ - const auto _es = ToString((long double)(E)); \ - const auto _as = ToString((long double)(A)); \ - const auto _ds = ToString((long double)(D)); \ + do { \ + if (std::abs((E) - (A)) > (D)) { \ + const auto _es = ToString((long double)(E)); \ + const auto _as = ToString((long double)(A)); \ + const auto _ds = ToString((long double)(D)); \ auto&& failMsg = Sprintf("std::abs(%s - %s) > %s %s", _es.data(), _as.data(), _ds.data(), (::TStringBuilder() << C).data()); \ - UNIT_FAIL_IMPL("assertion failure", failMsg); \ - } \ - } while (false) + UNIT_FAIL_IMPL("assertion failure", failMsg); \ + } \ + } while (false) #define UNIT_ASSERT_DOUBLES_EQUAL_DEPRECATED(E, A, D) UNIT_ASSERT_DOUBLES_EQUAL_DEPRECATED_C(E, A, D, "") @@ -472,72 +472,72 @@ public: \ #define UNIT_ASSERT_STRINGS_UNEQUAL(A, B) UNIT_ASSERT_STRINGS_UNEQUAL_C(A, B, "") //bool -#define UNIT_ASSERT_C(A, C) \ - do { \ - if (!(A)) { \ +#define UNIT_ASSERT_C(A, C) \ + do { \ + if (!(A)) { \ UNIT_FAIL_IMPL("assertion failed", Sprintf("(%s) %s", #A, (::TStringBuilder() << C).data())); \ - } \ - } while (false) + } \ + } while (false) #define UNIT_ASSERT(A) UNIT_ASSERT_C(A, "") //general -#define UNIT_ASSERT_EQUAL_C(A, B, C) \ - do { \ - if (!((A) == (B))) { \ +#define UNIT_ASSERT_EQUAL_C(A, B, C) \ + do { \ + if (!((A) == (B))) { \ UNIT_FAIL_IMPL("equal assertion failed", Sprintf("%s == %s %s", #A, #B, (::TStringBuilder() << C).data())); \ - } \ - } while (false) + } \ + } while (false) #define UNIT_ASSERT_EQUAL(A, B) UNIT_ASSERT_EQUAL_C(A, B, "") -#define UNIT_ASSERT_UNEQUAL_C(A, B, C) \ - do { \ - if ((A) == (B)) { \ +#define UNIT_ASSERT_UNEQUAL_C(A, B, C) \ + do { \ + if ((A) == (B)) { \ UNIT_FAIL_IMPL("unequal assertion failed", Sprintf("%s != %s %s", #A, #B, (::TStringBuilder() << C).data()));\ - } \ - } while (false) + } \ + } while (false) #define UNIT_ASSERT_UNEQUAL(A, B) UNIT_ASSERT_UNEQUAL_C(A, B, "") -#define UNIT_ASSERT_LT_C(A, B, C) \ - do { \ - if (!((A) < (B))) { \ +#define UNIT_ASSERT_LT_C(A, B, C) \ + do { \ + if (!((A) < (B))) { \ UNIT_FAIL_IMPL("less-than assertion failed", Sprintf("%s < %s %s", #A, #B, (::TStringBuilder() << C).data())); \ - } \ - } while (false) + } \ + } while (false) #define UNIT_ASSERT_LT(A, B) UNIT_ASSERT_LT_C(A, B, "") -#define UNIT_ASSERT_LE_C(A, B, C) \ - do { \ - if (!((A) <= (B))) { \ +#define UNIT_ASSERT_LE_C(A, B, C) \ + do { \ + if (!((A) <= (B))) { \ UNIT_FAIL_IMPL("less-or-equal assertion failed", Sprintf("%s <= %s %s", #A, #B, (::TStringBuilder() << C).data())); \ - } \ - } while (false) + } \ + } while (false) #define UNIT_ASSERT_LE(A, B) UNIT_ASSERT_LE_C(A, B, "") -#define UNIT_ASSERT_GT_C(A, B, C) \ - do { \ - if (!((A) > (B))) { \ +#define UNIT_ASSERT_GT_C(A, B, C) \ + do { \ + if (!((A) > (B))) { \ UNIT_FAIL_IMPL("greater-than assertion failed", Sprintf("%s > %s %s", #A, #B, (::TStringBuilder() << C).data())); \ - } \ - } while (false) + } \ + } while (false) #define UNIT_ASSERT_GT(A, B) UNIT_ASSERT_GT_C(A, B, "") #define UNIT_ASSERT_GE_C(A, B, C) \ - do { \ - if (!((A) >= (B))) { \ + do { \ + if (!((A) >= (B))) { \ UNIT_FAIL_IMPL("greater-or-equal assertion failed", Sprintf("%s >= %s %s", #A, #B, (::TStringBuilder() << C).data())); \ - } \ - } while (false) + } \ + } while (false) #define UNIT_ASSERT_GE(A, B) UNIT_ASSERT_GE_C(A, B, "") #define UNIT_CHECK_GENERATED_EXCEPTION_C(A, E, C) \ - do { \ + do { \ try { \ (void)(A); \ } catch (const ::NUnitTest::TAssertException&) { \ @@ -546,20 +546,20 @@ public: \ break; \ } \ UNIT_ASSERT_C(0, "Exception hasn't been thrown, but it should have happened " << C); \ - } while (false) + } while (false) #define UNIT_CHECK_GENERATED_EXCEPTION(A, E) UNIT_CHECK_GENERATED_EXCEPTION_C(A, E, "") -#define UNIT_CHECK_GENERATED_NO_EXCEPTION_C(A, E, C) \ - do { \ - try { \ - (void)(A); \ - } catch (const ::NUnitTest::TAssertException&) { \ - throw; \ - } catch (const E&) { \ - UNIT_ASSERT_C(0, "Exception has been thrown, but it shouldn't have happened " << C); \ - } \ - } while (false) +#define UNIT_CHECK_GENERATED_NO_EXCEPTION_C(A, E, C) \ + do { \ + try { \ + (void)(A); \ + } catch (const ::NUnitTest::TAssertException&) { \ + throw; \ + } catch (const E&) { \ + UNIT_ASSERT_C(0, "Exception has been thrown, but it shouldn't have happened " << C); \ + } \ + } while (false) #define UNIT_CHECK_GENERATED_NO_EXCEPTION(A, E) UNIT_CHECK_GENERATED_NO_EXCEPTION_C(A, E, "and exception message is:\n" << CurrentExceptionMessage()) |