00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef ACCUMULATOR_H
00034 #define ACCUMULATOR_H
00035
00036 #include <cassert>
00037 #include <string>
00038 #include "mhash_map.h"
00039 #include "Log.h"
00040 #include "TimeUtil.h"
00041 #include "ScopedLock.h"
00042 #include "BinaryLogObject.h"
00043
00049
00050
00079 class Accumulator {
00080 public:
00081 static const std::string NETWORK_READ;
00082 static const std::string NETWORK_READ_SELECTOR;
00083 static const std::string NETWORK_WRITE;
00084 static const std::string NETWORK_WRITE_SELECTOR;
00085 static const std::string TCP_READ;
00086 static const std::string TCP_READ_SELECTOR;
00087 static const std::string TCP_WRITE;
00088 static const std::string TCP_WRITE_SELECTOR;
00089 static const std::string UDP_READ;
00090 static const std::string UDP_READ_SELECTOR;
00091 static const std::string UDP_WRITE;
00092 static const std::string UDP_WRITE_SELECTOR;
00093 static const std::string HTTP_CLIENT_READ;
00094 static const std::string HTTP_CLIENT_READ_SELECTOR;
00095 static const std::string HTTP_CLIENT_WRITE;
00096 static const std::string HTTP_CLIENT_WRITE_SELECTOR;
00097 static const std::string HTTP_SERVER_READ;
00098 static const std::string HTTP_SERVER_READ_SELECTOR;
00099 static const std::string HTTP_SERVER_WRITE;
00100 static const std::string HTTP_SERVER_WRITE_SELECTOR;
00101 static const std::string TRANSPORT_SEND;
00102 static const std::string TRANSPORT_SEND_SELECTOR;
00103 static const std::string TRANSPORT_RECV;
00104 static const std::string TRANSPORT_RECV_SELECTOR;
00105 static const std::string TRANSPORT_RECV_CANCELED;
00106 static const std::string TRANSPORT_RECV_CANCELED_SELECTOR;
00107 static const std::string FILE_WRITE;
00108 static const std::string FILE_WRITE_SELECTOR;
00109 static const std::string APPLICATION_RECV;
00110 static const std::string APPLICATION_RECV_SELECTOR;
00111 static const std::string APPLICATION_SEND;
00112 static const std::string APPLICATION_SEND_SELECTOR;
00113 static const std::string DB_WRITE_BYTES;
00114 static const std::string DB_WRITE_BYTES_SELECTOR;
00115 static const std::string DB_WRITE_COUNT;
00116 static const std::string DB_WRITE_COUNT_SELECTOR;
00117 static const std::string DB_ERASE_COUNT;
00118 static const std::string DB_ERASE_COUNT_SELECTOR;
00119
00120 public:
00122 static Accumulator* Instance(const std::string& counter) {
00123 ScopedLock sl(alock);
00124 Accumulator* r = 0;
00125 AccumulatorMap::iterator i = instances.find(counter);
00126 if (i == instances.end()) {
00127 r = new Accumulator();
00128 r->logId = Log::getId("Accumulator::" + counter);
00129 instances[counter] = r;
00130 }
00131 else {
00132 r = i->second;
00133 }
00134 return r;
00135 }
00136
00147 void startTimer() {
00148 startTime = 0;
00149 useTimer = true;
00150 }
00151
00153 void stopTimer() { useTimer = false; }
00154
00163 void accumulate(unsigned int amount) {
00164 ScopedLock sl(alock);
00165 accumulateUnlocked(amount);
00166 }
00167
00176 void accumulateUnlocked(unsigned int amount) {
00177 totalBytes += amount;
00178 if (useTimer) {
00179 lastTime = TimeUtil::timeu();
00180 if (startTime == 0) {
00181 startTime = lastTime;
00182 }
00183 }
00184 }
00185
00187 uint64_t getAmount() const { return totalBytes; }
00189 uint64_t getDiff() const { return totalBytes - diff; }
00191 uint64_t resetDiff() {
00192
00193 uint64_t r = totalBytes - diff;
00194 diff = totalBytes;
00195 return r;
00196 }
00197
00198 uint64_t getStartTime() { return startTime; }
00199 uint64_t getLastTime() { return lastTime; }
00200
00201 static void dumpAll();
00202 static void logAll();
00203 static void startLogging(uint64_t interval = 1*1000*1000);
00204 static void stopLogging();
00205
00206 protected:
00207 static void* startLoggingThread(void* arg);
00208
00209 private:
00210 static void lock() {
00211 assert(pthread_mutex_lock(&alock) == 0);
00212 }
00213 static void unlock() {
00214 assert(pthread_mutex_unlock(&alock) == 0);
00215 }
00216
00217
00218 private:
00219 typedef mace::hash_map<std::string, Accumulator*, mace::SoftState, hash_string> AccumulatorMap;
00220 static AccumulatorMap instances;
00221 static bool isLogging;
00222 static pthread_t athread;
00223 static pthread_mutex_t alock;
00224
00225 uint64_t totalBytes;
00226 uint64_t diff;
00227 bool useTimer;
00228 uint64_t startTime;
00229 uint64_t lastTime;
00230 log_id_t logId;
00231
00232 Accumulator() : totalBytes(0), diff(0), useTimer(false), startTime(0), lastTime(0) {}
00233 };
00234
00235 class AccumulatorLogObject : public mace::BinaryLogObject, public mace::PrintPrintable {
00236 public:
00237 uint64_t total;
00238 uint64_t diff;
00239
00240 AccumulatorLogObject() : total(0), diff(0) {}
00241 AccumulatorLogObject(uint64_t t, uint64_t d) : total(t), diff(d) {}
00242
00243
00244 void serialize(std::string& __str) const {
00245 mace::serialize(__str, &total);
00246 mace::serialize(__str, &diff);
00247 }
00248
00249 int deserialize(std::istream& in) throw(mace::SerializationException) {
00250 int sz = 0;
00251 sz += mace::deserialize(in, &total);
00252 sz += mace::deserialize(in, &diff);
00253 return sz;
00254 }
00255
00256 void print(std::ostream& __out) const {
00257 __out << total << " " << diff;
00258 }
00259
00260 const std::string& getLogType() const {
00261 static const std::string type = "AC";
00262 return type;
00263 }
00264
00265 const std::string& getLogDescription() const {
00266 static const std::string desc = "Accumulator";
00267 return desc;
00268 }
00269
00270 LogClass getLogClass() const {
00271 return OTHER;
00272 }
00273
00274 static void init();
00275 };
00276
00277 #endif // ACCUMULATOR_H