Stroika Library 3.0d18
 
Loading...
Searching...
No Matches
OperationalStatistics.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2021. All rights reserved
3 */
4#include "Stroika/Frameworks/StroikaPreComp.h"
5
7#include "Stroika/Foundation/Common/GUID.h"
8#include "Stroika/Foundation/Common/Property.h"
12
13#include "OperationalStatistics.h"
14
15using namespace std;
16
17using namespace Stroika::Foundation;
20using namespace Stroika::Foundation::Execution;
21using namespace Stroika::Foundation::Time;
22
23using Memory::BLOB;
25
26using namespace Stroika::Samples::HTMLUI;
27
28// Comment this in to turn on aggressive noisy DbgTrace in this module
29// #define USE_NOISY_TRACE_IN_THIS_MODULE_ 1
30
31// @todo Lose DIGEST code and use new UUID::CreateNew () method when available.
32
33/*
34 ********************************************************************************
35 ***************** OperationalStatisticsMgr::ProcessAPICmd **********************
36 ********************************************************************************
37 */
38OperationalStatisticsMgr::ProcessAPICmd::~ProcessAPICmd ()
39{
40 TimePointSeconds now{Time::GetTickCount ()};
41 sThe.Add_ (Rec_{Rec_::Kind::eAPI, now, now - fStart_});
42}
43
44void OperationalStatisticsMgr::ProcessAPICmd::NoteError ()
45{
46 TimePointSeconds now{Time::GetTickCount ()};
47 sThe.Add_ (Rec_{.fKind = Rec_::Kind::eAPIError, .fAt = now, .fDuration = 0s});
48}
49
50/*
51 ********************************************************************************
52 ***************************** OperationalStatisticsMgr *************************
53 ********************************************************************************
54 */
55void OperationalStatisticsMgr::RecordActiveRunningTasksCount (size_t length)
56{
57 TimePointSeconds now{Time::GetTickCount ()};
58 sThe.Add_ (Rec_{.fKind = Rec_::Kind::eAPIActiveRunningTasks, .fAt = now, .fDuration = 0s, .fLength = length});
59}
60
61void OperationalStatisticsMgr::RecordOpenConnectionCount (size_t length)
62{
63 TimePointSeconds now{Time::GetTickCount ()};
64 sThe.Add_ (Rec_{.fKind = Rec_::Kind::eAPIOpenConnectionCount, .fAt = now, .fDuration = 0s, .fLength = length});
65}
66
67void OperationalStatisticsMgr::RecordProcessingConnectionCount (size_t length)
68{
69 TimePointSeconds now{Time::GetTickCount ()};
70 sThe.Add_ (Rec_{.fKind = Rec_::Kind::eAPIProcessingConnectionCount, .fAt = now, .fDuration = 0s, .fLength = length});
71}
72
73auto OperationalStatisticsMgr::GetStatistics () const -> Statistics
74{
75 Statistics result;
76
77 // hit every entry and just skip those with null events
78 TimePointSeconds skipBefore = Time::GetTickCount () - kLookbackInterval;
79
80 // could optimize slightly and skip a bunch in a row, but not worth the trouble probably
81 Iterable<Rec_> allApplicable = [&] () {
82 lock_guard lk{fMutex_};
83 return Sequence<Rec_>{begin (fRollingHistory_), end (fRollingHistory_)}.Where (
84 [&] (const Rec_& r) { return r.fAt >= skipBefore and r.fKind != Rec_::Kind::eNull; });
85 }();
86
87 {
88 Iterable<DurationSeconds> apiTimes = allApplicable.Map<Iterable<DurationSeconds>> ([] (const Rec_& r) -> optional<DurationSeconds> {
89 if (r.fKind == Rec_::Kind::eAPI)
90 return r.fDuration;
91 return nullopt;
92 });
93 if (not apiTimes.empty ()) {
94 result.fRecentAPI.fMeanDuration = Duration{Math::Mean (apiTimes)};
95 result.fRecentAPI.fMedianDuration = Duration{Math::Median (apiTimes)};
96 result.fRecentAPI.fMaxDuration = Duration{*apiTimes.Max ()};
97 }
98 result.fRecentAPI.fCallsCompleted = static_cast<unsigned int> (apiTimes.length ());
99 result.fRecentAPI.fErrors =
100 static_cast<unsigned int> (allApplicable.Count ([] (const Rec_& r) { return r.fKind == Rec_::Kind::eAPIError; }));
101 }
102 {
103 Iterable<float> activeRunningWSAPITasks = allApplicable.Map<Iterable<float>> ([] (const Rec_& r) -> optional<float> {
104 if (r.fKind == Rec_::Kind::eAPIActiveRunningTasks)
105 return static_cast<float> (r.fLength);
106 return nullopt;
107 });
108 if (not activeRunningWSAPITasks.empty ()) {
109 result.fRecentAPI.fMedianRunningAPITasks = Math::Median (activeRunningWSAPITasks);
110 }
111 }
112 return result;
113}
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
Definition Realtime.h:82
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual RESULT_CONTAINER Where(INCLUDE_PREDICATE &&includeIfTrue) const
Duration is a chrono::duration<double> (=.
Definition Duration.h:96
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237
nonvirtual optional< T > Max() const
Definition Iterable.inl:988
nonvirtual size_t length() const
STL-ish alias for size() - really in STL only used in string, I think, but still makes sense as an al...
nonvirtual RESULT_CONTAINER Map(ELEMENT_MAPPER &&elementMapper) const
functional API which iterates over all members of an Iterable, applies a map function to each element...
nonvirtual size_t Count() const
with no args, same as size, with function filter arg, returns number of items that pass.
nonvirtual bool empty() const
Returns true iff size() == 0.
Definition Iterable.inl:308
STL namespace.