logger.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. import console from './console';
  2. import { isArrayOrObject, TimeUtil, isInstanceOfError, stringifyError } from './common-utils';
  3. const LOGLEVEL_DEBUG = -1;
  4. const LOGLEVEL_LOG = 0;
  5. const LOGLEVEL_INFO = 1;
  6. const LOGLEVEL_WARN = 2;
  7. const LOGLEVEL_ERROR = 3;
  8. const LOGLEVEL_NON_LOGGING = 4; // 无日志记录级别,sdk将不打印任何日志
  9. const MAX_LOG_LENGTH = 1000;
  10. let globalLevel = LOGLEVEL_LOG; // 暂停使用 wx.getLogManager,没发现它能起到什么作用
  11. const bCanIUseWxLog = false;
  12. const timerMap = new Map();
  13. /**
  14. * 对齐毫秒字符串
  15. * @param {*} ms 毫秒
  16. * @returns {String} 对齐后的毫秒时间字符串
  17. */
  18. function padMs(ms) {
  19. const len = ms.toString().length;
  20. let ret;
  21. switch (len) {
  22. case 1:
  23. ret = `00${ms}`;
  24. break;
  25. case 2:
  26. ret = `0${ms}`;
  27. break;
  28. default:
  29. ret = ms;
  30. break;
  31. }
  32. return ret;
  33. }
  34. /**
  35. * log前缀
  36. * @returns {String} 日志前缀
  37. */
  38. function getPrefix() {
  39. const date = new Date();
  40. return `TUIKit ${date.toLocaleTimeString('en-US', {
  41. hour12: false
  42. })}.${padMs(date.getMilliseconds())}:`;
  43. }
  44. /**
  45. * wx LogManager是否可用
  46. * @returns {Boolean} true->I can use LogManager
  47. */
  48. // function canIUseWxLog() {
  49. // if (IN_WX_MINI_APP) {
  50. // // 必须是微信小程序环境,百度小程序目前还只能用console
  51. // const version = wx.getSystemInfoSync().SDKVersion;
  52. // // HBuilder等工具会在window对象下挂自己模拟的wx对象,但是又没抄好,做个防御
  53. // if (typeof version === 'undefined' ||
  54. // typeof wx.getLogManager === 'undefined') {
  55. // return false;
  56. // }
  57. // if (compareVersion(version, '2.1.0') >= 0) {
  58. // wx.getLogManager().log('I can use wx log. SDKVersion=' + version);
  59. // return true;
  60. // }
  61. // }
  62. // return false;
  63. // }
  64. /**
  65. * 比较wx SDKVersion
  66. * @param {String} v1 版本字符串
  67. * @param {String} v2 版本字符串
  68. * @returns {Number} v1>v2,返回1;v1<v2,返回-1;v1==v2,返回0
  69. */
  70. // function compareVersion(v1, v2) {
  71. // v1 = v1.split('.');
  72. // v2 = v2.split('.');
  73. // const len = Math.max(v1.length, v2.length);
  74. // while (v1.length < len) {
  75. // v1.push('0');
  76. // }
  77. // while (v2.length < len) {
  78. // v2.push('0');
  79. // }
  80. // for (let i = 0; i < len; i++) {
  81. // const num1 = parseInt(v1[i]);
  82. // const num2 = parseInt(v2[i]);
  83. // if (num1 > num2) {
  84. // return 1;
  85. // }
  86. // if (num1 < num2) {
  87. // return -1;
  88. // }
  89. // }
  90. // return 0;
  91. // }
  92. const logger = {
  93. _data: [],
  94. _length: 0,
  95. _visible: false,
  96. // 将函数参数拼成字符串
  97. arguments2String(args) {
  98. let s;
  99. if (args.length === 1) {
  100. s = getPrefix() + args[0];
  101. } else {
  102. s = getPrefix();
  103. for (let i = 0, {
  104. length
  105. } = args; i < length; i++) {
  106. if (isArrayOrObject(args[i])) {
  107. if (isInstanceOfError(args[i])) {
  108. s += stringifyError(args[i]);
  109. } else {
  110. s += JSON.stringify(args[i]);
  111. }
  112. } else {
  113. s += args[i];
  114. }
  115. s += ' ';
  116. }
  117. }
  118. return s;
  119. },
  120. /**
  121. * 打印调试日志
  122. */
  123. debug() {
  124. if (globalLevel <= LOGLEVEL_DEBUG) {
  125. // 对参数使用slice会阻止某些JavaScript引擎中的优化 (比如 V8 - 更多信息)
  126. // see:https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments
  127. const s = this.arguments2String(arguments);
  128. logger.record(s, 'debug');
  129. console.debug(s);
  130. if (bCanIUseWxLog) {
  131. wx.getLogManager().debug(s);
  132. }
  133. }
  134. },
  135. /**
  136. * 打印普通日志
  137. */
  138. log() {
  139. if (globalLevel <= LOGLEVEL_LOG) {
  140. const s = this.arguments2String(arguments);
  141. logger.record(s, 'log');
  142. console.log(s);
  143. if (bCanIUseWxLog) {
  144. wx.getLogManager().log(s);
  145. }
  146. }
  147. },
  148. /**
  149. * 打印release日志
  150. */
  151. info() {
  152. if (globalLevel <= LOGLEVEL_INFO) {
  153. const s = this.arguments2String(arguments);
  154. logger.record(s, 'info');
  155. console.info(s);
  156. if (bCanIUseWxLog) {
  157. wx.getLogManager().info(s);
  158. }
  159. }
  160. },
  161. /**
  162. * 打印告警日志
  163. */
  164. warn() {
  165. if (globalLevel <= LOGLEVEL_WARN) {
  166. const s = this.arguments2String(arguments);
  167. logger.record(s, 'warn');
  168. console.warn(s);
  169. if (bCanIUseWxLog) {
  170. wx.getLogManager().warn(s);
  171. }
  172. }
  173. },
  174. /**
  175. * 打印错误日志
  176. */
  177. error() {
  178. if (globalLevel <= LOGLEVEL_ERROR) {
  179. const s = this.arguments2String(arguments);
  180. logger.record(s, 'error');
  181. console.error(s); // 微信写不了error日志,就用warn代替了
  182. if (bCanIUseWxLog) {
  183. wx.getLogManager().warn(s);
  184. }
  185. }
  186. },
  187. time(label) {
  188. timerMap.set(label, TimeUtil.now());
  189. },
  190. timeEnd(label) {
  191. if (timerMap.has(label)) {
  192. const cost = TimeUtil.now() - timerMap.get(label);
  193. timerMap.delete(label);
  194. return cost;
  195. }
  196. console.warn(`未找到对应label: ${label}, 请在调用 logger.timeEnd 前,调用 logger.time`);
  197. return 0;
  198. },
  199. setLevel(newLevel) {
  200. if (newLevel < LOGLEVEL_NON_LOGGING) {
  201. console.log(`${getPrefix()} set level from ${globalLevel} to ${newLevel}`);
  202. }
  203. globalLevel = newLevel;
  204. },
  205. record(s, type) {
  206. if (bCanIUseWxLog) {
  207. // 小程序环境不在内存缓存日志
  208. return;
  209. }
  210. if (logger._length === MAX_LOG_LENGTH + 100) {
  211. logger._data.splice(0, 100);
  212. logger._length = MAX_LOG_LENGTH;
  213. }
  214. logger._length++;
  215. logger._data.push(`${s} [${type}] \n`);
  216. },
  217. getLog() {
  218. return logger._data;
  219. }
  220. };
  221. export default logger;