log4vendor.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /***********************************//**
  2. * @file log4vendor.h
  3. * @email guifaliao@gmail.com
  4. * @version 0.0.0.2
  5. * @date 2020-08-26
  6. * @copyright China Merchants Bank Co.,Ltd All rights reserved
  7. *
  8. * @brief Log class for VTM device vendor for developing device adapter
  9. * @details
  10. * 2020-4-28: strip log component from SpAgent Project and adjust it.
  11. * 2020-11-11: add log_init_config_c structure and new init api: log4vendor::initp
  12. **************************************/
  13. #ifndef _VTM_LOG4VENDOR_H_
  14. #define _VTM_LOG4VENDOR_H_
  15. #pragma once
  16. #include <sstream>
  17. #include <string>
  18. #include <cstring>
  19. #ifdef _WIN32
  20. #ifdef LIBLOG4VENDOR_EXPORTS
  21. #define LOG4VENDOR_API __declspec(dllexport)
  22. #else
  23. #define LOG4VENDOR_API __declspec(dllimport)
  24. #endif
  25. #else
  26. #if ( defined(__GNUC__) && __GNUC__ >= 4 )
  27. #define LOG4VENDOR_API __attribute__((visibility("default")))
  28. #else
  29. #define LOG4VENDOR_API
  30. #endif
  31. #endif
  32. #ifdef UNICODE
  33. #error This version is not support {UNICODE} char set!!
  34. #define LOG4VTM_TEXT2(STRING) L##STRING
  35. typedef std::wstring vtm_string;
  36. typedef wchar_t vtm_char;
  37. #else
  38. #define LOG4VTM_TEXT2(STRING) STRING
  39. typedef std::string vtm_string;
  40. typedef char vtm_char;
  41. #endif // UNICODE
  42. #define LOG4VTM_TEXT(STRING) LOG4VTM_TEXT2(STRING)
  43. #ifndef RVC_VENDOE_BUILDIN_TYPE
  44. #if (defined(_WIN32) || defined(_WIN64))
  45. typedef unsigned char BYTE;
  46. typedef unsigned short WORD;
  47. typedef unsigned long DWORD;
  48. typedef unsigned long* PDWORD;
  49. #else
  50. typedef uint8_t BYTE;
  51. typedef uint8_t* LPBYTE;
  52. typedef uint16_t WORD;
  53. typedef uint32_t DWORD;
  54. typedef uint32_t* PDWORD;
  55. typedef char CHAR;
  56. #endif
  57. #define RVC_VENDOE_BUILDIN_TYPE
  58. #endif // !RVC_VENDOE_BUILDIN_TYPE
  59. #if defined(_MSC_VER)
  60. #define LOG4VTM_START_DOWHILE_WARNING() \
  61. __pragma (warning (push)) \
  62. __pragma (warning (disable:4127))
  63. #define LOG4VTM_END_DOWHILE_WARNING() \
  64. __pragma (warning (pop))
  65. #else
  66. #define LOG4VTM_START_DOWHILE_WARNING()
  67. #define LOG4VTM_END_DOWHILE_WARNING()
  68. #endif
  69. #define CMB_LOG_TYPE_CONSOLE 1 /*控制台输出*/
  70. #define CMB_LOG_TYPE_FILE 2 /*文件记录输出*/
  71. #define CMB_LOG_TYPE_SOCKET 4 /*TCP传输输出,暂未实现*/
  72. #define CMB_LOG_LEVEL_OFF 6 /*关闭任何日志输出*/
  73. #define CMB_LOG_LEVEL_FATAL 5 /*非常严重类型的日志输出*/
  74. #define CMB_LOG_LEVEL_ERROR 4 /*错误类型的日志输出*/
  75. #define CMB_LOG_LEVEL_WARN 3 /*告警类型的日志输出*/
  76. #define CMB_LOG_LEVEL_INFO 2 /*普通日志输出*/
  77. #define CMB_LOG_LEVEL_DEBUG 1 /*调试日志输出*/
  78. #define CMB_LOG_LEVEL_TRACE 0 /*跟踪函数进出等输出*/
  79. #define CMB_LOG_LEVEL_ALL CMB_LOG_LEVEL_TRACE
  80. #define CMB_LOG_TRACE 1
  81. #define CMB_LOG_DEBUG 2
  82. #define CMB_LOG_INFO 3
  83. #define CMB_LOG_WARN 4
  84. #define CMB_LOG_ERROR 5
  85. #define CMB_LOG_FATAL 6
  86. //#define CMB_LOG_ASSERT 7
  87. #define CMB_INSTANTIATE_OSTRINGSTREAM(var) \
  88. std::basic_ostringstream<char>& var \
  89. = cmb::log4vendor::get_oss()
  90. #define CMB_LOG_BODY(logLevel, logEvent) \
  91. LOG4VTM_START_DOWHILE_WARNING() \
  92. do { \
  93. cmb::log4vendor* _l \
  94. = cmb::log4vendor::instance(); \
  95. CMB_INSTANTIATE_OSTRINGSTREAM (_log4cplus_buf); \
  96. _log4cplus_buf << logEvent; \
  97. _l->log(logLevel, _log4cplus_buf.str()); \
  98. } while (0) \
  99. LOG4VTM_END_DOWHILE_WARNING()
  100. /*!
  101. * @brief 打印日志的函数,所有等级的日志打印均通过该宏调用实现
  102. * @param[in]
  103. * severity: 日志等级 TRACE, INFO, WARN, ERROR, FATAL, ASSERT
  104. * ostr: 要打印的内容,支持 << 连续输出
  105. */
  106. #define LOG4VTM(severity, ostr) \
  107. CMB_LOG_BODY(CMB_LOG_ ## severity, ostr)
  108. /*!
  109. * @brief: 用于记录函数进出的宏定义,在进入目的函数时立即调用,在该函数退出时会打印日志
  110. */
  111. #define LOG4VTM_FUNCTION() cmb::log4vendor_tracer _FunctionTraceLogger(\
  112. __FUNCTION__, cmb::log4vendor_tracer::_get_file_name(__FILE__), __LINE__)
  113. /*!
  114. * @brief 类似于 LOG4VTM_FUNCTION(),除外还添加一个入参用于打印返回值,注意该入参的生命周期为整个函数内!!
  115. * @param[in]: pValue - 仅支持传入 int* 或 DWORD* 类型,在日志中会打印指针所存储的值
  116. */
  117. #define TRACE4VTM_FUNCTION(pValue) cmb::log4vendor_tracer _FunctionTraceLogger(\
  118. __FUNCTION__, cmb::log4vendor_tracer::_get_file_name(__FILE__), __LINE__, (pValue))
  119. #define VENDOR_BUFF_SIZE 256
  120. namespace cmb {
  121. struct log_init_config_c
  122. {
  123. short log_type; /*见上面 CMB_LOG_TYPE_FILE 等定义*/
  124. short log_level; /*见上面 CMB_LOG_TRACE 等定义*/
  125. char dev_name[VENDOR_BUFF_SIZE]; /*硬件名称,用于作为子目录的区分*/
  126. char log_dir[VENDOR_BUFF_SIZE]; /*在 log_type 包含 CMB_LOG_TYPE_FILE 时,该参数才有效,用于记录日志的目录*/
  127. };
  128. struct LOG4VENDOR_API log_init_config
  129. {
  130. short log_type; /*见上面 CMB_LOG_TYPE_FILE 等定义*/
  131. short log_level; /*见上面 CMB_LOG_TRACE 等定义*/
  132. std::string dev_name; /*硬件名称,用于作为子目录的区分*/
  133. std::string log_dir; /*在 log_type 包含 CMB_LOG_TYPE_FILE 时,该参数才有效,用于记录日志的目录*/
  134. log_init_config()
  135. :log_type(CMB_LOG_TYPE_FILE)
  136. ,log_level(CMB_LOG_TRACE)
  137. ,dev_name(LOG4VTM_TEXT("VTM")),log_dir(LOG4VTM_TEXT("")){}
  138. log_init_config(const log_init_config& rhs)
  139. :log_type(rhs.log_type)
  140. , log_level(rhs.log_level)
  141. , dev_name(rhs.dev_name), log_dir(rhs.log_dir)
  142. {
  143. }
  144. };
  145. class LOG4VENDOR_API log4vendor
  146. {
  147. public:
  148. static log4vendor* instance();
  149. /*!
  150. * @brief 在调用打印日志的相关宏时,请先调用此函数进行初始化,否则将不会打印任何形式的日志内容
  151. *
  152. * @param[in]
  153. * config: 日志初始化的配置参数
  154. * ret_msg: 防止传入的参数有误,在必要的时候记录错误信息,供上层打印排查
  155. *
  156. * 如传入的参数依次为:"PinPad", CMB_LOG_TYPE_FILE|CMB_LOG_TYPE_CONSOLE, "C:\\rvc\\dbg"
  157. * 那么将会日志记在 "C:\\rvc\\dbg\\PinPad\\{YYYYMMDD}.log" 内,并将支持控制台输出
  158. *
  159. */
  160. static void init(const log_init_config& config, vtm_string& ret_msg);
  161. static void initp(const log_init_config_c* pconfig, char pret_msg[VENDOR_BUFF_SIZE]);
  162. virtual void log(int log_level, const vtm_string& text) = 0;
  163. static std::basic_ostringstream<char>& get_oss();
  164. //static std::basic_ostringstream<wchar_t>& get_woss();
  165. #ifdef LIBLOG4VENDOR_EXPORTS
  166. public:
  167. #else
  168. private:
  169. #endif
  170. log4vendor() {}
  171. virtual ~log4vendor(){}
  172. private:
  173. log4vendor(const log4vendor& rhs);
  174. };
  175. //////////////////////////////////////////////////////////////////////////
  176. class LOG4VENDOR_API log4vendor_tracer
  177. {
  178. public:
  179. log4vendor_tracer(const char* message, const char* fileName, int nLine);
  180. log4vendor_tracer(const char* message, const char* fileName, int nLine, int* pRet);
  181. log4vendor_tracer(const char* message, const char* fileName, int nLine, PDWORD pRet);
  182. ~log4vendor_tracer();
  183. static const char* _get_file_name(const char* file_path);
  184. private:
  185. log4vendor_tracer (log4vendor_tracer const &);
  186. log4vendor_tracer & operator = (log4vendor_tracer const &);
  187. const char* m_pszMes;
  188. const char* m_pszFileN;
  189. int m_nLine;
  190. int* m_pnRet;
  191. PDWORD m_pDwRet;
  192. int* m_pfRet;
  193. int m_retType;
  194. };
  195. }
  196. #endif //_VTM_LOG4VENDOR_H_