|
|
@@ -1,6 +1,6 @@ |
|
|
|
// snfLOGmgr.cpp |
|
|
|
// |
|
|
|
// (C) Copyright 2006 - 2009 ARM Research Labs, LLC. |
|
|
|
// (C) Copyright 2006 - 2020 ARM Research Labs, LLC. |
|
|
|
// See www.armresearch.com for the copyright terms. |
|
|
|
// |
|
|
|
// Log Manager implementations see snfLOGmgr.hpp for details. |
|
|
@@ -14,14 +14,132 @@ |
|
|
|
|
|
|
|
namespace cd = codedweller; |
|
|
|
|
|
|
|
//// snfScanData /////////////////////////////////////////////////////////////// |
|
|
|
|
|
|
|
int snfScanData::IPScanCount() { // Return the number of IPs. |
|
|
|
return MyIPCount; |
|
|
|
} |
|
|
|
|
|
|
|
IPScanRecord& snfScanData::newIPScanRecord() { // Get the next free IP scan record. |
|
|
|
if(MaxIPsPerMessage <= MyIPCount) { // Check that we have more records. |
|
|
|
throw NoFreeIPScanRecords(); // If we do not then throw! |
|
|
|
} // If we do have more records then |
|
|
|
IPScanRecord& NewRecord = MyIPScanData[MyIPCount]; // Pick the next available one, |
|
|
|
NewRecord.Ordinal = MyIPCount; // set the ordinal value, |
|
|
|
++MyIPCount; // increase our count, and |
|
|
|
return NewRecord; // return the one we picked. |
|
|
|
} |
|
|
|
|
|
|
|
IPScanRecord& snfScanData::IPScanData(int i) { // Return the IP scan record i. |
|
|
|
if(MyIPCount <= i || 0 > i) { // First check that i is in bounds. |
|
|
|
throw OutOfBounds(); // if it is not then throw! |
|
|
|
} // If the record for [i] is available |
|
|
|
return MyIPScanData[i]; // return it. |
|
|
|
} |
|
|
|
|
|
|
|
void snfScanData::drillPastOrdinal(int O) { // Sets Drill Down flag for IP record O. |
|
|
|
if(0 <= O && O < MaxIPsPerMessage) { // If O is a useable Received ordinal |
|
|
|
DrillDownFlags[O] = true; // then set the Drill Down Flag for O. |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool snfScanData::isDrillDownSource(IPScanRecord& X) { // True if we drill through this source. |
|
|
|
if( |
|
|
|
(0UL != myCallerForcedSourceIP) || // If the source IP has been forced by |
|
|
|
(0UL != myHeaderDirectiveSourceIP) // the caller or by a header directive |
|
|
|
) return false; // then drilldowns are disabled. |
|
|
|
// Otherwise check for a drilldown flag. |
|
|
|
return DrillDownFlags[X.Ordinal]; // Presuming X is valid, return the flag. |
|
|
|
} // If X is not valid we may blow up! |
|
|
|
|
|
|
|
IPScanRecord& snfScanData::SourceIPRecord(IPScanRecord& X) { // Sets the source IP record. |
|
|
|
SourceIPOrdinal = X.Ordinal; // Here's the ordinal. |
|
|
|
SourceIPFoundFlag = true; // Here's the truth flag. |
|
|
|
return X; // Return what was set. |
|
|
|
} |
|
|
|
|
|
|
|
IPScanRecord& snfScanData::SourceIPRecord() { // Gets the source IP record. |
|
|
|
return IPScanData(SourceIPOrdinal); // Return the IP record, or throw |
|
|
|
} // OutOfBounds. |
|
|
|
|
|
|
|
bool snfScanData::FoundSourceIP() { // True if the source IP record was set. |
|
|
|
return SourceIPFoundFlag; // Return what the flag says. |
|
|
|
} |
|
|
|
|
|
|
|
snfIPRange snfScanData::SourceIPRange(snfIPRange R) { // Establish the IP range. |
|
|
|
return (SourceIPRangeFlag = R); // set and return the value w/ R. |
|
|
|
} |
|
|
|
|
|
|
|
snfIPRange snfScanData::SourceIPRange() { // Gets the source IP detection range. |
|
|
|
return SourceIPRangeFlag; // Return what the flag says. |
|
|
|
} |
|
|
|
|
|
|
|
cd::IP4Address snfScanData::HeaderDirectiveSourceIP(cd::IP4Address A) { // set Header directive source IP. |
|
|
|
if(0UL == myHeaderDirectiveSourceIP) myHeaderDirectiveSourceIP = A; // If this value is not set, set it. |
|
|
|
return myHeaderDirectiveSourceIP; // Return the value. |
|
|
|
} |
|
|
|
|
|
|
|
cd::IP4Address snfScanData::HeaderDirectiveSourceIP() { // get Header directive source IP. |
|
|
|
return myHeaderDirectiveSourceIP; // Return the current value. |
|
|
|
} |
|
|
|
|
|
|
|
cd::IP4Address snfScanData::CallerForcedSourceIP(cd::IP4Address A) { // set Caller forced source IP. |
|
|
|
if(0UL == myCallerForcedSourceIP) myCallerForcedSourceIP = A; // If this value is not set, set it. |
|
|
|
return myCallerForcedSourceIP; // Return the value. |
|
|
|
} |
|
|
|
|
|
|
|
cd::IP4Address snfScanData::CallerForcedSourceIP() { // get Caller forced source IP. |
|
|
|
return myCallerForcedSourceIP; // Return the current value. |
|
|
|
} |
|
|
|
|
|
|
|
//// snfLOGmgr ///////////////////////////////////////////////////////////////// |
|
|
|
|
|
|
|
void snfLOGmgr::updateActiveUTC(std::string ActiveUTC) { // Update Active Rulebase UTC. |
|
|
|
cd::ScopeMutex Freeze(MyMutex); // Protect the strings. |
|
|
|
ActiveRulebaseUTC = ActiveUTC; // Update the active timestamp. |
|
|
|
NewerRulebaseIsAvailable = false; // Update availability is now unknown. |
|
|
|
} |
|
|
|
|
|
|
|
void snfLOGmgr::updateAvailableUTC(std::string& AvailableRulebaseTimestamp) { // Changes update avialability stamp. |
|
|
|
cd::ScopeMutex Freeze(MyMutex); // Protect the strings. |
|
|
|
AvailableRulebaseUTC = AvailableRulebaseTimestamp; // Store the new timestamp. |
|
|
|
if(0 < AvailableRulebaseUTC.compare(ActiveRulebaseUTC)) { // If the available timestamp is newer |
|
|
|
NewerRulebaseIsAvailable = true; // than the active then set the flag. |
|
|
|
} else { // If it is not newer then |
|
|
|
NewerRulebaseIsAvailable = false; // reset the flag. |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
std::string snfLOGmgr::ActiveRulebaseTimestamp() { // Get active rulebase timestamp. |
|
|
|
cd::ScopeMutex Freeze(MyMutex); // Protect the string. |
|
|
|
return ActiveRulebaseUTC; // Return it. |
|
|
|
} |
|
|
|
|
|
|
|
std::string snfLOGmgr::AvailableRulebaseTimestamp() { // Get available rulebase timestamp. |
|
|
|
cd::ScopeMutex Freeze(MyMutex); // Protect the strings. |
|
|
|
return AvailableRulebaseUTC; // Return the available timestamp. |
|
|
|
} |
|
|
|
|
|
|
|
bool snfLOGmgr::isUpdateAvailable() { // True if update is available. |
|
|
|
return NewerRulebaseIsAvailable; // Return the flag's value. |
|
|
|
} |
|
|
|
|
|
|
|
int snfLOGmgr::LatestRuleID() { // Query the latest rule id. |
|
|
|
return Status.LatestRuleID; // This simple value is atomic |
|
|
|
} // so we can read it without the mutex. |
|
|
|
|
|
|
|
int snfLOGmgr::RunningTime() { // Get the time we've been alive. |
|
|
|
return (int) difftime(Timestamp(), StartupTime); |
|
|
|
} |
|
|
|
|
|
|
|
//// DiscLogger //////////////////////////////////////////////////////////////// |
|
|
|
|
|
|
|
const ThreadType DiscLogger::Type("DiscLogger"); // The thread's type. |
|
|
|
const cd::ThreadType DiscLogger::Type("DiscLogger"); // The thread's type. |
|
|
|
|
|
|
|
const ThreadState DiscLogger::DiscLogger_Flush("Flushing"); // Flushing state. |
|
|
|
const ThreadState DiscLogger::DiscLogger_Wait("Waiting"); // Waiting state. |
|
|
|
const cd::ThreadState DiscLogger::DiscLogger_Flush("Flushing"); // Flushing state. |
|
|
|
const cd::ThreadState DiscLogger::DiscLogger_Wait("Waiting"); // Waiting state. |
|
|
|
|
|
|
|
DiscLogger::DiscLogger(string N) : // When it is time to start... |
|
|
|
DiscLogger::DiscLogger(std::string N) : // When it is time to start... |
|
|
|
Thread(DiscLogger::Type, N), // DiscLogger Type and Name. |
|
|
|
UseANotB(true), // Set all of the flags to their |
|
|
|
isDirty(false), // appropriate initial state |
|
|
@@ -38,11 +156,11 @@ DiscLogger::~DiscLogger() { |
|
|
|
join(); // Wait for the thread to stop. |
|
|
|
} |
|
|
|
|
|
|
|
void DiscLogger::post(const string Input, const string NewPath) { // Post Input to log. |
|
|
|
void DiscLogger::post(const std::string Input, const std::string NewPath) { // Post Input to log. |
|
|
|
if(!isEnabled) return; // If we're not enabled, eat it. |
|
|
|
ScopeMutex PostingNewDataNobodyMove(BufferControlMutex); // Keep things static while posting. |
|
|
|
cd::ScopeMutex PostingNewDataNobodyMove(BufferControlMutex); // Keep things static while posting. |
|
|
|
if(0 < NewPath.length()) { myPath = NewPath; } // Reset the path if provided. |
|
|
|
string& Buffer = PostingBuffer(); // Grab the posting buffer. |
|
|
|
std::string& Buffer = PostingBuffer(); // Grab the posting buffer. |
|
|
|
if(!inAppendMode) Buffer.clear(); // If overwriting, clear the old. |
|
|
|
Buffer.append(Input); // Add the new data. |
|
|
|
isDirty = true; // We're dirty now. |
|
|
@@ -53,8 +171,8 @@ void DiscLogger::post(const string Input, const string NewPath) { |
|
|
|
// of data to build up in the buffers and that would be bad. |
|
|
|
|
|
|
|
void DiscLogger::flush() { // Flush right now! |
|
|
|
string FilePath; // Local copy of the path. |
|
|
|
ScopeMutex FlushingNow(FlushMutex); // We're flushing. |
|
|
|
std::string FilePath; // Local copy of the path. |
|
|
|
cd::ScopeMutex FlushingNow(FlushMutex); // We're flushing. |
|
|
|
if(isDirty) { // Nothing to do if not dirty. |
|
|
|
BufferControlMutex.lock(); // Lock the buffer controls. |
|
|
|
FlushingBuffer().clear(); // Clear the old flushing buffer. |
|
|
@@ -81,7 +199,7 @@ void DiscLogger::flush() { |
|
|
|
} |
|
|
|
|
|
|
|
void DiscLogger::myTask() { // Main thread task |
|
|
|
Sleeper WaitASecond(1000); // How to wait for 1 second. |
|
|
|
cd::Sleeper WaitASecond(1000); // How to wait for 1 second. |
|
|
|
while(!isTimeToStop) { // Until it is time to stop: |
|
|
|
CurrentThreadState(DiscLogger_Wait); // post our waiting and |
|
|
|
WaitASecond(); // we wait a second, then |
|
|
@@ -200,31 +318,31 @@ void snfCounterPack::reset() { |
|
|
|
|
|
|
|
//// IntervalTimer ///////////////////////////////////////////////////////////// |
|
|
|
|
|
|
|
Timer& IntervalTimer::Active() { // Return the active timer. |
|
|
|
cd::Timer& IntervalTimer::Active() { // Return the active timer. |
|
|
|
return ((ANotB)?A:B); // If A is active, return A |
|
|
|
} // otherwise return B. |
|
|
|
|
|
|
|
Timer& IntervalTimer::Inactive() { // Return the inactive timer. |
|
|
|
cd::Timer& IntervalTimer::Inactive() { // Return the inactive timer. |
|
|
|
return ((ANotB)?B:A); // If A is active, return B |
|
|
|
} // otherwise return A. |
|
|
|
|
|
|
|
msclock IntervalTimer::hack() { // Chop off a new interval & return it. |
|
|
|
cd::msclock IntervalTimer::hack() { // Chop off a new interval & return it. |
|
|
|
Inactive().start(Active().stop()); // Stop the active clock and reference |
|
|
|
ANotB = !ANotB; // it to start the new Active clock. |
|
|
|
return Interval(); // Flip the bit and return the Interval. |
|
|
|
} |
|
|
|
|
|
|
|
msclock IntervalTimer::Interval() { // Return the last interval. |
|
|
|
cd::msclock IntervalTimer::Interval() { // Return the last interval. |
|
|
|
return Inactive().getElapsedTime(); // Return the Inactive elapsed time. |
|
|
|
} |
|
|
|
|
|
|
|
msclock IntervalTimer::Elapsed() { // Return the time since last hack. |
|
|
|
cd::msclock IntervalTimer::Elapsed() { // Return the time since last hack. |
|
|
|
return Active().getElapsedTime(); // Return the Active elapsed time. |
|
|
|
} |
|
|
|
|
|
|
|
//// snfLOGmgr ///////////////////////////////////////////////////////////////// |
|
|
|
|
|
|
|
const ThreadType snfLOGmgr::Type("snfLOGmgr"); // The thread's type. |
|
|
|
const cd::ThreadType snfLOGmgr::Type("snfLOGmgr"); // The thread's type. |
|
|
|
|
|
|
|
snfLOGmgr::snfLOGmgr() : // Constructor for the LOG manager |
|
|
|
Thread(snfLOGmgr::Type, "Log Manager"), // snfLOGmgr Type and Name. |
|
|
@@ -333,19 +451,19 @@ void AppendRatesElement( |
|
|
|
const char* Name, // The name of the element (usually 1 char). |
|
|
|
snf_SMHDMY_Counter& D, // Data counter |
|
|
|
snf_SMHDMY_Counter& T, // Time counter |
|
|
|
ostringstream& S) { // Where to append the formatted output. |
|
|
|
std::ostringstream& S) { // Where to append the formatted output. |
|
|
|
S << "\t\t<" << Name << " " |
|
|
|
<< "s=\'" << snf_AveragePerSecond(D, T) << "\' " |
|
|
|
<< "m=\'" << snf_AveragePerMinute(D, T) << "\' " |
|
|
|
<< "h=\'" << snf_AveragePerHour(D, T) << "\' " |
|
|
|
<< "d=\'" << snf_AveragePerDay(D, T) << "\'/>" |
|
|
|
<< endl; |
|
|
|
<< std::endl; |
|
|
|
} |
|
|
|
|
|
|
|
void AppendHistogramElements(Histogram& H, ostringstream& S) { // Format & output a histogram. |
|
|
|
void AppendHistogramElements(cd::Histogram& H, std::ostringstream& S) { // Format & output a histogram. |
|
|
|
if(0 < H.size()) { // Don't output empty histograms. |
|
|
|
S << "\t\t<histogram hits=\'" << H.Hits() << "\'>" << endl; // Open tag w/ hits count. |
|
|
|
set<HistogramRecord>::iterator iH; // Use an iterator to |
|
|
|
std::set<cd::HistogramRecord>::iterator iH; // Use an iterator to |
|
|
|
for(iH = H.begin(); iH != H.end(); iH++) { // loop through all of the groups. |
|
|
|
S << "\t\t\t<g k=\'" // For each group in the histogram |
|
|
|
<< (*iH).Key << "\' c=\'" // output the key value and |
|
|
@@ -535,7 +653,7 @@ bool snfLOGmgr::do_SecondReport() { |
|
|
|
|
|
|
|
// Just before we go we save our stat for others to see. |
|
|
|
|
|
|
|
ScopeMutex HoldForStatusUpdate(StatusReportMutex); // Hold the mutex just long enough |
|
|
|
cd::ScopeMutex HoldForStatusUpdate(StatusReportMutex); // Hold the mutex just long enough |
|
|
|
SecondReportText = Report.str(); // to post our status and return |
|
|
|
|
|
|
|
// Finally we return the test - Do we have a complete cycle in Seconds? |
|
|
@@ -704,7 +822,7 @@ bool snfLOGmgr::do_MinuteReport() { |
|
|
|
|
|
|
|
// Just before we go we save our stat for others to see. |
|
|
|
|
|
|
|
ScopeMutex HoldForStatusUpdate(StatusReportMutex); // Hold the mutex just long enough |
|
|
|
cd::ScopeMutex HoldForStatusUpdate(StatusReportMutex); // Hold the mutex just long enough |
|
|
|
MinuteReportText = Report.str(); // to post our status and return |
|
|
|
|
|
|
|
return(TimeCounter.Cycled60Minutes()); // True at a full cycle of minutes. |
|
|
@@ -869,21 +987,21 @@ bool snfLOGmgr::do_HourReport() { |
|
|
|
|
|
|
|
// Just before we go we save our stat for others to see. |
|
|
|
|
|
|
|
ScopeMutex HoldForStatusUpdate(StatusReportMutex); // Hold the mutex just long enough |
|
|
|
cd::ScopeMutex HoldForStatusUpdate(StatusReportMutex); // Hold the mutex just long enough |
|
|
|
HourReportText = Report.str(); // to post our status and return |
|
|
|
|
|
|
|
return(TimeCounter.Cycled24Hours()); // True at a full cycle of hours. |
|
|
|
} |
|
|
|
|
|
|
|
void snfLOGmgr::do_StatusReports() { // Do the status reports. |
|
|
|
ScopeMutex PauseWhileITotalThis(MyMutex); // Everybody stop for a bit. Each report |
|
|
|
cd::ScopeMutex PauseWhileITotalThis(MyMutex); // Everybody stop for a bit. Each report |
|
|
|
if(do_SecondReport()) // returns true if it has cycled so |
|
|
|
if(do_MinuteReport()) // that the next report can be checked |
|
|
|
do_HourReport(); // to see if it has cycled. |
|
|
|
} |
|
|
|
|
|
|
|
void snfLOGmgr::myTask() { // Thread: Live stats & reports. |
|
|
|
Sleeper WaitATic(MillisecondsInASecond); // One second sleeper. |
|
|
|
cd::Sleeper WaitATic(MillisecondsInASecond); // One second sleeper. |
|
|
|
while(!TimeToDie) { // Do this until it's time to die. |
|
|
|
if(Configured) { // If we are configured do our work. |
|
|
|
do_StatusReports(); // Make our status reports (chained). |
|
|
@@ -900,7 +1018,7 @@ void snfLOGmgr::myTask() { |
|
|
|
// is a new persistent state. |
|
|
|
|
|
|
|
void snfLOGmgr::configure(snfCFGData& CFGData) { // Update the configuration. |
|
|
|
ScopeMutex HoldOnWhileITweakThisThing(ConfigMutex); |
|
|
|
cd::ScopeMutex HoldOnWhileITweakThisThing(ConfigMutex); |
|
|
|
PersistentFileName = CFGData.paths_workspace_path + ".state"; // Build the persistent state path. |
|
|
|
Status.restore(PersistentFileName); // Load our persistent state. |
|
|
|
NodeId = CFGData.node_licenseid; // Grab the node id for reports. |
|
|
@@ -984,10 +1102,10 @@ void snfLOGmgr::doXHDRs(snfCFGData& CFGData, snfScanData& ScanData) { |
|
|
|
O << "Unknown" // then we emit "Unknown". |
|
|
|
<< SMTPENDL; |
|
|
|
} else { // If the source was identified |
|
|
|
O << ScanData.SourceIPRecord().Ordinal << ", " // then we emit the ordial, |
|
|
|
<< (string) IP4Address(ScanData.SourceIPRecord().IP) << ", " // the IP, and then |
|
|
|
<< ScanData.SourceIPEvaluation // the IP evaluation that was |
|
|
|
<< SMTPENDL; // sent to the scanner. |
|
|
|
O << ScanData.SourceIPRecord().Ordinal << ", " // then we emit the ordial, |
|
|
|
<< (std::string) cd::IP4Address(ScanData.SourceIPRecord().IP) << ", " // the IP, and then |
|
|
|
<< ScanData.SourceIPEvaluation // the IP evaluation that was |
|
|
|
<< SMTPENDL; // sent to the scanner. |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -1158,7 +1276,7 @@ void snfLOGmgr::doXMLLogs(snfCFGData& CFGData, snfScanData& ScanData) { |
|
|
|
if(CFGData.Scan_XML_GBUdb && ScanData.FoundSourceIP()) { // Post gbudb data if needed & ready. |
|
|
|
O << "\t<g " |
|
|
|
<< "o=\'" << ScanData.SourceIPRecord().Ordinal << "\' " |
|
|
|
<< "i=\'" << (string) IP4Address(ScanData.SourceIPRecord().IP) << "\' " |
|
|
|
<< "i=\'" << (std::string) cd::IP4Address(ScanData.SourceIPRecord().IP) << "\' " |
|
|
|
<< "t=\'" << |
|
|
|
((Ugly == ScanData.SourceIPRecord().GBUdbData.Flag())? "u" : |
|
|
|
((Good == ScanData.SourceIPRecord().GBUdbData.Flag())? "g" : |
|
|
@@ -1295,7 +1413,7 @@ void snfLOGmgr::doClassicLogs(snfCFGData& CFGData, snfScanData& ScanData) { |
|
|
|
//// performLTSLogging() -- Mutex NOT locked, second section |
|
|
|
|
|
|
|
void snfLOGmgr::captureLTSMetrics(snfCFGData& CFGData, snfScanData& ScanData) { // LogThisScan section 1 |
|
|
|
ScopeMutex FreezeRightThereWhileITakeThisPicture(MyMutex); // Lock the object for this update. |
|
|
|
cd::ScopeMutex FreezeRightThereWhileITakeThisPicture(MyMutex); // Lock the object for this update. |
|
|
|
|
|
|
|
if(Status.LatestRuleID < ScanData.PatternID) { // If we have a new latest rule id |
|
|
|
Status.LatestRuleID = ScanData.PatternID; // then capture it. |
|
|
@@ -1560,7 +1678,7 @@ void snfLOGmgr::logThisIPTest(IPTestRecord& I, string Action) { |
|
|
|
|
|
|
|
void snfLOGmgr::logThisError(string ContextName, int Code, string Text) { // Log an error message. |
|
|
|
if(!Configured) return; // Do nothing if not configured. |
|
|
|
ScopeMutex LockCFG(MyMutex); // Don't change CFG. I'm using it! |
|
|
|
cd::ScopeMutex LockCFG(MyMutex); // Don't change CFG. I'm using it! |
|
|
|
if(LogOutputMode_File == XML_Log_Mode) { // If XML logs are turned on: |
|
|
|
stringstream O; // Stringstream to format the entry. |
|
|
|
string tmp; // String for use getting timestamp. |
|
|
@@ -1625,7 +1743,7 @@ void snfLOGmgr::logThisError(string ContextName, int Code, string Text) { |
|
|
|
|
|
|
|
void snfLOGmgr::logThisInfo(string ContextName, int Code, string Text) { // Log an informational message. |
|
|
|
if(!Configured) return; // Do nothing if not configured. |
|
|
|
ScopeMutex LockCFG(MyMutex); // Don't change CFG. I'm using it! |
|
|
|
cd::ScopeMutex LockCFG(MyMutex); // Don't change CFG. I'm using it! |
|
|
|
if(LogOutputMode_File == XML_Log_Mode) { // If XML logs are turned on: |
|
|
|
stringstream O; // Stringstream to format the entry. |
|
|
|
string tmp; // String for use getting timestamp. |
|
|
@@ -1687,13 +1805,13 @@ void snfLOGmgr::logThisInfo(string ContextName, int Code, string Text) { |
|
|
|
} |
|
|
|
|
|
|
|
string snfLOGmgr::PlatformVersion(string NewPlatformVersion) { // Set platform version info. |
|
|
|
ScopeMutex FreezeForNewData(MyMutex); // Get the ball and |
|
|
|
cd::ScopeMutex FreezeForNewData(MyMutex); // Get the ball and |
|
|
|
myPlatformVersion = NewPlatformVersion; // set the data. |
|
|
|
return myPlatformVersion; // return the new data. |
|
|
|
} |
|
|
|
|
|
|
|
string snfLOGmgr::PlatformVersion() { // Get platform version info. |
|
|
|
ScopeMutex DontChangeOnMe(MyMutex); // Get the ball and |
|
|
|
cd::ScopeMutex DontChangeOnMe(MyMutex); // Get the ball and |
|
|
|
return myPlatformVersion; // get the data. |
|
|
|
} |
|
|
|
|
|
|
@@ -1713,7 +1831,7 @@ snfCounterPack* snfLOGmgr::getSnapshot() { |
|
|
|
} |
|
|
|
|
|
|
|
bool snfLOGmgr::OkToPeek(int PeekOneInX) { // Test to see if it's ok to peek. |
|
|
|
ScopeMutex JustMe(PeekMutex); // Protect the peek enable counter. |
|
|
|
cd::ScopeMutex JustMe(PeekMutex); // Protect the peek enable counter. |
|
|
|
++PeekEnableCounter; // Bump the counter by one. |
|
|
|
if(PeekEnableCounter >= PeekOneInX) { // If we've made the threshold then |
|
|
|
PeekEnableCounter = 0; // reset the counter and |
|
|
@@ -1723,7 +1841,7 @@ bool snfLOGmgr::OkToPeek(int PeekOneInX) { |
|
|
|
} |
|
|
|
|
|
|
|
bool snfLOGmgr::OkToSample(int SampleOneInX) { // Test to see if it's ok to sample. |
|
|
|
ScopeMutex JustMe(SampleMutex); // Protect the sample enable counter. |
|
|
|
cd::ScopeMutex JustMe(SampleMutex); // Protect the sample enable counter. |
|
|
|
++SampleEnableCounter; // Bump the counter by one. |
|
|
|
if(SampleEnableCounter >= SampleOneInX) { // If we've made the threshold then |
|
|
|
SampleEnableCounter = 0; // reset the counter and |
|
|
@@ -1795,7 +1913,7 @@ string& snfLOGmgr::LocalTimestamp(string& s) { |
|
|
|
} |
|
|
|
|
|
|
|
unsigned int snfLOGmgr::SerialNumber() { // Returns the next serial number. |
|
|
|
ScopeMutex AtomicOperation(SerialNumberMutex); // Lock the serial number mutex. |
|
|
|
cd::ScopeMutex AtomicOperation(SerialNumberMutex); // Lock the serial number mutex. |
|
|
|
++Status.SerialNumberCounter; // Increment the serial number. |
|
|
|
unsigned int result = Status.SerialNumberCounter; // Capture the new value. |
|
|
|
return result; // Return the unique result. |
|
|
@@ -1960,21 +2078,21 @@ double snfLOGmgr::SamplePerMinute() { |
|
|
|
|
|
|
|
const string EmptyStatusSecondReport = "<stats class=\'second\'/>"; // Empty Status.Second looks like this. |
|
|
|
string snfLOGmgr::getStatusSecondReport() { // Get latest status.second report. |
|
|
|
ScopeMutex FlashBulb(StatusReportMutex); // Take a safe snapshot of the report. |
|
|
|
cd::ScopeMutex FlashBulb(StatusReportMutex); // Take a safe snapshot of the report. |
|
|
|
if(0 < SecondReportText.length()) return SecondReportText; // If it's posted then send it. If not |
|
|
|
return EmptyStatusSecondReport; // then send the empty version. |
|
|
|
} |
|
|
|
|
|
|
|
const string EmptyStatusMinuteReport = "<stats class=\'minute\'/>"; // Empty Status.Minute looks like this. |
|
|
|
string snfLOGmgr::getStatusMinuteReport() { // Get latest status.minute report. |
|
|
|
ScopeMutex FlashBulb(StatusReportMutex); // Take a safe snapshot of the report. |
|
|
|
cd::ScopeMutex FlashBulb(StatusReportMutex); // Take a safe snapshot of the report. |
|
|
|
if(0 < MinuteReportText.length()) return MinuteReportText; // If it's posted then send it. If not |
|
|
|
return EmptyStatusMinuteReport; // then send the empty version. |
|
|
|
} |
|
|
|
|
|
|
|
const string EmptyStatusHourReport = "<stats class=\'hour\'/>"; // Empty Status.Hour looks like this. |
|
|
|
string snfLOGmgr::getStatusHourReport() { // Get latest status.hour report. |
|
|
|
ScopeMutex FlashBulb(StatusReportMutex); // Take a safe snapshot of the report. |
|
|
|
cd::ScopeMutex FlashBulb(StatusReportMutex); // Take a safe snapshot of the report. |
|
|
|
if(0 < HourReportText.length()) return HourReportText; // If it's posted then send it. If not |
|
|
|
return EmptyStatusHourReport; // then send the empty version. |
|
|
|
} |