xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
libxrpl
core
detail
LoadMonitor.cpp
1
#include <xrpl/core/LoadMonitor.h>
2
3
#include <xrpl/basics/Log.h>
4
#include <xrpl/basics/UptimeClock.h>
5
#include <xrpl/beast/utility/Journal.h>
6
#include <xrpl/core/LoadEvent.h>
7
8
#include <
chrono
>
9
#include <
mutex
>
10
11
namespace
xrpl
{
12
13
/*
14
15
TODO
16
----
17
18
- Use Journal for logging
19
20
*/
21
22
//------------------------------------------------------------------------------
23
24
LoadMonitor::Stats::Stats
() :
latencyAvg
(0),
latencyPeak
(0)
25
{
26
}
27
28
//------------------------------------------------------------------------------
29
30
LoadMonitor::LoadMonitor
(
beast::Journal
j)
31
:
latencyMSAvg_
(0)
32
,
latencyMSPeak_
(0)
33
,
targetLatencyAvg_
(0)
34
,
targetLatencyPk_
(0)
35
,
lastUpdate_
(
UptimeClock
::now())
36
,
j_
(j)
37
{
38
}
39
40
// VFALCO NOTE WHY do we need "the mutex?" This dependence on
41
// a hidden global, especially a synchronization primitive,
42
// is a flawed design.
43
// It's not clear exactly which data needs to be protected.
44
//
45
// call with the mutex
46
void
47
LoadMonitor::update
()
48
{
49
using namespace
std::chrono_literals;
50
auto
now =
UptimeClock::now
();
51
if
(now ==
lastUpdate_
)
// current
52
return
;
53
54
// VFALCO TODO Why 8?
55
if
((now <
lastUpdate_
) || (now > (
lastUpdate_
+ 8s)))
56
{
57
// way out of date
58
counts_
= 0;
59
latencyEvents_
= 0;
60
latencyMSAvg_
= 0ms;
61
latencyMSPeak_
= 0ms;
62
lastUpdate_
= now;
63
return
;
64
}
65
66
// do exponential decay
67
/*
68
David:
69
70
"Imagine if you add 10 to something every second. And you
71
also reduce it by 1/4 every second. It will "idle" at 40,
72
corresponding to 10 counts per second."
73
*/
74
do
75
{
76
lastUpdate_
+= 1s;
77
counts_
-= ((
counts_
+ 3) / 4);
78
latencyEvents_
-= ((
latencyEvents_
+ 3) / 4);
79
latencyMSAvg_
-= (
latencyMSAvg_
/ 4);
80
latencyMSPeak_
-= (
latencyMSPeak_
/ 4);
81
}
while
(
lastUpdate_
< now);
82
}
83
84
void
85
LoadMonitor::addLoadSample
(
LoadEvent
const
& s)
86
{
87
using namespace
std::chrono
;
88
89
auto
const
total = s.
runTime
() + s.
waitTime
();
90
// Don't include "jitter" as part of the latency
91
auto
const
latency = total < 2ms ? 0ms : round<milliseconds>(total);
92
93
if
(latency > 500ms)
94
{
95
auto
mj = (latency > 1s) ?
j_
.warn() :
j_
.info();
96
JLOG(mj) <<
"Job: "
<< s.
name
() <<
" run: "
<<
round<milliseconds>
(s.
runTime
()).count()
97
<<
"ms"
98
<<
" wait: "
<<
round<milliseconds>
(s.
waitTime
()).count() <<
"ms"
;
99
}
100
101
addSamples
(1, latency);
102
}
103
109
void
110
LoadMonitor::addSamples
(
int
count
,
std::chrono::milliseconds
latency)
111
{
112
std::scoped_lock
const
sl(
mutex_
);
113
114
update
();
115
counts_
+=
count
;
116
latencyEvents_
+=
count
;
117
latencyMSAvg_
+= latency;
118
latencyMSPeak_
+= latency;
119
120
auto
const
latencyPeak =
latencyEvents_
* latency * 4 /
count
;
121
122
if
(
latencyMSPeak_
< latencyPeak)
123
latencyMSPeak_
= latencyPeak;
124
}
125
126
void
127
LoadMonitor::setTargetLatency
(
std::chrono::milliseconds
avg,
std::chrono::milliseconds
pk)
128
{
129
targetLatencyAvg_
= avg;
130
targetLatencyPk_
= pk;
131
}
132
133
bool
134
LoadMonitor::isOverTarget
(
std::chrono::milliseconds
avg,
std::chrono::milliseconds
peak)
135
{
136
using namespace
std::chrono_literals;
137
return
(
targetLatencyPk_
> 0ms && (peak >
targetLatencyPk_
)) ||
138
(
targetLatencyAvg_
> 0ms && (avg >
targetLatencyAvg_
));
139
}
140
141
bool
142
LoadMonitor::isOver
()
143
{
144
std::scoped_lock
const
sl(
mutex_
);
145
146
update
();
147
148
if
(
latencyEvents_
== 0)
149
return
false
;
150
151
return
isOverTarget
(
152
latencyMSAvg_
/ (
latencyEvents_
* 4),
latencyMSPeak_
/ (
latencyEvents_
* 4));
153
}
154
155
LoadMonitor::Stats
156
LoadMonitor::getStats
()
157
{
158
using namespace
std::chrono_literals;
159
Stats
stats;
160
161
std::scoped_lock
const
sl(
mutex_
);
162
163
update
();
164
165
stats.
count
=
counts_
/ 4;
166
167
if
(
latencyEvents_
== 0)
168
{
169
stats.
latencyAvg
= 0ms;
170
stats.
latencyPeak
= 0ms;
171
}
172
else
173
{
174
stats.
latencyAvg
=
latencyMSAvg_
/ (
latencyEvents_
* 4);
175
stats.
latencyPeak
=
latencyMSPeak_
/ (
latencyEvents_
* 4);
176
}
177
178
stats.
isOverloaded
=
isOverTarget
(stats.
latencyAvg
, stats.
latencyPeak
);
179
180
return
stats;
181
}
182
183
}
// namespace xrpl
chrono
beast::Journal
A generic endpoint for log messages.
Definition
Journal.h:44
xrpl::LoadEvent
Definition
LoadEvent.h:16
xrpl::LoadEvent::waitTime
std::chrono::steady_clock::duration waitTime() const
Definition
LoadEvent.cpp:35
xrpl::LoadEvent::runTime
std::chrono::steady_clock::duration runTime() const
Definition
LoadEvent.cpp:41
xrpl::LoadEvent::name
std::string const & name() const
Definition
LoadEvent.cpp:29
xrpl::LoadMonitor::latencyMSPeak_
std::chrono::milliseconds latencyMSPeak_
Definition
LoadMonitor.h:61
xrpl::LoadMonitor::addLoadSample
void addLoadSample(LoadEvent const &sample)
Definition
LoadMonitor.cpp:85
xrpl::LoadMonitor::counts_
std::uint64_t counts_
Definition
LoadMonitor.h:58
xrpl::LoadMonitor::setTargetLatency
void setTargetLatency(std::chrono::milliseconds avg, std::chrono::milliseconds pk)
Definition
LoadMonitor.cpp:127
xrpl::LoadMonitor::targetLatencyAvg_
std::chrono::milliseconds targetLatencyAvg_
Definition
LoadMonitor.h:62
xrpl::LoadMonitor::getStats
Stats getStats()
Definition
LoadMonitor.cpp:156
xrpl::LoadMonitor::latencyEvents_
int latencyEvents_
Definition
LoadMonitor.h:59
xrpl::LoadMonitor::isOverTarget
bool isOverTarget(std::chrono::milliseconds avg, std::chrono::milliseconds peak)
Definition
LoadMonitor.cpp:134
xrpl::LoadMonitor::addSamples
void addSamples(int count, std::chrono::milliseconds latency)
Add multiple samples.
Definition
LoadMonitor.cpp:110
xrpl::LoadMonitor::mutex_
std::mutex mutex_
Definition
LoadMonitor.h:56
xrpl::LoadMonitor::LoadMonitor
LoadMonitor(beast::Journal j)
Definition
LoadMonitor.cpp:30
xrpl::LoadMonitor::latencyMSAvg_
std::chrono::milliseconds latencyMSAvg_
Definition
LoadMonitor.h:60
xrpl::LoadMonitor::lastUpdate_
UptimeClock::time_point lastUpdate_
Definition
LoadMonitor.h:64
xrpl::LoadMonitor::update
void update()
Definition
LoadMonitor.cpp:47
xrpl::LoadMonitor::j_
beast::Journal const j_
Definition
LoadMonitor.h:65
xrpl::LoadMonitor::targetLatencyPk_
std::chrono::milliseconds targetLatencyPk_
Definition
LoadMonitor.h:63
xrpl::LoadMonitor::isOver
bool isOver()
Definition
LoadMonitor.cpp:142
xrpl::UptimeClock
Tracks program uptime to seconds precision.
Definition
UptimeClock.h:19
xrpl::UptimeClock::now
static time_point now()
Definition
UptimeClock.cpp:49
std::count
T count(T... args)
std::chrono::milliseconds
mutex
std::chrono
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
std::round
T round(T... args)
std::scoped_lock
xrpl::LoadMonitor::Stats
Definition
LoadMonitor.h:37
xrpl::LoadMonitor::Stats::latencyPeak
std::chrono::milliseconds latencyPeak
Definition
LoadMonitor.h:42
xrpl::LoadMonitor::Stats::latencyAvg
std::chrono::milliseconds latencyAvg
Definition
LoadMonitor.h:41
xrpl::LoadMonitor::Stats::Stats
Stats()
Definition
LoadMonitor.cpp:24
xrpl::LoadMonitor::Stats::isOverloaded
bool isOverloaded
Definition
LoadMonitor.h:43
xrpl::LoadMonitor::Stats::count
std::uint64_t count
Definition
LoadMonitor.h:40
Generated by
1.17.0