SHARE
TWEET

Untitled

a guest Feb 20th, 2019 64 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top