Advertisement
Guest User

Untitled

a guest
Jan 20th, 2015
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.27 KB | None | 0 0
  1. #include <iostream>
  2. #include <ratio>
  3. #include <chrono>
  4. #include <stdexcept>
  5. using namespace std;
  6. using namespace std::chrono;
  7.  
  8. #include "logging.h"
  9.  
  10. static map<Level, string> level_info = {
  11. {DEBUG, "DEBUG" },
  12. {INFO, "INFO" },
  13. {WARNING, "WARNING" },
  14. {_ERROR, "ERROR" },
  15. {CRITICAL, "CRITICAL" },
  16. };
  17.  
  18.  
  19. /********************************************/
  20. /* Formatter */
  21. /********************************************/
  22. Formatter::Formatter(string f)
  23. : format(f) {
  24. set_time_format("%Y-%m-%d %H:%M:%S,");
  25. }
  26.  
  27. void Formatter::set_time_format(string f) {
  28. time_format = f;
  29. }
  30.  
  31. string Formatter::get_string(Record &rec) {
  32. stringstream result;
  33. string unit;
  34. string buf = format;
  35. size_t start_index;
  36. size_t stop_index;
  37. int width;
  38.  
  39. while(!buf.empty()) {
  40. start_index = buf.find("[");
  41. stop_index = buf.find("]");
  42.  
  43. if(start_index == string::npos || stop_index == string::npos) {
  44. result << buf;
  45. return result.str();
  46. }
  47. unit = buf.substr(start_index + 1, stop_index - start_index - 1);
  48. result << buf.substr(0, start_index);
  49.  
  50. start_index = unit.find(":");
  51. if(start_index != string::npos) {
  52. try {
  53. width = stoi(unit.substr(start_index + 1));
  54. unit = unit.substr(0, start_index);
  55. } catch(const std::invalid_argument&) {
  56. width = 0;
  57. }
  58. }
  59. else {
  60. width = 0;
  61. }
  62. result.width(width);
  63.  
  64. if(unit == "TIME") {
  65. rec[unit] = get_time();
  66. }
  67.  
  68. if(!rec[unit].empty()) {
  69. result << rec[unit];
  70. }
  71. else {
  72. result << "[" + unit + "]";
  73. }
  74. buf.erase(0, stop_index + 1);
  75. }
  76. return result.str();
  77. }
  78.  
  79. string Formatter::get_time() {
  80. stringstream ss;
  81. auto tp = std::chrono::system_clock::now();
  82. auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
  83. size_t modulo = ms.count() % 1000;
  84. time_t seconds = std::chrono::duration_cast<std::chrono::seconds>( ms ).count();
  85.  
  86. #if HAS_STD_PUT_TIME
  87. ss << std::put_time(localtime(&seconds ), time_format.data() );
  88. #else
  89. char buf[30];
  90.  
  91. if(strftime(buf, sizeof(buf), time_format.data(), localtime(&seconds))) {
  92. ss << buf;
  93. }
  94. #endif // HAS_STD_PUT_TIME
  95.  
  96. ss.fill( '0' );
  97. ss.width( 3 );
  98. ss << modulo;
  99.  
  100. return ss.str();
  101. }
  102.  
  103. /********************************************/
  104. /* BaseHandler */
  105. /********************************************/
  106. BaseHandler::BaseHandler(string str) {
  107. if(str.empty()) {
  108. name = "BaseHandler";
  109. }
  110. else {
  111. name = str;
  112. }
  113. }
  114. BaseHandler::~BaseHandler() {
  115. if(formatter) {
  116. delete formatter;
  117. formatter = 0;
  118. }
  119. }
  120.  
  121. void BaseHandler::set_formatter(Formatter *f) {
  122. formatter = f;
  123. }
  124.  
  125. void BaseHandler::log(Level l, Record &rec) {
  126. rec["LEVEL"] = level_info[l];
  127. string s = formatter -> get_string(rec);
  128.  
  129. try {
  130. fflush(l, s);
  131. } catch (exception &e) {
  132. cerr << "Failed to fflush record in handler <" << name << ">" << endl;
  133. cerr << "\tdescription: " << e.what() << endl;
  134. cerr << "\tstring: " << s << endl;
  135. }
  136. }
  137.  
  138. /********************************************/
  139. /* Logger */
  140. /********************************************/
  141. Logger::Logger(string n)
  142. : is_single_param(false), name(n) {
  143. stream = new stringstream(ios::in | ios::out | ios::ate);
  144. _debug = new Log(DEBUG, *stream, this);
  145. _info = new Log(INFO, *stream, this);
  146. _warning = new Log(WARNING, *stream, this);
  147. _error = new Log(_ERROR, *stream, this);
  148. _critical = new Log(CRITICAL, *stream, this);
  149. }
  150.  
  151. Logger::~Logger() {
  152. if(_debug) {
  153. delete _debug;
  154. _debug = 0;
  155. }
  156. if(_info) {
  157. delete _info;
  158. _info = 0;
  159. }
  160. if(_warning) {
  161. delete _warning;
  162. _warning = 0;
  163. }
  164. if(_error) {
  165. delete _error;
  166. _error = 0;
  167. }
  168. if(_critical) {
  169. delete _critical;
  170. _critical = 0;
  171. }
  172. }
  173.  
  174. void Logger::add_handler(BaseHandler *hd) {
  175. handlers.push_back(hd);
  176. }
  177.  
  178. void Logger::fflush(Level l, Record &rec) {
  179. rec.insert(append_rec.begin(), append_rec.end());
  180. rec["NAME"] = name;
  181. for(auto it = handlers.begin(); it != handlers.end(); ++it) {
  182. (*it) -> log(l, rec);
  183. }
  184. if(is_single_param) {
  185. restore_param();
  186. }
  187. }
  188.  
  189. Log& Logger::debug() {
  190. return *_debug;
  191. }
  192.  
  193. Log& Logger::info() {
  194. return *_info;
  195. }
  196.  
  197. Log& Logger::warning() {
  198. return *_warning;
  199. }
  200.  
  201. Log& Logger::error() {
  202. return *_error;
  203. }
  204.  
  205. Log& Logger::critical() {
  206. return *_critical;
  207. }
  208.  
  209. /********************************************/
  210. /* Log */
  211. /********************************************/
  212. Log::Log(Level l, stringstream &ss, Logger *log)
  213. : buffer(ss), level(l), logger(log) {
  214. }
  215.  
  216. Log::~Log() {
  217. if(!buffer.str().empty() && buffer.str().back() != '\n') {
  218. buffer << '\n';
  219. fflush();
  220. }
  221. }
  222.  
  223. void Log::fflush() {
  224. if(level < LogManager::get_level()) {
  225. return;
  226. }
  227. Record rec;
  228. string current_str = buffer.str();
  229. size_t endl_index = current_str.find('\n');
  230. while(endl_index != string::npos) {
  231. rec["MESSAGE"] = current_str.substr(0, endl_index + 1);
  232. logger -> fflush(level, rec);
  233. current_str = current_str.substr(endl_index + 1);
  234. endl_index = current_str.find('\n');
  235. }
  236. buffer.str(current_str);
  237. }
  238.  
  239. /********************************************/
  240. /* Хендлеры */
  241. /********************************************/
  242. // Консольный
  243. ConsoleHandler::ConsoleHandler():
  244. BaseHandler("ConsoleHandler") {
  245. }
  246.  
  247. ConsoleHandler::~ConsoleHandler() {
  248. }
  249.  
  250. void ConsoleHandler::fflush(Level l, string &str) {
  251. switch(l) {
  252. case DEBUG:
  253. str = "\033[32m" + str + "\033[0m"; // Зеленый
  254. break;
  255.  
  256. case INFO:
  257. str = "\033[36m" + str + "\033[0m"; // Cyan
  258. break;
  259.  
  260. case WARNING:
  261. str = "\033[33;1m" + str + "\033[0m"; // Желтый
  262. break;
  263.  
  264. case _ERROR:
  265. str = "\033[31;1m" + str + "\033[0m"; // Красный
  266. break;
  267.  
  268. case CRITICAL:
  269. str = "\033[35;1m" + str + "\033[0m"; // Magenta
  270. break;
  271. }
  272. cout << str;
  273. }
  274.  
  275. // Файловый
  276. FileHandler::FileHandler(string f)
  277. : BaseHandler("FileHandler"), file_path(f) {
  278. fs.open(f, fstream::in | fstream::out | fstream::app);
  279. }
  280.  
  281. FileHandler::~FileHandler() {
  282. fs.close();
  283. }
  284.  
  285. void FileHandler::fflush(Level, string &str) {
  286. fs << str;
  287. fs.flush();
  288. }
  289.  
  290. /********************************************/
  291. /* Logging */
  292. /********************************************/
  293. LogManager* LogManager::base = 0;
  294. Level LogManager::custom_level = DEBUG;
  295.  
  296. LogManager* LogManager::get_logging() {
  297. if(base == 0) {
  298. base = new LogManager();
  299. }
  300. return base;
  301. }
  302.  
  303. LogManager::LogManager() {
  304. }
  305.  
  306. LogManager::~LogManager() {
  307. for(auto it = handlers.begin(); it != handlers.end(); ++it) {
  308. delete *it;
  309. }
  310. if(base) {
  311. delete base;
  312. base = 0;
  313. }
  314. }
  315.  
  316. void LogManager::add_handler(BaseHandler *hd) {
  317. handlers.push_back(hd);
  318. }
  319.  
  320. void LogManager::set_level(Level l) {
  321. custom_level = l;
  322. }
  323.  
  324. Level LogManager::get_level() {
  325. return custom_level;
  326. }
  327.  
  328. Logger* LogManager::get_logger(string name) {
  329. try {
  330. Logger *lg = loggers[name];
  331. if(!lg) {
  332. throw out_of_range("Key \"" + name + "\" not found");
  333. }
  334. return lg;
  335. }
  336. catch (out_of_range &) {
  337. Logger *lg = new Logger(name);
  338. loggers[name] = lg;
  339. for(auto it = handlers.begin(); it != handlers.end(); ++it) {
  340. lg -> add_handler(*it);
  341. }
  342. return lg;
  343. }
  344. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement