00001
00006 #include <ctime>
00007 #include <sstream>
00008 #include <iostream>
00009 #include <fstream>
00010 #include <cerrno>
00011 #include <csignal>
00012 #include <cstring>
00013
00014 #include <errno.h>
00015 #include <sys/stat.h>
00016 #include <sys/types.h>
00017
00018 #include "ServerLogger.h"
00019 #include "functions.h"
00020
00021 void ServerLogger::operator()() {
00022 while (true) {
00023 saveLogs();
00024 usleep(1000 * interval);
00025 }
00026 }
00027
00028 ServerLogger::ServerLogger(unsigned ninterval, std::string ndirectory) {
00029
00030 pthread_mutex_init(&mutex, NULL);
00031
00032 interval = ninterval;
00033 directory = ndirectory;
00034 reqId = 1;
00035
00036 time_t now;
00037 now = time(NULL);
00038 struct tm *ts;
00039 ts = localtime(&now);
00040 char buf[80];
00041 strftime(buf, sizeof(buf), "%Y-%m-%d %H.%M.%S", ts);
00042 dumpToFile = false;
00043
00044 if (mkdir(directory.c_str(), S_IREAD | S_IWRITE | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH) == -1) {
00045 if (errno == EEXIST) {
00046 dumpToFile = true;
00047 }
00048 } else {
00049 dumpToFile = true;
00050 }
00051
00052 if (dumpToFile) {
00053 fileName = directory + "//";
00054 fileName += buf;
00055
00056 std::ofstream * of = new std::ofstream(fileName.c_str(), std::ios::out);
00057
00058
00059 if (of) {
00060 output = of;
00061 } else {
00062 dumpToFile = false;
00063 output = &std::cout;
00064 }
00065 } else {
00066 output = &std::cout;
00067 }
00068
00069 int ret;
00070 if ((ret = pthread_create(&threadID, NULL, ServerLoggerThread, this))) {
00071 fprintf(stderr, "Server:\tduring starting logger: pthread_create: %s\n", strerror(ret));
00072 exit(1);
00073 }
00074 }
00075
00076 ServerLogger::~ServerLogger() {
00077
00078 pthread_kill(threadID, SIGUSR1);
00079
00080 output->flush();
00081 if (dumpToFile) {
00082 delete output;
00083 }
00084
00085 }
00086
00087 void ServerLogger::saveLogs() {
00088
00089
00090
00091 MUTEX_LOCK(mutex);
00092 std::queue<std::string> copy = logBuffer;
00093 while (!logBuffer.empty()) {
00094 logBuffer.pop();
00095 }
00096 MUTEX_UNLOCK(mutex);
00097
00098 while (!copy.empty()) {
00099
00100 std::string log = copy.front();
00101
00102 *output << log;
00103 output -> flush();
00104
00105 copy.pop();
00106 }
00107
00108
00109 }
00110
00111 void ServerLogger::logNewConnection(const std::string& ip, unsigned port) {
00112
00113 std::ostringstream portStr;
00114 portStr << port;
00115 MUTEX_LOCK(mutex);
00116 logBuffer.push("NEW CONNECTION FROM: " + ip + ":" + portStr.str() + "\n");
00117 MUTEX_UNLOCK(mutex);
00118 }
00119 void ServerLogger::logConnectionRemoved(const std::string& ip, unsigned port) {
00120
00121 std::ostringstream portStr;
00122 portStr << port;
00123 MUTEX_LOCK(mutex);
00124 logBuffer.push("REMOVED CONNECTION: " + ip + ":" + portStr.str() + "\n");
00125 MUTEX_UNLOCK(mutex);
00126 }
00127 void ServerLogger::logWaitingForNewRequest() {
00128
00129 MUTEX_LOCK(mutex);
00130 logBuffer.push("WAITING FOR NEW REQUEST\n");
00131 MUTEX_UNLOCK(mutex);
00132 }
00133 long long ServerLogger::logRequestStart(std::vector<std::string> fields) {
00134
00135 MUTEX_LOCK(mutex);
00136 std::string req = "";
00137 for (unsigned i = 0; i < fields.size(); i++)
00138 req += fields[i] + "|";
00139 long long reqAct = reqId++;
00140 std::ostringstream idStr;
00141 idStr << reqAct;
00142 logBuffer.push("STARTED PROCESSING REQUEST: ID=" + idStr.str() + " REQ=" + req + "\n");
00143 MUTEX_UNLOCK(mutex);
00144 return reqAct;
00145 }
00146
00147 long long ServerLogger::logRequestStart(std::vector<std::string> fields, std::string object) {
00148
00149 MUTEX_LOCK(mutex);
00150 std::string req = "";
00151 for (unsigned i = 0; i < fields.size(); i++)
00152 req += fields[i] + "|";
00153 req += object + "|";
00154 long long reqAct = reqId++;
00155 std::ostringstream idStr;
00156 idStr << reqAct;
00157 logBuffer.push("STARTED PROCESSING REQUEST: ID=" + idStr.str() + " REQ=" + req + "\n");
00158 MUTEX_UNLOCK(mutex);
00159 return reqAct;
00160 }
00161
00162 void ServerLogger::logRequestPerformed(long long id) {
00163
00164 MUTEX_LOCK(mutex);
00165 std::ostringstream idStr;
00166 idStr << id;
00167 logBuffer.push("PROCESSED REQUEST ID=" + idStr.str() + "\n");
00168 MUTEX_UNLOCK(mutex);
00169 }
00170 void ServerLogger::logReplySent(long long id) {
00171
00172 MUTEX_LOCK(mutex);
00173 std::ostringstream idStr;
00174 idStr << id;
00175 logBuffer.push("SENT REPLY TO REQUEST ID=" + idStr.str() + "\n");
00176 MUTEX_UNLOCK(mutex);
00177 }
00178 void ServerLogger::logConnectionTimeout() {
00179
00180 MUTEX_LOCK(mutex);
00181 logBuffer.push("CONNECTION TIMED OUT\n");
00182 MUTEX_UNLOCK(mutex);
00183 }
00184
00185 void ServerLogger::logSocketError() {
00186 MUTEX_LOCK(mutex);
00187 logBuffer.push("TERRIBLE SOCKET ERROR\n");
00188 logBuffer.push(std::string(strerror(errno)) + "\n");
00189 MUTEX_UNLOCK(mutex);
00190 }
00191
00192 void * ServerLoggerThread(void * arg) {
00193
00194 ServerLogger * l = (ServerLogger *) arg;
00195
00196 l->operator ()();
00197
00198 return NULL;
00199
00200 }
00201
00202
00203
00204
00205
00206
00207