Attached is a Stats class that I wrote for Nimbus for keeping track and
reporting on various internal events. I could be used to replace a
modest amount of Falcon code scattered around various sub-systems.
In Nimbus, I used the cycle manager thread to do reporting. The
reporting code looks something like this:
Thread *thread = Thread::getThread("MasterCatalog::cycleManager");
Stats snapshot;
snapshot.snapshot(stats);
int dumpMemory = 0;
while (!shutdown)
{
thread->sleep(CYCLE_SLEEP * 1000);
if (verbose & VERBOSE_STATS)
{
snapshot.computeDelta(stats);
if (snapshot.change)
snapshot.log(InterestingStats);
snapshot.snapshot(stats);
}
}
There is also a central Stats object (stats) that is updated with code like:
stats->bump(statNetIn);
in appropriate strategic locations.
Having a single object that is just counters and another to capture the
initial values for an interval, computer the differences, and report
(selected) results is really quite convenient.
Consider it donated without encumbrance.
--
Jim Starkey
President, NimbusDB, Inc.
978 526-1376
#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/time.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <memory.h>
#include "Cloud.h"
#include "Stats.h"
#include "Interlock.h"
#include "Log.h"
#include "LogLock.h"
static const char *names[] = {
"Objects",
"created",
"saved",
"imported",
"exported",
"loaded",
"purged",
"dropped",
"deleted",
"rcvd",
"sent",
"in",
"out",
"---"
};
Stats::Stats(void)
{
memset(buckets, 0, sizeof(buckets));
active = true;
change = false;
}
Stats::~Stats(void)
{
}
void Stats::bump(StatBuckets bucket)
{
if (active)
INTERLOCKED_INCREMENT(buckets[bucket]);
}
int64 Stats::getTime(void)
{
#ifdef _WIN32
return (int64) GetTickCount() * 1000;
#else
struct timeval microTime;
int ret = gettimeofday(µTime, NULL);
return (int64) microTime.tv_sec * 1000000 + microTime.tv_usec;
#endif
}
void Stats::snapshot(Stats* stats)
{
for (int n = 1; n < statMax; ++n)
buckets[n] = stats->buckets[n];
buckets[0] = stats->numberObjects();
startTime = getTime();
}
void Stats::computeDelta(Stats* stats)
{
change = false;
for (int n = 1; n < statMax; ++n)
if ( (buckets[n] = stats->buckets[n] - buckets[n]) > 0)
change = true;
buckets[0] = stats->numberObjects();
deltaTime = getTime() - startTime;
}
void Stats::log(int mask)
{
LogLock logLock;
const char *sep = "";
for (int n = 0; n < statMax; ++n)
if ((mask & (1 << n)) && buckets[n])
{
Log::log(LogInfo, "%s%d %s", sep, buckets[n], names[n]);
sep = ", ";
}
if (sep[0])
Log::log(LogInfo, " in %.1f sec\n", (double) deltaTime / 1000000.0);
}
int Stats::numberObjects(void)
{
return buckets[statObjectsCreated] + buckets[statObjectsImported] -
(buckets[statObjectsDropped] + buckets[statObjectsDeleted]);
}
void Stats::logDelta(int64 start, int64 finish, const char* text, ...)
{
va_list args;
va_start (args, text);
char temp[1024];
if (vsnprintf (temp, sizeof (temp) - 1, text, args) < 0)
temp [sizeof (temp) - 1] = 0;
Log::log(LogInfo, "%s in %.1f seconds\n", temp, (double) (finish - start) / 1000000.0);
}
void Stats::printDelta(int64 start, int64 finish, const char* text, ...)
{
va_list args;
va_start (args, text);
char temp[1024];
if (vsnprintf (temp, sizeof (temp) - 1, text, args) < 0)
temp [sizeof (temp) - 1] = 0;
printf("%s in %.1f seconds\n", temp, (double) (finish - start) / 1000000.0);
}
#ifndef _STATS_H_
#define _STATS_H_
enum StatBuckets {
statObjects = 0,
statObjectsCreated,
statObjectsSaved,
statObjectsImported,
statObjectsExported,
statObjectsLoaded,
statObjectsPurged,
statObjectsDropped,
statObjectsDeleted,
statMsgIn,
statMsgOut,
statNetIn,
statNetOut,
statMax
};
#define M(bit) (1 << bit)
static const int InterestingStats = -1 & ~( M(statNetIn) | M(statNetOut) );
#undef M
class Stats
{
public:
Stats(void);
~Stats(void);
void bump(StatBuckets bucket);
void snapshot(Stats* stats);
void computeDelta(Stats* stats);
void log(int mask);
int numberObjects(void);
static int64 getTime(void);
static void logDelta(int64 start, int64 finish, const char* text, ...);
static void printDelta(int64 start, int64 finish, const char* text, ...);
int64 startTime;
int64 deltaTime;
int buckets[statMax];
bool change;
bool active;
};
#endif
| Thread |
|---|
| • Stats Class | Jim Starkey | 4 Nov |