aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Larsson <[email protected]>2021-09-30 12:26:08 +0200
committerPer Larsson <[email protected]>2021-09-30 12:26:08 +0200
commit37be048744dacdee0c8acc1630794ede73457788 (patch)
tree287948744482cf830d85bbcbef4d48b1fd4277b9
parentFixed compact binary to JSON float/double format specifier. (diff)
parentstructured cache: added request meter and stats reporting (diff)
downloadzen-37be048744dacdee0c8acc1630794ede73457788.tar.xz
zen-37be048744dacdee0c8acc1630794ede73457788.zip
Merged main.
-rw-r--r--zencore/include/zencore/stats.h20
-rw-r--r--zencore/stats.cpp46
-rw-r--r--zenserver/cache/structuredcache.cpp7
-rw-r--r--zenserver/cache/structuredcache.h1
4 files changed, 59 insertions, 15 deletions
diff --git a/zencore/include/zencore/stats.h b/zencore/include/zencore/stats.h
index 7665d0cf5..f61184ced 100644
--- a/zencore/include/zencore/stats.h
+++ b/zencore/include/zencore/stats.h
@@ -7,6 +7,10 @@
#include <atomic>
#include <random>
+namespace zen {
+class CbObjectWriter;
+}
+
namespace zen::metrics {
template<typename T>
@@ -77,18 +81,19 @@ public:
Meter();
~Meter();
- double Rate1(); // One-minute rate
- double Rate5(); // Five-minute rate
- double Rate15(); // Fifteen-minute rate
- double MeanRate(); // Mean rate since instantiation of this meter
- void Mark(uint64_t Count = 1); // Register one or more events
+ inline uint64_t Count() const { return m_TotalCount; }
+ double Rate1(); // One-minute rate
+ double Rate5(); // Five-minute rate
+ double Rate15(); // Fifteen-minute rate
+ double MeanRate() const; // Mean rate since instantiation of this meter
+ void Mark(uint64_t Count = 1); // Register one or more events
private:
std::atomic<uint64_t> m_TotalCount{0}; // Accumulator counting number of marks since beginning
std::atomic<uint64_t> m_PendingCount{0}; // Pending EWMA update accumulator
std::atomic<uint64_t> m_StartTick{0}; // Time this was instantiated (for mean)
std::atomic<uint64_t> m_LastTick{0}; // Timestamp of last EWMA tick
- std::atomic<int64_t> m_Remain{0}; // Tracks the "modulo" of tick time
+ std::atomic<int64_t> m_Remainder{0}; // Tracks the "modulo" of tick time
bool m_IsFirstTick = true;
RawEWMA m_RateM1;
RawEWMA m_RateM5;
@@ -175,6 +180,9 @@ private:
std::atomic<int64_t> m_Count{0};
};
+void EmitSnapshot(std::string_view Tag, const Histogram& Stat, CbObjectWriter& Cbo);
+void EmitSnapshot(std::string_view Tag, Meter& Stat, CbObjectWriter& Cbo);
+
} // namespace zen::metrics
namespace zen {
diff --git a/zencore/stats.cpp b/zencore/stats.cpp
index 2a9b0a06f..53086f3ec 100644
--- a/zencore/stats.cpp
+++ b/zencore/stats.cpp
@@ -1,6 +1,8 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "zencore/stats.h"
+
+#include <zencore/compactbinarybuilder.h>
#include "zencore/intmath.h"
#include "zencore/thread.h"
#include "zencore/timer.h"
@@ -79,18 +81,18 @@ Meter::TickIfNecessary()
if (m_LastTick.compare_exchange_strong(OldTick, NewTick))
{
- m_Remain.fetch_add(Age);
+ m_Remainder.fetch_add(Age);
do
{
- int64_t Remain = m_Remain.load(std::memory_order_relaxed);
+ int64_t Remain = m_Remainder.load(std::memory_order_relaxed);
if (Remain < 0)
{
return;
}
- if (m_Remain.compare_exchange_strong(Remain, Remain - CountPerTick))
+ if (m_Remainder.compare_exchange_strong(Remain, Remain - CountPerTick))
{
Tick();
}
@@ -140,7 +142,7 @@ Meter::Rate15()
}
double
-Meter::MeanRate()
+Meter::MeanRate() const
{
const uint64_t Count = m_TotalCount.load(std::memory_order_relaxed);
@@ -222,7 +224,7 @@ UniformSample::Update(int64_t Value)
SampleSnapshot
UniformSample::Snapshot() const
{
- uint64_t ValuesSize = Size();
+ uint64_t ValuesSize = Size();
std::vector<double> Values(ValuesSize);
for (int i = 0; i < ValuesSize; ++i)
@@ -336,8 +338,8 @@ SampleSnapshot::GetQuantileValue(double Quantile)
}
const int32_t Index = (int32_t)Pos;
- const double Lower = m_Values[Index - 1];
- const double Upper = m_Values[Index];
+ const double Lower = m_Values[Index - 1];
+ const double Upper = m_Values[Index];
// Lerp
return Lower + (Pos - std::floor(Pos)) * (Upper - Lower);
@@ -351,6 +353,34 @@ SampleSnapshot::GetValues() const
//////////////////////////////////////////////////////////////////////////
+void
+EmitSnapshot(std::string_view Tag, const Histogram& Stat, CbObjectWriter& Cbo)
+{
+ Cbo.BeginObject(Tag);
+
+ SampleSnapshot Snap = Stat.Snapshot();
+
+ Cbo << "count" << Stat.Count() << "avg" << Stat.Mean();
+ Cbo << "min" << Stat.Min() << "max" << Stat.Max();
+ Cbo << "p75" << Snap.Get75Percentile() << "p95" << Snap.Get95Percentile() << "p99" << Snap.Get99Percentile() << "p999"
+ << Snap.Get999Percentile();
+
+ Cbo.EndObject();
+}
+
+void
+EmitSnapshot(std::string_view Tag, Meter& Stat, CbObjectWriter& Cbo)
+{
+ Cbo.BeginObject(Tag);
+
+ Cbo << "count" << Stat.Count() << "rate_mean" << Stat.MeanRate();
+ Cbo << "rate_1" << Stat.Rate1() << "rate_5" << Stat.Rate5() << "rate_15" << Stat.Rate15();
+
+ Cbo.EndObject();
+}
+
+//////////////////////////////////////////////////////////////////////////
+
#if ZEN_WITH_TESTS
TEST_CASE("Core.Stats.Histogram")
@@ -378,7 +408,7 @@ TEST_CASE("Core.Stats.Histogram")
Histo.Update(-2);
CHECK_EQ(Histo.Min(), -2);
CHECK_EQ(Histo.Max(), 2);
- CHECK_EQ(Histo.Mean(), 1/3.0);
+ CHECK_EQ(Histo.Mean(), 1 / 3.0);
SampleSnapshot Snap4 = Histo.Snapshot();
CHECK_EQ(Snap4.Size(), 3);
diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp
index eee3f8279..c3b60ea8d 100644
--- a/zenserver/cache/structuredcache.cpp
+++ b/zenserver/cache/structuredcache.cpp
@@ -194,6 +194,8 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request)
{
CacheRef Ref;
+ m_HttpRequestMeter.Mark(1);
+
Stopwatch Timer;
auto _ = MakeGuard([&] { m_HttpRequests.Update(Timer.GetElapsedTicks()); });
@@ -843,7 +845,10 @@ void
HttpStructuredCacheService::HandleStatusRequest(zen::HttpServerRequest& Request)
{
CbObjectWriter Cbo;
- Cbo << "ok" << true << "http_requests" << m_HttpRequests.Count();
+ Cbo << "ok" << true;
+
+ EmitSnapshot("requests", m_HttpRequests, Cbo);
+ EmitSnapshot("request_rate", m_HttpRequestMeter, Cbo);
Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
}
diff --git a/zenserver/cache/structuredcache.h b/zenserver/cache/structuredcache.h
index 5dfff08ad..f68efa3fd 100644
--- a/zenserver/cache/structuredcache.h
+++ b/zenserver/cache/structuredcache.h
@@ -90,6 +90,7 @@ private:
uint64_t m_LastScrubTime = 0;
metrics::Histogram m_HttpRequests;
+ metrics::Meter m_HttpRequestMeter;
};
} // namespace zen