Advertisement
Guest User

Untitled

a guest
Feb 20th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.64 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <deque>
  4. #include <string>
  5. #include <fstream>
  6. #include <map>
  7. #include <iostream>
  8. #include <pthread.h>
  9. #include <time.h>
  10.  
  11. #define MAX_LINES 1000
  12. #define MESSAGES_PER_WRITE 100
  13.  
  14. class AtlLogger
  15. {
  16. friend class Driver;
  17. friend class OrderManagementSystem;
  18.  
  19. public:
  20. static AtlLogger* Instance();
  21.  
  22. void Log(const std::string line, const std::string prefix);
  23. void DeleteInstance();
  24.  
  25. void WriteToFile();
  26. private:
  27. AtlLogger();
  28.  
  29. //the pointer versions of logging is reserved for internal use
  30. //we don't want a strategy to log with pointers and deal with
  31. //memory management
  32. void Log(const std::string*);
  33. void Log(const std::string*, std::string prefix);
  34.  
  35. struct LogRequest
  36. {
  37. const std::string* line;
  38. std::string prefix;
  39. };
  40.  
  41. struct FileInfo
  42. {
  43. std::string* name;
  44. std::ofstream ofs;
  45. int lines;
  46. };
  47.  
  48. static AtlLogger* instance;
  49.  
  50. void OpenLogFile(const std::string&);
  51. void CloseLogFile(const std::string&);
  52.  
  53. bool run;
  54.  
  55. std::deque<LogRequest*> message_queue;
  56. std::map<std::string, FileInfo*> file_map;
  57. };
  58.  
  59. #include "AtlLogger.h"
  60.  
  61. AtlLogger* AtlLogger::instance = NULL;
  62. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  63.  
  64. using std::cout;
  65. using std::endl;
  66.  
  67. /*
  68. * @construct
  69. * @param
  70. * @description creates a logger to record system information
  71. */
  72. AtlLogger::AtlLogger()
  73. {
  74. std::string prefix("Audit");
  75. OpenLogFile(prefix);
  76. run = true;
  77. }
  78.  
  79. /*
  80. * @return instance: pointer to singleton class
  81. * @description creates an instance of the singleton
  82. * if it does not already exist
  83. */
  84. AtlLogger* AtlLogger::Instance()
  85. {
  86. if(instance == NULL)
  87. {
  88. instance = new AtlLogger;
  89. }
  90.  
  91. return instance;
  92. }
  93.  
  94. /*
  95. * @param
  96. * @return
  97. * @description deletes the logger after closing all IO
  98. */
  99. void AtlLogger::DeleteInstance()
  100. {
  101. usleep(100000);
  102. pthread_mutex_lock(&mutex);
  103. run = false;
  104. std::map<std::string, FileInfo* >::iterator it;
  105. for (it = file_map.begin(); it != file_map.end(); it++)
  106. {
  107. //TODO ofstream* file = (*file_it).second;
  108. //file->close();
  109. }
  110. pthread_mutex_unlock(&mutex);
  111.  
  112. delete instance;
  113. instance = NULL;
  114. }
  115.  
  116. /*
  117. * @param line: string to be logged
  118. * @return
  119. * @description adds a line to the queue of lines that
  120. * will be written to the log
  121. */
  122. void AtlLogger::Log(const std::string* line)
  123. {
  124. pthread_mutex_lock(&mutex);
  125. LogRequest* request = new LogRequest;
  126. request->line = line;
  127. request->prefix = "Audit";
  128. message_queue.push_back(request);
  129. pthread_mutex_unlock(&mutex);
  130. }
  131.  
  132. /*
  133. * @param line: string to be logged
  134. * @param name: name of the file to log with
  135. * @return
  136. * @description add the line to the given log file
  137. */
  138. void AtlLogger::Log(const std::string* line, std::string prefix)
  139. {
  140. pthread_mutex_lock(&mutex);
  141. if (file_map.find(prefix) == file_map.end())
  142. {
  143. OpenLogFile(prefix);
  144. }
  145.  
  146. LogRequest* request = new LogRequest;
  147. request->line = line;
  148. request->prefix = prefix;
  149. message_queue.push_back(request);
  150. pthread_mutex_unlock(&mutex);
  151. }
  152.  
  153. /*
  154. * @param line: string to be logged
  155. * @param name: name of the file to log with
  156. * @return
  157. * @description add the line to the given log file
  158. */
  159. void AtlLogger::Log(const std::string line, std::string prefix)
  160. {
  161. pthread_mutex_lock(&mutex);
  162. if (file_map.find(prefix) == file_map.end())
  163. {
  164. OpenLogFile(prefix);
  165. }
  166.  
  167. LogRequest* request = new LogRequest;
  168. request->line = new std::string(line);
  169. request->prefix = prefix;
  170. message_queue.push_back(request);
  171. pthread_mutex_unlock(&mutex);
  172. }
  173.  
  174. /*
  175. * @param
  176. * @return
  177. * @description runs in its own thread, checking whether it needs
  178. * to write log statements periodically
  179. */
  180. void AtlLogger::WriteToFile()
  181. {
  182. std::map<std::string, FileInfo* >::iterator it;
  183.  
  184. while(run)
  185. {
  186. char timestamp[16];
  187. time_t now;
  188. time(&now);
  189. struct tm* current = localtime(&now);
  190. sprintf(timestamp, "%02u%02u%04u|%02u%02u%02u|", (current->tm_mon+1),
  191. current->tm_mday,(1900 + current->tm_year), current->tm_hour,
  192. current->tm_min, current->tm_sec);
  193.  
  194. pthread_mutex_lock(&mutex);
  195. for(it=file_map.begin(); it != file_map.end(); ++it)
  196. {
  197. if(it->second->lines > MAX_LINES)
  198. {
  199. CloseLogFile(it->first);
  200. OpenLogFile(it->first);
  201. }
  202. else
  203. {
  204. int written = 0;
  205.  
  206. while(!message_queue.empty() && written < MESSAGES_PER_WRITE)
  207. {
  208. LogRequest* request = message_queue.front();
  209. message_queue.pop_front();
  210.  
  211. std::string line(timestamp, 16);
  212. line.append(*(request->line));
  213.  
  214. FileInfo* info = file_map[request->prefix];
  215. info->ofs << line << std::endl;
  216. info->lines++;
  217. written++;
  218. delete request;
  219. }
  220. }
  221. }
  222. pthread_mutex_unlock(&mutex);
  223.  
  224. usleep(1000);
  225. }
  226. }
  227.  
  228. /*
  229. * @param
  230. * @return
  231. * @description opens a new file for logging with a timestamp
  232. * as the filename
  233. */
  234. void AtlLogger::OpenLogFile(const std::string& prefix)
  235. {
  236. //get timestamp to use
  237. char timestamp[15];
  238. time_t now;
  239. time(&now);
  240. struct tm* current = localtime(&now);
  241. sprintf(timestamp, "%02u%02u%04u_%02u%02u%02u", (current->tm_mon+1),
  242. current->tm_mday,(1900 + current->tm_year), current->tm_hour,
  243. current->tm_min, current->tm_sec);
  244.  
  245. FileInfo* info = new FileInfo;
  246. cout << "1" << endl;
  247. cout << prefix << endl;
  248. info->name = new std::string("logs/" + prefix + ".log_" + timestamp);
  249. cout << "2" << endl;
  250. cout << "3" << endl;
  251. cout << info->name->c_str() << endl;
  252. info->ofs.open(info->name->c_str());
  253. cout << "4" << endl;
  254. info->lines = 0;
  255. cout << "5" << endl;
  256.  
  257. file_map[prefix] = info;
  258.  
  259. cout << "Creating New Log File: " << timestamp << endl;
  260. }
  261.  
  262. /*
  263. * @param
  264. * @return
  265. * @description closes the current log file
  266. */
  267. void AtlLogger::CloseLogFile(const std::string& prefix)
  268. {
  269. cout << "Attempting to Close File!" << endl;
  270. cout << prefix << endl;
  271. cout << "Is Open?: " << file_map[prefix]->ofs.is_open() << endl;
  272. cout << "good?: " << file_map[prefix]->ofs.good() << endl;
  273. cout << "eof?: " << file_map[prefix]->ofs.eof() << endl;
  274. cout << "fail?: " << file_map[prefix]->ofs.fail() << endl;
  275. cout << "bad?: " << file_map[prefix]->ofs.bad() << endl;
  276. cout << "name? " << *file_map[prefix]->name << endl;
  277. cout << "lines? " << file_map[prefix]->lines << endl;
  278. //cout << "rdbuf: " << file_map[prefix]->ofs.rdbuf() << endl;
  279. cout << "rdbuf open?: " << file_map[prefix]->ofs.rdbuf()->is_open() << endl;
  280. file_map[prefix]->ofs.close();
  281. cout << "closed stream" << endl;
  282. delete file_map[prefix];
  283. cout << "deleted memory" << endl;
  284. file_map.erase(prefix);
  285. cout << "Close File End!"<< endl;
  286. }
  287.  
  288. 0 0x0000003d8786d1b3 in _IO_un_link_internal () from /lib64/libc.so.6
  289. 1 0x0000003d87860da7 in fclose@@GLIBC_2.2.5 () from /lib64/libc.so.6
  290. 2 0x000000336febb968 in std::__basic_file<char>::close() () from /usr/lib64/libstdc++.so.6
  291. 3 0x000000336fe69c17 in std::basic_filebuf<char, std::char_traits<char> >::close() ()
  292. from /usr/lib64/libstdc++.so.6
  293. 4 0x000000336fe69cad in std::basic_ofstream<char, std::char_traits<char> >::close() () from /usr/lib64/libstdc++.so.6
  294. 5 0x00000000004c2a25 in AtlLogger::CloseLogFile() ()
  295. 6 0x00000000004c2ef1 in AtlLogger::WriteToFile() ()
  296. 7 0x0000000000482270 in Driver::launchLog (this=0x7fffffffe86f) at driver.cpp:672
  297. 8 0x000000000048228f in launchLogThread (ptr=0x7fffffffe86f) at driver.cpp:654
  298. 9 0x0000003d8840673d in start_thread () from /lib64/libpthread.so.0
  299. 10 0x0000003d878d3d1d in clone () from /lib64/libc.so.6
  300.  
  301. Attempting to Close File!
  302. test
  303. Is Open?: 1
  304. good?: 1
  305. eof?: 0
  306. fail?: 0
  307. bad?: 0
  308. name? logs/test.log_09132012_095549
  309. lines? 1001
  310. rdbuf open?: 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement