re-common 10.0.37__py3-none-any.whl → 10.0.39__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. re_common/baselibrary/__init__.py +4 -4
  2. re_common/baselibrary/baseabs/__init__.py +6 -6
  3. re_common/baselibrary/baseabs/baseabs.py +26 -26
  4. re_common/baselibrary/database/mbuilder.py +132 -132
  5. re_common/baselibrary/database/moudle.py +93 -93
  6. re_common/baselibrary/database/msqlite3.py +194 -194
  7. re_common/baselibrary/database/mysql.py +169 -169
  8. re_common/baselibrary/database/sql_factory.py +26 -26
  9. re_common/baselibrary/mthread/MThreadingRun.py +486 -486
  10. re_common/baselibrary/mthread/MThreadingRunEvent.py +349 -349
  11. re_common/baselibrary/mthread/__init__.py +2 -2
  12. re_common/baselibrary/mthread/mythreading.py +695 -695
  13. re_common/baselibrary/pakge_other/socks.py +404 -404
  14. re_common/baselibrary/readconfig/config_factory.py +18 -18
  15. re_common/baselibrary/readconfig/ini_config.py +317 -317
  16. re_common/baselibrary/readconfig/toml_config.py +49 -49
  17. re_common/baselibrary/temporary/envdata.py +36 -36
  18. re_common/baselibrary/tools/all_requests/aiohttp_request.py +118 -118
  19. re_common/baselibrary/tools/all_requests/httpx_requet.py +102 -102
  20. re_common/baselibrary/tools/all_requests/mrequest.py +412 -412
  21. re_common/baselibrary/tools/all_requests/requests_request.py +81 -81
  22. re_common/baselibrary/tools/batch_compre/bijiao_batch.py +31 -31
  23. re_common/baselibrary/tools/contrast_db3.py +123 -123
  24. re_common/baselibrary/tools/copy_file.py +39 -39
  25. re_common/baselibrary/tools/db3_2_sizedb3.py +102 -102
  26. re_common/baselibrary/tools/foreachgz.py +39 -39
  27. re_common/baselibrary/tools/get_attr.py +10 -10
  28. re_common/baselibrary/tools/image_to_pdf.py +61 -61
  29. re_common/baselibrary/tools/java_code_deal.py +139 -139
  30. re_common/baselibrary/tools/javacode.py +79 -79
  31. re_common/baselibrary/tools/mdb_db3.py +48 -48
  32. re_common/baselibrary/tools/merge_file.py +171 -171
  33. re_common/baselibrary/tools/merge_gz_file.py +165 -165
  34. re_common/baselibrary/tools/mhdfstools/down_hdfs_files.py +42 -42
  35. re_common/baselibrary/tools/mhdfstools/hdfst.py +42 -42
  36. re_common/baselibrary/tools/mhdfstools/up_hdfs_files.py +38 -38
  37. re_common/baselibrary/tools/mongo_tools.py +50 -50
  38. re_common/baselibrary/tools/move_file.py +170 -170
  39. re_common/baselibrary/tools/move_mongo/mongo_table_to_file.py +63 -63
  40. re_common/baselibrary/tools/move_mongo/move_mongo_table.py +354 -354
  41. re_common/baselibrary/tools/move_mongo/use_mttf.py +18 -18
  42. re_common/baselibrary/tools/move_mongo/use_mv.py +93 -93
  43. re_common/baselibrary/tools/mpandas/mpandasreadexcel.py +125 -125
  44. re_common/baselibrary/tools/mpandas/pandas_visualization.py +7 -7
  45. re_common/baselibrary/tools/myparsel.py +104 -104
  46. re_common/baselibrary/tools/rename_dir_file.py +37 -37
  47. re_common/baselibrary/tools/sequoiadb_utils.py +398 -398
  48. re_common/baselibrary/tools/split_line_to_many.py +25 -25
  49. re_common/baselibrary/tools/stringtodicts.py +33 -33
  50. re_common/baselibrary/tools/workwechant_bot.py +84 -84
  51. re_common/baselibrary/utils/baseaiohttp.py +296 -296
  52. re_common/baselibrary/utils/baseaiomysql.py +87 -87
  53. re_common/baselibrary/utils/baseallstep.py +191 -191
  54. re_common/baselibrary/utils/baseavro.py +19 -19
  55. re_common/baselibrary/utils/baseboto3.py +291 -291
  56. re_common/baselibrary/utils/basecsv.py +32 -32
  57. re_common/baselibrary/utils/basedict.py +133 -133
  58. re_common/baselibrary/utils/basedir.py +241 -241
  59. re_common/baselibrary/utils/baseencode.py +351 -351
  60. re_common/baselibrary/utils/baseencoding.py +28 -28
  61. re_common/baselibrary/utils/baseesdsl.py +86 -86
  62. re_common/baselibrary/utils/baseexcel.py +264 -264
  63. re_common/baselibrary/utils/baseexcept.py +109 -109
  64. re_common/baselibrary/utils/basefile.py +654 -654
  65. re_common/baselibrary/utils/baseftp.py +214 -214
  66. re_common/baselibrary/utils/basegzip.py +60 -60
  67. re_common/baselibrary/utils/basehdfs.py +135 -135
  68. re_common/baselibrary/utils/basehttpx.py +268 -268
  69. re_common/baselibrary/utils/baseip.py +87 -87
  70. re_common/baselibrary/utils/basejson.py +2 -2
  71. re_common/baselibrary/utils/baselist.py +32 -32
  72. re_common/baselibrary/utils/basemotor.py +190 -190
  73. re_common/baselibrary/utils/basemssql.py +98 -98
  74. re_common/baselibrary/utils/baseodbc.py +113 -113
  75. re_common/baselibrary/utils/basepandas.py +302 -302
  76. re_common/baselibrary/utils/basepeewee.py +11 -11
  77. re_common/baselibrary/utils/basepika.py +180 -180
  78. re_common/baselibrary/utils/basepydash.py +143 -143
  79. re_common/baselibrary/utils/basepymongo.py +230 -230
  80. re_common/baselibrary/utils/basequeue.py +22 -22
  81. re_common/baselibrary/utils/baserar.py +57 -57
  82. re_common/baselibrary/utils/baserequest.py +279 -279
  83. re_common/baselibrary/utils/baseset.py +8 -8
  84. re_common/baselibrary/utils/basesmb.py +403 -403
  85. re_common/baselibrary/utils/basestring.py +382 -382
  86. re_common/baselibrary/utils/basetime.py +320 -320
  87. re_common/baselibrary/utils/baseurl.py +121 -121
  88. re_common/baselibrary/utils/basezip.py +57 -57
  89. re_common/baselibrary/utils/core/__init__.py +7 -7
  90. re_common/baselibrary/utils/core/bottomutils.py +18 -18
  91. re_common/baselibrary/utils/core/mdeprecated.py +327 -327
  92. re_common/baselibrary/utils/core/mlamada.py +16 -16
  93. re_common/baselibrary/utils/core/msginfo.py +25 -25
  94. re_common/baselibrary/utils/core/requests_core.py +103 -103
  95. re_common/baselibrary/utils/fateadm.py +429 -429
  96. re_common/baselibrary/utils/importfun.py +123 -123
  97. re_common/baselibrary/utils/mfaker.py +57 -57
  98. re_common/baselibrary/utils/my_abc/__init__.py +3 -3
  99. re_common/baselibrary/utils/my_abc/better_abc.py +32 -32
  100. re_common/baselibrary/utils/mylogger.py +414 -414
  101. re_common/baselibrary/utils/myredisclient.py +861 -861
  102. re_common/baselibrary/utils/pipupgrade.py +21 -21
  103. re_common/baselibrary/utils/ringlist.py +85 -85
  104. re_common/baselibrary/utils/version_compare.py +36 -36
  105. re_common/baselibrary/utils/ydmhttp.py +126 -126
  106. re_common/facade/lazy_import.py +11 -11
  107. re_common/facade/loggerfacade.py +25 -25
  108. re_common/facade/mysqlfacade.py +467 -467
  109. re_common/facade/now.py +31 -31
  110. re_common/facade/sqlite3facade.py +257 -257
  111. re_common/facade/use/mq_use_facade.py +83 -83
  112. re_common/facade/use/proxy_use_facade.py +19 -19
  113. re_common/libtest/base_dict_test.py +19 -19
  114. re_common/libtest/baseavro_test.py +13 -13
  115. re_common/libtest/basefile_test.py +14 -14
  116. re_common/libtest/basemssql_test.py +77 -77
  117. re_common/libtest/baseodbc_test.py +7 -7
  118. re_common/libtest/basepandas_test.py +38 -38
  119. re_common/libtest/get_attr_test/get_attr_test_settings.py +14 -14
  120. re_common/libtest/get_attr_test/settings.py +54 -54
  121. re_common/libtest/idencode_test.py +53 -53
  122. re_common/libtest/iniconfig_test.py +35 -35
  123. re_common/libtest/ip_test.py +34 -34
  124. re_common/libtest/merge_file_test.py +20 -20
  125. re_common/libtest/mfaker_test.py +8 -8
  126. re_common/libtest/mm3_test.py +31 -31
  127. re_common/libtest/mylogger_test.py +88 -88
  128. re_common/libtest/myparsel_test.py +27 -27
  129. re_common/libtest/mysql_test.py +151 -151
  130. re_common/libtest/pymongo_test.py +21 -21
  131. re_common/libtest/split_test.py +11 -11
  132. re_common/libtest/sqlite3_merge_test.py +5 -5
  133. re_common/libtest/sqlite3_test.py +34 -34
  134. re_common/libtest/tomlconfig_test.py +30 -30
  135. re_common/libtest/use_tools_test/__init__.py +2 -2
  136. re_common/libtest/user/__init__.py +4 -4
  137. re_common/studio/__init__.py +4 -4
  138. re_common/studio/assignment_expressions.py +36 -36
  139. re_common/studio/mydash/test1.py +18 -18
  140. re_common/studio/pydashstudio/first.py +9 -9
  141. re_common/studio/streamlitstudio/first_app.py +65 -65
  142. re_common/studio/streamlitstudio/uber_pickups.py +23 -23
  143. re_common/studio/test.py +18 -18
  144. re_common/v2/baselibrary/business_utils/BusinessStringUtil.py +219 -219
  145. re_common/v2/baselibrary/business_utils/baseencodeid.py +100 -100
  146. re_common/v2/baselibrary/business_utils/full_doi_path.py +116 -116
  147. re_common/v2/baselibrary/business_utils/rel_tools.py +6 -6
  148. re_common/v2/baselibrary/decorators/utils.py +59 -59
  149. re_common/v2/baselibrary/helpers/search_packge/NearestNeighbors_test.py +105 -105
  150. re_common/v2/baselibrary/helpers/search_packge/fit_text_match.py +253 -253
  151. re_common/v2/baselibrary/helpers/search_packge/scikit_learn_text_matcher.py +260 -260
  152. re_common/v2/baselibrary/helpers/search_packge/test.py +1 -1
  153. re_common/v2/baselibrary/s3object/baseboto3.py +230 -230
  154. re_common/v2/baselibrary/tools/WeChatRobot.py +95 -95
  155. re_common/v2/baselibrary/tools/ac_ahocorasick.py +75 -75
  156. re_common/v2/baselibrary/tools/concurrency.py +35 -35
  157. re_common/v2/baselibrary/tools/data_processer/base.py +53 -53
  158. re_common/v2/baselibrary/tools/data_processer/data_processer.py +508 -508
  159. re_common/v2/baselibrary/tools/data_processer/data_reader.py +187 -187
  160. re_common/v2/baselibrary/tools/data_processer/data_writer.py +38 -38
  161. re_common/v2/baselibrary/tools/dict_tools.py +44 -44
  162. re_common/v2/baselibrary/tools/dolphinscheduler.py +187 -187
  163. re_common/v2/baselibrary/tools/hdfs_base_processor.py +204 -204
  164. re_common/v2/baselibrary/tools/hdfs_bulk_processor.py +67 -67
  165. re_common/v2/baselibrary/tools/hdfs_data_processer.py +338 -338
  166. re_common/v2/baselibrary/tools/hdfs_line_processor.py +74 -74
  167. re_common/v2/baselibrary/tools/list_tools.py +69 -69
  168. re_common/v2/baselibrary/tools/resume_tracker.py +94 -94
  169. re_common/v2/baselibrary/tools/search_hash_tools.py +54 -54
  170. re_common/v2/baselibrary/tools/text_matcher.py +326 -326
  171. re_common/v2/baselibrary/tools/unionfind_tools.py +60 -60
  172. re_common/v2/baselibrary/utils/BusinessStringUtil.py +196 -196
  173. re_common/v2/baselibrary/utils/api_net_utils.py +270 -270
  174. re_common/v2/baselibrary/utils/author_smi.py +361 -361
  175. re_common/v2/baselibrary/utils/base_string_similarity.py +158 -158
  176. re_common/v2/baselibrary/utils/basedict.py +37 -37
  177. re_common/v2/baselibrary/utils/basehdfs.py +163 -163
  178. re_common/v2/baselibrary/utils/basepika.py +180 -180
  179. re_common/v2/baselibrary/utils/basetime.py +77 -77
  180. re_common/v2/baselibrary/utils/db.py +156 -156
  181. re_common/v2/baselibrary/utils/json_cls.py +16 -16
  182. re_common/v2/baselibrary/utils/mq.py +83 -83
  183. re_common/v2/baselibrary/utils/n_ary_expression_tree.py +243 -243
  184. re_common/v2/baselibrary/utils/string_bool.py +186 -186
  185. re_common/v2/baselibrary/utils/string_clear.py +246 -246
  186. re_common/v2/baselibrary/utils/string_smi.py +18 -18
  187. re_common/v2/baselibrary/utils/stringutils.py +271 -278
  188. re_common/vip/base_step_process.py +11 -11
  189. re_common/vip/baseencodeid.py +90 -90
  190. re_common/vip/changetaskname.py +28 -28
  191. re_common/vip/core_var.py +24 -24
  192. re_common/vip/mmh3Hash.py +89 -89
  193. re_common/vip/proxy/allproxys.py +127 -127
  194. re_common/vip/proxy/allproxys_thread.py +159 -159
  195. re_common/vip/proxy/cnki_proxy.py +153 -153
  196. re_common/vip/proxy/kuaidaili.py +87 -87
  197. re_common/vip/proxy/proxy_all.py +113 -113
  198. re_common/vip/proxy/update_kuaidaili_0.py +42 -42
  199. re_common/vip/proxy/wanfang_proxy.py +152 -152
  200. re_common/vip/proxy/wp_proxy_all.py +181 -181
  201. re_common/vip/read_rawid_to_txt.py +91 -91
  202. re_common/vip/title/__init__.py +5 -5
  203. re_common/vip/title/transform/TransformBookTitleToZt.py +125 -125
  204. re_common/vip/title/transform/TransformConferenceTitleToZt.py +139 -139
  205. re_common/vip/title/transform/TransformCstadTitleToZt.py +195 -195
  206. re_common/vip/title/transform/TransformJournalTitleToZt.py +203 -203
  207. re_common/vip/title/transform/TransformPatentTitleToZt.py +132 -132
  208. re_common/vip/title/transform/TransformRegulationTitleToZt.py +114 -114
  209. re_common/vip/title/transform/TransformStandardTitleToZt.py +135 -135
  210. re_common/vip/title/transform/TransformThesisTitleToZt.py +135 -135
  211. re_common/vip/title/transform/__init__.py +10 -10
  212. {re_common-10.0.37.dist-info → re_common-10.0.39.dist-info}/LICENSE +201 -201
  213. {re_common-10.0.37.dist-info → re_common-10.0.39.dist-info}/METADATA +16 -16
  214. re_common-10.0.39.dist-info/RECORD +248 -0
  215. {re_common-10.0.37.dist-info → re_common-10.0.39.dist-info}/WHEEL +1 -1
  216. re_common-10.0.37.dist-info/RECORD +0 -248
  217. {re_common-10.0.37.dist-info → re_common-10.0.39.dist-info}/top_level.txt +0 -0
@@ -1,414 +1,414 @@
1
- #!/usr/local/bin/python
2
- # -*- coding:utf-8 -*-
3
-
4
- # 由于每个配置必须要有root 所以这里有个root,但我们不使用他,因为在logger对象中无法获取root的hander
5
- # 来设置过滤器,这里我们使用all代表文件和控制台的输出,配置文件的使用模式是在[loggers]中申明有哪些logger
6
- # 在 [logger_xxx]中对应每个logger的配置,下面的结构完全遵循这一结构
7
-
8
- import logging
9
- import logging.config
10
- import os
11
- import sys
12
- import time
13
- from functools import wraps
14
- from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler
15
- from os import path
16
-
17
- """
18
- 这个是logger的过滤器 可以过滤掉多余的日志 让对应级别的日志写入对应级别的文件
19
- 通过日志的级别和传入的级别对比 返回true or false
20
- """
21
-
22
-
23
- class BaseLogFilter(logging.Filter):
24
- def __init__(self, name='', logname="_1"):
25
- super(BaseLogFilter, self).__init__(name)
26
- self.logname = logname
27
-
28
-
29
- class LogLevelFilter(BaseLogFilter):
30
- def __init__(self, name='', level=logging.DEBUG, levels=None):
31
- super(LogLevelFilter, self).__init__(name)
32
- self.level = level
33
- self.levels = levels
34
-
35
- def filter(self, record):
36
- if self.levels == None:
37
- return record.levelno == self.level
38
- else:
39
- for level in self.levels:
40
- if record.levelno == level:
41
- return True
42
- return False
43
-
44
-
45
- """
46
- 单例模式的一种实现
47
- """
48
-
49
-
50
- def singleton(cls):
51
- instances = {}
52
-
53
- @wraps(cls)
54
- def getinstance(*args, **kw):
55
- if cls not in instances:
56
- instances[cls] = cls(*args, **kw)
57
- return instances[cls]
58
-
59
- return getinstance
60
-
61
-
62
- """
63
- Logger的主体,主要靠这个实现
64
- 加入单例模式下遇到MLogger调用静态方法会出问题
65
- """
66
-
67
-
68
- # @singleton
69
- class MLogger(object):
70
- def __init__(self, logfiledir=None, filter=None):
71
- if logfiledir:
72
- # 获取logger实例,如果参数为空则返回root logger
73
- self.confFilePath(logfiledir)
74
- # 这是输出流
75
- self.streamoutlogger = self.streamOutLogger()
76
- # 这是错误流
77
- self.streamerrlogger = self.streamErrLogger()
78
-
79
- self.streamlogger = self.streamLogger()
80
-
81
- self._alllogger = None
82
- self._filelogger = None
83
- self._timerotatingfilelogger = None
84
- self._rotatingfilelogger = None
85
- self.fileter = filter
86
-
87
- self.maxBytes = 1024 * 1024 * 1024
88
- self.backupCount = 10
89
-
90
- def set_logfiledir(self, logfiledir):
91
- self.confFilePath(logfiledir)
92
-
93
- @property
94
- def alllogger(self):
95
- # logger 对象是alllogger 及所有日志对象
96
- if not self._alllogger:
97
- self._alllogger = self.allLogger(self.logfiledir)
98
- return self._alllogger
99
-
100
- @alllogger.setter
101
- def alllogger(self, value):
102
- self._alllogger = value
103
-
104
- @property
105
- def filelogger(self):
106
- if not self._filelogger:
107
- self._filelogger = self.fileLogger(self.logfiledir)
108
- return self._filelogger
109
-
110
- @filelogger.setter
111
- def filelogger(self, value):
112
- self._filelogger = value
113
-
114
- @property
115
- def timerotatingfilelogger(self):
116
- if not self._timerotatingfilelogger:
117
- self._timerotatingfilelogger = self.timeRotatingFileLogger(self.logfiledir, self.fileter)
118
- return self._timerotatingfilelogger
119
-
120
- @timerotatingfilelogger.setter
121
- def timerotatingfilelogger(self, value):
122
- self._timerotatingfilelogger = value
123
-
124
- @property
125
- def rotatingfilelogger(self):
126
- if not self._rotatingfilelogger:
127
- self._rotatingfilelogger = self.RotatingFileLogger(self.logfiledir, self.fileter, maxBytes=self.maxBytes,
128
- backupCount=self.backupCount)
129
- return self._rotatingfilelogger
130
-
131
- @rotatingfilelogger.setter
132
- def rotatingfilelogger(self, value):
133
- self._rotatingfilelogger = value
134
-
135
- def confFilePath(self, path=None):
136
- """
137
- 这里定义了log日志存放的目录
138
- :param path: log日志存放的路径 如果没有 就默认当前目录的logs文件夹
139
- :return:
140
- """
141
- if path is None or path == '':
142
- # 如果没有指定文件路径
143
- self.logfiledir = "./logs"
144
- if not os.path.exists(self.logfiledir):
145
- os.makedirs(self.logfiledir)
146
- else:
147
- try:
148
- if not os.path.exists(path):
149
- os.makedirs(path)
150
- self.logfiledir = path
151
- except Exception as e:
152
- raise e
153
-
154
- @staticmethod
155
- def formatter():
156
- # fmt = "%(asctime)s %(levelname)s {%(message)s} %(pathname)s:%(funcName)s:%(lineno)s:%(module)s %(name)s %(processName)s:%(process)d %(threadName)s:%(thread)d"
157
- fmt = "[%(asctime)s %(levelname)s/%(processName)s:%(process)d/%(threadName)s:%(thread)d] %(message)s ==> %(pathname)s->%(module)s->%(funcName)s->%(lineno)s %(name)s"
158
- datefmt = "%a %d %b %Y %H:%M:%S" # Thu 22 Feb 2018
159
- datefmt = "%Y-%m-%d %H:%M:%S" # 2018-02-22
160
- formatter = logging.Formatter(fmt, datefmt)
161
- return formatter
162
-
163
- @staticmethod
164
- def BaseHandler(std, level, filter=None):
165
- # 错误流的handler warn及其以上
166
- streamerrhandler = logging.StreamHandler(std)
167
- if filter != None:
168
- # 添加过滤器
169
- streamerrhandler.addFilter(filter)
170
- # 获取输出格式
171
- streamerrhandler.setFormatter(MLogger.formatter())
172
- # 设置级别
173
- streamerrhandler.setLevel(level)
174
- return streamerrhandler
175
-
176
- @staticmethod
177
- def BaseFileHandler(level, filename, filter=None, encoding='utf-8'):
178
- fileHandler = logging.FileHandler(filename, encoding=encoding)
179
- if filter != None:
180
- fileHandler.addFilter(filter)
181
- fileHandler.setFormatter(MLogger.formatter())
182
- fileHandler.setLevel(level)
183
- return fileHandler
184
-
185
- # 错误流会输出WARN及以上的级别
186
- @staticmethod
187
- def streamErrHandlers():
188
- return MLogger.BaseHandler(sys.stderr, logging.WARN)
189
-
190
- @staticmethod
191
- def streamHandlers():
192
- return MLogger.BaseHandler(sys.stdout, logging.DEBUG)
193
-
194
- # 输出流只会输出INFO 和 DEBUG 两个级别的数据
195
- # https://yinzo.github.io/14610807170718.html 小坑
196
- @staticmethod
197
- def streamOutHandler():
198
- filter_stdout = LogLevelFilter(levels=[logging.INFO, logging.DEBUG])
199
- return MLogger.BaseHandler(sys.stdout, logging.DEBUG, filter_stdout)
200
-
201
- # 文件流会将所有级别的日志写入mylog.log这个文件
202
- @staticmethod
203
- def fileHandler(filepath):
204
- log_file_path = path.join(filepath, time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
205
- return MLogger.BaseFileHandler(logging.DEBUG, log_file_path)
206
-
207
- @staticmethod
208
- def timeRotatingFileHandler(filepath, filter=None):
209
- suffix = ""
210
- if filter != None:
211
- suffix = filter.logname
212
- log_file_path = path.join(filepath, time.strftime('%Y%m%d', time.localtime(time.time())) + suffix + ".log")
213
- hander = TimedRotatingFileHandler(log_file_path, when="D", interval=1, backupCount=30)
214
- if filter != None:
215
- # 添加过滤器
216
- hander.addFilter(filter)
217
- hander.setFormatter(MLogger.formatter())
218
- hander.setLevel(logging.DEBUG)
219
- return hander
220
-
221
- @staticmethod
222
- def RotatingFileHandler(filepath, filter=None, maxBytes=1024 * 1024 * 1024, backupCount=10):
223
- suffix = ""
224
- if filter != None:
225
- suffix = filter.logname
226
- log_file_path = path.join(filepath, time.strftime('%Y%m%d', time.localtime(time.time())) + suffix + ".log")
227
- hander = RotatingFileHandler(log_file_path, maxBytes=maxBytes, backupCount=backupCount)
228
- if filter != None:
229
- # 添加过滤器
230
- hander.addFilter(filter)
231
- hander.setFormatter(MLogger.formatter())
232
- hander.setLevel(logging.DEBUG)
233
- return hander
234
-
235
- """
236
- 下面这些只会将对应级别的日志写入对应的文件
237
- """
238
-
239
- @staticmethod
240
- def fileDebugHandler(filepath):
241
- log_file_path = path.join(filepath,
242
- "mydebuglog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
243
- filter_debug = LogLevelFilter(level=logging.DEBUG)
244
- return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_debug)
245
-
246
- @staticmethod
247
- def fileInfoHandler(filepath):
248
- log_file_path = path.join(filepath,
249
- "myinfolog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
250
- filter_info = LogLevelFilter(level=logging.INFO)
251
-
252
- return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_info)
253
-
254
- @staticmethod
255
- def fileWarnHandler(filepath):
256
- log_file_path = path.join(filepath,
257
- "mywarnlog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
258
- filter_warn = LogLevelFilter(level=logging.WARN)
259
-
260
- return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_warn)
261
-
262
- @staticmethod
263
- def fileErrorHandler(filepath):
264
- log_file_path = path.join(filepath,
265
- "myerrorlog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
266
- filter_error = LogLevelFilter(level=logging.ERROR)
267
-
268
- return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_error)
269
-
270
- @staticmethod
271
- def fileExceptionHandler(filepath):
272
- log_file_path = path.join(filepath,
273
- "myexceptionlog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
274
- filter_exception = LogLevelFilter(level=logging.ERROR) # 会返回错误堆栈
275
-
276
- return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_exception)
277
-
278
- @staticmethod
279
- def fileCriticalHandler(filepath):
280
- log_file_path = path.join(filepath,
281
- "mycriticallog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
282
- filter_critical = LogLevelFilter(level=logging.CRITICAL)
283
- return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_critical)
284
-
285
- """
286
- 下面是各种各样的logger 用于不同的输出
287
- 比如你用errlogger就会只打印错误的logger 而不会打印输出信息的logger且不会写入文件
288
- 我们可以自由组合我们的logger方便使用,只要定义出不同组合的logger就行了,我现在一般使用allloger
289
- 记录下所有的信息
290
- """
291
-
292
- @staticmethod
293
- def streamErrLogger(level=logging.DEBUG):
294
- # 获取logger对象
295
- logger = logging.getLogger("streamErrLogger")
296
- # 设置logger获取的级别
297
- logger.setLevel(level)
298
- logger.handlers = []
299
- # 为logger添加handler
300
- logger.addHandler(MLogger.streamErrHandlers())
301
- return logger
302
-
303
- @staticmethod
304
- def streamOutLogger(level=logging.DEBUG):
305
- logger = logging.getLogger("streamOutLogger")
306
- logger.setLevel(level)
307
- logger.handlers = []
308
- logger.addHandler(MLogger.streamOutHandler())
309
- return logger
310
-
311
- @staticmethod
312
- def allLogger(filepath,level=logging.DEBUG):
313
- # 获取all代表不管输出和文件都会有流产生
314
- logger = logging.getLogger("all")
315
- logger.setLevel(level)
316
- logger.handlers = []
317
- # http://www.aiuxian.com/article/p-483639.html
318
- logger.addHandler(MLogger.streamOutHandler()) # 输出流
319
- logger.addHandler(MLogger.streamErrHandlers()) # 错误流
320
- # 这是所有的日志都会输出到这个文件
321
- logger.addHandler(MLogger.fileHandler(filepath))
322
- # 下面是各个级别的日志流都会输入到对应的文件中
323
- logger.addHandler(MLogger.fileDebugHandler(filepath))
324
- logger.addHandler(MLogger.fileInfoHandler(filepath))
325
- logger.addHandler(MLogger.fileWarnHandler(filepath))
326
- logger.addHandler(MLogger.fileErrorHandler(filepath))
327
- logger.addHandler(MLogger.fileExceptionHandler(filepath))
328
- logger.addHandler(MLogger.fileCriticalHandler(filepath))
329
- return logger
330
-
331
- @staticmethod
332
- def multifile_logger(filepath,level=logging.DEBUG):
333
- # 获取all代表不管输出和文件都会有流产生
334
- logger = logging.getLogger("multifile")
335
- logger.setLevel(level)
336
- logger.handlers = []
337
- # 下面是各个级别的日志流都会输入到对应的文件中
338
- logger.addHandler(MLogger.fileDebugHandler(filepath))
339
- logger.addHandler(MLogger.fileInfoHandler(filepath))
340
- logger.addHandler(MLogger.fileWarnHandler(filepath))
341
- logger.addHandler(MLogger.fileErrorHandler(filepath))
342
- logger.addHandler(MLogger.fileExceptionHandler(filepath))
343
- logger.addHandler(MLogger.fileCriticalHandler(filepath))
344
- return logger
345
-
346
- @staticmethod
347
- def fileLogger(filepath,level=logging.DEBUG):
348
- # 获取all代表不管输出和文件都会有流产生
349
- logger = logging.getLogger("file")
350
- logger.setLevel(level)
351
- # 防止多次写入
352
- logger.handlers = []
353
- # http://www.aiuxian.com/article/p-483639.html
354
- logger.addHandler(MLogger.streamOutHandler()) # 输出流
355
- logger.addHandler(MLogger.streamErrHandlers()) # 错误流
356
- # 这是所有的日志都会输出到这个文件
357
- logger.addHandler(MLogger.fileHandler(filepath))
358
- return logger
359
-
360
- @staticmethod
361
- def timeRotatingFileLogger(filepath, fileter,level=logging.DEBUG):
362
- # 获取all代表不管输出和文件都会有流产生
363
- logger = logging.getLogger("timerotatingfile")
364
- logger.setLevel(level)
365
- # 防止多次写入
366
- logger.handlers = []
367
- # http://www.aiuxian.com/article/p-483639.html
368
- logger.addHandler(MLogger.streamOutHandler()) # 输出流
369
- logger.addHandler(MLogger.streamErrHandlers()) # 错误流
370
- if fileter:
371
- logger.addHandler(MLogger.timeRotatingFileHandler(filepath, fileter))
372
- # 这是所有的日志都会输出到这个文件
373
- logger.addHandler(MLogger.timeRotatingFileHandler(filepath))
374
- return logger
375
-
376
- @staticmethod
377
- def RotatingFileLogger(filepath, fileter, maxBytes=1024 * 1024 * 1024, backupCount=10,level=logging.DEBUG):
378
- # 获取all代表不管输出和文件都会有流产生
379
- logger = logging.getLogger("rotatingfile")
380
- logger.setLevel(level)
381
- # 防止多次写入
382
- logger.handlers = []
383
- # http://www.aiuxian.com/article/p-483639.html
384
- logger.addHandler(MLogger.streamOutHandler()) # 输出流
385
- logger.addHandler(MLogger.streamErrHandlers()) # 错误流
386
- if fileter:
387
- logger.addHandler(
388
- MLogger.RotatingFileHandler(filepath, fileter, maxBytes=maxBytes, backupCount=backupCount))
389
- # 这是所有的日志都会输出到这个文件
390
- logger.addHandler(MLogger.RotatingFileHandler(filepath, maxBytes=maxBytes, backupCount=backupCount))
391
- return logger
392
-
393
- def streamLogger(self,level=logging.DEBUG):
394
- # 全局对象个数有getLogger的参数决定
395
- logger = logging.getLogger("streamLogger")
396
- logger.setLevel(level)
397
- # 防止多次打印
398
- logger.handlers = []
399
- logger.addHandler(MLogger.streamHandlers())
400
- return logger
401
-
402
- # def main():
403
- #
404
- # # 使用教程
405
- # log_file_path = path.join(path.dirname(path.abspath(__file__)), 'logs')
406
- # logger = MLogger(log_file_path).streamlogger
407
- # logger.debug('debug message')
408
- # logger.info('info message')
409
- # logger.warning('warn message')
410
- # logger.error('error message')
411
- # logger.exception('exception message')
412
- # logger.critical('critical message')
413
- #
414
- # main()
1
+ #!/usr/local/bin/python
2
+ # -*- coding:utf-8 -*-
3
+
4
+ # 由于每个配置必须要有root 所以这里有个root,但我们不使用他,因为在logger对象中无法获取root的hander
5
+ # 来设置过滤器,这里我们使用all代表文件和控制台的输出,配置文件的使用模式是在[loggers]中申明有哪些logger
6
+ # 在 [logger_xxx]中对应每个logger的配置,下面的结构完全遵循这一结构
7
+
8
+ import logging
9
+ import logging.config
10
+ import os
11
+ import sys
12
+ import time
13
+ from functools import wraps
14
+ from logging.handlers import TimedRotatingFileHandler, RotatingFileHandler
15
+ from os import path
16
+
17
+ """
18
+ 这个是logger的过滤器 可以过滤掉多余的日志 让对应级别的日志写入对应级别的文件
19
+ 通过日志的级别和传入的级别对比 返回true or false
20
+ """
21
+
22
+
23
+ class BaseLogFilter(logging.Filter):
24
+ def __init__(self, name='', logname="_1"):
25
+ super(BaseLogFilter, self).__init__(name)
26
+ self.logname = logname
27
+
28
+
29
+ class LogLevelFilter(BaseLogFilter):
30
+ def __init__(self, name='', level=logging.DEBUG, levels=None):
31
+ super(LogLevelFilter, self).__init__(name)
32
+ self.level = level
33
+ self.levels = levels
34
+
35
+ def filter(self, record):
36
+ if self.levels == None:
37
+ return record.levelno == self.level
38
+ else:
39
+ for level in self.levels:
40
+ if record.levelno == level:
41
+ return True
42
+ return False
43
+
44
+
45
+ """
46
+ 单例模式的一种实现
47
+ """
48
+
49
+
50
+ def singleton(cls):
51
+ instances = {}
52
+
53
+ @wraps(cls)
54
+ def getinstance(*args, **kw):
55
+ if cls not in instances:
56
+ instances[cls] = cls(*args, **kw)
57
+ return instances[cls]
58
+
59
+ return getinstance
60
+
61
+
62
+ """
63
+ Logger的主体,主要靠这个实现
64
+ 加入单例模式下遇到MLogger调用静态方法会出问题
65
+ """
66
+
67
+
68
+ # @singleton
69
+ class MLogger(object):
70
+ def __init__(self, logfiledir=None, filter=None):
71
+ if logfiledir:
72
+ # 获取logger实例,如果参数为空则返回root logger
73
+ self.confFilePath(logfiledir)
74
+ # 这是输出流
75
+ self.streamoutlogger = self.streamOutLogger()
76
+ # 这是错误流
77
+ self.streamerrlogger = self.streamErrLogger()
78
+
79
+ self.streamlogger = self.streamLogger()
80
+
81
+ self._alllogger = None
82
+ self._filelogger = None
83
+ self._timerotatingfilelogger = None
84
+ self._rotatingfilelogger = None
85
+ self.fileter = filter
86
+
87
+ self.maxBytes = 1024 * 1024 * 1024
88
+ self.backupCount = 10
89
+
90
+ def set_logfiledir(self, logfiledir):
91
+ self.confFilePath(logfiledir)
92
+
93
+ @property
94
+ def alllogger(self):
95
+ # logger 对象是alllogger 及所有日志对象
96
+ if not self._alllogger:
97
+ self._alllogger = self.allLogger(self.logfiledir)
98
+ return self._alllogger
99
+
100
+ @alllogger.setter
101
+ def alllogger(self, value):
102
+ self._alllogger = value
103
+
104
+ @property
105
+ def filelogger(self):
106
+ if not self._filelogger:
107
+ self._filelogger = self.fileLogger(self.logfiledir)
108
+ return self._filelogger
109
+
110
+ @filelogger.setter
111
+ def filelogger(self, value):
112
+ self._filelogger = value
113
+
114
+ @property
115
+ def timerotatingfilelogger(self):
116
+ if not self._timerotatingfilelogger:
117
+ self._timerotatingfilelogger = self.timeRotatingFileLogger(self.logfiledir, self.fileter)
118
+ return self._timerotatingfilelogger
119
+
120
+ @timerotatingfilelogger.setter
121
+ def timerotatingfilelogger(self, value):
122
+ self._timerotatingfilelogger = value
123
+
124
+ @property
125
+ def rotatingfilelogger(self):
126
+ if not self._rotatingfilelogger:
127
+ self._rotatingfilelogger = self.RotatingFileLogger(self.logfiledir, self.fileter, maxBytes=self.maxBytes,
128
+ backupCount=self.backupCount)
129
+ return self._rotatingfilelogger
130
+
131
+ @rotatingfilelogger.setter
132
+ def rotatingfilelogger(self, value):
133
+ self._rotatingfilelogger = value
134
+
135
+ def confFilePath(self, path=None):
136
+ """
137
+ 这里定义了log日志存放的目录
138
+ :param path: log日志存放的路径 如果没有 就默认当前目录的logs文件夹
139
+ :return:
140
+ """
141
+ if path is None or path == '':
142
+ # 如果没有指定文件路径
143
+ self.logfiledir = "./logs"
144
+ if not os.path.exists(self.logfiledir):
145
+ os.makedirs(self.logfiledir)
146
+ else:
147
+ try:
148
+ if not os.path.exists(path):
149
+ os.makedirs(path)
150
+ self.logfiledir = path
151
+ except Exception as e:
152
+ raise e
153
+
154
+ @staticmethod
155
+ def formatter():
156
+ # fmt = "%(asctime)s %(levelname)s {%(message)s} %(pathname)s:%(funcName)s:%(lineno)s:%(module)s %(name)s %(processName)s:%(process)d %(threadName)s:%(thread)d"
157
+ fmt = "[%(asctime)s %(levelname)s/%(processName)s:%(process)d/%(threadName)s:%(thread)d] %(message)s ==> %(pathname)s->%(module)s->%(funcName)s->%(lineno)s %(name)s"
158
+ datefmt = "%a %d %b %Y %H:%M:%S" # Thu 22 Feb 2018
159
+ datefmt = "%Y-%m-%d %H:%M:%S" # 2018-02-22
160
+ formatter = logging.Formatter(fmt, datefmt)
161
+ return formatter
162
+
163
+ @staticmethod
164
+ def BaseHandler(std, level, filter=None):
165
+ # 错误流的handler warn及其以上
166
+ streamerrhandler = logging.StreamHandler(std)
167
+ if filter != None:
168
+ # 添加过滤器
169
+ streamerrhandler.addFilter(filter)
170
+ # 获取输出格式
171
+ streamerrhandler.setFormatter(MLogger.formatter())
172
+ # 设置级别
173
+ streamerrhandler.setLevel(level)
174
+ return streamerrhandler
175
+
176
+ @staticmethod
177
+ def BaseFileHandler(level, filename, filter=None, encoding='utf-8'):
178
+ fileHandler = logging.FileHandler(filename, encoding=encoding)
179
+ if filter != None:
180
+ fileHandler.addFilter(filter)
181
+ fileHandler.setFormatter(MLogger.formatter())
182
+ fileHandler.setLevel(level)
183
+ return fileHandler
184
+
185
+ # 错误流会输出WARN及以上的级别
186
+ @staticmethod
187
+ def streamErrHandlers():
188
+ return MLogger.BaseHandler(sys.stderr, logging.WARN)
189
+
190
+ @staticmethod
191
+ def streamHandlers():
192
+ return MLogger.BaseHandler(sys.stdout, logging.DEBUG)
193
+
194
+ # 输出流只会输出INFO 和 DEBUG 两个级别的数据
195
+ # https://yinzo.github.io/14610807170718.html 小坑
196
+ @staticmethod
197
+ def streamOutHandler():
198
+ filter_stdout = LogLevelFilter(levels=[logging.INFO, logging.DEBUG])
199
+ return MLogger.BaseHandler(sys.stdout, logging.DEBUG, filter_stdout)
200
+
201
+ # 文件流会将所有级别的日志写入mylog.log这个文件
202
+ @staticmethod
203
+ def fileHandler(filepath):
204
+ log_file_path = path.join(filepath, time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
205
+ return MLogger.BaseFileHandler(logging.DEBUG, log_file_path)
206
+
207
+ @staticmethod
208
+ def timeRotatingFileHandler(filepath, filter=None):
209
+ suffix = ""
210
+ if filter != None:
211
+ suffix = filter.logname
212
+ log_file_path = path.join(filepath, time.strftime('%Y%m%d', time.localtime(time.time())) + suffix + ".log")
213
+ hander = TimedRotatingFileHandler(log_file_path, when="D", interval=1, backupCount=30)
214
+ if filter != None:
215
+ # 添加过滤器
216
+ hander.addFilter(filter)
217
+ hander.setFormatter(MLogger.formatter())
218
+ hander.setLevel(logging.DEBUG)
219
+ return hander
220
+
221
+ @staticmethod
222
+ def RotatingFileHandler(filepath, filter=None, maxBytes=1024 * 1024 * 1024, backupCount=10):
223
+ suffix = ""
224
+ if filter != None:
225
+ suffix = filter.logname
226
+ log_file_path = path.join(filepath, time.strftime('%Y%m%d', time.localtime(time.time())) + suffix + ".log")
227
+ hander = RotatingFileHandler(log_file_path, maxBytes=maxBytes, backupCount=backupCount)
228
+ if filter != None:
229
+ # 添加过滤器
230
+ hander.addFilter(filter)
231
+ hander.setFormatter(MLogger.formatter())
232
+ hander.setLevel(logging.DEBUG)
233
+ return hander
234
+
235
+ """
236
+ 下面这些只会将对应级别的日志写入对应的文件
237
+ """
238
+
239
+ @staticmethod
240
+ def fileDebugHandler(filepath):
241
+ log_file_path = path.join(filepath,
242
+ "mydebuglog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
243
+ filter_debug = LogLevelFilter(level=logging.DEBUG)
244
+ return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_debug)
245
+
246
+ @staticmethod
247
+ def fileInfoHandler(filepath):
248
+ log_file_path = path.join(filepath,
249
+ "myinfolog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
250
+ filter_info = LogLevelFilter(level=logging.INFO)
251
+
252
+ return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_info)
253
+
254
+ @staticmethod
255
+ def fileWarnHandler(filepath):
256
+ log_file_path = path.join(filepath,
257
+ "mywarnlog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
258
+ filter_warn = LogLevelFilter(level=logging.WARN)
259
+
260
+ return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_warn)
261
+
262
+ @staticmethod
263
+ def fileErrorHandler(filepath):
264
+ log_file_path = path.join(filepath,
265
+ "myerrorlog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
266
+ filter_error = LogLevelFilter(level=logging.ERROR)
267
+
268
+ return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_error)
269
+
270
+ @staticmethod
271
+ def fileExceptionHandler(filepath):
272
+ log_file_path = path.join(filepath,
273
+ "myexceptionlog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
274
+ filter_exception = LogLevelFilter(level=logging.ERROR) # 会返回错误堆栈
275
+
276
+ return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_exception)
277
+
278
+ @staticmethod
279
+ def fileCriticalHandler(filepath):
280
+ log_file_path = path.join(filepath,
281
+ "mycriticallog_" + time.strftime('%Y%m%d', time.localtime(time.time())) + ".log")
282
+ filter_critical = LogLevelFilter(level=logging.CRITICAL)
283
+ return MLogger.BaseFileHandler(logging.DEBUG, log_file_path, filter_critical)
284
+
285
+ """
286
+ 下面是各种各样的logger 用于不同的输出
287
+ 比如你用errlogger就会只打印错误的logger 而不会打印输出信息的logger且不会写入文件
288
+ 我们可以自由组合我们的logger方便使用,只要定义出不同组合的logger就行了,我现在一般使用allloger
289
+ 记录下所有的信息
290
+ """
291
+
292
+ @staticmethod
293
+ def streamErrLogger(level=logging.DEBUG):
294
+ # 获取logger对象
295
+ logger = logging.getLogger("streamErrLogger")
296
+ # 设置logger获取的级别
297
+ logger.setLevel(level)
298
+ logger.handlers = []
299
+ # 为logger添加handler
300
+ logger.addHandler(MLogger.streamErrHandlers())
301
+ return logger
302
+
303
+ @staticmethod
304
+ def streamOutLogger(level=logging.DEBUG):
305
+ logger = logging.getLogger("streamOutLogger")
306
+ logger.setLevel(level)
307
+ logger.handlers = []
308
+ logger.addHandler(MLogger.streamOutHandler())
309
+ return logger
310
+
311
+ @staticmethod
312
+ def allLogger(filepath,level=logging.DEBUG):
313
+ # 获取all代表不管输出和文件都会有流产生
314
+ logger = logging.getLogger("all")
315
+ logger.setLevel(level)
316
+ logger.handlers = []
317
+ # http://www.aiuxian.com/article/p-483639.html
318
+ logger.addHandler(MLogger.streamOutHandler()) # 输出流
319
+ logger.addHandler(MLogger.streamErrHandlers()) # 错误流
320
+ # 这是所有的日志都会输出到这个文件
321
+ logger.addHandler(MLogger.fileHandler(filepath))
322
+ # 下面是各个级别的日志流都会输入到对应的文件中
323
+ logger.addHandler(MLogger.fileDebugHandler(filepath))
324
+ logger.addHandler(MLogger.fileInfoHandler(filepath))
325
+ logger.addHandler(MLogger.fileWarnHandler(filepath))
326
+ logger.addHandler(MLogger.fileErrorHandler(filepath))
327
+ logger.addHandler(MLogger.fileExceptionHandler(filepath))
328
+ logger.addHandler(MLogger.fileCriticalHandler(filepath))
329
+ return logger
330
+
331
+ @staticmethod
332
+ def multifile_logger(filepath,level=logging.DEBUG):
333
+ # 获取all代表不管输出和文件都会有流产生
334
+ logger = logging.getLogger("multifile")
335
+ logger.setLevel(level)
336
+ logger.handlers = []
337
+ # 下面是各个级别的日志流都会输入到对应的文件中
338
+ logger.addHandler(MLogger.fileDebugHandler(filepath))
339
+ logger.addHandler(MLogger.fileInfoHandler(filepath))
340
+ logger.addHandler(MLogger.fileWarnHandler(filepath))
341
+ logger.addHandler(MLogger.fileErrorHandler(filepath))
342
+ logger.addHandler(MLogger.fileExceptionHandler(filepath))
343
+ logger.addHandler(MLogger.fileCriticalHandler(filepath))
344
+ return logger
345
+
346
+ @staticmethod
347
+ def fileLogger(filepath,level=logging.DEBUG):
348
+ # 获取all代表不管输出和文件都会有流产生
349
+ logger = logging.getLogger("file")
350
+ logger.setLevel(level)
351
+ # 防止多次写入
352
+ logger.handlers = []
353
+ # http://www.aiuxian.com/article/p-483639.html
354
+ logger.addHandler(MLogger.streamOutHandler()) # 输出流
355
+ logger.addHandler(MLogger.streamErrHandlers()) # 错误流
356
+ # 这是所有的日志都会输出到这个文件
357
+ logger.addHandler(MLogger.fileHandler(filepath))
358
+ return logger
359
+
360
+ @staticmethod
361
+ def timeRotatingFileLogger(filepath, fileter,level=logging.DEBUG):
362
+ # 获取all代表不管输出和文件都会有流产生
363
+ logger = logging.getLogger("timerotatingfile")
364
+ logger.setLevel(level)
365
+ # 防止多次写入
366
+ logger.handlers = []
367
+ # http://www.aiuxian.com/article/p-483639.html
368
+ logger.addHandler(MLogger.streamOutHandler()) # 输出流
369
+ logger.addHandler(MLogger.streamErrHandlers()) # 错误流
370
+ if fileter:
371
+ logger.addHandler(MLogger.timeRotatingFileHandler(filepath, fileter))
372
+ # 这是所有的日志都会输出到这个文件
373
+ logger.addHandler(MLogger.timeRotatingFileHandler(filepath))
374
+ return logger
375
+
376
+ @staticmethod
377
+ def RotatingFileLogger(filepath, fileter, maxBytes=1024 * 1024 * 1024, backupCount=10,level=logging.DEBUG):
378
+ # 获取all代表不管输出和文件都会有流产生
379
+ logger = logging.getLogger("rotatingfile")
380
+ logger.setLevel(level)
381
+ # 防止多次写入
382
+ logger.handlers = []
383
+ # http://www.aiuxian.com/article/p-483639.html
384
+ logger.addHandler(MLogger.streamOutHandler()) # 输出流
385
+ logger.addHandler(MLogger.streamErrHandlers()) # 错误流
386
+ if fileter:
387
+ logger.addHandler(
388
+ MLogger.RotatingFileHandler(filepath, fileter, maxBytes=maxBytes, backupCount=backupCount))
389
+ # 这是所有的日志都会输出到这个文件
390
+ logger.addHandler(MLogger.RotatingFileHandler(filepath, maxBytes=maxBytes, backupCount=backupCount))
391
+ return logger
392
+
393
+ def streamLogger(self,level=logging.DEBUG):
394
+ # 全局对象个数有getLogger的参数决定
395
+ logger = logging.getLogger("streamLogger")
396
+ logger.setLevel(level)
397
+ # 防止多次打印
398
+ logger.handlers = []
399
+ logger.addHandler(MLogger.streamHandlers())
400
+ return logger
401
+
402
+ # def main():
403
+ #
404
+ # # 使用教程
405
+ # log_file_path = path.join(path.dirname(path.abspath(__file__)), 'logs')
406
+ # logger = MLogger(log_file_path).streamlogger
407
+ # logger.debug('debug message')
408
+ # logger.info('info message')
409
+ # logger.warning('warn message')
410
+ # logger.error('error message')
411
+ # logger.exception('exception message')
412
+ # logger.critical('critical message')
413
+ #
414
+ # main()