log4cplus_helper.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. #include "log4cplus_helper.h"
  2. #include <iostream>
  3. #include <string>
  4. #include <string.h>
  5. #include <mutex>
  6. #include "log4link.h"
  7. #include "exLog/skyeyeLog.h"
  8. #if defined(_WIN32) && defined (LOG4CPLUS_HAVE_WIN32_CONSOLE)
  9. #include <log4cplus/win32consoleappender.h>
  10. #define WIN32_CONSOLE 1
  11. #endif
  12. using namespace log4cplus;
  13. using namespace log4cplus::helpers;
  14. #define MAX_BUFFER_LENGTH 4096
  15. #define LOG4PLUS_LOG(TYPE, LOGGER, msg) \
  16. LOG4CPLUS_##TYPE(LOGGER, msg);
  17. static inline vtm_string w2s(const std::wstring wstr)
  18. {
  19. #if defined(_MSC_VER)
  20. char* str = NULL;
  21. int n = ::WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
  22. if (n > 0) {
  23. str = new char[n+1];
  24. if(str == NULL) {
  25. return vtm_string();
  26. }
  27. std::memset(str, 0, sizeof(char)*(n+1));
  28. ::WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &str[0], n, NULL, NULL);
  29. vtm_string strr(str);
  30. delete str;
  31. return strr;
  32. }
  33. return vtm_string();
  34. #else
  35. if (wstr.empty())
  36. {
  37. return "";
  38. }
  39. unsigned len = wcstombs(NULL, wstr.c_str(), 0) + 1;
  40. if (NULL == setlocale(LC_ALL, "zh_CN.gbk"))
  41. {
  42. }
  43. char* p = new char[len];
  44. wcstombs(p, wstr.c_str(), len);
  45. p[len - 1] = '\0';
  46. std::string str(p);
  47. delete[] p;
  48. return str;
  49. #endif // _MSC_VER
  50. }
  51. namespace cmb {
  52. log4cplus_helper* log4cplus_helper::_instance = NULL;
  53. mutex log4cplus_helper::_mutex;
  54. log4cplus_helper::log4cplus_helper(void)
  55. :_append_console(NULL),_append_file(NULL),_append_socket(NULL),_append_none(NULL)
  56. ,_socket_send_running(false)
  57. ,_initialized(false),_append_type(0),_log_server_port(0),_log_listen_port(0)
  58. ,_initilzed_zip(false),_cur_upload_log(""),_cur_upload_offset(0),_log_level(NOT_SET_LOG_LEVEL), _initialize_uploaded(false)
  59. {
  60. _log_dir.clear();
  61. _log_server_ip.clear();
  62. _log_server_port = 0;
  63. _log_key_name = "vtm";
  64. }
  65. log4cplus_helper::~log4cplus_helper(void)
  66. {
  67. uninit();
  68. while(!_zip_logs.empty()) {
  69. _zip_logs.pop();
  70. }
  71. }
  72. log4cplus_helper* log4cplus_helper::get_instance()
  73. {
  74. if(_instance == NULL) {
  75. unique_lock lock_(_mutex);
  76. if(_instance == NULL) {
  77. _instance = new log4cplus_helper();
  78. }
  79. }
  80. return _instance;
  81. }
  82. bool log4cplus_helper::init(const char* name)
  83. {
  84. if(_initialized) {
  85. return true;
  86. }
  87. if(name == NULL || strlen(name) == 0)
  88. return false;
  89. if((_append_type & log_append_file) && _log_dir.empty()) {
  90. return false;
  91. }
  92. _log_key_name = name;
  93. log4cplus::initialize();
  94. #ifdef _DEBUG
  95. LogLog::getLogLog()->setInternalDebugging(true);
  96. #else
  97. LogLog::getLogLog()->setInternalDebugging(false);
  98. #endif
  99. log4cplus::Logger logger = get_logger();
  100. logger.setLogLevel(_log_level);
  101. if ((_append_type & log_append_console) == log_append_console)
  102. {
  103. _append_console = new ConsoleAppender(false, true);
  104. log4cplus::tstring pattern = LOG4CPLUS_TEXT("%d{%H:%M:%S,%Q} [%t] %-5p %c{2} - %m%n");
  105. _append_console->setLayout( std::auto_ptr<Layout>(new PatternLayout(pattern)) );
  106. logger.addAppender(_append_console);
  107. _append_console->setName(LOG4CPLUS_TEXT("console"));
  108. }
  109. if ((_append_type & log_append_file) == log_append_file)
  110. {
  111. tostringstream propsOStream;
  112. propsOStream << LOG4CPLUS_TEXT("CreateDirs=true\n")
  113. << LOG4CPLUS_TEXT("Append=true\n")
  114. << LOG4CPLUS_TEXT("MaxHistory=999\n")
  115. << LOG4CPLUS_TEXT("ImmediateFlush=true\n")
  116. << LOG4CPLUS_TEXT("RollOnClose=false\n");
  117. vtm_string log_path(_log_dir);
  118. assert(!log_path.empty());
  119. log_path += name;
  120. #if defined(_MSC_VER)
  121. log_path += LOG4CPLUS_TEXT("\\");
  122. #else
  123. log_path += LOG4CPLUS_TEXT("/");
  124. #endif //_MSC_VER
  125. tstring str(LOG4CPLUS_TEXT("FilenamePattern="));
  126. str += log_path;
  127. str += LOG4CPLUS_TEXT("%d{yyyyMMdd}.log\n");
  128. propsOStream << str;
  129. tistringstream propsStream (propsOStream.str());
  130. helpers::Properties props (propsStream);
  131. _append_file = new TimeBasedRollingFileAppender(props);
  132. log4cplus::tstring pattern = LOG4CPLUS_TEXT("[%D{%H:%M:%S.%Q}][%-5p][%t] %m %n");
  133. //<%x> - %X{key}
  134. _append_file->setLayout( std::auto_ptr<Layout>(new PatternLayout(pattern)) );
  135. logger.addAppender(_append_file);
  136. _append_file->setName(LOG4CPLUS_TEXT("file_log"));
  137. }
  138. if (_append_type <= log_append_none || _append_type > log_append_all)
  139. {
  140. _append_none = new NullAppender();
  141. _append_none->setLayout( std::auto_ptr<Layout>(new log4cplus::TTCCLayout()) );
  142. logger.addAppender(_append_none);
  143. _append_none->setName(LOG4CPLUS_TEXT("none_log"));
  144. }
  145. _initialized = true;
  146. return _initialized;
  147. }
  148. void log4cplus_helper::config_remote_logger(const char* remote_name)
  149. {
  150. LOG4VTM(INFO, "Enter config remote logger: " << remote_name);
  151. if(remote_name == NULL || strlen(remote_name) == 0) {
  152. LOG4VTM(ERROR, "remote log name is empty, config remote logger failed!");
  153. return;
  154. }
  155. if(strcmp(remote_name, _log_key_name.c_str()) == 0) {
  156. LOG4VTM(WARN, "the remote name is the same with the local key name, use local config.");
  157. return;
  158. }
  159. log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT(remote_name));
  160. //todo
  161. logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL);
  162. if ((_append_type & log_append_console) == log_append_console)
  163. {
  164. #ifdef WIN32_CONSOLE
  165. static SharedAppenderPtr append_1(new Win32ConsoleAppender(false, false,
  166. FOREGROUND_GREEN | FOREGROUND_INTENSITY));
  167. #else
  168. static SharedAppenderPtr append_1(new ConsoleAppender(false, true));
  169. #endif
  170. log4cplus::tstring pattern = LOG4CPLUS_TEXT("%d{%H:%M:%S,%Q} [%t] %-5p %c{2} - %m%n");
  171. append_1->setLayout( std::auto_ptr<Layout>(new PatternLayout(pattern)) );
  172. logger.addAppender(append_1);
  173. append_1->setName(LOG4CPLUS_TEXT("android_console"));
  174. }
  175. if ((_append_type & log_append_file) == log_append_file)
  176. {
  177. tostringstream propsOStream;
  178. propsOStream << LOG4CPLUS_TEXT("CreateDirs=true\n")
  179. << LOG4CPLUS_TEXT("Append=true\n")
  180. << LOG4CPLUS_TEXT("MaxHistory=999\n")
  181. << LOG4CPLUS_TEXT("ImmediateFlush=true\n")
  182. << LOG4CPLUS_TEXT("RollOnClose=false\n");
  183. vtm_string log_path(_log_dir);
  184. assert(!log_path.empty());
  185. log_path += remote_name;
  186. #if defined(_MSC_VER)
  187. log_path += "\\";
  188. #else
  189. log_path += "/";
  190. #endif //_MSC_VER
  191. tstring str(LOG4CPLUS_TEXT("FilenamePattern="));
  192. str += log_path;
  193. str += LOG4CPLUS_TEXT("%d{yyyyMMdd}.log\n");
  194. propsOStream << str;
  195. tistringstream propsStream (propsOStream.str());
  196. helpers::Properties props (propsStream);
  197. static SharedAppenderPtr append_2(new TimeBasedRollingFileAppender(props));
  198. log4cplus::tstring pattern = LOG4CPLUS_TEXT("[%D{%H:%M:%S.%Q}][%-5p] %m %n");
  199. append_2->setLayout( std::auto_ptr<Layout>(new PatternLayout(pattern)) );
  200. logger.addAppender(append_2);
  201. append_2->setName(LOG4CPLUS_TEXT("android_file_log"));
  202. }
  203. }
  204. int log4cplus_helper::run_log_sender(const vtm_string& ip,const unsigned short port)
  205. {
  206. unique_lock lock_(_mutex_4_update_socket);
  207. LOG4VTM(INFO, "Enter run_log_sender...");
  208. if(!_initialized) {
  209. LOG4VTM(WARN, "log4cplus helper has not been initialized");
  210. return -1;
  211. }
  212. if ((_append_type & log_append_socket) == log_append_socket)
  213. {
  214. if(ip == _log_server_ip && _log_server_port == port) {
  215. LOG4VTM(WARN, "log4cplus has been set as the same server ip and port!");
  216. return -1;
  217. }
  218. if (!ip.empty() && port != 0) {
  219. if(_socket_send_running) {
  220. LOG4VTM(INFO, "remove appender");
  221. get_logger().removeAppender(_append_socket);
  222. _append_socket->close();
  223. _append_socket = NULL;
  224. }
  225. LOG4VTM(INFO, "new socket appender");
  226. tostringstream propsOStream;
  227. propsOStream << LOG4CPLUS_TEXT("Appender=log4cplus::SocketAppender\n")
  228. << LOG4CPLUS_TEXT("QueueLimit=10000\n");
  229. {
  230. propsOStream << LOG4CPLUS_TEXT("Appender.host=");
  231. propsOStream << ip << "\n";
  232. }
  233. {
  234. propsOStream << LOG4CPLUS_TEXT("Appender.port=");
  235. propsOStream << port << "\n";
  236. }
  237. {
  238. propsOStream << LOG4CPLUS_TEXT("Appender.ServerName=");
  239. propsOStream << _log_key_name << "\n";
  240. }
  241. tistringstream propsStream (propsOStream.str());
  242. helpers::Properties props (propsStream);
  243. _append_socket = new AsyncAppender(props);
  244. LOG4VTM(INFO, "new socket appender done");
  245. _append_socket->setLayout( std::auto_ptr<Layout>(new log4cplus::TTCCLayout()) );
  246. _append_socket->setName(LOG4CPLUS_TEXT("socket_log"));
  247. LOG4VTM(INFO, "add appender");
  248. get_logger().addAppender(_append_socket);
  249. LOG4VTM(INFO, "add appender done");
  250. _socket_send_running = true;
  251. _log_server_ip = ip;
  252. _log_server_port = port;
  253. LOG4VTM(INFO, "update log sender successfully: " << ip << "::" << port);
  254. return 0;
  255. } else {
  256. LOG4VTM(ERROR, "the remote log ip or port are not config !");
  257. return -1;
  258. }
  259. } else {
  260. LOG4VTM(ERROR, "the current log type is not supported ! " << _append_type);
  261. return -1;
  262. }
  263. return 0;
  264. }
  265. void log4cplus_helper::uninit()
  266. {
  267. if(_initialized) {
  268. get_logger().removeAllAppenders();
  269. _append_console = NULL;
  270. _append_file = NULL;
  271. _append_none = NULL;
  272. _append_socket = NULL;
  273. log4cplus::Logger::shutdown();
  274. #ifndef USE_SKYEYELOG
  275. _upload_helper.unitialize();
  276. #endif
  277. _initialized = false;
  278. }
  279. }
  280. std::ostream& log4cplus_helper::stream()
  281. {
  282. LOG4CPLUS_MACRO_INSTANTIATE_OSTRINGSTREAM (_log4cplus_buf);
  283. return _log4cplus_buf;
  284. }
  285. void log4cplus_helper::trace(const vtm_string& text)
  286. {
  287. if(_initialized) {
  288. LOG4PLUS_LOG(TRACE, get_logger(), text.c_str());
  289. loglink(LOG_LEVEL_DEBUG, text);
  290. }
  291. }
  292. void log4cplus_helper::trace(const char* text)
  293. {
  294. if(_initialized) {
  295. LOG4PLUS_LOG(TRACE, get_logger(), text);
  296. loglink(LOG_LEVEL_DEBUG, text);
  297. }
  298. }
  299. void log4cplus_helper::info(const vtm_string& text)
  300. {
  301. if(_initialized) {
  302. LOG4PLUS_LOG(INFO, get_logger(), text.c_str());
  303. loglink(LOG_LEVEL_INFO, text);
  304. }
  305. }
  306. void log4cplus_helper::info(const char* text)
  307. {
  308. if(_initialized) {
  309. LOG4PLUS_LOG(INFO, get_logger(), text);
  310. loglink(LOG_LEVEL_INFO, text);
  311. }
  312. }
  313. void log4cplus_helper::debug(const vtm_string& text)
  314. {
  315. #if !defined(NDEBUG)
  316. if(_initialized) {
  317. LOG4PLUS_LOG(DEBUG, get_logger(), text.c_str());
  318. loglink(LOG_LEVEL_DEBUG, text);
  319. }
  320. #endif //!defined(NDEBUG)
  321. }
  322. void log4cplus_helper::debug(const char* text)
  323. {
  324. #if !defined(NDEBUG)
  325. if(_initialized) {
  326. LOG4PLUS_LOG(DEBUG, get_logger(), text);
  327. loglink(LOG_LEVEL_DEBUG, text);
  328. }
  329. #endif //!defined(NDEBUG)
  330. }
  331. void log4cplus_helper::warn(const vtm_string& text)
  332. {
  333. if(_initialized) {
  334. LOG4PLUS_LOG(WARN, get_logger(), text.c_str());
  335. loglink(LOG_LEVEL_WARN, text);
  336. }
  337. }
  338. void log4cplus_helper::warn(const char* text)
  339. {
  340. if(_initialized) {
  341. LOG4PLUS_LOG(WARN, get_logger(), text);
  342. loglink(LOG_LEVEL_WARN, text);
  343. }
  344. }
  345. void log4cplus_helper::error(const vtm_string& text)
  346. {
  347. if(_initialized) {
  348. LOG4PLUS_LOG(ERROR, get_logger(), text.c_str());
  349. loglink(LOG_LEVEL_ERROR, text);
  350. }
  351. }
  352. void log4cplus_helper::error(const char* text)
  353. {
  354. if(_initialized) {
  355. LOG4PLUS_LOG(ERROR, get_logger(), text);
  356. loglink(LOG_LEVEL_ERROR, text);
  357. }
  358. }
  359. void log4cplus_helper::fatal(const vtm_string& text)
  360. {
  361. if(_initialized) {
  362. LOG4PLUS_LOG(FATAL, get_logger(), text.c_str());
  363. loglink(LOG_LEVEL_FATAL, text);
  364. }
  365. }
  366. void log4cplus_helper::fatal(const char* text)
  367. {
  368. if(_initialized) {
  369. LOG4PLUS_LOG(FATAL, get_logger(), text);
  370. loglink(LOG_LEVEL_FATAL, text);
  371. }
  372. }
  373. vtm_string log4cplus_helper::format(const char *ft, ...)
  374. {
  375. va_list arg;
  376. va_start (arg, ft);
  377. vtm_string formatted = format(ft, arg);
  378. return formatted;
  379. }
  380. vtm_string log4cplus_helper::format(const char *ft,va_list& arg)
  381. {
  382. int len = 0;
  383. vtm_string formatted = "";
  384. char* buffer = NULL;
  385. #if defined(_WIN32)
  386. len = _vscprintf(ft, arg) + 1;
  387. buffer = (char*)malloc(len * sizeof(char));
  388. len = vsprintf_s(buffer, len, ft, arg);
  389. #else
  390. buffer = (char*)malloc(MAX_BUFFER_LENGTH + 1);
  391. sprintf(buffer, ft, arg);
  392. #endif
  393. formatted = buffer ;
  394. free(buffer);
  395. return formatted;
  396. }
  397. void log4cplus_helper::log(const char *file_name, const char *func_name, int line,
  398. const char* ft, int type /*= log_level_debug*/)
  399. {
  400. std::stringstream sstream;
  401. sstream << file_name << " " << func_name << " " << line << " " << ft << std::endl;
  402. switch(type) {
  403. case log_level_debug:
  404. debug(sstream.str());
  405. break;
  406. case log_level_trace:
  407. trace(sstream.str());
  408. break;
  409. case log_level_info:
  410. info(sstream.str());
  411. break;
  412. case log_level_warn:
  413. warn(sstream.str());
  414. break;
  415. case log_level_error:
  416. error(sstream.str());
  417. break;
  418. case log_level_fatal:
  419. fatal(sstream.str());
  420. break;
  421. default:
  422. trace(sstream.str());
  423. break;
  424. }
  425. return;
  426. }
  427. void log4cplus_helper::log(int log_level, const vtm_string& text)
  428. {
  429. switch (log_level) {
  430. case CMB_LOG_TRACE:
  431. trace(text);
  432. break;
  433. case CMB_LOG_DEBUG:
  434. debug(text);
  435. break;
  436. case CMB_LOG_INFO:
  437. info(text);
  438. break;
  439. case CMB_LOG_WARN:
  440. warn(text);
  441. break;
  442. case CMB_LOG_ERROR:
  443. error(text);
  444. break;
  445. case CMB_LOG_FATAL:
  446. fatal(text);
  447. break;
  448. default:
  449. trace(text);
  450. break;
  451. }
  452. return;
  453. }
  454. void log4cplus_helper::log(const char *file_name, const char *func_name, int line,
  455. int type ,const char *ft /*= ""*/, ...)
  456. {
  457. va_list arg;
  458. va_start (arg, ft);
  459. vtm_string formatted = format(ft, arg);
  460. va_end (arg);
  461. log(file_name, func_name, line, formatted.c_str(),type);
  462. }
  463. void log4cplus_helper::logw(int log_level, const std::wstring& wtext)
  464. {
  465. auto text = ::w2s(wtext);
  466. log(log_level, text);
  467. }
  468. void log4cplus_helper::initialize_linklog(const log_init_config& config)
  469. {
  470. #ifdef USE_SKYEYELOG
  471. CreateDefaultLogger(config.terminalno, RVC_VERSION_STR, config.dev_name, "100");
  472. #else
  473. _upload_helper.initialize(config);
  474. #endif
  475. }
  476. void log4cplus_helper::loglink(LOG_LEVEL_E level, vtm_string text)
  477. {
  478. #ifdef USE_SKYEYELOG
  479. static std::mutex logMtx;
  480. logMtx.lock();
  481. GetDefaultLogger()(level, text.c_str());
  482. logMtx.unlock();
  483. #else
  484. if (_upload_helper.is_initialized()) {
  485. /*LOG_LEVEL_DEBUG = 0, LOG_LEVEL_INFO = 1, LOG_LEVEL_WARN = 2, LOG_LEVEL_ERROR = 3, LOG_LEVEL_FATAL = 4*/
  486. const int converted_ll = ((int)(level)+1) * 10000;
  487. if (_log_level <= converted_ll) {
  488. log_link link_item((VENDORLOG_LEVEL_E)(int)(level), VENDORLOG_TYPE_SYSTEM);
  489. log_item logitem;
  490. long cur_time = time(NULL);
  491. link_item.result_msg(text).with_extend_log_or_not(false).fetch_log_item(logitem);
  492. _upload_helper.pinst_log_producer_client_add_log(_upload_helper._client, &logitem, 1, cur_time);
  493. }
  494. }
  495. #endif
  496. }
  497. }